diff --git a/app/build.gradle b/app/build.gradle index 0ae369f..687b02b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -15,7 +15,6 @@ } compileSdkVersion 31 - buildToolsVersion "30.0.3" defaultConfig { applicationId "com.casic.xz.meterage" @@ -84,11 +83,13 @@ implementation 'top.zibin:Luban:1.1.8' //官方Json解析库 implementation 'com.google.code.gson:gson:2.9.0' + //阿里巴巴JSON库 + implementation 'com.alibaba.fastjson2:fastjson2:2.0.24' //Kotlin协程 implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.5.1' //MVVM+LiveData implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.5.1" - implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.0" + implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1" implementation "androidx.lifecycle:lifecycle-extensions:2.2.0" //返回值转换器 implementation 'com.jakewharton.retrofit:retrofit2-kotlin-coroutines-adapter:0.9.2' @@ -109,4 +110,8 @@ implementation 'com.github.barteksc:android-pdf-viewer:2.8.2' //绕过Android 11反射限制 implementation 'com.github.tiann:FreeReflection:3.1.0' + //单项/数字、二三级联动、日期/时间等滚轮选择器 + implementation 'com.github.gzu-liyujiang.AndroidPicker:WheelPicker:4.1.8' + //文件/目录选择器 + implementation 'com.github.gzu-liyujiang.AndroidPicker:FilePicker:4.1.1' } \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 0ae369f..687b02b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -15,7 +15,6 @@ } compileSdkVersion 31 - buildToolsVersion "30.0.3" defaultConfig { applicationId "com.casic.xz.meterage" @@ -84,11 +83,13 @@ implementation 'top.zibin:Luban:1.1.8' //官方Json解析库 implementation 'com.google.code.gson:gson:2.9.0' + //阿里巴巴JSON库 + implementation 'com.alibaba.fastjson2:fastjson2:2.0.24' //Kotlin协程 implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.5.1' //MVVM+LiveData implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.5.1" - implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.0" + implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1" implementation "androidx.lifecycle:lifecycle-extensions:2.2.0" //返回值转换器 implementation 'com.jakewharton.retrofit:retrofit2-kotlin-coroutines-adapter:0.9.2' @@ -109,4 +110,8 @@ implementation 'com.github.barteksc:android-pdf-viewer:2.8.2' //绕过Android 11反射限制 implementation 'com.github.tiann:FreeReflection:3.1.0' + //单项/数字、二三级联动、日期/时间等滚轮选择器 + implementation 'com.github.gzu-liyujiang.AndroidPicker:WheelPicker:4.1.8' + //文件/目录选择器 + implementation 'com.github.gzu-liyujiang.AndroidPicker:FilePicker:4.1.1' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 1ccc12b..0fba91b 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -60,6 +60,8 @@ + + diff --git a/app/build.gradle b/app/build.gradle index 0ae369f..687b02b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -15,7 +15,6 @@ } compileSdkVersion 31 - buildToolsVersion "30.0.3" defaultConfig { applicationId "com.casic.xz.meterage" @@ -84,11 +83,13 @@ implementation 'top.zibin:Luban:1.1.8' //官方Json解析库 implementation 'com.google.code.gson:gson:2.9.0' + //阿里巴巴JSON库 + implementation 'com.alibaba.fastjson2:fastjson2:2.0.24' //Kotlin协程 implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.5.1' //MVVM+LiveData implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.5.1" - implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.0" + implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1" implementation "androidx.lifecycle:lifecycle-extensions:2.2.0" //返回值转换器 implementation 'com.jakewharton.retrofit:retrofit2-kotlin-coroutines-adapter:0.9.2' @@ -109,4 +110,8 @@ implementation 'com.github.barteksc:android-pdf-viewer:2.8.2' //绕过Android 11反射限制 implementation 'com.github.tiann:FreeReflection:3.1.0' + //单项/数字、二三级联动、日期/时间等滚轮选择器 + implementation 'com.github.gzu-liyujiang.AndroidPicker:WheelPicker:4.1.8' + //文件/目录选择器 + implementation 'com.github.gzu-liyujiang.AndroidPicker:FilePicker:4.1.1' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 1ccc12b..0fba91b 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -60,6 +60,8 @@ + + diff --git a/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt b/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt new file mode 100644 index 0000000..21a71d8 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt @@ -0,0 +1,70 @@ +package com.casic.xz.meterage.adapter + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import com.casic.xz.meterage.R +import com.casic.xz.meterage.extensions.toChineseGrade +import com.casic.xz.meterage.model.CustomerListModel + +class SelectCustomerAdapter( + context: Context, private val dataRows: MutableList +) : RecyclerView.Adapter() { + + private var layoutInflater = LayoutInflater.from(context) + + //选择的位置 + private var selectedPosition = 0 + + //临时记录上次选择的位置 + private var temp = -1 + + override fun getItemCount(): Int = dataRows.size + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ItemViewHolder( + layoutInflater.inflate(R.layout.item_select_customer_lv, parent, false) + ) + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + //绑定数据 + val rowsBean = dataRows[position] + holder.agreementLevelView.text = rowsBean.grade.toChineseGrade() + holder.customerNameView.text = rowsBean.customerName + holder.scaleView.text = rowsBean.companySizeName + holder.overallView.text = "公司规模:${rowsBean.evaluationName}" + holder.fullAddressView.text = "公司地址:${rowsBean.fullAddress}" + + holder.itemView.isSelected = holder.layoutPosition == selectedPosition + holder.itemView.setOnClickListener { + itemCheckedListener?.onItemChecked(rowsBean) + + holder.itemView.isSelected = true + temp = selectedPosition + //设置新的位置 + selectedPosition = holder.layoutPosition + //更新旧位置 + notifyItemChanged(temp) + } + } + + inner class ItemViewHolder(view: View) : RecyclerView.ViewHolder(view) { + var agreementLevelView: TextView = view.findViewById(R.id.agreementLevelView) + var customerNameView: TextView = view.findViewById(R.id.customerNameView) + var scaleView: TextView = view.findViewById(R.id.scaleView) + var overallView: TextView = view.findViewById(R.id.overallView) + var fullAddressView: TextView = view.findViewById(R.id.fullAddressView) + } + + private var itemCheckedListener: OnItemCheckedListener? = null + + interface OnItemCheckedListener { + fun onItemChecked(item: CustomerListModel.DataModel.RowsModel) + } + + fun setOnCheckedListener(listener: OnItemCheckedListener?) { + itemCheckedListener = listener + } +} \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 0ae369f..687b02b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -15,7 +15,6 @@ } compileSdkVersion 31 - buildToolsVersion "30.0.3" defaultConfig { applicationId "com.casic.xz.meterage" @@ -84,11 +83,13 @@ implementation 'top.zibin:Luban:1.1.8' //官方Json解析库 implementation 'com.google.code.gson:gson:2.9.0' + //阿里巴巴JSON库 + implementation 'com.alibaba.fastjson2:fastjson2:2.0.24' //Kotlin协程 implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.5.1' //MVVM+LiveData implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.5.1" - implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.0" + implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1" implementation "androidx.lifecycle:lifecycle-extensions:2.2.0" //返回值转换器 implementation 'com.jakewharton.retrofit:retrofit2-kotlin-coroutines-adapter:0.9.2' @@ -109,4 +110,8 @@ implementation 'com.github.barteksc:android-pdf-viewer:2.8.2' //绕过Android 11反射限制 implementation 'com.github.tiann:FreeReflection:3.1.0' + //单项/数字、二三级联动、日期/时间等滚轮选择器 + implementation 'com.github.gzu-liyujiang.AndroidPicker:WheelPicker:4.1.8' + //文件/目录选择器 + implementation 'com.github.gzu-liyujiang.AndroidPicker:FilePicker:4.1.1' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 1ccc12b..0fba91b 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -60,6 +60,8 @@ + + diff --git a/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt b/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt new file mode 100644 index 0000000..21a71d8 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt @@ -0,0 +1,70 @@ +package com.casic.xz.meterage.adapter + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import com.casic.xz.meterage.R +import com.casic.xz.meterage.extensions.toChineseGrade +import com.casic.xz.meterage.model.CustomerListModel + +class SelectCustomerAdapter( + context: Context, private val dataRows: MutableList +) : RecyclerView.Adapter() { + + private var layoutInflater = LayoutInflater.from(context) + + //选择的位置 + private var selectedPosition = 0 + + //临时记录上次选择的位置 + private var temp = -1 + + override fun getItemCount(): Int = dataRows.size + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ItemViewHolder( + layoutInflater.inflate(R.layout.item_select_customer_lv, parent, false) + ) + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + //绑定数据 + val rowsBean = dataRows[position] + holder.agreementLevelView.text = rowsBean.grade.toChineseGrade() + holder.customerNameView.text = rowsBean.customerName + holder.scaleView.text = rowsBean.companySizeName + holder.overallView.text = "公司规模:${rowsBean.evaluationName}" + holder.fullAddressView.text = "公司地址:${rowsBean.fullAddress}" + + holder.itemView.isSelected = holder.layoutPosition == selectedPosition + holder.itemView.setOnClickListener { + itemCheckedListener?.onItemChecked(rowsBean) + + holder.itemView.isSelected = true + temp = selectedPosition + //设置新的位置 + selectedPosition = holder.layoutPosition + //更新旧位置 + notifyItemChanged(temp) + } + } + + inner class ItemViewHolder(view: View) : RecyclerView.ViewHolder(view) { + var agreementLevelView: TextView = view.findViewById(R.id.agreementLevelView) + var customerNameView: TextView = view.findViewById(R.id.customerNameView) + var scaleView: TextView = view.findViewById(R.id.scaleView) + var overallView: TextView = view.findViewById(R.id.overallView) + var fullAddressView: TextView = view.findViewById(R.id.fullAddressView) + } + + private var itemCheckedListener: OnItemCheckedListener? = null + + interface OnItemCheckedListener { + fun onItemChecked(item: CustomerListModel.DataModel.RowsModel) + } + + fun setOnCheckedListener(listener: OnItemCheckedListener?) { + itemCheckedListener = listener + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt b/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt new file mode 100644 index 0000000..c29461e --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt @@ -0,0 +1,68 @@ +package com.casic.xz.meterage.adapter + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import com.casic.xz.meterage.R +import com.casic.xz.meterage.model.SampleListModel + +class SelectSampleAdapter( + context: Context, private val dataRows: MutableList +) : RecyclerView.Adapter() { + + private var layoutInflater = LayoutInflater.from(context) + private var multipleSelected = mutableSetOf() + private var sampleModes = ArrayList() + + override fun getItemCount(): Int = dataRows.size + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ItemViewHolder( + layoutInflater.inflate(R.layout.item_select_sample_lv, parent, false) + ) + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + //绑定数据 + val rowsBean = dataRows[position] + holder.sampleNameView.text = "${rowsBean.sampleName}【${rowsBean.sampleModel}】" + holder.manufacturingCodeView.text = "出厂编号:${rowsBean.manufacturingNo}" + holder.sampleCodeView.text = "样品编号:${rowsBean.sampleNo}" + holder.validDateView.text = "有效期至:${rowsBean.validDeadline}" + + holder.checkImageView.isSelected = multipleSelected.contains(position) + holder.itemView.setOnClickListener { + if (multipleSelected.contains(position)) { + multipleSelected.remove(position) + sampleModes.remove(dataRows[position]) + holder.checkImageView.isSelected = false + } else { + multipleSelected.add(position) + sampleModes.add(dataRows[position]) + holder.checkImageView.isSelected = true + } + + itemCheckedListener?.onItemChecked(sampleModes) + } + } + + inner class ItemViewHolder(view: View) : RecyclerView.ViewHolder(view) { + var sampleNameView: TextView = view.findViewById(R.id.sampleNameView) + var manufacturingCodeView: TextView = view.findViewById(R.id.manufacturingCodeView) + var sampleCodeView: TextView = view.findViewById(R.id.sampleCodeView) + var validDateView: TextView = view.findViewById(R.id.validDateView) + var checkImageView: ImageView = view.findViewById(R.id.checkImageView) + } + + private var itemCheckedListener: OnItemCheckedListener? = null + + interface OnItemCheckedListener { + fun onItemChecked(items: ArrayList) + } + + fun setOnCheckedListener(listener: OnItemCheckedListener?) { + itemCheckedListener = listener + } +} \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 0ae369f..687b02b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -15,7 +15,6 @@ } compileSdkVersion 31 - buildToolsVersion "30.0.3" defaultConfig { applicationId "com.casic.xz.meterage" @@ -84,11 +83,13 @@ implementation 'top.zibin:Luban:1.1.8' //官方Json解析库 implementation 'com.google.code.gson:gson:2.9.0' + //阿里巴巴JSON库 + implementation 'com.alibaba.fastjson2:fastjson2:2.0.24' //Kotlin协程 implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.5.1' //MVVM+LiveData implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.5.1" - implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.0" + implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1" implementation "androidx.lifecycle:lifecycle-extensions:2.2.0" //返回值转换器 implementation 'com.jakewharton.retrofit:retrofit2-kotlin-coroutines-adapter:0.9.2' @@ -109,4 +110,8 @@ implementation 'com.github.barteksc:android-pdf-viewer:2.8.2' //绕过Android 11反射限制 implementation 'com.github.tiann:FreeReflection:3.1.0' + //单项/数字、二三级联动、日期/时间等滚轮选择器 + implementation 'com.github.gzu-liyujiang.AndroidPicker:WheelPicker:4.1.8' + //文件/目录选择器 + implementation 'com.github.gzu-liyujiang.AndroidPicker:FilePicker:4.1.1' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 1ccc12b..0fba91b 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -60,6 +60,8 @@ + + diff --git a/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt b/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt new file mode 100644 index 0000000..21a71d8 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt @@ -0,0 +1,70 @@ +package com.casic.xz.meterage.adapter + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import com.casic.xz.meterage.R +import com.casic.xz.meterage.extensions.toChineseGrade +import com.casic.xz.meterage.model.CustomerListModel + +class SelectCustomerAdapter( + context: Context, private val dataRows: MutableList +) : RecyclerView.Adapter() { + + private var layoutInflater = LayoutInflater.from(context) + + //选择的位置 + private var selectedPosition = 0 + + //临时记录上次选择的位置 + private var temp = -1 + + override fun getItemCount(): Int = dataRows.size + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ItemViewHolder( + layoutInflater.inflate(R.layout.item_select_customer_lv, parent, false) + ) + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + //绑定数据 + val rowsBean = dataRows[position] + holder.agreementLevelView.text = rowsBean.grade.toChineseGrade() + holder.customerNameView.text = rowsBean.customerName + holder.scaleView.text = rowsBean.companySizeName + holder.overallView.text = "公司规模:${rowsBean.evaluationName}" + holder.fullAddressView.text = "公司地址:${rowsBean.fullAddress}" + + holder.itemView.isSelected = holder.layoutPosition == selectedPosition + holder.itemView.setOnClickListener { + itemCheckedListener?.onItemChecked(rowsBean) + + holder.itemView.isSelected = true + temp = selectedPosition + //设置新的位置 + selectedPosition = holder.layoutPosition + //更新旧位置 + notifyItemChanged(temp) + } + } + + inner class ItemViewHolder(view: View) : RecyclerView.ViewHolder(view) { + var agreementLevelView: TextView = view.findViewById(R.id.agreementLevelView) + var customerNameView: TextView = view.findViewById(R.id.customerNameView) + var scaleView: TextView = view.findViewById(R.id.scaleView) + var overallView: TextView = view.findViewById(R.id.overallView) + var fullAddressView: TextView = view.findViewById(R.id.fullAddressView) + } + + private var itemCheckedListener: OnItemCheckedListener? = null + + interface OnItemCheckedListener { + fun onItemChecked(item: CustomerListModel.DataModel.RowsModel) + } + + fun setOnCheckedListener(listener: OnItemCheckedListener?) { + itemCheckedListener = listener + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt b/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt new file mode 100644 index 0000000..c29461e --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt @@ -0,0 +1,68 @@ +package com.casic.xz.meterage.adapter + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import com.casic.xz.meterage.R +import com.casic.xz.meterage.model.SampleListModel + +class SelectSampleAdapter( + context: Context, private val dataRows: MutableList +) : RecyclerView.Adapter() { + + private var layoutInflater = LayoutInflater.from(context) + private var multipleSelected = mutableSetOf() + private var sampleModes = ArrayList() + + override fun getItemCount(): Int = dataRows.size + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ItemViewHolder( + layoutInflater.inflate(R.layout.item_select_sample_lv, parent, false) + ) + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + //绑定数据 + val rowsBean = dataRows[position] + holder.sampleNameView.text = "${rowsBean.sampleName}【${rowsBean.sampleModel}】" + holder.manufacturingCodeView.text = "出厂编号:${rowsBean.manufacturingNo}" + holder.sampleCodeView.text = "样品编号:${rowsBean.sampleNo}" + holder.validDateView.text = "有效期至:${rowsBean.validDeadline}" + + holder.checkImageView.isSelected = multipleSelected.contains(position) + holder.itemView.setOnClickListener { + if (multipleSelected.contains(position)) { + multipleSelected.remove(position) + sampleModes.remove(dataRows[position]) + holder.checkImageView.isSelected = false + } else { + multipleSelected.add(position) + sampleModes.add(dataRows[position]) + holder.checkImageView.isSelected = true + } + + itemCheckedListener?.onItemChecked(sampleModes) + } + } + + inner class ItemViewHolder(view: View) : RecyclerView.ViewHolder(view) { + var sampleNameView: TextView = view.findViewById(R.id.sampleNameView) + var manufacturingCodeView: TextView = view.findViewById(R.id.manufacturingCodeView) + var sampleCodeView: TextView = view.findViewById(R.id.sampleCodeView) + var validDateView: TextView = view.findViewById(R.id.validDateView) + var checkImageView: ImageView = view.findViewById(R.id.checkImageView) + } + + private var itemCheckedListener: OnItemCheckedListener? = null + + interface OnItemCheckedListener { + fun onItemChecked(items: ArrayList) + } + + fun setOnCheckedListener(listener: OnItemCheckedListener?) { + itemCheckedListener = listener + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/callback/DateSelectedCallback.kt b/app/src/main/java/com/casic/xz/meterage/callback/DateSelectedCallback.kt new file mode 100644 index 0000000..8196110 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/callback/DateSelectedCallback.kt @@ -0,0 +1,5 @@ +package com.casic.xz.meterage.callback + +interface DateSelectedCallback { + fun onDateSelected(date: String) +} \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 0ae369f..687b02b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -15,7 +15,6 @@ } compileSdkVersion 31 - buildToolsVersion "30.0.3" defaultConfig { applicationId "com.casic.xz.meterage" @@ -84,11 +83,13 @@ implementation 'top.zibin:Luban:1.1.8' //官方Json解析库 implementation 'com.google.code.gson:gson:2.9.0' + //阿里巴巴JSON库 + implementation 'com.alibaba.fastjson2:fastjson2:2.0.24' //Kotlin协程 implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.5.1' //MVVM+LiveData implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.5.1" - implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.0" + implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1" implementation "androidx.lifecycle:lifecycle-extensions:2.2.0" //返回值转换器 implementation 'com.jakewharton.retrofit:retrofit2-kotlin-coroutines-adapter:0.9.2' @@ -109,4 +110,8 @@ implementation 'com.github.barteksc:android-pdf-viewer:2.8.2' //绕过Android 11反射限制 implementation 'com.github.tiann:FreeReflection:3.1.0' + //单项/数字、二三级联动、日期/时间等滚轮选择器 + implementation 'com.github.gzu-liyujiang.AndroidPicker:WheelPicker:4.1.8' + //文件/目录选择器 + implementation 'com.github.gzu-liyujiang.AndroidPicker:FilePicker:4.1.1' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 1ccc12b..0fba91b 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -60,6 +60,8 @@ + + diff --git a/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt b/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt new file mode 100644 index 0000000..21a71d8 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt @@ -0,0 +1,70 @@ +package com.casic.xz.meterage.adapter + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import com.casic.xz.meterage.R +import com.casic.xz.meterage.extensions.toChineseGrade +import com.casic.xz.meterage.model.CustomerListModel + +class SelectCustomerAdapter( + context: Context, private val dataRows: MutableList +) : RecyclerView.Adapter() { + + private var layoutInflater = LayoutInflater.from(context) + + //选择的位置 + private var selectedPosition = 0 + + //临时记录上次选择的位置 + private var temp = -1 + + override fun getItemCount(): Int = dataRows.size + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ItemViewHolder( + layoutInflater.inflate(R.layout.item_select_customer_lv, parent, false) + ) + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + //绑定数据 + val rowsBean = dataRows[position] + holder.agreementLevelView.text = rowsBean.grade.toChineseGrade() + holder.customerNameView.text = rowsBean.customerName + holder.scaleView.text = rowsBean.companySizeName + holder.overallView.text = "公司规模:${rowsBean.evaluationName}" + holder.fullAddressView.text = "公司地址:${rowsBean.fullAddress}" + + holder.itemView.isSelected = holder.layoutPosition == selectedPosition + holder.itemView.setOnClickListener { + itemCheckedListener?.onItemChecked(rowsBean) + + holder.itemView.isSelected = true + temp = selectedPosition + //设置新的位置 + selectedPosition = holder.layoutPosition + //更新旧位置 + notifyItemChanged(temp) + } + } + + inner class ItemViewHolder(view: View) : RecyclerView.ViewHolder(view) { + var agreementLevelView: TextView = view.findViewById(R.id.agreementLevelView) + var customerNameView: TextView = view.findViewById(R.id.customerNameView) + var scaleView: TextView = view.findViewById(R.id.scaleView) + var overallView: TextView = view.findViewById(R.id.overallView) + var fullAddressView: TextView = view.findViewById(R.id.fullAddressView) + } + + private var itemCheckedListener: OnItemCheckedListener? = null + + interface OnItemCheckedListener { + fun onItemChecked(item: CustomerListModel.DataModel.RowsModel) + } + + fun setOnCheckedListener(listener: OnItemCheckedListener?) { + itemCheckedListener = listener + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt b/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt new file mode 100644 index 0000000..c29461e --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt @@ -0,0 +1,68 @@ +package com.casic.xz.meterage.adapter + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import com.casic.xz.meterage.R +import com.casic.xz.meterage.model.SampleListModel + +class SelectSampleAdapter( + context: Context, private val dataRows: MutableList +) : RecyclerView.Adapter() { + + private var layoutInflater = LayoutInflater.from(context) + private var multipleSelected = mutableSetOf() + private var sampleModes = ArrayList() + + override fun getItemCount(): Int = dataRows.size + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ItemViewHolder( + layoutInflater.inflate(R.layout.item_select_sample_lv, parent, false) + ) + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + //绑定数据 + val rowsBean = dataRows[position] + holder.sampleNameView.text = "${rowsBean.sampleName}【${rowsBean.sampleModel}】" + holder.manufacturingCodeView.text = "出厂编号:${rowsBean.manufacturingNo}" + holder.sampleCodeView.text = "样品编号:${rowsBean.sampleNo}" + holder.validDateView.text = "有效期至:${rowsBean.validDeadline}" + + holder.checkImageView.isSelected = multipleSelected.contains(position) + holder.itemView.setOnClickListener { + if (multipleSelected.contains(position)) { + multipleSelected.remove(position) + sampleModes.remove(dataRows[position]) + holder.checkImageView.isSelected = false + } else { + multipleSelected.add(position) + sampleModes.add(dataRows[position]) + holder.checkImageView.isSelected = true + } + + itemCheckedListener?.onItemChecked(sampleModes) + } + } + + inner class ItemViewHolder(view: View) : RecyclerView.ViewHolder(view) { + var sampleNameView: TextView = view.findViewById(R.id.sampleNameView) + var manufacturingCodeView: TextView = view.findViewById(R.id.manufacturingCodeView) + var sampleCodeView: TextView = view.findViewById(R.id.sampleCodeView) + var validDateView: TextView = view.findViewById(R.id.validDateView) + var checkImageView: ImageView = view.findViewById(R.id.checkImageView) + } + + private var itemCheckedListener: OnItemCheckedListener? = null + + interface OnItemCheckedListener { + fun onItemChecked(items: ArrayList) + } + + fun setOnCheckedListener(listener: OnItemCheckedListener?) { + itemCheckedListener = listener + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/callback/DateSelectedCallback.kt b/app/src/main/java/com/casic/xz/meterage/callback/DateSelectedCallback.kt new file mode 100644 index 0000000..8196110 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/callback/DateSelectedCallback.kt @@ -0,0 +1,5 @@ +package com.casic.xz.meterage.callback + +interface DateSelectedCallback { + fun onDateSelected(date: String) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/Activity.kt b/app/src/main/java/com/casic/xz/meterage/extensions/Activity.kt new file mode 100644 index 0000000..e112d1c --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/extensions/Activity.kt @@ -0,0 +1,33 @@ +package com.casic.xz.meterage.extensions + +import android.app.Activity +import com.casic.xz.meterage.R +import com.casic.xz.meterage.callback.DateSelectedCallback +import com.github.gzuliyujiang.wheelpicker.DatePicker +import com.github.gzuliyujiang.wheelpicker.annotation.DateMode +import com.github.gzuliyujiang.wheelpicker.entity.DateEntity +import com.pengxh.kt.lite.extensions.convertColor +import com.pengxh.kt.lite.extensions.sp2px + +fun Activity.showDatePicker(callback: DateSelectedCallback) { + val datePicker = DatePicker(this) + + val layout = datePicker.wheelLayout + layout.setDateMode(DateMode.YEAR_MONTH_DAY) + layout.setDateLabel("年", "月", "日"); + layout.setTextSize(14f.sp2px(this).toFloat()) + layout.setSelectedTextSize(16f.sp2px(this).toFloat()) + layout.setSelectedTextColor(R.color.themeColor.convertColor(this)) + layout.setSelectedTextBold(true) + layout.setResetWhenLinkage(false) + layout.setRange( + DateEntity.today(), + DateEntity.target(2050, 12, 31), + DateEntity.today() + ) + + datePicker.setOnDatePickedListener { year, month, day -> + callback.onDateSelected(String.format("%s-%s-%s", year, month, day)) + } + datePicker.show() +} \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 0ae369f..687b02b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -15,7 +15,6 @@ } compileSdkVersion 31 - buildToolsVersion "30.0.3" defaultConfig { applicationId "com.casic.xz.meterage" @@ -84,11 +83,13 @@ implementation 'top.zibin:Luban:1.1.8' //官方Json解析库 implementation 'com.google.code.gson:gson:2.9.0' + //阿里巴巴JSON库 + implementation 'com.alibaba.fastjson2:fastjson2:2.0.24' //Kotlin协程 implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.5.1' //MVVM+LiveData implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.5.1" - implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.0" + implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1" implementation "androidx.lifecycle:lifecycle-extensions:2.2.0" //返回值转换器 implementation 'com.jakewharton.retrofit:retrofit2-kotlin-coroutines-adapter:0.9.2' @@ -109,4 +110,8 @@ implementation 'com.github.barteksc:android-pdf-viewer:2.8.2' //绕过Android 11反射限制 implementation 'com.github.tiann:FreeReflection:3.1.0' + //单项/数字、二三级联动、日期/时间等滚轮选择器 + implementation 'com.github.gzu-liyujiang.AndroidPicker:WheelPicker:4.1.8' + //文件/目录选择器 + implementation 'com.github.gzu-liyujiang.AndroidPicker:FilePicker:4.1.1' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 1ccc12b..0fba91b 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -60,6 +60,8 @@ + + diff --git a/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt b/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt new file mode 100644 index 0000000..21a71d8 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt @@ -0,0 +1,70 @@ +package com.casic.xz.meterage.adapter + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import com.casic.xz.meterage.R +import com.casic.xz.meterage.extensions.toChineseGrade +import com.casic.xz.meterage.model.CustomerListModel + +class SelectCustomerAdapter( + context: Context, private val dataRows: MutableList +) : RecyclerView.Adapter() { + + private var layoutInflater = LayoutInflater.from(context) + + //选择的位置 + private var selectedPosition = 0 + + //临时记录上次选择的位置 + private var temp = -1 + + override fun getItemCount(): Int = dataRows.size + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ItemViewHolder( + layoutInflater.inflate(R.layout.item_select_customer_lv, parent, false) + ) + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + //绑定数据 + val rowsBean = dataRows[position] + holder.agreementLevelView.text = rowsBean.grade.toChineseGrade() + holder.customerNameView.text = rowsBean.customerName + holder.scaleView.text = rowsBean.companySizeName + holder.overallView.text = "公司规模:${rowsBean.evaluationName}" + holder.fullAddressView.text = "公司地址:${rowsBean.fullAddress}" + + holder.itemView.isSelected = holder.layoutPosition == selectedPosition + holder.itemView.setOnClickListener { + itemCheckedListener?.onItemChecked(rowsBean) + + holder.itemView.isSelected = true + temp = selectedPosition + //设置新的位置 + selectedPosition = holder.layoutPosition + //更新旧位置 + notifyItemChanged(temp) + } + } + + inner class ItemViewHolder(view: View) : RecyclerView.ViewHolder(view) { + var agreementLevelView: TextView = view.findViewById(R.id.agreementLevelView) + var customerNameView: TextView = view.findViewById(R.id.customerNameView) + var scaleView: TextView = view.findViewById(R.id.scaleView) + var overallView: TextView = view.findViewById(R.id.overallView) + var fullAddressView: TextView = view.findViewById(R.id.fullAddressView) + } + + private var itemCheckedListener: OnItemCheckedListener? = null + + interface OnItemCheckedListener { + fun onItemChecked(item: CustomerListModel.DataModel.RowsModel) + } + + fun setOnCheckedListener(listener: OnItemCheckedListener?) { + itemCheckedListener = listener + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt b/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt new file mode 100644 index 0000000..c29461e --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt @@ -0,0 +1,68 @@ +package com.casic.xz.meterage.adapter + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import com.casic.xz.meterage.R +import com.casic.xz.meterage.model.SampleListModel + +class SelectSampleAdapter( + context: Context, private val dataRows: MutableList +) : RecyclerView.Adapter() { + + private var layoutInflater = LayoutInflater.from(context) + private var multipleSelected = mutableSetOf() + private var sampleModes = ArrayList() + + override fun getItemCount(): Int = dataRows.size + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ItemViewHolder( + layoutInflater.inflate(R.layout.item_select_sample_lv, parent, false) + ) + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + //绑定数据 + val rowsBean = dataRows[position] + holder.sampleNameView.text = "${rowsBean.sampleName}【${rowsBean.sampleModel}】" + holder.manufacturingCodeView.text = "出厂编号:${rowsBean.manufacturingNo}" + holder.sampleCodeView.text = "样品编号:${rowsBean.sampleNo}" + holder.validDateView.text = "有效期至:${rowsBean.validDeadline}" + + holder.checkImageView.isSelected = multipleSelected.contains(position) + holder.itemView.setOnClickListener { + if (multipleSelected.contains(position)) { + multipleSelected.remove(position) + sampleModes.remove(dataRows[position]) + holder.checkImageView.isSelected = false + } else { + multipleSelected.add(position) + sampleModes.add(dataRows[position]) + holder.checkImageView.isSelected = true + } + + itemCheckedListener?.onItemChecked(sampleModes) + } + } + + inner class ItemViewHolder(view: View) : RecyclerView.ViewHolder(view) { + var sampleNameView: TextView = view.findViewById(R.id.sampleNameView) + var manufacturingCodeView: TextView = view.findViewById(R.id.manufacturingCodeView) + var sampleCodeView: TextView = view.findViewById(R.id.sampleCodeView) + var validDateView: TextView = view.findViewById(R.id.validDateView) + var checkImageView: ImageView = view.findViewById(R.id.checkImageView) + } + + private var itemCheckedListener: OnItemCheckedListener? = null + + interface OnItemCheckedListener { + fun onItemChecked(items: ArrayList) + } + + fun setOnCheckedListener(listener: OnItemCheckedListener?) { + itemCheckedListener = listener + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/callback/DateSelectedCallback.kt b/app/src/main/java/com/casic/xz/meterage/callback/DateSelectedCallback.kt new file mode 100644 index 0000000..8196110 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/callback/DateSelectedCallback.kt @@ -0,0 +1,5 @@ +package com.casic.xz.meterage.callback + +interface DateSelectedCallback { + fun onDateSelected(date: String) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/Activity.kt b/app/src/main/java/com/casic/xz/meterage/extensions/Activity.kt new file mode 100644 index 0000000..e112d1c --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/extensions/Activity.kt @@ -0,0 +1,33 @@ +package com.casic.xz.meterage.extensions + +import android.app.Activity +import com.casic.xz.meterage.R +import com.casic.xz.meterage.callback.DateSelectedCallback +import com.github.gzuliyujiang.wheelpicker.DatePicker +import com.github.gzuliyujiang.wheelpicker.annotation.DateMode +import com.github.gzuliyujiang.wheelpicker.entity.DateEntity +import com.pengxh.kt.lite.extensions.convertColor +import com.pengxh.kt.lite.extensions.sp2px + +fun Activity.showDatePicker(callback: DateSelectedCallback) { + val datePicker = DatePicker(this) + + val layout = datePicker.wheelLayout + layout.setDateMode(DateMode.YEAR_MONTH_DAY) + layout.setDateLabel("年", "月", "日"); + layout.setTextSize(14f.sp2px(this).toFloat()) + layout.setSelectedTextSize(16f.sp2px(this).toFloat()) + layout.setSelectedTextColor(R.color.themeColor.convertColor(this)) + layout.setSelectedTextBold(true) + layout.setResetWhenLinkage(false) + layout.setRange( + DateEntity.today(), + DateEntity.target(2050, 12, 31), + DateEntity.today() + ) + + datePicker.setOnDatePickedListener { year, month, day -> + callback.onDateSelected(String.format("%s-%s-%s", year, month, day)) + } + datePicker.show() +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt b/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt index 016ebcb..cf6bf49 100644 --- a/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt +++ b/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt @@ -4,7 +4,7 @@ * ArrayList扩展方法 */ -//将图片集合格式化成满足上传格式的数据 +//将集合格式化成满足上传格式的数据 fun ArrayList.reformat(): String { if (this.isEmpty()) return "" val builder = StringBuilder() diff --git a/app/build.gradle b/app/build.gradle index 0ae369f..687b02b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -15,7 +15,6 @@ } compileSdkVersion 31 - buildToolsVersion "30.0.3" defaultConfig { applicationId "com.casic.xz.meterage" @@ -84,11 +83,13 @@ implementation 'top.zibin:Luban:1.1.8' //官方Json解析库 implementation 'com.google.code.gson:gson:2.9.0' + //阿里巴巴JSON库 + implementation 'com.alibaba.fastjson2:fastjson2:2.0.24' //Kotlin协程 implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.5.1' //MVVM+LiveData implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.5.1" - implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.0" + implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1" implementation "androidx.lifecycle:lifecycle-extensions:2.2.0" //返回值转换器 implementation 'com.jakewharton.retrofit:retrofit2-kotlin-coroutines-adapter:0.9.2' @@ -109,4 +110,8 @@ implementation 'com.github.barteksc:android-pdf-viewer:2.8.2' //绕过Android 11反射限制 implementation 'com.github.tiann:FreeReflection:3.1.0' + //单项/数字、二三级联动、日期/时间等滚轮选择器 + implementation 'com.github.gzu-liyujiang.AndroidPicker:WheelPicker:4.1.8' + //文件/目录选择器 + implementation 'com.github.gzu-liyujiang.AndroidPicker:FilePicker:4.1.1' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 1ccc12b..0fba91b 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -60,6 +60,8 @@ + + diff --git a/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt b/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt new file mode 100644 index 0000000..21a71d8 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt @@ -0,0 +1,70 @@ +package com.casic.xz.meterage.adapter + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import com.casic.xz.meterage.R +import com.casic.xz.meterage.extensions.toChineseGrade +import com.casic.xz.meterage.model.CustomerListModel + +class SelectCustomerAdapter( + context: Context, private val dataRows: MutableList +) : RecyclerView.Adapter() { + + private var layoutInflater = LayoutInflater.from(context) + + //选择的位置 + private var selectedPosition = 0 + + //临时记录上次选择的位置 + private var temp = -1 + + override fun getItemCount(): Int = dataRows.size + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ItemViewHolder( + layoutInflater.inflate(R.layout.item_select_customer_lv, parent, false) + ) + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + //绑定数据 + val rowsBean = dataRows[position] + holder.agreementLevelView.text = rowsBean.grade.toChineseGrade() + holder.customerNameView.text = rowsBean.customerName + holder.scaleView.text = rowsBean.companySizeName + holder.overallView.text = "公司规模:${rowsBean.evaluationName}" + holder.fullAddressView.text = "公司地址:${rowsBean.fullAddress}" + + holder.itemView.isSelected = holder.layoutPosition == selectedPosition + holder.itemView.setOnClickListener { + itemCheckedListener?.onItemChecked(rowsBean) + + holder.itemView.isSelected = true + temp = selectedPosition + //设置新的位置 + selectedPosition = holder.layoutPosition + //更新旧位置 + notifyItemChanged(temp) + } + } + + inner class ItemViewHolder(view: View) : RecyclerView.ViewHolder(view) { + var agreementLevelView: TextView = view.findViewById(R.id.agreementLevelView) + var customerNameView: TextView = view.findViewById(R.id.customerNameView) + var scaleView: TextView = view.findViewById(R.id.scaleView) + var overallView: TextView = view.findViewById(R.id.overallView) + var fullAddressView: TextView = view.findViewById(R.id.fullAddressView) + } + + private var itemCheckedListener: OnItemCheckedListener? = null + + interface OnItemCheckedListener { + fun onItemChecked(item: CustomerListModel.DataModel.RowsModel) + } + + fun setOnCheckedListener(listener: OnItemCheckedListener?) { + itemCheckedListener = listener + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt b/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt new file mode 100644 index 0000000..c29461e --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt @@ -0,0 +1,68 @@ +package com.casic.xz.meterage.adapter + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import com.casic.xz.meterage.R +import com.casic.xz.meterage.model.SampleListModel + +class SelectSampleAdapter( + context: Context, private val dataRows: MutableList +) : RecyclerView.Adapter() { + + private var layoutInflater = LayoutInflater.from(context) + private var multipleSelected = mutableSetOf() + private var sampleModes = ArrayList() + + override fun getItemCount(): Int = dataRows.size + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ItemViewHolder( + layoutInflater.inflate(R.layout.item_select_sample_lv, parent, false) + ) + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + //绑定数据 + val rowsBean = dataRows[position] + holder.sampleNameView.text = "${rowsBean.sampleName}【${rowsBean.sampleModel}】" + holder.manufacturingCodeView.text = "出厂编号:${rowsBean.manufacturingNo}" + holder.sampleCodeView.text = "样品编号:${rowsBean.sampleNo}" + holder.validDateView.text = "有效期至:${rowsBean.validDeadline}" + + holder.checkImageView.isSelected = multipleSelected.contains(position) + holder.itemView.setOnClickListener { + if (multipleSelected.contains(position)) { + multipleSelected.remove(position) + sampleModes.remove(dataRows[position]) + holder.checkImageView.isSelected = false + } else { + multipleSelected.add(position) + sampleModes.add(dataRows[position]) + holder.checkImageView.isSelected = true + } + + itemCheckedListener?.onItemChecked(sampleModes) + } + } + + inner class ItemViewHolder(view: View) : RecyclerView.ViewHolder(view) { + var sampleNameView: TextView = view.findViewById(R.id.sampleNameView) + var manufacturingCodeView: TextView = view.findViewById(R.id.manufacturingCodeView) + var sampleCodeView: TextView = view.findViewById(R.id.sampleCodeView) + var validDateView: TextView = view.findViewById(R.id.validDateView) + var checkImageView: ImageView = view.findViewById(R.id.checkImageView) + } + + private var itemCheckedListener: OnItemCheckedListener? = null + + interface OnItemCheckedListener { + fun onItemChecked(items: ArrayList) + } + + fun setOnCheckedListener(listener: OnItemCheckedListener?) { + itemCheckedListener = listener + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/callback/DateSelectedCallback.kt b/app/src/main/java/com/casic/xz/meterage/callback/DateSelectedCallback.kt new file mode 100644 index 0000000..8196110 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/callback/DateSelectedCallback.kt @@ -0,0 +1,5 @@ +package com.casic.xz.meterage.callback + +interface DateSelectedCallback { + fun onDateSelected(date: String) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/Activity.kt b/app/src/main/java/com/casic/xz/meterage/extensions/Activity.kt new file mode 100644 index 0000000..e112d1c --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/extensions/Activity.kt @@ -0,0 +1,33 @@ +package com.casic.xz.meterage.extensions + +import android.app.Activity +import com.casic.xz.meterage.R +import com.casic.xz.meterage.callback.DateSelectedCallback +import com.github.gzuliyujiang.wheelpicker.DatePicker +import com.github.gzuliyujiang.wheelpicker.annotation.DateMode +import com.github.gzuliyujiang.wheelpicker.entity.DateEntity +import com.pengxh.kt.lite.extensions.convertColor +import com.pengxh.kt.lite.extensions.sp2px + +fun Activity.showDatePicker(callback: DateSelectedCallback) { + val datePicker = DatePicker(this) + + val layout = datePicker.wheelLayout + layout.setDateMode(DateMode.YEAR_MONTH_DAY) + layout.setDateLabel("年", "月", "日"); + layout.setTextSize(14f.sp2px(this).toFloat()) + layout.setSelectedTextSize(16f.sp2px(this).toFloat()) + layout.setSelectedTextColor(R.color.themeColor.convertColor(this)) + layout.setSelectedTextBold(true) + layout.setResetWhenLinkage(false) + layout.setRange( + DateEntity.today(), + DateEntity.target(2050, 12, 31), + DateEntity.today() + ) + + datePicker.setOnDatePickedListener { year, month, day -> + callback.onDateSelected(String.format("%s-%s-%s", year, month, day)) + } + datePicker.show() +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt b/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt index 016ebcb..cf6bf49 100644 --- a/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt +++ b/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt @@ -4,7 +4,7 @@ * ArrayList扩展方法 */ -//将图片集合格式化成满足上传格式的数据 +//将集合格式化成满足上传格式的数据 fun ArrayList.reformat(): String { if (this.isEmpty()) return "" val builder = StringBuilder() diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt b/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt index 7c57643..aa9b92b 100644 --- a/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt +++ b/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt @@ -1,7 +1,6 @@ package com.casic.xz.meterage.extensions import android.content.Context -import android.util.Log import android.view.ViewGroup import com.casic.xz.meterage.base.BaseApplication import com.pengxh.kt.lite.extensions.dp2px @@ -9,9 +8,8 @@ fun Context.initLayoutImmersionBar(rootView: ViewGroup) { var statusBarHeight = QMUIDisplayHelper.getStatusBarHeight(this) - Log.d("Casic", "状态栏高度: $statusBarHeight") if (statusBarHeight == 0) { - statusBarHeight = 44f.dp2px(BaseApplication.get()) + statusBarHeight = 40f.dp2px(BaseApplication.get()) } rootView.setPadding(0, statusBarHeight, 0, 0) rootView.requestLayout() diff --git a/app/build.gradle b/app/build.gradle index 0ae369f..687b02b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -15,7 +15,6 @@ } compileSdkVersion 31 - buildToolsVersion "30.0.3" defaultConfig { applicationId "com.casic.xz.meterage" @@ -84,11 +83,13 @@ implementation 'top.zibin:Luban:1.1.8' //官方Json解析库 implementation 'com.google.code.gson:gson:2.9.0' + //阿里巴巴JSON库 + implementation 'com.alibaba.fastjson2:fastjson2:2.0.24' //Kotlin协程 implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.5.1' //MVVM+LiveData implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.5.1" - implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.0" + implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1" implementation "androidx.lifecycle:lifecycle-extensions:2.2.0" //返回值转换器 implementation 'com.jakewharton.retrofit:retrofit2-kotlin-coroutines-adapter:0.9.2' @@ -109,4 +110,8 @@ implementation 'com.github.barteksc:android-pdf-viewer:2.8.2' //绕过Android 11反射限制 implementation 'com.github.tiann:FreeReflection:3.1.0' + //单项/数字、二三级联动、日期/时间等滚轮选择器 + implementation 'com.github.gzu-liyujiang.AndroidPicker:WheelPicker:4.1.8' + //文件/目录选择器 + implementation 'com.github.gzu-liyujiang.AndroidPicker:FilePicker:4.1.1' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 1ccc12b..0fba91b 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -60,6 +60,8 @@ + + diff --git a/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt b/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt new file mode 100644 index 0000000..21a71d8 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt @@ -0,0 +1,70 @@ +package com.casic.xz.meterage.adapter + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import com.casic.xz.meterage.R +import com.casic.xz.meterage.extensions.toChineseGrade +import com.casic.xz.meterage.model.CustomerListModel + +class SelectCustomerAdapter( + context: Context, private val dataRows: MutableList +) : RecyclerView.Adapter() { + + private var layoutInflater = LayoutInflater.from(context) + + //选择的位置 + private var selectedPosition = 0 + + //临时记录上次选择的位置 + private var temp = -1 + + override fun getItemCount(): Int = dataRows.size + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ItemViewHolder( + layoutInflater.inflate(R.layout.item_select_customer_lv, parent, false) + ) + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + //绑定数据 + val rowsBean = dataRows[position] + holder.agreementLevelView.text = rowsBean.grade.toChineseGrade() + holder.customerNameView.text = rowsBean.customerName + holder.scaleView.text = rowsBean.companySizeName + holder.overallView.text = "公司规模:${rowsBean.evaluationName}" + holder.fullAddressView.text = "公司地址:${rowsBean.fullAddress}" + + holder.itemView.isSelected = holder.layoutPosition == selectedPosition + holder.itemView.setOnClickListener { + itemCheckedListener?.onItemChecked(rowsBean) + + holder.itemView.isSelected = true + temp = selectedPosition + //设置新的位置 + selectedPosition = holder.layoutPosition + //更新旧位置 + notifyItemChanged(temp) + } + } + + inner class ItemViewHolder(view: View) : RecyclerView.ViewHolder(view) { + var agreementLevelView: TextView = view.findViewById(R.id.agreementLevelView) + var customerNameView: TextView = view.findViewById(R.id.customerNameView) + var scaleView: TextView = view.findViewById(R.id.scaleView) + var overallView: TextView = view.findViewById(R.id.overallView) + var fullAddressView: TextView = view.findViewById(R.id.fullAddressView) + } + + private var itemCheckedListener: OnItemCheckedListener? = null + + interface OnItemCheckedListener { + fun onItemChecked(item: CustomerListModel.DataModel.RowsModel) + } + + fun setOnCheckedListener(listener: OnItemCheckedListener?) { + itemCheckedListener = listener + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt b/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt new file mode 100644 index 0000000..c29461e --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt @@ -0,0 +1,68 @@ +package com.casic.xz.meterage.adapter + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import com.casic.xz.meterage.R +import com.casic.xz.meterage.model.SampleListModel + +class SelectSampleAdapter( + context: Context, private val dataRows: MutableList +) : RecyclerView.Adapter() { + + private var layoutInflater = LayoutInflater.from(context) + private var multipleSelected = mutableSetOf() + private var sampleModes = ArrayList() + + override fun getItemCount(): Int = dataRows.size + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ItemViewHolder( + layoutInflater.inflate(R.layout.item_select_sample_lv, parent, false) + ) + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + //绑定数据 + val rowsBean = dataRows[position] + holder.sampleNameView.text = "${rowsBean.sampleName}【${rowsBean.sampleModel}】" + holder.manufacturingCodeView.text = "出厂编号:${rowsBean.manufacturingNo}" + holder.sampleCodeView.text = "样品编号:${rowsBean.sampleNo}" + holder.validDateView.text = "有效期至:${rowsBean.validDeadline}" + + holder.checkImageView.isSelected = multipleSelected.contains(position) + holder.itemView.setOnClickListener { + if (multipleSelected.contains(position)) { + multipleSelected.remove(position) + sampleModes.remove(dataRows[position]) + holder.checkImageView.isSelected = false + } else { + multipleSelected.add(position) + sampleModes.add(dataRows[position]) + holder.checkImageView.isSelected = true + } + + itemCheckedListener?.onItemChecked(sampleModes) + } + } + + inner class ItemViewHolder(view: View) : RecyclerView.ViewHolder(view) { + var sampleNameView: TextView = view.findViewById(R.id.sampleNameView) + var manufacturingCodeView: TextView = view.findViewById(R.id.manufacturingCodeView) + var sampleCodeView: TextView = view.findViewById(R.id.sampleCodeView) + var validDateView: TextView = view.findViewById(R.id.validDateView) + var checkImageView: ImageView = view.findViewById(R.id.checkImageView) + } + + private var itemCheckedListener: OnItemCheckedListener? = null + + interface OnItemCheckedListener { + fun onItemChecked(items: ArrayList) + } + + fun setOnCheckedListener(listener: OnItemCheckedListener?) { + itemCheckedListener = listener + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/callback/DateSelectedCallback.kt b/app/src/main/java/com/casic/xz/meterage/callback/DateSelectedCallback.kt new file mode 100644 index 0000000..8196110 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/callback/DateSelectedCallback.kt @@ -0,0 +1,5 @@ +package com.casic.xz.meterage.callback + +interface DateSelectedCallback { + fun onDateSelected(date: String) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/Activity.kt b/app/src/main/java/com/casic/xz/meterage/extensions/Activity.kt new file mode 100644 index 0000000..e112d1c --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/extensions/Activity.kt @@ -0,0 +1,33 @@ +package com.casic.xz.meterage.extensions + +import android.app.Activity +import com.casic.xz.meterage.R +import com.casic.xz.meterage.callback.DateSelectedCallback +import com.github.gzuliyujiang.wheelpicker.DatePicker +import com.github.gzuliyujiang.wheelpicker.annotation.DateMode +import com.github.gzuliyujiang.wheelpicker.entity.DateEntity +import com.pengxh.kt.lite.extensions.convertColor +import com.pengxh.kt.lite.extensions.sp2px + +fun Activity.showDatePicker(callback: DateSelectedCallback) { + val datePicker = DatePicker(this) + + val layout = datePicker.wheelLayout + layout.setDateMode(DateMode.YEAR_MONTH_DAY) + layout.setDateLabel("年", "月", "日"); + layout.setTextSize(14f.sp2px(this).toFloat()) + layout.setSelectedTextSize(16f.sp2px(this).toFloat()) + layout.setSelectedTextColor(R.color.themeColor.convertColor(this)) + layout.setSelectedTextBold(true) + layout.setResetWhenLinkage(false) + layout.setRange( + DateEntity.today(), + DateEntity.target(2050, 12, 31), + DateEntity.today() + ) + + datePicker.setOnDatePickedListener { year, month, day -> + callback.onDateSelected(String.format("%s-%s-%s", year, month, day)) + } + datePicker.show() +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt b/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt index 016ebcb..cf6bf49 100644 --- a/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt +++ b/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt @@ -4,7 +4,7 @@ * ArrayList扩展方法 */ -//将图片集合格式化成满足上传格式的数据 +//将集合格式化成满足上传格式的数据 fun ArrayList.reformat(): String { if (this.isEmpty()) return "" val builder = StringBuilder() diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt b/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt index 7c57643..aa9b92b 100644 --- a/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt +++ b/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt @@ -1,7 +1,6 @@ package com.casic.xz.meterage.extensions import android.content.Context -import android.util.Log import android.view.ViewGroup import com.casic.xz.meterage.base.BaseApplication import com.pengxh.kt.lite.extensions.dp2px @@ -9,9 +8,8 @@ fun Context.initLayoutImmersionBar(rootView: ViewGroup) { var statusBarHeight = QMUIDisplayHelper.getStatusBarHeight(this) - Log.d("Casic", "状态栏高度: $statusBarHeight") if (statusBarHeight == 0) { - statusBarHeight = 44f.dp2px(BaseApplication.get()) + statusBarHeight = 40f.dp2px(BaseApplication.get()) } rootView.setPadding(0, statusBarHeight, 0, 0) rootView.requestLayout() diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/String.kt b/app/src/main/java/com/casic/xz/meterage/extensions/String.kt index 28f70d8..6234d43 100644 --- a/app/src/main/java/com/casic/xz/meterage/extensions/String.kt +++ b/app/src/main/java/com/casic/xz/meterage/extensions/String.kt @@ -128,9 +128,10 @@ fun String.combineImagePath(): String { if (this.isEmpty()) return this val defaultValue = SaveKeyValues.getValue( - LocaleConstant.DEFAULT_SERVER_CONFIG, LocaleConstant.SERVER_BASE_URL + LocaleConstant.FILE_SERVER_CONFIG, LocaleConstant.File_SERVER_URL ) as String - return "$defaultValue/static/${this.replace("\\", "/")}" + //http://111.198.10.15:21408/test/1677479806059688_1677479806038.jpeg + return "$defaultValue/test/${this.replace("\\", "/")}" } fun String.isEarlier(time: String): Boolean { diff --git a/app/build.gradle b/app/build.gradle index 0ae369f..687b02b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -15,7 +15,6 @@ } compileSdkVersion 31 - buildToolsVersion "30.0.3" defaultConfig { applicationId "com.casic.xz.meterage" @@ -84,11 +83,13 @@ implementation 'top.zibin:Luban:1.1.8' //官方Json解析库 implementation 'com.google.code.gson:gson:2.9.0' + //阿里巴巴JSON库 + implementation 'com.alibaba.fastjson2:fastjson2:2.0.24' //Kotlin协程 implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.5.1' //MVVM+LiveData implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.5.1" - implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.0" + implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1" implementation "androidx.lifecycle:lifecycle-extensions:2.2.0" //返回值转换器 implementation 'com.jakewharton.retrofit:retrofit2-kotlin-coroutines-adapter:0.9.2' @@ -109,4 +110,8 @@ implementation 'com.github.barteksc:android-pdf-viewer:2.8.2' //绕过Android 11反射限制 implementation 'com.github.tiann:FreeReflection:3.1.0' + //单项/数字、二三级联动、日期/时间等滚轮选择器 + implementation 'com.github.gzu-liyujiang.AndroidPicker:WheelPicker:4.1.8' + //文件/目录选择器 + implementation 'com.github.gzu-liyujiang.AndroidPicker:FilePicker:4.1.1' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 1ccc12b..0fba91b 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -60,6 +60,8 @@ + + diff --git a/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt b/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt new file mode 100644 index 0000000..21a71d8 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt @@ -0,0 +1,70 @@ +package com.casic.xz.meterage.adapter + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import com.casic.xz.meterage.R +import com.casic.xz.meterage.extensions.toChineseGrade +import com.casic.xz.meterage.model.CustomerListModel + +class SelectCustomerAdapter( + context: Context, private val dataRows: MutableList +) : RecyclerView.Adapter() { + + private var layoutInflater = LayoutInflater.from(context) + + //选择的位置 + private var selectedPosition = 0 + + //临时记录上次选择的位置 + private var temp = -1 + + override fun getItemCount(): Int = dataRows.size + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ItemViewHolder( + layoutInflater.inflate(R.layout.item_select_customer_lv, parent, false) + ) + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + //绑定数据 + val rowsBean = dataRows[position] + holder.agreementLevelView.text = rowsBean.grade.toChineseGrade() + holder.customerNameView.text = rowsBean.customerName + holder.scaleView.text = rowsBean.companySizeName + holder.overallView.text = "公司规模:${rowsBean.evaluationName}" + holder.fullAddressView.text = "公司地址:${rowsBean.fullAddress}" + + holder.itemView.isSelected = holder.layoutPosition == selectedPosition + holder.itemView.setOnClickListener { + itemCheckedListener?.onItemChecked(rowsBean) + + holder.itemView.isSelected = true + temp = selectedPosition + //设置新的位置 + selectedPosition = holder.layoutPosition + //更新旧位置 + notifyItemChanged(temp) + } + } + + inner class ItemViewHolder(view: View) : RecyclerView.ViewHolder(view) { + var agreementLevelView: TextView = view.findViewById(R.id.agreementLevelView) + var customerNameView: TextView = view.findViewById(R.id.customerNameView) + var scaleView: TextView = view.findViewById(R.id.scaleView) + var overallView: TextView = view.findViewById(R.id.overallView) + var fullAddressView: TextView = view.findViewById(R.id.fullAddressView) + } + + private var itemCheckedListener: OnItemCheckedListener? = null + + interface OnItemCheckedListener { + fun onItemChecked(item: CustomerListModel.DataModel.RowsModel) + } + + fun setOnCheckedListener(listener: OnItemCheckedListener?) { + itemCheckedListener = listener + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt b/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt new file mode 100644 index 0000000..c29461e --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt @@ -0,0 +1,68 @@ +package com.casic.xz.meterage.adapter + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import com.casic.xz.meterage.R +import com.casic.xz.meterage.model.SampleListModel + +class SelectSampleAdapter( + context: Context, private val dataRows: MutableList +) : RecyclerView.Adapter() { + + private var layoutInflater = LayoutInflater.from(context) + private var multipleSelected = mutableSetOf() + private var sampleModes = ArrayList() + + override fun getItemCount(): Int = dataRows.size + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ItemViewHolder( + layoutInflater.inflate(R.layout.item_select_sample_lv, parent, false) + ) + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + //绑定数据 + val rowsBean = dataRows[position] + holder.sampleNameView.text = "${rowsBean.sampleName}【${rowsBean.sampleModel}】" + holder.manufacturingCodeView.text = "出厂编号:${rowsBean.manufacturingNo}" + holder.sampleCodeView.text = "样品编号:${rowsBean.sampleNo}" + holder.validDateView.text = "有效期至:${rowsBean.validDeadline}" + + holder.checkImageView.isSelected = multipleSelected.contains(position) + holder.itemView.setOnClickListener { + if (multipleSelected.contains(position)) { + multipleSelected.remove(position) + sampleModes.remove(dataRows[position]) + holder.checkImageView.isSelected = false + } else { + multipleSelected.add(position) + sampleModes.add(dataRows[position]) + holder.checkImageView.isSelected = true + } + + itemCheckedListener?.onItemChecked(sampleModes) + } + } + + inner class ItemViewHolder(view: View) : RecyclerView.ViewHolder(view) { + var sampleNameView: TextView = view.findViewById(R.id.sampleNameView) + var manufacturingCodeView: TextView = view.findViewById(R.id.manufacturingCodeView) + var sampleCodeView: TextView = view.findViewById(R.id.sampleCodeView) + var validDateView: TextView = view.findViewById(R.id.validDateView) + var checkImageView: ImageView = view.findViewById(R.id.checkImageView) + } + + private var itemCheckedListener: OnItemCheckedListener? = null + + interface OnItemCheckedListener { + fun onItemChecked(items: ArrayList) + } + + fun setOnCheckedListener(listener: OnItemCheckedListener?) { + itemCheckedListener = listener + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/callback/DateSelectedCallback.kt b/app/src/main/java/com/casic/xz/meterage/callback/DateSelectedCallback.kt new file mode 100644 index 0000000..8196110 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/callback/DateSelectedCallback.kt @@ -0,0 +1,5 @@ +package com.casic.xz.meterage.callback + +interface DateSelectedCallback { + fun onDateSelected(date: String) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/Activity.kt b/app/src/main/java/com/casic/xz/meterage/extensions/Activity.kt new file mode 100644 index 0000000..e112d1c --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/extensions/Activity.kt @@ -0,0 +1,33 @@ +package com.casic.xz.meterage.extensions + +import android.app.Activity +import com.casic.xz.meterage.R +import com.casic.xz.meterage.callback.DateSelectedCallback +import com.github.gzuliyujiang.wheelpicker.DatePicker +import com.github.gzuliyujiang.wheelpicker.annotation.DateMode +import com.github.gzuliyujiang.wheelpicker.entity.DateEntity +import com.pengxh.kt.lite.extensions.convertColor +import com.pengxh.kt.lite.extensions.sp2px + +fun Activity.showDatePicker(callback: DateSelectedCallback) { + val datePicker = DatePicker(this) + + val layout = datePicker.wheelLayout + layout.setDateMode(DateMode.YEAR_MONTH_DAY) + layout.setDateLabel("年", "月", "日"); + layout.setTextSize(14f.sp2px(this).toFloat()) + layout.setSelectedTextSize(16f.sp2px(this).toFloat()) + layout.setSelectedTextColor(R.color.themeColor.convertColor(this)) + layout.setSelectedTextBold(true) + layout.setResetWhenLinkage(false) + layout.setRange( + DateEntity.today(), + DateEntity.target(2050, 12, 31), + DateEntity.today() + ) + + datePicker.setOnDatePickedListener { year, month, day -> + callback.onDateSelected(String.format("%s-%s-%s", year, month, day)) + } + datePicker.show() +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt b/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt index 016ebcb..cf6bf49 100644 --- a/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt +++ b/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt @@ -4,7 +4,7 @@ * ArrayList扩展方法 */ -//将图片集合格式化成满足上传格式的数据 +//将集合格式化成满足上传格式的数据 fun ArrayList.reformat(): String { if (this.isEmpty()) return "" val builder = StringBuilder() diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt b/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt index 7c57643..aa9b92b 100644 --- a/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt +++ b/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt @@ -1,7 +1,6 @@ package com.casic.xz.meterage.extensions import android.content.Context -import android.util.Log import android.view.ViewGroup import com.casic.xz.meterage.base.BaseApplication import com.pengxh.kt.lite.extensions.dp2px @@ -9,9 +8,8 @@ fun Context.initLayoutImmersionBar(rootView: ViewGroup) { var statusBarHeight = QMUIDisplayHelper.getStatusBarHeight(this) - Log.d("Casic", "状态栏高度: $statusBarHeight") if (statusBarHeight == 0) { - statusBarHeight = 44f.dp2px(BaseApplication.get()) + statusBarHeight = 40f.dp2px(BaseApplication.get()) } rootView.setPadding(0, statusBarHeight, 0, 0) rootView.requestLayout() diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/String.kt b/app/src/main/java/com/casic/xz/meterage/extensions/String.kt index 28f70d8..6234d43 100644 --- a/app/src/main/java/com/casic/xz/meterage/extensions/String.kt +++ b/app/src/main/java/com/casic/xz/meterage/extensions/String.kt @@ -128,9 +128,10 @@ fun String.combineImagePath(): String { if (this.isEmpty()) return this val defaultValue = SaveKeyValues.getValue( - LocaleConstant.DEFAULT_SERVER_CONFIG, LocaleConstant.SERVER_BASE_URL + LocaleConstant.FILE_SERVER_CONFIG, LocaleConstant.File_SERVER_URL ) as String - return "$defaultValue/static/${this.replace("\\", "/")}" + //http://111.198.10.15:21408/test/1677479806059688_1677479806038.jpeg + return "$defaultValue/test/${this.replace("\\", "/")}" } fun String.isEarlier(time: String): Boolean { diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt index 25fa87b..a0e1358 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt @@ -1,18 +1,12 @@ package com.casic.xz.meterage.fragment.customer +import android.graphics.Color import android.graphics.Paint import com.casic.xz.meterage.R -import com.casic.xz.meterage.extensions.combineImagePath import com.casic.xz.meterage.extensions.toChineseGrade +import com.casic.xz.meterage.extensions.watchAttachFile import com.casic.xz.meterage.model.CustomerDetailModel -import com.casic.xz.meterage.view.BigImageActivity -import com.casic.xz.meterage.view.notice.PreviewDocumentActivity -import com.casic.xz.meterage.view.notice.PreviewPdfActivity -import com.casic.xz.meterage.view.notice.PreviewTextActivity import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.extensions.show import kotlinx.android.synthetic.main.fragment_customer_basic_information.* class BasicInformationFragment(private val data: CustomerDetailModel.DataModel) : @@ -48,30 +42,11 @@ val textPaint = minioFileView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - minioFileView.setTextColor(R.color.themeColor.convertColor(requireContext())) + minioFileView.setTextColor(Color.BLUE) minioFileView.setOnClickListener { //查看附件 - if (minioFileName.endsWith("pdf")) { - requireContext().navigatePageTo(minioFileName) - } else if ( - minioFileName.endsWith("doc") || - minioFileName.endsWith("docx") - ) { - requireContext().navigatePageTo(minioFileName) - } else if (minioFileName.endsWith("txt")) { - requireContext().navigatePageTo(minioFileName) - } else if ( - minioFileName.endsWith("png") || - minioFileName.endsWith("jpeg") || - minioFileName.endsWith("jpg") - ) { - val urls = ArrayList() - urls.add(minioFileName.combineImagePath()) - requireContext().navigatePageTo(0, urls) - } else { - "文件类型未知,无法打开附件".show(requireContext()) - } + minioFileName.watchAttachFile(requireContext()) } } } diff --git a/app/build.gradle b/app/build.gradle index 0ae369f..687b02b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -15,7 +15,6 @@ } compileSdkVersion 31 - buildToolsVersion "30.0.3" defaultConfig { applicationId "com.casic.xz.meterage" @@ -84,11 +83,13 @@ implementation 'top.zibin:Luban:1.1.8' //官方Json解析库 implementation 'com.google.code.gson:gson:2.9.0' + //阿里巴巴JSON库 + implementation 'com.alibaba.fastjson2:fastjson2:2.0.24' //Kotlin协程 implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.5.1' //MVVM+LiveData implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.5.1" - implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.0" + implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1" implementation "androidx.lifecycle:lifecycle-extensions:2.2.0" //返回值转换器 implementation 'com.jakewharton.retrofit:retrofit2-kotlin-coroutines-adapter:0.9.2' @@ -109,4 +110,8 @@ implementation 'com.github.barteksc:android-pdf-viewer:2.8.2' //绕过Android 11反射限制 implementation 'com.github.tiann:FreeReflection:3.1.0' + //单项/数字、二三级联动、日期/时间等滚轮选择器 + implementation 'com.github.gzu-liyujiang.AndroidPicker:WheelPicker:4.1.8' + //文件/目录选择器 + implementation 'com.github.gzu-liyujiang.AndroidPicker:FilePicker:4.1.1' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 1ccc12b..0fba91b 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -60,6 +60,8 @@ + + diff --git a/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt b/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt new file mode 100644 index 0000000..21a71d8 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt @@ -0,0 +1,70 @@ +package com.casic.xz.meterage.adapter + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import com.casic.xz.meterage.R +import com.casic.xz.meterage.extensions.toChineseGrade +import com.casic.xz.meterage.model.CustomerListModel + +class SelectCustomerAdapter( + context: Context, private val dataRows: MutableList +) : RecyclerView.Adapter() { + + private var layoutInflater = LayoutInflater.from(context) + + //选择的位置 + private var selectedPosition = 0 + + //临时记录上次选择的位置 + private var temp = -1 + + override fun getItemCount(): Int = dataRows.size + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ItemViewHolder( + layoutInflater.inflate(R.layout.item_select_customer_lv, parent, false) + ) + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + //绑定数据 + val rowsBean = dataRows[position] + holder.agreementLevelView.text = rowsBean.grade.toChineseGrade() + holder.customerNameView.text = rowsBean.customerName + holder.scaleView.text = rowsBean.companySizeName + holder.overallView.text = "公司规模:${rowsBean.evaluationName}" + holder.fullAddressView.text = "公司地址:${rowsBean.fullAddress}" + + holder.itemView.isSelected = holder.layoutPosition == selectedPosition + holder.itemView.setOnClickListener { + itemCheckedListener?.onItemChecked(rowsBean) + + holder.itemView.isSelected = true + temp = selectedPosition + //设置新的位置 + selectedPosition = holder.layoutPosition + //更新旧位置 + notifyItemChanged(temp) + } + } + + inner class ItemViewHolder(view: View) : RecyclerView.ViewHolder(view) { + var agreementLevelView: TextView = view.findViewById(R.id.agreementLevelView) + var customerNameView: TextView = view.findViewById(R.id.customerNameView) + var scaleView: TextView = view.findViewById(R.id.scaleView) + var overallView: TextView = view.findViewById(R.id.overallView) + var fullAddressView: TextView = view.findViewById(R.id.fullAddressView) + } + + private var itemCheckedListener: OnItemCheckedListener? = null + + interface OnItemCheckedListener { + fun onItemChecked(item: CustomerListModel.DataModel.RowsModel) + } + + fun setOnCheckedListener(listener: OnItemCheckedListener?) { + itemCheckedListener = listener + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt b/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt new file mode 100644 index 0000000..c29461e --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt @@ -0,0 +1,68 @@ +package com.casic.xz.meterage.adapter + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import com.casic.xz.meterage.R +import com.casic.xz.meterage.model.SampleListModel + +class SelectSampleAdapter( + context: Context, private val dataRows: MutableList +) : RecyclerView.Adapter() { + + private var layoutInflater = LayoutInflater.from(context) + private var multipleSelected = mutableSetOf() + private var sampleModes = ArrayList() + + override fun getItemCount(): Int = dataRows.size + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ItemViewHolder( + layoutInflater.inflate(R.layout.item_select_sample_lv, parent, false) + ) + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + //绑定数据 + val rowsBean = dataRows[position] + holder.sampleNameView.text = "${rowsBean.sampleName}【${rowsBean.sampleModel}】" + holder.manufacturingCodeView.text = "出厂编号:${rowsBean.manufacturingNo}" + holder.sampleCodeView.text = "样品编号:${rowsBean.sampleNo}" + holder.validDateView.text = "有效期至:${rowsBean.validDeadline}" + + holder.checkImageView.isSelected = multipleSelected.contains(position) + holder.itemView.setOnClickListener { + if (multipleSelected.contains(position)) { + multipleSelected.remove(position) + sampleModes.remove(dataRows[position]) + holder.checkImageView.isSelected = false + } else { + multipleSelected.add(position) + sampleModes.add(dataRows[position]) + holder.checkImageView.isSelected = true + } + + itemCheckedListener?.onItemChecked(sampleModes) + } + } + + inner class ItemViewHolder(view: View) : RecyclerView.ViewHolder(view) { + var sampleNameView: TextView = view.findViewById(R.id.sampleNameView) + var manufacturingCodeView: TextView = view.findViewById(R.id.manufacturingCodeView) + var sampleCodeView: TextView = view.findViewById(R.id.sampleCodeView) + var validDateView: TextView = view.findViewById(R.id.validDateView) + var checkImageView: ImageView = view.findViewById(R.id.checkImageView) + } + + private var itemCheckedListener: OnItemCheckedListener? = null + + interface OnItemCheckedListener { + fun onItemChecked(items: ArrayList) + } + + fun setOnCheckedListener(listener: OnItemCheckedListener?) { + itemCheckedListener = listener + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/callback/DateSelectedCallback.kt b/app/src/main/java/com/casic/xz/meterage/callback/DateSelectedCallback.kt new file mode 100644 index 0000000..8196110 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/callback/DateSelectedCallback.kt @@ -0,0 +1,5 @@ +package com.casic.xz.meterage.callback + +interface DateSelectedCallback { + fun onDateSelected(date: String) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/Activity.kt b/app/src/main/java/com/casic/xz/meterage/extensions/Activity.kt new file mode 100644 index 0000000..e112d1c --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/extensions/Activity.kt @@ -0,0 +1,33 @@ +package com.casic.xz.meterage.extensions + +import android.app.Activity +import com.casic.xz.meterage.R +import com.casic.xz.meterage.callback.DateSelectedCallback +import com.github.gzuliyujiang.wheelpicker.DatePicker +import com.github.gzuliyujiang.wheelpicker.annotation.DateMode +import com.github.gzuliyujiang.wheelpicker.entity.DateEntity +import com.pengxh.kt.lite.extensions.convertColor +import com.pengxh.kt.lite.extensions.sp2px + +fun Activity.showDatePicker(callback: DateSelectedCallback) { + val datePicker = DatePicker(this) + + val layout = datePicker.wheelLayout + layout.setDateMode(DateMode.YEAR_MONTH_DAY) + layout.setDateLabel("年", "月", "日"); + layout.setTextSize(14f.sp2px(this).toFloat()) + layout.setSelectedTextSize(16f.sp2px(this).toFloat()) + layout.setSelectedTextColor(R.color.themeColor.convertColor(this)) + layout.setSelectedTextBold(true) + layout.setResetWhenLinkage(false) + layout.setRange( + DateEntity.today(), + DateEntity.target(2050, 12, 31), + DateEntity.today() + ) + + datePicker.setOnDatePickedListener { year, month, day -> + callback.onDateSelected(String.format("%s-%s-%s", year, month, day)) + } + datePicker.show() +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt b/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt index 016ebcb..cf6bf49 100644 --- a/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt +++ b/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt @@ -4,7 +4,7 @@ * ArrayList扩展方法 */ -//将图片集合格式化成满足上传格式的数据 +//将集合格式化成满足上传格式的数据 fun ArrayList.reformat(): String { if (this.isEmpty()) return "" val builder = StringBuilder() diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt b/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt index 7c57643..aa9b92b 100644 --- a/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt +++ b/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt @@ -1,7 +1,6 @@ package com.casic.xz.meterage.extensions import android.content.Context -import android.util.Log import android.view.ViewGroup import com.casic.xz.meterage.base.BaseApplication import com.pengxh.kt.lite.extensions.dp2px @@ -9,9 +8,8 @@ fun Context.initLayoutImmersionBar(rootView: ViewGroup) { var statusBarHeight = QMUIDisplayHelper.getStatusBarHeight(this) - Log.d("Casic", "状态栏高度: $statusBarHeight") if (statusBarHeight == 0) { - statusBarHeight = 44f.dp2px(BaseApplication.get()) + statusBarHeight = 40f.dp2px(BaseApplication.get()) } rootView.setPadding(0, statusBarHeight, 0, 0) rootView.requestLayout() diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/String.kt b/app/src/main/java/com/casic/xz/meterage/extensions/String.kt index 28f70d8..6234d43 100644 --- a/app/src/main/java/com/casic/xz/meterage/extensions/String.kt +++ b/app/src/main/java/com/casic/xz/meterage/extensions/String.kt @@ -128,9 +128,10 @@ fun String.combineImagePath(): String { if (this.isEmpty()) return this val defaultValue = SaveKeyValues.getValue( - LocaleConstant.DEFAULT_SERVER_CONFIG, LocaleConstant.SERVER_BASE_URL + LocaleConstant.FILE_SERVER_CONFIG, LocaleConstant.File_SERVER_URL ) as String - return "$defaultValue/static/${this.replace("\\", "/")}" + //http://111.198.10.15:21408/test/1677479806059688_1677479806038.jpeg + return "$defaultValue/test/${this.replace("\\", "/")}" } fun String.isEarlier(time: String): Boolean { diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt index 25fa87b..a0e1358 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt @@ -1,18 +1,12 @@ package com.casic.xz.meterage.fragment.customer +import android.graphics.Color import android.graphics.Paint import com.casic.xz.meterage.R -import com.casic.xz.meterage.extensions.combineImagePath import com.casic.xz.meterage.extensions.toChineseGrade +import com.casic.xz.meterage.extensions.watchAttachFile import com.casic.xz.meterage.model.CustomerDetailModel -import com.casic.xz.meterage.view.BigImageActivity -import com.casic.xz.meterage.view.notice.PreviewDocumentActivity -import com.casic.xz.meterage.view.notice.PreviewPdfActivity -import com.casic.xz.meterage.view.notice.PreviewTextActivity import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.extensions.show import kotlinx.android.synthetic.main.fragment_customer_basic_information.* class BasicInformationFragment(private val data: CustomerDetailModel.DataModel) : @@ -48,30 +42,11 @@ val textPaint = minioFileView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - minioFileView.setTextColor(R.color.themeColor.convertColor(requireContext())) + minioFileView.setTextColor(Color.BLUE) minioFileView.setOnClickListener { //查看附件 - if (minioFileName.endsWith("pdf")) { - requireContext().navigatePageTo(minioFileName) - } else if ( - minioFileName.endsWith("doc") || - minioFileName.endsWith("docx") - ) { - requireContext().navigatePageTo(minioFileName) - } else if (minioFileName.endsWith("txt")) { - requireContext().navigatePageTo(minioFileName) - } else if ( - minioFileName.endsWith("png") || - minioFileName.endsWith("jpeg") || - minioFileName.endsWith("jpg") - ) { - val urls = ArrayList() - urls.add(minioFileName.combineImagePath()) - requireContext().navigatePageTo(0, urls) - } else { - "文件类型未知,无法打开附件".show(requireContext()) - } + minioFileName.watchAttachFile(requireContext()) } } } diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt index 77846b4..3a0fe2e 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt @@ -1,5 +1,6 @@ package com.casic.xz.meterage.fragment.device +import android.graphics.Color import android.graphics.Paint import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R @@ -7,7 +8,6 @@ import com.casic.xz.meterage.utils.LoadingDialogHub import com.casic.xz.meterage.vm.EquipmentViewModel import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor import com.pengxh.kt.lite.vm.LoadState import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import kotlinx.android.synthetic.main.fragment_device_basic_information.* @@ -56,7 +56,7 @@ val textPaint = documentsView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - documentsView.setTextColor(R.color.themeColor.convertColor(requireContext())) + documentsView.setTextColor(Color.BLUE) val files = ArrayList() data.fileList.forEach { file -> @@ -66,7 +66,7 @@ BottomActionSheet.Builder() .setContext(requireContext()) .setActionItemTitle(files) - .setItemTextColor(R.color.themeColor.convertColor(requireContext())) + .setItemTextColor(Color.BLUE) .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { override fun onActionItemClick(position: Int) { diff --git a/app/build.gradle b/app/build.gradle index 0ae369f..687b02b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -15,7 +15,6 @@ } compileSdkVersion 31 - buildToolsVersion "30.0.3" defaultConfig { applicationId "com.casic.xz.meterage" @@ -84,11 +83,13 @@ implementation 'top.zibin:Luban:1.1.8' //官方Json解析库 implementation 'com.google.code.gson:gson:2.9.0' + //阿里巴巴JSON库 + implementation 'com.alibaba.fastjson2:fastjson2:2.0.24' //Kotlin协程 implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.5.1' //MVVM+LiveData implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.5.1" - implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.0" + implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1" implementation "androidx.lifecycle:lifecycle-extensions:2.2.0" //返回值转换器 implementation 'com.jakewharton.retrofit:retrofit2-kotlin-coroutines-adapter:0.9.2' @@ -109,4 +110,8 @@ implementation 'com.github.barteksc:android-pdf-viewer:2.8.2' //绕过Android 11反射限制 implementation 'com.github.tiann:FreeReflection:3.1.0' + //单项/数字、二三级联动、日期/时间等滚轮选择器 + implementation 'com.github.gzu-liyujiang.AndroidPicker:WheelPicker:4.1.8' + //文件/目录选择器 + implementation 'com.github.gzu-liyujiang.AndroidPicker:FilePicker:4.1.1' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 1ccc12b..0fba91b 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -60,6 +60,8 @@ + + diff --git a/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt b/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt new file mode 100644 index 0000000..21a71d8 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt @@ -0,0 +1,70 @@ +package com.casic.xz.meterage.adapter + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import com.casic.xz.meterage.R +import com.casic.xz.meterage.extensions.toChineseGrade +import com.casic.xz.meterage.model.CustomerListModel + +class SelectCustomerAdapter( + context: Context, private val dataRows: MutableList +) : RecyclerView.Adapter() { + + private var layoutInflater = LayoutInflater.from(context) + + //选择的位置 + private var selectedPosition = 0 + + //临时记录上次选择的位置 + private var temp = -1 + + override fun getItemCount(): Int = dataRows.size + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ItemViewHolder( + layoutInflater.inflate(R.layout.item_select_customer_lv, parent, false) + ) + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + //绑定数据 + val rowsBean = dataRows[position] + holder.agreementLevelView.text = rowsBean.grade.toChineseGrade() + holder.customerNameView.text = rowsBean.customerName + holder.scaleView.text = rowsBean.companySizeName + holder.overallView.text = "公司规模:${rowsBean.evaluationName}" + holder.fullAddressView.text = "公司地址:${rowsBean.fullAddress}" + + holder.itemView.isSelected = holder.layoutPosition == selectedPosition + holder.itemView.setOnClickListener { + itemCheckedListener?.onItemChecked(rowsBean) + + holder.itemView.isSelected = true + temp = selectedPosition + //设置新的位置 + selectedPosition = holder.layoutPosition + //更新旧位置 + notifyItemChanged(temp) + } + } + + inner class ItemViewHolder(view: View) : RecyclerView.ViewHolder(view) { + var agreementLevelView: TextView = view.findViewById(R.id.agreementLevelView) + var customerNameView: TextView = view.findViewById(R.id.customerNameView) + var scaleView: TextView = view.findViewById(R.id.scaleView) + var overallView: TextView = view.findViewById(R.id.overallView) + var fullAddressView: TextView = view.findViewById(R.id.fullAddressView) + } + + private var itemCheckedListener: OnItemCheckedListener? = null + + interface OnItemCheckedListener { + fun onItemChecked(item: CustomerListModel.DataModel.RowsModel) + } + + fun setOnCheckedListener(listener: OnItemCheckedListener?) { + itemCheckedListener = listener + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt b/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt new file mode 100644 index 0000000..c29461e --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt @@ -0,0 +1,68 @@ +package com.casic.xz.meterage.adapter + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import com.casic.xz.meterage.R +import com.casic.xz.meterage.model.SampleListModel + +class SelectSampleAdapter( + context: Context, private val dataRows: MutableList +) : RecyclerView.Adapter() { + + private var layoutInflater = LayoutInflater.from(context) + private var multipleSelected = mutableSetOf() + private var sampleModes = ArrayList() + + override fun getItemCount(): Int = dataRows.size + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ItemViewHolder( + layoutInflater.inflate(R.layout.item_select_sample_lv, parent, false) + ) + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + //绑定数据 + val rowsBean = dataRows[position] + holder.sampleNameView.text = "${rowsBean.sampleName}【${rowsBean.sampleModel}】" + holder.manufacturingCodeView.text = "出厂编号:${rowsBean.manufacturingNo}" + holder.sampleCodeView.text = "样品编号:${rowsBean.sampleNo}" + holder.validDateView.text = "有效期至:${rowsBean.validDeadline}" + + holder.checkImageView.isSelected = multipleSelected.contains(position) + holder.itemView.setOnClickListener { + if (multipleSelected.contains(position)) { + multipleSelected.remove(position) + sampleModes.remove(dataRows[position]) + holder.checkImageView.isSelected = false + } else { + multipleSelected.add(position) + sampleModes.add(dataRows[position]) + holder.checkImageView.isSelected = true + } + + itemCheckedListener?.onItemChecked(sampleModes) + } + } + + inner class ItemViewHolder(view: View) : RecyclerView.ViewHolder(view) { + var sampleNameView: TextView = view.findViewById(R.id.sampleNameView) + var manufacturingCodeView: TextView = view.findViewById(R.id.manufacturingCodeView) + var sampleCodeView: TextView = view.findViewById(R.id.sampleCodeView) + var validDateView: TextView = view.findViewById(R.id.validDateView) + var checkImageView: ImageView = view.findViewById(R.id.checkImageView) + } + + private var itemCheckedListener: OnItemCheckedListener? = null + + interface OnItemCheckedListener { + fun onItemChecked(items: ArrayList) + } + + fun setOnCheckedListener(listener: OnItemCheckedListener?) { + itemCheckedListener = listener + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/callback/DateSelectedCallback.kt b/app/src/main/java/com/casic/xz/meterage/callback/DateSelectedCallback.kt new file mode 100644 index 0000000..8196110 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/callback/DateSelectedCallback.kt @@ -0,0 +1,5 @@ +package com.casic.xz.meterage.callback + +interface DateSelectedCallback { + fun onDateSelected(date: String) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/Activity.kt b/app/src/main/java/com/casic/xz/meterage/extensions/Activity.kt new file mode 100644 index 0000000..e112d1c --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/extensions/Activity.kt @@ -0,0 +1,33 @@ +package com.casic.xz.meterage.extensions + +import android.app.Activity +import com.casic.xz.meterage.R +import com.casic.xz.meterage.callback.DateSelectedCallback +import com.github.gzuliyujiang.wheelpicker.DatePicker +import com.github.gzuliyujiang.wheelpicker.annotation.DateMode +import com.github.gzuliyujiang.wheelpicker.entity.DateEntity +import com.pengxh.kt.lite.extensions.convertColor +import com.pengxh.kt.lite.extensions.sp2px + +fun Activity.showDatePicker(callback: DateSelectedCallback) { + val datePicker = DatePicker(this) + + val layout = datePicker.wheelLayout + layout.setDateMode(DateMode.YEAR_MONTH_DAY) + layout.setDateLabel("年", "月", "日"); + layout.setTextSize(14f.sp2px(this).toFloat()) + layout.setSelectedTextSize(16f.sp2px(this).toFloat()) + layout.setSelectedTextColor(R.color.themeColor.convertColor(this)) + layout.setSelectedTextBold(true) + layout.setResetWhenLinkage(false) + layout.setRange( + DateEntity.today(), + DateEntity.target(2050, 12, 31), + DateEntity.today() + ) + + datePicker.setOnDatePickedListener { year, month, day -> + callback.onDateSelected(String.format("%s-%s-%s", year, month, day)) + } + datePicker.show() +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt b/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt index 016ebcb..cf6bf49 100644 --- a/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt +++ b/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt @@ -4,7 +4,7 @@ * ArrayList扩展方法 */ -//将图片集合格式化成满足上传格式的数据 +//将集合格式化成满足上传格式的数据 fun ArrayList.reformat(): String { if (this.isEmpty()) return "" val builder = StringBuilder() diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt b/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt index 7c57643..aa9b92b 100644 --- a/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt +++ b/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt @@ -1,7 +1,6 @@ package com.casic.xz.meterage.extensions import android.content.Context -import android.util.Log import android.view.ViewGroup import com.casic.xz.meterage.base.BaseApplication import com.pengxh.kt.lite.extensions.dp2px @@ -9,9 +8,8 @@ fun Context.initLayoutImmersionBar(rootView: ViewGroup) { var statusBarHeight = QMUIDisplayHelper.getStatusBarHeight(this) - Log.d("Casic", "状态栏高度: $statusBarHeight") if (statusBarHeight == 0) { - statusBarHeight = 44f.dp2px(BaseApplication.get()) + statusBarHeight = 40f.dp2px(BaseApplication.get()) } rootView.setPadding(0, statusBarHeight, 0, 0) rootView.requestLayout() diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/String.kt b/app/src/main/java/com/casic/xz/meterage/extensions/String.kt index 28f70d8..6234d43 100644 --- a/app/src/main/java/com/casic/xz/meterage/extensions/String.kt +++ b/app/src/main/java/com/casic/xz/meterage/extensions/String.kt @@ -128,9 +128,10 @@ fun String.combineImagePath(): String { if (this.isEmpty()) return this val defaultValue = SaveKeyValues.getValue( - LocaleConstant.DEFAULT_SERVER_CONFIG, LocaleConstant.SERVER_BASE_URL + LocaleConstant.FILE_SERVER_CONFIG, LocaleConstant.File_SERVER_URL ) as String - return "$defaultValue/static/${this.replace("\\", "/")}" + //http://111.198.10.15:21408/test/1677479806059688_1677479806038.jpeg + return "$defaultValue/test/${this.replace("\\", "/")}" } fun String.isEarlier(time: String): Boolean { diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt index 25fa87b..a0e1358 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt @@ -1,18 +1,12 @@ package com.casic.xz.meterage.fragment.customer +import android.graphics.Color import android.graphics.Paint import com.casic.xz.meterage.R -import com.casic.xz.meterage.extensions.combineImagePath import com.casic.xz.meterage.extensions.toChineseGrade +import com.casic.xz.meterage.extensions.watchAttachFile import com.casic.xz.meterage.model.CustomerDetailModel -import com.casic.xz.meterage.view.BigImageActivity -import com.casic.xz.meterage.view.notice.PreviewDocumentActivity -import com.casic.xz.meterage.view.notice.PreviewPdfActivity -import com.casic.xz.meterage.view.notice.PreviewTextActivity import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.extensions.show import kotlinx.android.synthetic.main.fragment_customer_basic_information.* class BasicInformationFragment(private val data: CustomerDetailModel.DataModel) : @@ -48,30 +42,11 @@ val textPaint = minioFileView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - minioFileView.setTextColor(R.color.themeColor.convertColor(requireContext())) + minioFileView.setTextColor(Color.BLUE) minioFileView.setOnClickListener { //查看附件 - if (minioFileName.endsWith("pdf")) { - requireContext().navigatePageTo(minioFileName) - } else if ( - minioFileName.endsWith("doc") || - minioFileName.endsWith("docx") - ) { - requireContext().navigatePageTo(minioFileName) - } else if (minioFileName.endsWith("txt")) { - requireContext().navigatePageTo(minioFileName) - } else if ( - minioFileName.endsWith("png") || - minioFileName.endsWith("jpeg") || - minioFileName.endsWith("jpg") - ) { - val urls = ArrayList() - urls.add(minioFileName.combineImagePath()) - requireContext().navigatePageTo(0, urls) - } else { - "文件类型未知,无法打开附件".show(requireContext()) - } + minioFileName.watchAttachFile(requireContext()) } } } diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt index 77846b4..3a0fe2e 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt @@ -1,5 +1,6 @@ package com.casic.xz.meterage.fragment.device +import android.graphics.Color import android.graphics.Paint import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R @@ -7,7 +8,6 @@ import com.casic.xz.meterage.utils.LoadingDialogHub import com.casic.xz.meterage.vm.EquipmentViewModel import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor import com.pengxh.kt.lite.vm.LoadState import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import kotlinx.android.synthetic.main.fragment_device_basic_information.* @@ -56,7 +56,7 @@ val textPaint = documentsView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - documentsView.setTextColor(R.color.themeColor.convertColor(requireContext())) + documentsView.setTextColor(Color.BLUE) val files = ArrayList() data.fileList.forEach { file -> @@ -66,7 +66,7 @@ BottomActionSheet.Builder() .setContext(requireContext()) .setActionItemTitle(files) - .setItemTextColor(R.color.themeColor.convertColor(requireContext())) + .setItemTextColor(Color.BLUE) .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { override fun onActionItemClick(position: Int) { diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt index 15dc3d2..10eeff8 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt @@ -1,5 +1,6 @@ package com.casic.xz.meterage.fragment.entrust +import android.graphics.Color import android.graphics.Paint import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R @@ -9,7 +10,6 @@ import com.casic.xz.meterage.model.EntrustDetailModel import com.casic.xz.meterage.vm.DictionaryViewModel import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor import kotlinx.android.synthetic.main.fragment_entrust_basic_information.* class BasicInformationFragment(private val data: EntrustDetailModel.DataModel) : @@ -38,7 +38,7 @@ val textPaint = annexView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - annexView.setTextColor(R.color.themeColor.convertColor(requireContext())) + annexView.setTextColor(Color.BLUE) annexView.setOnClickListener { minioFileName.watchAttachFile(requireContext()) @@ -59,9 +59,9 @@ //加急 if (data.isUrgent == "0") { - RadioButton2.isChecked = true + radioButton2.isChecked = true } else { - RadioButton1.isChecked = true + radioButton1.isChecked = true } //样品 diff --git a/app/build.gradle b/app/build.gradle index 0ae369f..687b02b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -15,7 +15,6 @@ } compileSdkVersion 31 - buildToolsVersion "30.0.3" defaultConfig { applicationId "com.casic.xz.meterage" @@ -84,11 +83,13 @@ implementation 'top.zibin:Luban:1.1.8' //官方Json解析库 implementation 'com.google.code.gson:gson:2.9.0' + //阿里巴巴JSON库 + implementation 'com.alibaba.fastjson2:fastjson2:2.0.24' //Kotlin协程 implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.5.1' //MVVM+LiveData implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.5.1" - implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.0" + implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1" implementation "androidx.lifecycle:lifecycle-extensions:2.2.0" //返回值转换器 implementation 'com.jakewharton.retrofit:retrofit2-kotlin-coroutines-adapter:0.9.2' @@ -109,4 +110,8 @@ implementation 'com.github.barteksc:android-pdf-viewer:2.8.2' //绕过Android 11反射限制 implementation 'com.github.tiann:FreeReflection:3.1.0' + //单项/数字、二三级联动、日期/时间等滚轮选择器 + implementation 'com.github.gzu-liyujiang.AndroidPicker:WheelPicker:4.1.8' + //文件/目录选择器 + implementation 'com.github.gzu-liyujiang.AndroidPicker:FilePicker:4.1.1' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 1ccc12b..0fba91b 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -60,6 +60,8 @@ + + diff --git a/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt b/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt new file mode 100644 index 0000000..21a71d8 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt @@ -0,0 +1,70 @@ +package com.casic.xz.meterage.adapter + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import com.casic.xz.meterage.R +import com.casic.xz.meterage.extensions.toChineseGrade +import com.casic.xz.meterage.model.CustomerListModel + +class SelectCustomerAdapter( + context: Context, private val dataRows: MutableList +) : RecyclerView.Adapter() { + + private var layoutInflater = LayoutInflater.from(context) + + //选择的位置 + private var selectedPosition = 0 + + //临时记录上次选择的位置 + private var temp = -1 + + override fun getItemCount(): Int = dataRows.size + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ItemViewHolder( + layoutInflater.inflate(R.layout.item_select_customer_lv, parent, false) + ) + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + //绑定数据 + val rowsBean = dataRows[position] + holder.agreementLevelView.text = rowsBean.grade.toChineseGrade() + holder.customerNameView.text = rowsBean.customerName + holder.scaleView.text = rowsBean.companySizeName + holder.overallView.text = "公司规模:${rowsBean.evaluationName}" + holder.fullAddressView.text = "公司地址:${rowsBean.fullAddress}" + + holder.itemView.isSelected = holder.layoutPosition == selectedPosition + holder.itemView.setOnClickListener { + itemCheckedListener?.onItemChecked(rowsBean) + + holder.itemView.isSelected = true + temp = selectedPosition + //设置新的位置 + selectedPosition = holder.layoutPosition + //更新旧位置 + notifyItemChanged(temp) + } + } + + inner class ItemViewHolder(view: View) : RecyclerView.ViewHolder(view) { + var agreementLevelView: TextView = view.findViewById(R.id.agreementLevelView) + var customerNameView: TextView = view.findViewById(R.id.customerNameView) + var scaleView: TextView = view.findViewById(R.id.scaleView) + var overallView: TextView = view.findViewById(R.id.overallView) + var fullAddressView: TextView = view.findViewById(R.id.fullAddressView) + } + + private var itemCheckedListener: OnItemCheckedListener? = null + + interface OnItemCheckedListener { + fun onItemChecked(item: CustomerListModel.DataModel.RowsModel) + } + + fun setOnCheckedListener(listener: OnItemCheckedListener?) { + itemCheckedListener = listener + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt b/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt new file mode 100644 index 0000000..c29461e --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt @@ -0,0 +1,68 @@ +package com.casic.xz.meterage.adapter + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import com.casic.xz.meterage.R +import com.casic.xz.meterage.model.SampleListModel + +class SelectSampleAdapter( + context: Context, private val dataRows: MutableList +) : RecyclerView.Adapter() { + + private var layoutInflater = LayoutInflater.from(context) + private var multipleSelected = mutableSetOf() + private var sampleModes = ArrayList() + + override fun getItemCount(): Int = dataRows.size + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ItemViewHolder( + layoutInflater.inflate(R.layout.item_select_sample_lv, parent, false) + ) + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + //绑定数据 + val rowsBean = dataRows[position] + holder.sampleNameView.text = "${rowsBean.sampleName}【${rowsBean.sampleModel}】" + holder.manufacturingCodeView.text = "出厂编号:${rowsBean.manufacturingNo}" + holder.sampleCodeView.text = "样品编号:${rowsBean.sampleNo}" + holder.validDateView.text = "有效期至:${rowsBean.validDeadline}" + + holder.checkImageView.isSelected = multipleSelected.contains(position) + holder.itemView.setOnClickListener { + if (multipleSelected.contains(position)) { + multipleSelected.remove(position) + sampleModes.remove(dataRows[position]) + holder.checkImageView.isSelected = false + } else { + multipleSelected.add(position) + sampleModes.add(dataRows[position]) + holder.checkImageView.isSelected = true + } + + itemCheckedListener?.onItemChecked(sampleModes) + } + } + + inner class ItemViewHolder(view: View) : RecyclerView.ViewHolder(view) { + var sampleNameView: TextView = view.findViewById(R.id.sampleNameView) + var manufacturingCodeView: TextView = view.findViewById(R.id.manufacturingCodeView) + var sampleCodeView: TextView = view.findViewById(R.id.sampleCodeView) + var validDateView: TextView = view.findViewById(R.id.validDateView) + var checkImageView: ImageView = view.findViewById(R.id.checkImageView) + } + + private var itemCheckedListener: OnItemCheckedListener? = null + + interface OnItemCheckedListener { + fun onItemChecked(items: ArrayList) + } + + fun setOnCheckedListener(listener: OnItemCheckedListener?) { + itemCheckedListener = listener + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/callback/DateSelectedCallback.kt b/app/src/main/java/com/casic/xz/meterage/callback/DateSelectedCallback.kt new file mode 100644 index 0000000..8196110 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/callback/DateSelectedCallback.kt @@ -0,0 +1,5 @@ +package com.casic.xz.meterage.callback + +interface DateSelectedCallback { + fun onDateSelected(date: String) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/Activity.kt b/app/src/main/java/com/casic/xz/meterage/extensions/Activity.kt new file mode 100644 index 0000000..e112d1c --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/extensions/Activity.kt @@ -0,0 +1,33 @@ +package com.casic.xz.meterage.extensions + +import android.app.Activity +import com.casic.xz.meterage.R +import com.casic.xz.meterage.callback.DateSelectedCallback +import com.github.gzuliyujiang.wheelpicker.DatePicker +import com.github.gzuliyujiang.wheelpicker.annotation.DateMode +import com.github.gzuliyujiang.wheelpicker.entity.DateEntity +import com.pengxh.kt.lite.extensions.convertColor +import com.pengxh.kt.lite.extensions.sp2px + +fun Activity.showDatePicker(callback: DateSelectedCallback) { + val datePicker = DatePicker(this) + + val layout = datePicker.wheelLayout + layout.setDateMode(DateMode.YEAR_MONTH_DAY) + layout.setDateLabel("年", "月", "日"); + layout.setTextSize(14f.sp2px(this).toFloat()) + layout.setSelectedTextSize(16f.sp2px(this).toFloat()) + layout.setSelectedTextColor(R.color.themeColor.convertColor(this)) + layout.setSelectedTextBold(true) + layout.setResetWhenLinkage(false) + layout.setRange( + DateEntity.today(), + DateEntity.target(2050, 12, 31), + DateEntity.today() + ) + + datePicker.setOnDatePickedListener { year, month, day -> + callback.onDateSelected(String.format("%s-%s-%s", year, month, day)) + } + datePicker.show() +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt b/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt index 016ebcb..cf6bf49 100644 --- a/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt +++ b/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt @@ -4,7 +4,7 @@ * ArrayList扩展方法 */ -//将图片集合格式化成满足上传格式的数据 +//将集合格式化成满足上传格式的数据 fun ArrayList.reformat(): String { if (this.isEmpty()) return "" val builder = StringBuilder() diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt b/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt index 7c57643..aa9b92b 100644 --- a/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt +++ b/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt @@ -1,7 +1,6 @@ package com.casic.xz.meterage.extensions import android.content.Context -import android.util.Log import android.view.ViewGroup import com.casic.xz.meterage.base.BaseApplication import com.pengxh.kt.lite.extensions.dp2px @@ -9,9 +8,8 @@ fun Context.initLayoutImmersionBar(rootView: ViewGroup) { var statusBarHeight = QMUIDisplayHelper.getStatusBarHeight(this) - Log.d("Casic", "状态栏高度: $statusBarHeight") if (statusBarHeight == 0) { - statusBarHeight = 44f.dp2px(BaseApplication.get()) + statusBarHeight = 40f.dp2px(BaseApplication.get()) } rootView.setPadding(0, statusBarHeight, 0, 0) rootView.requestLayout() diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/String.kt b/app/src/main/java/com/casic/xz/meterage/extensions/String.kt index 28f70d8..6234d43 100644 --- a/app/src/main/java/com/casic/xz/meterage/extensions/String.kt +++ b/app/src/main/java/com/casic/xz/meterage/extensions/String.kt @@ -128,9 +128,10 @@ fun String.combineImagePath(): String { if (this.isEmpty()) return this val defaultValue = SaveKeyValues.getValue( - LocaleConstant.DEFAULT_SERVER_CONFIG, LocaleConstant.SERVER_BASE_URL + LocaleConstant.FILE_SERVER_CONFIG, LocaleConstant.File_SERVER_URL ) as String - return "$defaultValue/static/${this.replace("\\", "/")}" + //http://111.198.10.15:21408/test/1677479806059688_1677479806038.jpeg + return "$defaultValue/test/${this.replace("\\", "/")}" } fun String.isEarlier(time: String): Boolean { diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt index 25fa87b..a0e1358 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt @@ -1,18 +1,12 @@ package com.casic.xz.meterage.fragment.customer +import android.graphics.Color import android.graphics.Paint import com.casic.xz.meterage.R -import com.casic.xz.meterage.extensions.combineImagePath import com.casic.xz.meterage.extensions.toChineseGrade +import com.casic.xz.meterage.extensions.watchAttachFile import com.casic.xz.meterage.model.CustomerDetailModel -import com.casic.xz.meterage.view.BigImageActivity -import com.casic.xz.meterage.view.notice.PreviewDocumentActivity -import com.casic.xz.meterage.view.notice.PreviewPdfActivity -import com.casic.xz.meterage.view.notice.PreviewTextActivity import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.extensions.show import kotlinx.android.synthetic.main.fragment_customer_basic_information.* class BasicInformationFragment(private val data: CustomerDetailModel.DataModel) : @@ -48,30 +42,11 @@ val textPaint = minioFileView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - minioFileView.setTextColor(R.color.themeColor.convertColor(requireContext())) + minioFileView.setTextColor(Color.BLUE) minioFileView.setOnClickListener { //查看附件 - if (minioFileName.endsWith("pdf")) { - requireContext().navigatePageTo(minioFileName) - } else if ( - minioFileName.endsWith("doc") || - minioFileName.endsWith("docx") - ) { - requireContext().navigatePageTo(minioFileName) - } else if (minioFileName.endsWith("txt")) { - requireContext().navigatePageTo(minioFileName) - } else if ( - minioFileName.endsWith("png") || - minioFileName.endsWith("jpeg") || - minioFileName.endsWith("jpg") - ) { - val urls = ArrayList() - urls.add(minioFileName.combineImagePath()) - requireContext().navigatePageTo(0, urls) - } else { - "文件类型未知,无法打开附件".show(requireContext()) - } + minioFileName.watchAttachFile(requireContext()) } } } diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt index 77846b4..3a0fe2e 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt @@ -1,5 +1,6 @@ package com.casic.xz.meterage.fragment.device +import android.graphics.Color import android.graphics.Paint import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R @@ -7,7 +8,6 @@ import com.casic.xz.meterage.utils.LoadingDialogHub import com.casic.xz.meterage.vm.EquipmentViewModel import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor import com.pengxh.kt.lite.vm.LoadState import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import kotlinx.android.synthetic.main.fragment_device_basic_information.* @@ -56,7 +56,7 @@ val textPaint = documentsView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - documentsView.setTextColor(R.color.themeColor.convertColor(requireContext())) + documentsView.setTextColor(Color.BLUE) val files = ArrayList() data.fileList.forEach { file -> @@ -66,7 +66,7 @@ BottomActionSheet.Builder() .setContext(requireContext()) .setActionItemTitle(files) - .setItemTextColor(R.color.themeColor.convertColor(requireContext())) + .setItemTextColor(Color.BLUE) .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { override fun onActionItemClick(position: Int) { diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt index 15dc3d2..10eeff8 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt @@ -1,5 +1,6 @@ package com.casic.xz.meterage.fragment.entrust +import android.graphics.Color import android.graphics.Paint import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R @@ -9,7 +10,6 @@ import com.casic.xz.meterage.model.EntrustDetailModel import com.casic.xz.meterage.vm.DictionaryViewModel import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor import kotlinx.android.synthetic.main.fragment_entrust_basic_information.* class BasicInformationFragment(private val data: EntrustDetailModel.DataModel) : @@ -38,7 +38,7 @@ val textPaint = annexView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - annexView.setTextColor(R.color.themeColor.convertColor(requireContext())) + annexView.setTextColor(Color.BLUE) annexView.setOnClickListener { minioFileName.watchAttachFile(requireContext()) @@ -59,9 +59,9 @@ //加急 if (data.isUrgent == "0") { - RadioButton2.isChecked = true + radioButton2.isChecked = true } else { - RadioButton1.isChecked = true + radioButton1.isChecked = true } //样品 diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/equipment/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/equipment/BasicInformationFragment.kt index 72b523c..7bc3b01 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/equipment/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/equipment/BasicInformationFragment.kt @@ -1,5 +1,6 @@ package com.casic.xz.meterage.fragment.equipment +import android.graphics.Color import android.graphics.Paint import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R @@ -7,7 +8,6 @@ import com.casic.xz.meterage.utils.LoadingDialogHub import com.casic.xz.meterage.vm.EquipmentViewModel import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor import com.pengxh.kt.lite.vm.LoadState import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import kotlinx.android.synthetic.main.fragment_equipment_basic_information.* @@ -74,7 +74,7 @@ val textPaint = instructionsView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - instructionsView.setTextColor(R.color.themeColor.convertColor(requireContext())) + instructionsView.setTextColor(Color.BLUE) val files = ArrayList() data.fileList.forEach { file -> @@ -84,7 +84,7 @@ BottomActionSheet.Builder() .setContext(requireContext()) .setActionItemTitle(files) - .setItemTextColor(R.color.themeColor.convertColor(requireContext())) + .setItemTextColor(Color.BLUE) .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { override fun onActionItemClick(position: Int) { diff --git a/app/build.gradle b/app/build.gradle index 0ae369f..687b02b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -15,7 +15,6 @@ } compileSdkVersion 31 - buildToolsVersion "30.0.3" defaultConfig { applicationId "com.casic.xz.meterage" @@ -84,11 +83,13 @@ implementation 'top.zibin:Luban:1.1.8' //官方Json解析库 implementation 'com.google.code.gson:gson:2.9.0' + //阿里巴巴JSON库 + implementation 'com.alibaba.fastjson2:fastjson2:2.0.24' //Kotlin协程 implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.5.1' //MVVM+LiveData implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.5.1" - implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.0" + implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1" implementation "androidx.lifecycle:lifecycle-extensions:2.2.0" //返回值转换器 implementation 'com.jakewharton.retrofit:retrofit2-kotlin-coroutines-adapter:0.9.2' @@ -109,4 +110,8 @@ implementation 'com.github.barteksc:android-pdf-viewer:2.8.2' //绕过Android 11反射限制 implementation 'com.github.tiann:FreeReflection:3.1.0' + //单项/数字、二三级联动、日期/时间等滚轮选择器 + implementation 'com.github.gzu-liyujiang.AndroidPicker:WheelPicker:4.1.8' + //文件/目录选择器 + implementation 'com.github.gzu-liyujiang.AndroidPicker:FilePicker:4.1.1' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 1ccc12b..0fba91b 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -60,6 +60,8 @@ + + diff --git a/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt b/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt new file mode 100644 index 0000000..21a71d8 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt @@ -0,0 +1,70 @@ +package com.casic.xz.meterage.adapter + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import com.casic.xz.meterage.R +import com.casic.xz.meterage.extensions.toChineseGrade +import com.casic.xz.meterage.model.CustomerListModel + +class SelectCustomerAdapter( + context: Context, private val dataRows: MutableList +) : RecyclerView.Adapter() { + + private var layoutInflater = LayoutInflater.from(context) + + //选择的位置 + private var selectedPosition = 0 + + //临时记录上次选择的位置 + private var temp = -1 + + override fun getItemCount(): Int = dataRows.size + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ItemViewHolder( + layoutInflater.inflate(R.layout.item_select_customer_lv, parent, false) + ) + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + //绑定数据 + val rowsBean = dataRows[position] + holder.agreementLevelView.text = rowsBean.grade.toChineseGrade() + holder.customerNameView.text = rowsBean.customerName + holder.scaleView.text = rowsBean.companySizeName + holder.overallView.text = "公司规模:${rowsBean.evaluationName}" + holder.fullAddressView.text = "公司地址:${rowsBean.fullAddress}" + + holder.itemView.isSelected = holder.layoutPosition == selectedPosition + holder.itemView.setOnClickListener { + itemCheckedListener?.onItemChecked(rowsBean) + + holder.itemView.isSelected = true + temp = selectedPosition + //设置新的位置 + selectedPosition = holder.layoutPosition + //更新旧位置 + notifyItemChanged(temp) + } + } + + inner class ItemViewHolder(view: View) : RecyclerView.ViewHolder(view) { + var agreementLevelView: TextView = view.findViewById(R.id.agreementLevelView) + var customerNameView: TextView = view.findViewById(R.id.customerNameView) + var scaleView: TextView = view.findViewById(R.id.scaleView) + var overallView: TextView = view.findViewById(R.id.overallView) + var fullAddressView: TextView = view.findViewById(R.id.fullAddressView) + } + + private var itemCheckedListener: OnItemCheckedListener? = null + + interface OnItemCheckedListener { + fun onItemChecked(item: CustomerListModel.DataModel.RowsModel) + } + + fun setOnCheckedListener(listener: OnItemCheckedListener?) { + itemCheckedListener = listener + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt b/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt new file mode 100644 index 0000000..c29461e --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt @@ -0,0 +1,68 @@ +package com.casic.xz.meterage.adapter + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import com.casic.xz.meterage.R +import com.casic.xz.meterage.model.SampleListModel + +class SelectSampleAdapter( + context: Context, private val dataRows: MutableList +) : RecyclerView.Adapter() { + + private var layoutInflater = LayoutInflater.from(context) + private var multipleSelected = mutableSetOf() + private var sampleModes = ArrayList() + + override fun getItemCount(): Int = dataRows.size + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ItemViewHolder( + layoutInflater.inflate(R.layout.item_select_sample_lv, parent, false) + ) + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + //绑定数据 + val rowsBean = dataRows[position] + holder.sampleNameView.text = "${rowsBean.sampleName}【${rowsBean.sampleModel}】" + holder.manufacturingCodeView.text = "出厂编号:${rowsBean.manufacturingNo}" + holder.sampleCodeView.text = "样品编号:${rowsBean.sampleNo}" + holder.validDateView.text = "有效期至:${rowsBean.validDeadline}" + + holder.checkImageView.isSelected = multipleSelected.contains(position) + holder.itemView.setOnClickListener { + if (multipleSelected.contains(position)) { + multipleSelected.remove(position) + sampleModes.remove(dataRows[position]) + holder.checkImageView.isSelected = false + } else { + multipleSelected.add(position) + sampleModes.add(dataRows[position]) + holder.checkImageView.isSelected = true + } + + itemCheckedListener?.onItemChecked(sampleModes) + } + } + + inner class ItemViewHolder(view: View) : RecyclerView.ViewHolder(view) { + var sampleNameView: TextView = view.findViewById(R.id.sampleNameView) + var manufacturingCodeView: TextView = view.findViewById(R.id.manufacturingCodeView) + var sampleCodeView: TextView = view.findViewById(R.id.sampleCodeView) + var validDateView: TextView = view.findViewById(R.id.validDateView) + var checkImageView: ImageView = view.findViewById(R.id.checkImageView) + } + + private var itemCheckedListener: OnItemCheckedListener? = null + + interface OnItemCheckedListener { + fun onItemChecked(items: ArrayList) + } + + fun setOnCheckedListener(listener: OnItemCheckedListener?) { + itemCheckedListener = listener + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/callback/DateSelectedCallback.kt b/app/src/main/java/com/casic/xz/meterage/callback/DateSelectedCallback.kt new file mode 100644 index 0000000..8196110 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/callback/DateSelectedCallback.kt @@ -0,0 +1,5 @@ +package com.casic.xz.meterage.callback + +interface DateSelectedCallback { + fun onDateSelected(date: String) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/Activity.kt b/app/src/main/java/com/casic/xz/meterage/extensions/Activity.kt new file mode 100644 index 0000000..e112d1c --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/extensions/Activity.kt @@ -0,0 +1,33 @@ +package com.casic.xz.meterage.extensions + +import android.app.Activity +import com.casic.xz.meterage.R +import com.casic.xz.meterage.callback.DateSelectedCallback +import com.github.gzuliyujiang.wheelpicker.DatePicker +import com.github.gzuliyujiang.wheelpicker.annotation.DateMode +import com.github.gzuliyujiang.wheelpicker.entity.DateEntity +import com.pengxh.kt.lite.extensions.convertColor +import com.pengxh.kt.lite.extensions.sp2px + +fun Activity.showDatePicker(callback: DateSelectedCallback) { + val datePicker = DatePicker(this) + + val layout = datePicker.wheelLayout + layout.setDateMode(DateMode.YEAR_MONTH_DAY) + layout.setDateLabel("年", "月", "日"); + layout.setTextSize(14f.sp2px(this).toFloat()) + layout.setSelectedTextSize(16f.sp2px(this).toFloat()) + layout.setSelectedTextColor(R.color.themeColor.convertColor(this)) + layout.setSelectedTextBold(true) + layout.setResetWhenLinkage(false) + layout.setRange( + DateEntity.today(), + DateEntity.target(2050, 12, 31), + DateEntity.today() + ) + + datePicker.setOnDatePickedListener { year, month, day -> + callback.onDateSelected(String.format("%s-%s-%s", year, month, day)) + } + datePicker.show() +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt b/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt index 016ebcb..cf6bf49 100644 --- a/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt +++ b/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt @@ -4,7 +4,7 @@ * ArrayList扩展方法 */ -//将图片集合格式化成满足上传格式的数据 +//将集合格式化成满足上传格式的数据 fun ArrayList.reformat(): String { if (this.isEmpty()) return "" val builder = StringBuilder() diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt b/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt index 7c57643..aa9b92b 100644 --- a/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt +++ b/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt @@ -1,7 +1,6 @@ package com.casic.xz.meterage.extensions import android.content.Context -import android.util.Log import android.view.ViewGroup import com.casic.xz.meterage.base.BaseApplication import com.pengxh.kt.lite.extensions.dp2px @@ -9,9 +8,8 @@ fun Context.initLayoutImmersionBar(rootView: ViewGroup) { var statusBarHeight = QMUIDisplayHelper.getStatusBarHeight(this) - Log.d("Casic", "状态栏高度: $statusBarHeight") if (statusBarHeight == 0) { - statusBarHeight = 44f.dp2px(BaseApplication.get()) + statusBarHeight = 40f.dp2px(BaseApplication.get()) } rootView.setPadding(0, statusBarHeight, 0, 0) rootView.requestLayout() diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/String.kt b/app/src/main/java/com/casic/xz/meterage/extensions/String.kt index 28f70d8..6234d43 100644 --- a/app/src/main/java/com/casic/xz/meterage/extensions/String.kt +++ b/app/src/main/java/com/casic/xz/meterage/extensions/String.kt @@ -128,9 +128,10 @@ fun String.combineImagePath(): String { if (this.isEmpty()) return this val defaultValue = SaveKeyValues.getValue( - LocaleConstant.DEFAULT_SERVER_CONFIG, LocaleConstant.SERVER_BASE_URL + LocaleConstant.FILE_SERVER_CONFIG, LocaleConstant.File_SERVER_URL ) as String - return "$defaultValue/static/${this.replace("\\", "/")}" + //http://111.198.10.15:21408/test/1677479806059688_1677479806038.jpeg + return "$defaultValue/test/${this.replace("\\", "/")}" } fun String.isEarlier(time: String): Boolean { diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt index 25fa87b..a0e1358 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt @@ -1,18 +1,12 @@ package com.casic.xz.meterage.fragment.customer +import android.graphics.Color import android.graphics.Paint import com.casic.xz.meterage.R -import com.casic.xz.meterage.extensions.combineImagePath import com.casic.xz.meterage.extensions.toChineseGrade +import com.casic.xz.meterage.extensions.watchAttachFile import com.casic.xz.meterage.model.CustomerDetailModel -import com.casic.xz.meterage.view.BigImageActivity -import com.casic.xz.meterage.view.notice.PreviewDocumentActivity -import com.casic.xz.meterage.view.notice.PreviewPdfActivity -import com.casic.xz.meterage.view.notice.PreviewTextActivity import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.extensions.show import kotlinx.android.synthetic.main.fragment_customer_basic_information.* class BasicInformationFragment(private val data: CustomerDetailModel.DataModel) : @@ -48,30 +42,11 @@ val textPaint = minioFileView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - minioFileView.setTextColor(R.color.themeColor.convertColor(requireContext())) + minioFileView.setTextColor(Color.BLUE) minioFileView.setOnClickListener { //查看附件 - if (minioFileName.endsWith("pdf")) { - requireContext().navigatePageTo(minioFileName) - } else if ( - minioFileName.endsWith("doc") || - minioFileName.endsWith("docx") - ) { - requireContext().navigatePageTo(minioFileName) - } else if (minioFileName.endsWith("txt")) { - requireContext().navigatePageTo(minioFileName) - } else if ( - minioFileName.endsWith("png") || - minioFileName.endsWith("jpeg") || - minioFileName.endsWith("jpg") - ) { - val urls = ArrayList() - urls.add(minioFileName.combineImagePath()) - requireContext().navigatePageTo(0, urls) - } else { - "文件类型未知,无法打开附件".show(requireContext()) - } + minioFileName.watchAttachFile(requireContext()) } } } diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt index 77846b4..3a0fe2e 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt @@ -1,5 +1,6 @@ package com.casic.xz.meterage.fragment.device +import android.graphics.Color import android.graphics.Paint import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R @@ -7,7 +8,6 @@ import com.casic.xz.meterage.utils.LoadingDialogHub import com.casic.xz.meterage.vm.EquipmentViewModel import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor import com.pengxh.kt.lite.vm.LoadState import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import kotlinx.android.synthetic.main.fragment_device_basic_information.* @@ -56,7 +56,7 @@ val textPaint = documentsView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - documentsView.setTextColor(R.color.themeColor.convertColor(requireContext())) + documentsView.setTextColor(Color.BLUE) val files = ArrayList() data.fileList.forEach { file -> @@ -66,7 +66,7 @@ BottomActionSheet.Builder() .setContext(requireContext()) .setActionItemTitle(files) - .setItemTextColor(R.color.themeColor.convertColor(requireContext())) + .setItemTextColor(Color.BLUE) .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { override fun onActionItemClick(position: Int) { diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt index 15dc3d2..10eeff8 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt @@ -1,5 +1,6 @@ package com.casic.xz.meterage.fragment.entrust +import android.graphics.Color import android.graphics.Paint import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R @@ -9,7 +10,6 @@ import com.casic.xz.meterage.model.EntrustDetailModel import com.casic.xz.meterage.vm.DictionaryViewModel import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor import kotlinx.android.synthetic.main.fragment_entrust_basic_information.* class BasicInformationFragment(private val data: EntrustDetailModel.DataModel) : @@ -38,7 +38,7 @@ val textPaint = annexView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - annexView.setTextColor(R.color.themeColor.convertColor(requireContext())) + annexView.setTextColor(Color.BLUE) annexView.setOnClickListener { minioFileName.watchAttachFile(requireContext()) @@ -59,9 +59,9 @@ //加急 if (data.isUrgent == "0") { - RadioButton2.isChecked = true + radioButton2.isChecked = true } else { - RadioButton1.isChecked = true + radioButton1.isChecked = true } //样品 diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/equipment/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/equipment/BasicInformationFragment.kt index 72b523c..7bc3b01 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/equipment/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/equipment/BasicInformationFragment.kt @@ -1,5 +1,6 @@ package com.casic.xz.meterage.fragment.equipment +import android.graphics.Color import android.graphics.Paint import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R @@ -7,7 +8,6 @@ import com.casic.xz.meterage.utils.LoadingDialogHub import com.casic.xz.meterage.vm.EquipmentViewModel import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor import com.pengxh.kt.lite.vm.LoadState import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import kotlinx.android.synthetic.main.fragment_equipment_basic_information.* @@ -74,7 +74,7 @@ val textPaint = instructionsView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - instructionsView.setTextColor(R.color.themeColor.convertColor(requireContext())) + instructionsView.setTextColor(Color.BLUE) val files = ArrayList() data.fileList.forEach { file -> @@ -84,7 +84,7 @@ BottomActionSheet.Builder() .setContext(requireContext()) .setActionItemTitle(files) - .setItemTextColor(R.color.themeColor.convertColor(requireContext())) + .setItemTextColor(Color.BLUE) .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { override fun onActionItemClick(position: Int) { diff --git a/app/src/main/java/com/casic/xz/meterage/model/SampleListModel.java b/app/src/main/java/com/casic/xz/meterage/model/SampleListModel.java new file mode 100644 index 0000000..5784343 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/model/SampleListModel.java @@ -0,0 +1,193 @@ +package com.casic.xz.meterage.model; + +import java.util.List; + +public class SampleListModel { + + private int code; + private DataModel data; + private String message; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataModel getData() { + return data; + } + + public void setData(DataModel data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public static class DataModel { + private List rows; + private int total; + + public List getRows() { + return rows; + } + + public void setRows(List rows) { + this.rows = rows; + } + + public int getTotal() { + return total; + } + + public void setTotal(int total) { + this.total = total; + } + + public static class RowsModel { + private String certificationStatus; + private String customerName; + private String customerNo; + private String id; + private String manufacturingNo; + private String measureLastTime; + private String measurePeriod; + private String orderId; + private String remark; + private String sampleModel; + private String sampleName; + private String sampleNo; + private String sampleSatus; + private String sampleSatusName; + private String validDeadline; + + public String getCertificationStatus() { + return certificationStatus; + } + + public void setCertificationStatus(String certificationStatus) { + this.certificationStatus = certificationStatus; + } + + public String getCustomerName() { + return customerName; + } + + public void setCustomerName(String customerName) { + this.customerName = customerName; + } + + public String getCustomerNo() { + return customerNo; + } + + public void setCustomerNo(String customerNo) { + this.customerNo = customerNo; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getManufacturingNo() { + return manufacturingNo; + } + + public void setManufacturingNo(String manufacturingNo) { + this.manufacturingNo = manufacturingNo; + } + + public String getMeasureLastTime() { + return measureLastTime; + } + + public void setMeasureLastTime(String measureLastTime) { + this.measureLastTime = measureLastTime; + } + + public String getMeasurePeriod() { + return measurePeriod; + } + + public void setMeasurePeriod(String measurePeriod) { + this.measurePeriod = measurePeriod; + } + + public String getOrderId() { + return orderId; + } + + public void setOrderId(String orderId) { + this.orderId = orderId; + } + + public String getRemark() { + return remark; + } + + public void setRemark(String remark) { + this.remark = remark; + } + + public String getSampleModel() { + return sampleModel; + } + + public void setSampleModel(String sampleModel) { + this.sampleModel = sampleModel; + } + + public String getSampleName() { + return sampleName; + } + + public void setSampleName(String sampleName) { + this.sampleName = sampleName; + } + + public String getSampleNo() { + return sampleNo; + } + + public void setSampleNo(String sampleNo) { + this.sampleNo = sampleNo; + } + + public String getSampleSatus() { + return sampleSatus; + } + + public void setSampleSatus(String sampleSatus) { + this.sampleSatus = sampleSatus; + } + + public String getSampleSatusName() { + return sampleSatusName; + } + + public void setSampleSatusName(String sampleSatusName) { + this.sampleSatusName = sampleSatusName; + } + + public String getValidDeadline() { + return validDeadline; + } + + public void setValidDeadline(String validDeadline) { + this.validDeadline = validDeadline; + } + } + } +} diff --git a/app/build.gradle b/app/build.gradle index 0ae369f..687b02b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -15,7 +15,6 @@ } compileSdkVersion 31 - buildToolsVersion "30.0.3" defaultConfig { applicationId "com.casic.xz.meterage" @@ -84,11 +83,13 @@ implementation 'top.zibin:Luban:1.1.8' //官方Json解析库 implementation 'com.google.code.gson:gson:2.9.0' + //阿里巴巴JSON库 + implementation 'com.alibaba.fastjson2:fastjson2:2.0.24' //Kotlin协程 implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.5.1' //MVVM+LiveData implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.5.1" - implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.0" + implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1" implementation "androidx.lifecycle:lifecycle-extensions:2.2.0" //返回值转换器 implementation 'com.jakewharton.retrofit:retrofit2-kotlin-coroutines-adapter:0.9.2' @@ -109,4 +110,8 @@ implementation 'com.github.barteksc:android-pdf-viewer:2.8.2' //绕过Android 11反射限制 implementation 'com.github.tiann:FreeReflection:3.1.0' + //单项/数字、二三级联动、日期/时间等滚轮选择器 + implementation 'com.github.gzu-liyujiang.AndroidPicker:WheelPicker:4.1.8' + //文件/目录选择器 + implementation 'com.github.gzu-liyujiang.AndroidPicker:FilePicker:4.1.1' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 1ccc12b..0fba91b 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -60,6 +60,8 @@ + + diff --git a/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt b/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt new file mode 100644 index 0000000..21a71d8 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt @@ -0,0 +1,70 @@ +package com.casic.xz.meterage.adapter + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import com.casic.xz.meterage.R +import com.casic.xz.meterage.extensions.toChineseGrade +import com.casic.xz.meterage.model.CustomerListModel + +class SelectCustomerAdapter( + context: Context, private val dataRows: MutableList +) : RecyclerView.Adapter() { + + private var layoutInflater = LayoutInflater.from(context) + + //选择的位置 + private var selectedPosition = 0 + + //临时记录上次选择的位置 + private var temp = -1 + + override fun getItemCount(): Int = dataRows.size + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ItemViewHolder( + layoutInflater.inflate(R.layout.item_select_customer_lv, parent, false) + ) + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + //绑定数据 + val rowsBean = dataRows[position] + holder.agreementLevelView.text = rowsBean.grade.toChineseGrade() + holder.customerNameView.text = rowsBean.customerName + holder.scaleView.text = rowsBean.companySizeName + holder.overallView.text = "公司规模:${rowsBean.evaluationName}" + holder.fullAddressView.text = "公司地址:${rowsBean.fullAddress}" + + holder.itemView.isSelected = holder.layoutPosition == selectedPosition + holder.itemView.setOnClickListener { + itemCheckedListener?.onItemChecked(rowsBean) + + holder.itemView.isSelected = true + temp = selectedPosition + //设置新的位置 + selectedPosition = holder.layoutPosition + //更新旧位置 + notifyItemChanged(temp) + } + } + + inner class ItemViewHolder(view: View) : RecyclerView.ViewHolder(view) { + var agreementLevelView: TextView = view.findViewById(R.id.agreementLevelView) + var customerNameView: TextView = view.findViewById(R.id.customerNameView) + var scaleView: TextView = view.findViewById(R.id.scaleView) + var overallView: TextView = view.findViewById(R.id.overallView) + var fullAddressView: TextView = view.findViewById(R.id.fullAddressView) + } + + private var itemCheckedListener: OnItemCheckedListener? = null + + interface OnItemCheckedListener { + fun onItemChecked(item: CustomerListModel.DataModel.RowsModel) + } + + fun setOnCheckedListener(listener: OnItemCheckedListener?) { + itemCheckedListener = listener + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt b/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt new file mode 100644 index 0000000..c29461e --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt @@ -0,0 +1,68 @@ +package com.casic.xz.meterage.adapter + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import com.casic.xz.meterage.R +import com.casic.xz.meterage.model.SampleListModel + +class SelectSampleAdapter( + context: Context, private val dataRows: MutableList +) : RecyclerView.Adapter() { + + private var layoutInflater = LayoutInflater.from(context) + private var multipleSelected = mutableSetOf() + private var sampleModes = ArrayList() + + override fun getItemCount(): Int = dataRows.size + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ItemViewHolder( + layoutInflater.inflate(R.layout.item_select_sample_lv, parent, false) + ) + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + //绑定数据 + val rowsBean = dataRows[position] + holder.sampleNameView.text = "${rowsBean.sampleName}【${rowsBean.sampleModel}】" + holder.manufacturingCodeView.text = "出厂编号:${rowsBean.manufacturingNo}" + holder.sampleCodeView.text = "样品编号:${rowsBean.sampleNo}" + holder.validDateView.text = "有效期至:${rowsBean.validDeadline}" + + holder.checkImageView.isSelected = multipleSelected.contains(position) + holder.itemView.setOnClickListener { + if (multipleSelected.contains(position)) { + multipleSelected.remove(position) + sampleModes.remove(dataRows[position]) + holder.checkImageView.isSelected = false + } else { + multipleSelected.add(position) + sampleModes.add(dataRows[position]) + holder.checkImageView.isSelected = true + } + + itemCheckedListener?.onItemChecked(sampleModes) + } + } + + inner class ItemViewHolder(view: View) : RecyclerView.ViewHolder(view) { + var sampleNameView: TextView = view.findViewById(R.id.sampleNameView) + var manufacturingCodeView: TextView = view.findViewById(R.id.manufacturingCodeView) + var sampleCodeView: TextView = view.findViewById(R.id.sampleCodeView) + var validDateView: TextView = view.findViewById(R.id.validDateView) + var checkImageView: ImageView = view.findViewById(R.id.checkImageView) + } + + private var itemCheckedListener: OnItemCheckedListener? = null + + interface OnItemCheckedListener { + fun onItemChecked(items: ArrayList) + } + + fun setOnCheckedListener(listener: OnItemCheckedListener?) { + itemCheckedListener = listener + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/callback/DateSelectedCallback.kt b/app/src/main/java/com/casic/xz/meterage/callback/DateSelectedCallback.kt new file mode 100644 index 0000000..8196110 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/callback/DateSelectedCallback.kt @@ -0,0 +1,5 @@ +package com.casic.xz.meterage.callback + +interface DateSelectedCallback { + fun onDateSelected(date: String) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/Activity.kt b/app/src/main/java/com/casic/xz/meterage/extensions/Activity.kt new file mode 100644 index 0000000..e112d1c --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/extensions/Activity.kt @@ -0,0 +1,33 @@ +package com.casic.xz.meterage.extensions + +import android.app.Activity +import com.casic.xz.meterage.R +import com.casic.xz.meterage.callback.DateSelectedCallback +import com.github.gzuliyujiang.wheelpicker.DatePicker +import com.github.gzuliyujiang.wheelpicker.annotation.DateMode +import com.github.gzuliyujiang.wheelpicker.entity.DateEntity +import com.pengxh.kt.lite.extensions.convertColor +import com.pengxh.kt.lite.extensions.sp2px + +fun Activity.showDatePicker(callback: DateSelectedCallback) { + val datePicker = DatePicker(this) + + val layout = datePicker.wheelLayout + layout.setDateMode(DateMode.YEAR_MONTH_DAY) + layout.setDateLabel("年", "月", "日"); + layout.setTextSize(14f.sp2px(this).toFloat()) + layout.setSelectedTextSize(16f.sp2px(this).toFloat()) + layout.setSelectedTextColor(R.color.themeColor.convertColor(this)) + layout.setSelectedTextBold(true) + layout.setResetWhenLinkage(false) + layout.setRange( + DateEntity.today(), + DateEntity.target(2050, 12, 31), + DateEntity.today() + ) + + datePicker.setOnDatePickedListener { year, month, day -> + callback.onDateSelected(String.format("%s-%s-%s", year, month, day)) + } + datePicker.show() +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt b/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt index 016ebcb..cf6bf49 100644 --- a/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt +++ b/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt @@ -4,7 +4,7 @@ * ArrayList扩展方法 */ -//将图片集合格式化成满足上传格式的数据 +//将集合格式化成满足上传格式的数据 fun ArrayList.reformat(): String { if (this.isEmpty()) return "" val builder = StringBuilder() diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt b/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt index 7c57643..aa9b92b 100644 --- a/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt +++ b/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt @@ -1,7 +1,6 @@ package com.casic.xz.meterage.extensions import android.content.Context -import android.util.Log import android.view.ViewGroup import com.casic.xz.meterage.base.BaseApplication import com.pengxh.kt.lite.extensions.dp2px @@ -9,9 +8,8 @@ fun Context.initLayoutImmersionBar(rootView: ViewGroup) { var statusBarHeight = QMUIDisplayHelper.getStatusBarHeight(this) - Log.d("Casic", "状态栏高度: $statusBarHeight") if (statusBarHeight == 0) { - statusBarHeight = 44f.dp2px(BaseApplication.get()) + statusBarHeight = 40f.dp2px(BaseApplication.get()) } rootView.setPadding(0, statusBarHeight, 0, 0) rootView.requestLayout() diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/String.kt b/app/src/main/java/com/casic/xz/meterage/extensions/String.kt index 28f70d8..6234d43 100644 --- a/app/src/main/java/com/casic/xz/meterage/extensions/String.kt +++ b/app/src/main/java/com/casic/xz/meterage/extensions/String.kt @@ -128,9 +128,10 @@ fun String.combineImagePath(): String { if (this.isEmpty()) return this val defaultValue = SaveKeyValues.getValue( - LocaleConstant.DEFAULT_SERVER_CONFIG, LocaleConstant.SERVER_BASE_URL + LocaleConstant.FILE_SERVER_CONFIG, LocaleConstant.File_SERVER_URL ) as String - return "$defaultValue/static/${this.replace("\\", "/")}" + //http://111.198.10.15:21408/test/1677479806059688_1677479806038.jpeg + return "$defaultValue/test/${this.replace("\\", "/")}" } fun String.isEarlier(time: String): Boolean { diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt index 25fa87b..a0e1358 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt @@ -1,18 +1,12 @@ package com.casic.xz.meterage.fragment.customer +import android.graphics.Color import android.graphics.Paint import com.casic.xz.meterage.R -import com.casic.xz.meterage.extensions.combineImagePath import com.casic.xz.meterage.extensions.toChineseGrade +import com.casic.xz.meterage.extensions.watchAttachFile import com.casic.xz.meterage.model.CustomerDetailModel -import com.casic.xz.meterage.view.BigImageActivity -import com.casic.xz.meterage.view.notice.PreviewDocumentActivity -import com.casic.xz.meterage.view.notice.PreviewPdfActivity -import com.casic.xz.meterage.view.notice.PreviewTextActivity import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.extensions.show import kotlinx.android.synthetic.main.fragment_customer_basic_information.* class BasicInformationFragment(private val data: CustomerDetailModel.DataModel) : @@ -48,30 +42,11 @@ val textPaint = minioFileView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - minioFileView.setTextColor(R.color.themeColor.convertColor(requireContext())) + minioFileView.setTextColor(Color.BLUE) minioFileView.setOnClickListener { //查看附件 - if (minioFileName.endsWith("pdf")) { - requireContext().navigatePageTo(minioFileName) - } else if ( - minioFileName.endsWith("doc") || - minioFileName.endsWith("docx") - ) { - requireContext().navigatePageTo(minioFileName) - } else if (minioFileName.endsWith("txt")) { - requireContext().navigatePageTo(minioFileName) - } else if ( - minioFileName.endsWith("png") || - minioFileName.endsWith("jpeg") || - minioFileName.endsWith("jpg") - ) { - val urls = ArrayList() - urls.add(minioFileName.combineImagePath()) - requireContext().navigatePageTo(0, urls) - } else { - "文件类型未知,无法打开附件".show(requireContext()) - } + minioFileName.watchAttachFile(requireContext()) } } } diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt index 77846b4..3a0fe2e 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt @@ -1,5 +1,6 @@ package com.casic.xz.meterage.fragment.device +import android.graphics.Color import android.graphics.Paint import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R @@ -7,7 +8,6 @@ import com.casic.xz.meterage.utils.LoadingDialogHub import com.casic.xz.meterage.vm.EquipmentViewModel import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor import com.pengxh.kt.lite.vm.LoadState import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import kotlinx.android.synthetic.main.fragment_device_basic_information.* @@ -56,7 +56,7 @@ val textPaint = documentsView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - documentsView.setTextColor(R.color.themeColor.convertColor(requireContext())) + documentsView.setTextColor(Color.BLUE) val files = ArrayList() data.fileList.forEach { file -> @@ -66,7 +66,7 @@ BottomActionSheet.Builder() .setContext(requireContext()) .setActionItemTitle(files) - .setItemTextColor(R.color.themeColor.convertColor(requireContext())) + .setItemTextColor(Color.BLUE) .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { override fun onActionItemClick(position: Int) { diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt index 15dc3d2..10eeff8 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt @@ -1,5 +1,6 @@ package com.casic.xz.meterage.fragment.entrust +import android.graphics.Color import android.graphics.Paint import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R @@ -9,7 +10,6 @@ import com.casic.xz.meterage.model.EntrustDetailModel import com.casic.xz.meterage.vm.DictionaryViewModel import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor import kotlinx.android.synthetic.main.fragment_entrust_basic_information.* class BasicInformationFragment(private val data: EntrustDetailModel.DataModel) : @@ -38,7 +38,7 @@ val textPaint = annexView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - annexView.setTextColor(R.color.themeColor.convertColor(requireContext())) + annexView.setTextColor(Color.BLUE) annexView.setOnClickListener { minioFileName.watchAttachFile(requireContext()) @@ -59,9 +59,9 @@ //加急 if (data.isUrgent == "0") { - RadioButton2.isChecked = true + radioButton2.isChecked = true } else { - RadioButton1.isChecked = true + radioButton1.isChecked = true } //样品 diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/equipment/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/equipment/BasicInformationFragment.kt index 72b523c..7bc3b01 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/equipment/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/equipment/BasicInformationFragment.kt @@ -1,5 +1,6 @@ package com.casic.xz.meterage.fragment.equipment +import android.graphics.Color import android.graphics.Paint import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R @@ -7,7 +8,6 @@ import com.casic.xz.meterage.utils.LoadingDialogHub import com.casic.xz.meterage.vm.EquipmentViewModel import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor import com.pengxh.kt.lite.vm.LoadState import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import kotlinx.android.synthetic.main.fragment_equipment_basic_information.* @@ -74,7 +74,7 @@ val textPaint = instructionsView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - instructionsView.setTextColor(R.color.themeColor.convertColor(requireContext())) + instructionsView.setTextColor(Color.BLUE) val files = ArrayList() data.fileList.forEach { file -> @@ -84,7 +84,7 @@ BottomActionSheet.Builder() .setContext(requireContext()) .setActionItemTitle(files) - .setItemTextColor(R.color.themeColor.convertColor(requireContext())) + .setItemTextColor(Color.BLUE) .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { override fun onActionItemClick(position: Int) { diff --git a/app/src/main/java/com/casic/xz/meterage/model/SampleListModel.java b/app/src/main/java/com/casic/xz/meterage/model/SampleListModel.java new file mode 100644 index 0000000..5784343 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/model/SampleListModel.java @@ -0,0 +1,193 @@ +package com.casic.xz.meterage.model; + +import java.util.List; + +public class SampleListModel { + + private int code; + private DataModel data; + private String message; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataModel getData() { + return data; + } + + public void setData(DataModel data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public static class DataModel { + private List rows; + private int total; + + public List getRows() { + return rows; + } + + public void setRows(List rows) { + this.rows = rows; + } + + public int getTotal() { + return total; + } + + public void setTotal(int total) { + this.total = total; + } + + public static class RowsModel { + private String certificationStatus; + private String customerName; + private String customerNo; + private String id; + private String manufacturingNo; + private String measureLastTime; + private String measurePeriod; + private String orderId; + private String remark; + private String sampleModel; + private String sampleName; + private String sampleNo; + private String sampleSatus; + private String sampleSatusName; + private String validDeadline; + + public String getCertificationStatus() { + return certificationStatus; + } + + public void setCertificationStatus(String certificationStatus) { + this.certificationStatus = certificationStatus; + } + + public String getCustomerName() { + return customerName; + } + + public void setCustomerName(String customerName) { + this.customerName = customerName; + } + + public String getCustomerNo() { + return customerNo; + } + + public void setCustomerNo(String customerNo) { + this.customerNo = customerNo; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getManufacturingNo() { + return manufacturingNo; + } + + public void setManufacturingNo(String manufacturingNo) { + this.manufacturingNo = manufacturingNo; + } + + public String getMeasureLastTime() { + return measureLastTime; + } + + public void setMeasureLastTime(String measureLastTime) { + this.measureLastTime = measureLastTime; + } + + public String getMeasurePeriod() { + return measurePeriod; + } + + public void setMeasurePeriod(String measurePeriod) { + this.measurePeriod = measurePeriod; + } + + public String getOrderId() { + return orderId; + } + + public void setOrderId(String orderId) { + this.orderId = orderId; + } + + public String getRemark() { + return remark; + } + + public void setRemark(String remark) { + this.remark = remark; + } + + public String getSampleModel() { + return sampleModel; + } + + public void setSampleModel(String sampleModel) { + this.sampleModel = sampleModel; + } + + public String getSampleName() { + return sampleName; + } + + public void setSampleName(String sampleName) { + this.sampleName = sampleName; + } + + public String getSampleNo() { + return sampleNo; + } + + public void setSampleNo(String sampleNo) { + this.sampleNo = sampleNo; + } + + public String getSampleSatus() { + return sampleSatus; + } + + public void setSampleSatus(String sampleSatus) { + this.sampleSatus = sampleSatus; + } + + public String getSampleSatusName() { + return sampleSatusName; + } + + public void setSampleSatusName(String sampleSatusName) { + this.sampleSatusName = sampleSatusName; + } + + public String getValidDeadline() { + return validDeadline; + } + + public void setValidDeadline(String validDeadline) { + this.validDeadline = validDeadline; + } + } + } +} diff --git a/app/src/main/java/com/casic/xz/meterage/model/UploadResultModel.java b/app/src/main/java/com/casic/xz/meterage/model/UploadResultModel.java new file mode 100644 index 0000000..f2a6a41 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/model/UploadResultModel.java @@ -0,0 +1,34 @@ +package com.casic.xz.meterage.model; + +import java.util.List; + +public class UploadResultModel { + + private int code; + private List data; + private String message; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public List getData() { + return data; + } + + public void setData(List data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } +} diff --git a/app/build.gradle b/app/build.gradle index 0ae369f..687b02b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -15,7 +15,6 @@ } compileSdkVersion 31 - buildToolsVersion "30.0.3" defaultConfig { applicationId "com.casic.xz.meterage" @@ -84,11 +83,13 @@ implementation 'top.zibin:Luban:1.1.8' //官方Json解析库 implementation 'com.google.code.gson:gson:2.9.0' + //阿里巴巴JSON库 + implementation 'com.alibaba.fastjson2:fastjson2:2.0.24' //Kotlin协程 implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.5.1' //MVVM+LiveData implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.5.1" - implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.0" + implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1" implementation "androidx.lifecycle:lifecycle-extensions:2.2.0" //返回值转换器 implementation 'com.jakewharton.retrofit:retrofit2-kotlin-coroutines-adapter:0.9.2' @@ -109,4 +110,8 @@ implementation 'com.github.barteksc:android-pdf-viewer:2.8.2' //绕过Android 11反射限制 implementation 'com.github.tiann:FreeReflection:3.1.0' + //单项/数字、二三级联动、日期/时间等滚轮选择器 + implementation 'com.github.gzu-liyujiang.AndroidPicker:WheelPicker:4.1.8' + //文件/目录选择器 + implementation 'com.github.gzu-liyujiang.AndroidPicker:FilePicker:4.1.1' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 1ccc12b..0fba91b 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -60,6 +60,8 @@ + + diff --git a/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt b/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt new file mode 100644 index 0000000..21a71d8 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt @@ -0,0 +1,70 @@ +package com.casic.xz.meterage.adapter + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import com.casic.xz.meterage.R +import com.casic.xz.meterage.extensions.toChineseGrade +import com.casic.xz.meterage.model.CustomerListModel + +class SelectCustomerAdapter( + context: Context, private val dataRows: MutableList +) : RecyclerView.Adapter() { + + private var layoutInflater = LayoutInflater.from(context) + + //选择的位置 + private var selectedPosition = 0 + + //临时记录上次选择的位置 + private var temp = -1 + + override fun getItemCount(): Int = dataRows.size + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ItemViewHolder( + layoutInflater.inflate(R.layout.item_select_customer_lv, parent, false) + ) + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + //绑定数据 + val rowsBean = dataRows[position] + holder.agreementLevelView.text = rowsBean.grade.toChineseGrade() + holder.customerNameView.text = rowsBean.customerName + holder.scaleView.text = rowsBean.companySizeName + holder.overallView.text = "公司规模:${rowsBean.evaluationName}" + holder.fullAddressView.text = "公司地址:${rowsBean.fullAddress}" + + holder.itemView.isSelected = holder.layoutPosition == selectedPosition + holder.itemView.setOnClickListener { + itemCheckedListener?.onItemChecked(rowsBean) + + holder.itemView.isSelected = true + temp = selectedPosition + //设置新的位置 + selectedPosition = holder.layoutPosition + //更新旧位置 + notifyItemChanged(temp) + } + } + + inner class ItemViewHolder(view: View) : RecyclerView.ViewHolder(view) { + var agreementLevelView: TextView = view.findViewById(R.id.agreementLevelView) + var customerNameView: TextView = view.findViewById(R.id.customerNameView) + var scaleView: TextView = view.findViewById(R.id.scaleView) + var overallView: TextView = view.findViewById(R.id.overallView) + var fullAddressView: TextView = view.findViewById(R.id.fullAddressView) + } + + private var itemCheckedListener: OnItemCheckedListener? = null + + interface OnItemCheckedListener { + fun onItemChecked(item: CustomerListModel.DataModel.RowsModel) + } + + fun setOnCheckedListener(listener: OnItemCheckedListener?) { + itemCheckedListener = listener + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt b/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt new file mode 100644 index 0000000..c29461e --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt @@ -0,0 +1,68 @@ +package com.casic.xz.meterage.adapter + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import com.casic.xz.meterage.R +import com.casic.xz.meterage.model.SampleListModel + +class SelectSampleAdapter( + context: Context, private val dataRows: MutableList +) : RecyclerView.Adapter() { + + private var layoutInflater = LayoutInflater.from(context) + private var multipleSelected = mutableSetOf() + private var sampleModes = ArrayList() + + override fun getItemCount(): Int = dataRows.size + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ItemViewHolder( + layoutInflater.inflate(R.layout.item_select_sample_lv, parent, false) + ) + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + //绑定数据 + val rowsBean = dataRows[position] + holder.sampleNameView.text = "${rowsBean.sampleName}【${rowsBean.sampleModel}】" + holder.manufacturingCodeView.text = "出厂编号:${rowsBean.manufacturingNo}" + holder.sampleCodeView.text = "样品编号:${rowsBean.sampleNo}" + holder.validDateView.text = "有效期至:${rowsBean.validDeadline}" + + holder.checkImageView.isSelected = multipleSelected.contains(position) + holder.itemView.setOnClickListener { + if (multipleSelected.contains(position)) { + multipleSelected.remove(position) + sampleModes.remove(dataRows[position]) + holder.checkImageView.isSelected = false + } else { + multipleSelected.add(position) + sampleModes.add(dataRows[position]) + holder.checkImageView.isSelected = true + } + + itemCheckedListener?.onItemChecked(sampleModes) + } + } + + inner class ItemViewHolder(view: View) : RecyclerView.ViewHolder(view) { + var sampleNameView: TextView = view.findViewById(R.id.sampleNameView) + var manufacturingCodeView: TextView = view.findViewById(R.id.manufacturingCodeView) + var sampleCodeView: TextView = view.findViewById(R.id.sampleCodeView) + var validDateView: TextView = view.findViewById(R.id.validDateView) + var checkImageView: ImageView = view.findViewById(R.id.checkImageView) + } + + private var itemCheckedListener: OnItemCheckedListener? = null + + interface OnItemCheckedListener { + fun onItemChecked(items: ArrayList) + } + + fun setOnCheckedListener(listener: OnItemCheckedListener?) { + itemCheckedListener = listener + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/callback/DateSelectedCallback.kt b/app/src/main/java/com/casic/xz/meterage/callback/DateSelectedCallback.kt new file mode 100644 index 0000000..8196110 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/callback/DateSelectedCallback.kt @@ -0,0 +1,5 @@ +package com.casic.xz.meterage.callback + +interface DateSelectedCallback { + fun onDateSelected(date: String) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/Activity.kt b/app/src/main/java/com/casic/xz/meterage/extensions/Activity.kt new file mode 100644 index 0000000..e112d1c --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/extensions/Activity.kt @@ -0,0 +1,33 @@ +package com.casic.xz.meterage.extensions + +import android.app.Activity +import com.casic.xz.meterage.R +import com.casic.xz.meterage.callback.DateSelectedCallback +import com.github.gzuliyujiang.wheelpicker.DatePicker +import com.github.gzuliyujiang.wheelpicker.annotation.DateMode +import com.github.gzuliyujiang.wheelpicker.entity.DateEntity +import com.pengxh.kt.lite.extensions.convertColor +import com.pengxh.kt.lite.extensions.sp2px + +fun Activity.showDatePicker(callback: DateSelectedCallback) { + val datePicker = DatePicker(this) + + val layout = datePicker.wheelLayout + layout.setDateMode(DateMode.YEAR_MONTH_DAY) + layout.setDateLabel("年", "月", "日"); + layout.setTextSize(14f.sp2px(this).toFloat()) + layout.setSelectedTextSize(16f.sp2px(this).toFloat()) + layout.setSelectedTextColor(R.color.themeColor.convertColor(this)) + layout.setSelectedTextBold(true) + layout.setResetWhenLinkage(false) + layout.setRange( + DateEntity.today(), + DateEntity.target(2050, 12, 31), + DateEntity.today() + ) + + datePicker.setOnDatePickedListener { year, month, day -> + callback.onDateSelected(String.format("%s-%s-%s", year, month, day)) + } + datePicker.show() +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt b/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt index 016ebcb..cf6bf49 100644 --- a/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt +++ b/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt @@ -4,7 +4,7 @@ * ArrayList扩展方法 */ -//将图片集合格式化成满足上传格式的数据 +//将集合格式化成满足上传格式的数据 fun ArrayList.reformat(): String { if (this.isEmpty()) return "" val builder = StringBuilder() diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt b/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt index 7c57643..aa9b92b 100644 --- a/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt +++ b/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt @@ -1,7 +1,6 @@ package com.casic.xz.meterage.extensions import android.content.Context -import android.util.Log import android.view.ViewGroup import com.casic.xz.meterage.base.BaseApplication import com.pengxh.kt.lite.extensions.dp2px @@ -9,9 +8,8 @@ fun Context.initLayoutImmersionBar(rootView: ViewGroup) { var statusBarHeight = QMUIDisplayHelper.getStatusBarHeight(this) - Log.d("Casic", "状态栏高度: $statusBarHeight") if (statusBarHeight == 0) { - statusBarHeight = 44f.dp2px(BaseApplication.get()) + statusBarHeight = 40f.dp2px(BaseApplication.get()) } rootView.setPadding(0, statusBarHeight, 0, 0) rootView.requestLayout() diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/String.kt b/app/src/main/java/com/casic/xz/meterage/extensions/String.kt index 28f70d8..6234d43 100644 --- a/app/src/main/java/com/casic/xz/meterage/extensions/String.kt +++ b/app/src/main/java/com/casic/xz/meterage/extensions/String.kt @@ -128,9 +128,10 @@ fun String.combineImagePath(): String { if (this.isEmpty()) return this val defaultValue = SaveKeyValues.getValue( - LocaleConstant.DEFAULT_SERVER_CONFIG, LocaleConstant.SERVER_BASE_URL + LocaleConstant.FILE_SERVER_CONFIG, LocaleConstant.File_SERVER_URL ) as String - return "$defaultValue/static/${this.replace("\\", "/")}" + //http://111.198.10.15:21408/test/1677479806059688_1677479806038.jpeg + return "$defaultValue/test/${this.replace("\\", "/")}" } fun String.isEarlier(time: String): Boolean { diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt index 25fa87b..a0e1358 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt @@ -1,18 +1,12 @@ package com.casic.xz.meterage.fragment.customer +import android.graphics.Color import android.graphics.Paint import com.casic.xz.meterage.R -import com.casic.xz.meterage.extensions.combineImagePath import com.casic.xz.meterage.extensions.toChineseGrade +import com.casic.xz.meterage.extensions.watchAttachFile import com.casic.xz.meterage.model.CustomerDetailModel -import com.casic.xz.meterage.view.BigImageActivity -import com.casic.xz.meterage.view.notice.PreviewDocumentActivity -import com.casic.xz.meterage.view.notice.PreviewPdfActivity -import com.casic.xz.meterage.view.notice.PreviewTextActivity import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.extensions.show import kotlinx.android.synthetic.main.fragment_customer_basic_information.* class BasicInformationFragment(private val data: CustomerDetailModel.DataModel) : @@ -48,30 +42,11 @@ val textPaint = minioFileView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - minioFileView.setTextColor(R.color.themeColor.convertColor(requireContext())) + minioFileView.setTextColor(Color.BLUE) minioFileView.setOnClickListener { //查看附件 - if (minioFileName.endsWith("pdf")) { - requireContext().navigatePageTo(minioFileName) - } else if ( - minioFileName.endsWith("doc") || - minioFileName.endsWith("docx") - ) { - requireContext().navigatePageTo(minioFileName) - } else if (minioFileName.endsWith("txt")) { - requireContext().navigatePageTo(minioFileName) - } else if ( - minioFileName.endsWith("png") || - minioFileName.endsWith("jpeg") || - minioFileName.endsWith("jpg") - ) { - val urls = ArrayList() - urls.add(minioFileName.combineImagePath()) - requireContext().navigatePageTo(0, urls) - } else { - "文件类型未知,无法打开附件".show(requireContext()) - } + minioFileName.watchAttachFile(requireContext()) } } } diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt index 77846b4..3a0fe2e 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt @@ -1,5 +1,6 @@ package com.casic.xz.meterage.fragment.device +import android.graphics.Color import android.graphics.Paint import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R @@ -7,7 +8,6 @@ import com.casic.xz.meterage.utils.LoadingDialogHub import com.casic.xz.meterage.vm.EquipmentViewModel import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor import com.pengxh.kt.lite.vm.LoadState import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import kotlinx.android.synthetic.main.fragment_device_basic_information.* @@ -56,7 +56,7 @@ val textPaint = documentsView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - documentsView.setTextColor(R.color.themeColor.convertColor(requireContext())) + documentsView.setTextColor(Color.BLUE) val files = ArrayList() data.fileList.forEach { file -> @@ -66,7 +66,7 @@ BottomActionSheet.Builder() .setContext(requireContext()) .setActionItemTitle(files) - .setItemTextColor(R.color.themeColor.convertColor(requireContext())) + .setItemTextColor(Color.BLUE) .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { override fun onActionItemClick(position: Int) { diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt index 15dc3d2..10eeff8 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt @@ -1,5 +1,6 @@ package com.casic.xz.meterage.fragment.entrust +import android.graphics.Color import android.graphics.Paint import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R @@ -9,7 +10,6 @@ import com.casic.xz.meterage.model.EntrustDetailModel import com.casic.xz.meterage.vm.DictionaryViewModel import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor import kotlinx.android.synthetic.main.fragment_entrust_basic_information.* class BasicInformationFragment(private val data: EntrustDetailModel.DataModel) : @@ -38,7 +38,7 @@ val textPaint = annexView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - annexView.setTextColor(R.color.themeColor.convertColor(requireContext())) + annexView.setTextColor(Color.BLUE) annexView.setOnClickListener { minioFileName.watchAttachFile(requireContext()) @@ -59,9 +59,9 @@ //加急 if (data.isUrgent == "0") { - RadioButton2.isChecked = true + radioButton2.isChecked = true } else { - RadioButton1.isChecked = true + radioButton1.isChecked = true } //样品 diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/equipment/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/equipment/BasicInformationFragment.kt index 72b523c..7bc3b01 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/equipment/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/equipment/BasicInformationFragment.kt @@ -1,5 +1,6 @@ package com.casic.xz.meterage.fragment.equipment +import android.graphics.Color import android.graphics.Paint import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R @@ -7,7 +8,6 @@ import com.casic.xz.meterage.utils.LoadingDialogHub import com.casic.xz.meterage.vm.EquipmentViewModel import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor import com.pengxh.kt.lite.vm.LoadState import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import kotlinx.android.synthetic.main.fragment_equipment_basic_information.* @@ -74,7 +74,7 @@ val textPaint = instructionsView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - instructionsView.setTextColor(R.color.themeColor.convertColor(requireContext())) + instructionsView.setTextColor(Color.BLUE) val files = ArrayList() data.fileList.forEach { file -> @@ -84,7 +84,7 @@ BottomActionSheet.Builder() .setContext(requireContext()) .setActionItemTitle(files) - .setItemTextColor(R.color.themeColor.convertColor(requireContext())) + .setItemTextColor(Color.BLUE) .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { override fun onActionItemClick(position: Int) { diff --git a/app/src/main/java/com/casic/xz/meterage/model/SampleListModel.java b/app/src/main/java/com/casic/xz/meterage/model/SampleListModel.java new file mode 100644 index 0000000..5784343 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/model/SampleListModel.java @@ -0,0 +1,193 @@ +package com.casic.xz.meterage.model; + +import java.util.List; + +public class SampleListModel { + + private int code; + private DataModel data; + private String message; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataModel getData() { + return data; + } + + public void setData(DataModel data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public static class DataModel { + private List rows; + private int total; + + public List getRows() { + return rows; + } + + public void setRows(List rows) { + this.rows = rows; + } + + public int getTotal() { + return total; + } + + public void setTotal(int total) { + this.total = total; + } + + public static class RowsModel { + private String certificationStatus; + private String customerName; + private String customerNo; + private String id; + private String manufacturingNo; + private String measureLastTime; + private String measurePeriod; + private String orderId; + private String remark; + private String sampleModel; + private String sampleName; + private String sampleNo; + private String sampleSatus; + private String sampleSatusName; + private String validDeadline; + + public String getCertificationStatus() { + return certificationStatus; + } + + public void setCertificationStatus(String certificationStatus) { + this.certificationStatus = certificationStatus; + } + + public String getCustomerName() { + return customerName; + } + + public void setCustomerName(String customerName) { + this.customerName = customerName; + } + + public String getCustomerNo() { + return customerNo; + } + + public void setCustomerNo(String customerNo) { + this.customerNo = customerNo; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getManufacturingNo() { + return manufacturingNo; + } + + public void setManufacturingNo(String manufacturingNo) { + this.manufacturingNo = manufacturingNo; + } + + public String getMeasureLastTime() { + return measureLastTime; + } + + public void setMeasureLastTime(String measureLastTime) { + this.measureLastTime = measureLastTime; + } + + public String getMeasurePeriod() { + return measurePeriod; + } + + public void setMeasurePeriod(String measurePeriod) { + this.measurePeriod = measurePeriod; + } + + public String getOrderId() { + return orderId; + } + + public void setOrderId(String orderId) { + this.orderId = orderId; + } + + public String getRemark() { + return remark; + } + + public void setRemark(String remark) { + this.remark = remark; + } + + public String getSampleModel() { + return sampleModel; + } + + public void setSampleModel(String sampleModel) { + this.sampleModel = sampleModel; + } + + public String getSampleName() { + return sampleName; + } + + public void setSampleName(String sampleName) { + this.sampleName = sampleName; + } + + public String getSampleNo() { + return sampleNo; + } + + public void setSampleNo(String sampleNo) { + this.sampleNo = sampleNo; + } + + public String getSampleSatus() { + return sampleSatus; + } + + public void setSampleSatus(String sampleSatus) { + this.sampleSatus = sampleSatus; + } + + public String getSampleSatusName() { + return sampleSatusName; + } + + public void setSampleSatusName(String sampleSatusName) { + this.sampleSatusName = sampleSatusName; + } + + public String getValidDeadline() { + return validDeadline; + } + + public void setValidDeadline(String validDeadline) { + this.validDeadline = validDeadline; + } + } + } +} diff --git a/app/src/main/java/com/casic/xz/meterage/model/UploadResultModel.java b/app/src/main/java/com/casic/xz/meterage/model/UploadResultModel.java new file mode 100644 index 0000000..f2a6a41 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/model/UploadResultModel.java @@ -0,0 +1,34 @@ +package com.casic.xz.meterage.model; + +import java.util.List; + +public class UploadResultModel { + + private int code; + private List data; + private String message; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public List getData() { + return data; + } + + public void setData(List data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } +} diff --git a/app/src/main/java/com/casic/xz/meterage/utils/FileType.kt b/app/src/main/java/com/casic/xz/meterage/utils/FileType.kt new file mode 100644 index 0000000..17e2bca --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/utils/FileType.kt @@ -0,0 +1,23 @@ +package com.casic.xz.meterage.utils + +sealed class FileType { + /** + * PDF文件 + */ + object PDF : FileType() + + /** + * WORD文件 + */ + object WORD : FileType() + + /** + * IMAGE图片 + */ + object IMAGE : FileType() + + /** + * 未知类型(Excel) + */ + object UNKNOWN : FileType() +} diff --git a/app/build.gradle b/app/build.gradle index 0ae369f..687b02b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -15,7 +15,6 @@ } compileSdkVersion 31 - buildToolsVersion "30.0.3" defaultConfig { applicationId "com.casic.xz.meterage" @@ -84,11 +83,13 @@ implementation 'top.zibin:Luban:1.1.8' //官方Json解析库 implementation 'com.google.code.gson:gson:2.9.0' + //阿里巴巴JSON库 + implementation 'com.alibaba.fastjson2:fastjson2:2.0.24' //Kotlin协程 implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.5.1' //MVVM+LiveData implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.5.1" - implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.0" + implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1" implementation "androidx.lifecycle:lifecycle-extensions:2.2.0" //返回值转换器 implementation 'com.jakewharton.retrofit:retrofit2-kotlin-coroutines-adapter:0.9.2' @@ -109,4 +110,8 @@ implementation 'com.github.barteksc:android-pdf-viewer:2.8.2' //绕过Android 11反射限制 implementation 'com.github.tiann:FreeReflection:3.1.0' + //单项/数字、二三级联动、日期/时间等滚轮选择器 + implementation 'com.github.gzu-liyujiang.AndroidPicker:WheelPicker:4.1.8' + //文件/目录选择器 + implementation 'com.github.gzu-liyujiang.AndroidPicker:FilePicker:4.1.1' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 1ccc12b..0fba91b 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -60,6 +60,8 @@ + + diff --git a/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt b/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt new file mode 100644 index 0000000..21a71d8 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt @@ -0,0 +1,70 @@ +package com.casic.xz.meterage.adapter + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import com.casic.xz.meterage.R +import com.casic.xz.meterage.extensions.toChineseGrade +import com.casic.xz.meterage.model.CustomerListModel + +class SelectCustomerAdapter( + context: Context, private val dataRows: MutableList +) : RecyclerView.Adapter() { + + private var layoutInflater = LayoutInflater.from(context) + + //选择的位置 + private var selectedPosition = 0 + + //临时记录上次选择的位置 + private var temp = -1 + + override fun getItemCount(): Int = dataRows.size + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ItemViewHolder( + layoutInflater.inflate(R.layout.item_select_customer_lv, parent, false) + ) + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + //绑定数据 + val rowsBean = dataRows[position] + holder.agreementLevelView.text = rowsBean.grade.toChineseGrade() + holder.customerNameView.text = rowsBean.customerName + holder.scaleView.text = rowsBean.companySizeName + holder.overallView.text = "公司规模:${rowsBean.evaluationName}" + holder.fullAddressView.text = "公司地址:${rowsBean.fullAddress}" + + holder.itemView.isSelected = holder.layoutPosition == selectedPosition + holder.itemView.setOnClickListener { + itemCheckedListener?.onItemChecked(rowsBean) + + holder.itemView.isSelected = true + temp = selectedPosition + //设置新的位置 + selectedPosition = holder.layoutPosition + //更新旧位置 + notifyItemChanged(temp) + } + } + + inner class ItemViewHolder(view: View) : RecyclerView.ViewHolder(view) { + var agreementLevelView: TextView = view.findViewById(R.id.agreementLevelView) + var customerNameView: TextView = view.findViewById(R.id.customerNameView) + var scaleView: TextView = view.findViewById(R.id.scaleView) + var overallView: TextView = view.findViewById(R.id.overallView) + var fullAddressView: TextView = view.findViewById(R.id.fullAddressView) + } + + private var itemCheckedListener: OnItemCheckedListener? = null + + interface OnItemCheckedListener { + fun onItemChecked(item: CustomerListModel.DataModel.RowsModel) + } + + fun setOnCheckedListener(listener: OnItemCheckedListener?) { + itemCheckedListener = listener + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt b/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt new file mode 100644 index 0000000..c29461e --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt @@ -0,0 +1,68 @@ +package com.casic.xz.meterage.adapter + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import com.casic.xz.meterage.R +import com.casic.xz.meterage.model.SampleListModel + +class SelectSampleAdapter( + context: Context, private val dataRows: MutableList +) : RecyclerView.Adapter() { + + private var layoutInflater = LayoutInflater.from(context) + private var multipleSelected = mutableSetOf() + private var sampleModes = ArrayList() + + override fun getItemCount(): Int = dataRows.size + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ItemViewHolder( + layoutInflater.inflate(R.layout.item_select_sample_lv, parent, false) + ) + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + //绑定数据 + val rowsBean = dataRows[position] + holder.sampleNameView.text = "${rowsBean.sampleName}【${rowsBean.sampleModel}】" + holder.manufacturingCodeView.text = "出厂编号:${rowsBean.manufacturingNo}" + holder.sampleCodeView.text = "样品编号:${rowsBean.sampleNo}" + holder.validDateView.text = "有效期至:${rowsBean.validDeadline}" + + holder.checkImageView.isSelected = multipleSelected.contains(position) + holder.itemView.setOnClickListener { + if (multipleSelected.contains(position)) { + multipleSelected.remove(position) + sampleModes.remove(dataRows[position]) + holder.checkImageView.isSelected = false + } else { + multipleSelected.add(position) + sampleModes.add(dataRows[position]) + holder.checkImageView.isSelected = true + } + + itemCheckedListener?.onItemChecked(sampleModes) + } + } + + inner class ItemViewHolder(view: View) : RecyclerView.ViewHolder(view) { + var sampleNameView: TextView = view.findViewById(R.id.sampleNameView) + var manufacturingCodeView: TextView = view.findViewById(R.id.manufacturingCodeView) + var sampleCodeView: TextView = view.findViewById(R.id.sampleCodeView) + var validDateView: TextView = view.findViewById(R.id.validDateView) + var checkImageView: ImageView = view.findViewById(R.id.checkImageView) + } + + private var itemCheckedListener: OnItemCheckedListener? = null + + interface OnItemCheckedListener { + fun onItemChecked(items: ArrayList) + } + + fun setOnCheckedListener(listener: OnItemCheckedListener?) { + itemCheckedListener = listener + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/callback/DateSelectedCallback.kt b/app/src/main/java/com/casic/xz/meterage/callback/DateSelectedCallback.kt new file mode 100644 index 0000000..8196110 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/callback/DateSelectedCallback.kt @@ -0,0 +1,5 @@ +package com.casic.xz.meterage.callback + +interface DateSelectedCallback { + fun onDateSelected(date: String) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/Activity.kt b/app/src/main/java/com/casic/xz/meterage/extensions/Activity.kt new file mode 100644 index 0000000..e112d1c --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/extensions/Activity.kt @@ -0,0 +1,33 @@ +package com.casic.xz.meterage.extensions + +import android.app.Activity +import com.casic.xz.meterage.R +import com.casic.xz.meterage.callback.DateSelectedCallback +import com.github.gzuliyujiang.wheelpicker.DatePicker +import com.github.gzuliyujiang.wheelpicker.annotation.DateMode +import com.github.gzuliyujiang.wheelpicker.entity.DateEntity +import com.pengxh.kt.lite.extensions.convertColor +import com.pengxh.kt.lite.extensions.sp2px + +fun Activity.showDatePicker(callback: DateSelectedCallback) { + val datePicker = DatePicker(this) + + val layout = datePicker.wheelLayout + layout.setDateMode(DateMode.YEAR_MONTH_DAY) + layout.setDateLabel("年", "月", "日"); + layout.setTextSize(14f.sp2px(this).toFloat()) + layout.setSelectedTextSize(16f.sp2px(this).toFloat()) + layout.setSelectedTextColor(R.color.themeColor.convertColor(this)) + layout.setSelectedTextBold(true) + layout.setResetWhenLinkage(false) + layout.setRange( + DateEntity.today(), + DateEntity.target(2050, 12, 31), + DateEntity.today() + ) + + datePicker.setOnDatePickedListener { year, month, day -> + callback.onDateSelected(String.format("%s-%s-%s", year, month, day)) + } + datePicker.show() +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt b/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt index 016ebcb..cf6bf49 100644 --- a/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt +++ b/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt @@ -4,7 +4,7 @@ * ArrayList扩展方法 */ -//将图片集合格式化成满足上传格式的数据 +//将集合格式化成满足上传格式的数据 fun ArrayList.reformat(): String { if (this.isEmpty()) return "" val builder = StringBuilder() diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt b/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt index 7c57643..aa9b92b 100644 --- a/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt +++ b/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt @@ -1,7 +1,6 @@ package com.casic.xz.meterage.extensions import android.content.Context -import android.util.Log import android.view.ViewGroup import com.casic.xz.meterage.base.BaseApplication import com.pengxh.kt.lite.extensions.dp2px @@ -9,9 +8,8 @@ fun Context.initLayoutImmersionBar(rootView: ViewGroup) { var statusBarHeight = QMUIDisplayHelper.getStatusBarHeight(this) - Log.d("Casic", "状态栏高度: $statusBarHeight") if (statusBarHeight == 0) { - statusBarHeight = 44f.dp2px(BaseApplication.get()) + statusBarHeight = 40f.dp2px(BaseApplication.get()) } rootView.setPadding(0, statusBarHeight, 0, 0) rootView.requestLayout() diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/String.kt b/app/src/main/java/com/casic/xz/meterage/extensions/String.kt index 28f70d8..6234d43 100644 --- a/app/src/main/java/com/casic/xz/meterage/extensions/String.kt +++ b/app/src/main/java/com/casic/xz/meterage/extensions/String.kt @@ -128,9 +128,10 @@ fun String.combineImagePath(): String { if (this.isEmpty()) return this val defaultValue = SaveKeyValues.getValue( - LocaleConstant.DEFAULT_SERVER_CONFIG, LocaleConstant.SERVER_BASE_URL + LocaleConstant.FILE_SERVER_CONFIG, LocaleConstant.File_SERVER_URL ) as String - return "$defaultValue/static/${this.replace("\\", "/")}" + //http://111.198.10.15:21408/test/1677479806059688_1677479806038.jpeg + return "$defaultValue/test/${this.replace("\\", "/")}" } fun String.isEarlier(time: String): Boolean { diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt index 25fa87b..a0e1358 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt @@ -1,18 +1,12 @@ package com.casic.xz.meterage.fragment.customer +import android.graphics.Color import android.graphics.Paint import com.casic.xz.meterage.R -import com.casic.xz.meterage.extensions.combineImagePath import com.casic.xz.meterage.extensions.toChineseGrade +import com.casic.xz.meterage.extensions.watchAttachFile import com.casic.xz.meterage.model.CustomerDetailModel -import com.casic.xz.meterage.view.BigImageActivity -import com.casic.xz.meterage.view.notice.PreviewDocumentActivity -import com.casic.xz.meterage.view.notice.PreviewPdfActivity -import com.casic.xz.meterage.view.notice.PreviewTextActivity import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.extensions.show import kotlinx.android.synthetic.main.fragment_customer_basic_information.* class BasicInformationFragment(private val data: CustomerDetailModel.DataModel) : @@ -48,30 +42,11 @@ val textPaint = minioFileView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - minioFileView.setTextColor(R.color.themeColor.convertColor(requireContext())) + minioFileView.setTextColor(Color.BLUE) minioFileView.setOnClickListener { //查看附件 - if (minioFileName.endsWith("pdf")) { - requireContext().navigatePageTo(minioFileName) - } else if ( - minioFileName.endsWith("doc") || - minioFileName.endsWith("docx") - ) { - requireContext().navigatePageTo(minioFileName) - } else if (minioFileName.endsWith("txt")) { - requireContext().navigatePageTo(minioFileName) - } else if ( - minioFileName.endsWith("png") || - minioFileName.endsWith("jpeg") || - minioFileName.endsWith("jpg") - ) { - val urls = ArrayList() - urls.add(minioFileName.combineImagePath()) - requireContext().navigatePageTo(0, urls) - } else { - "文件类型未知,无法打开附件".show(requireContext()) - } + minioFileName.watchAttachFile(requireContext()) } } } diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt index 77846b4..3a0fe2e 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt @@ -1,5 +1,6 @@ package com.casic.xz.meterage.fragment.device +import android.graphics.Color import android.graphics.Paint import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R @@ -7,7 +8,6 @@ import com.casic.xz.meterage.utils.LoadingDialogHub import com.casic.xz.meterage.vm.EquipmentViewModel import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor import com.pengxh.kt.lite.vm.LoadState import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import kotlinx.android.synthetic.main.fragment_device_basic_information.* @@ -56,7 +56,7 @@ val textPaint = documentsView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - documentsView.setTextColor(R.color.themeColor.convertColor(requireContext())) + documentsView.setTextColor(Color.BLUE) val files = ArrayList() data.fileList.forEach { file -> @@ -66,7 +66,7 @@ BottomActionSheet.Builder() .setContext(requireContext()) .setActionItemTitle(files) - .setItemTextColor(R.color.themeColor.convertColor(requireContext())) + .setItemTextColor(Color.BLUE) .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { override fun onActionItemClick(position: Int) { diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt index 15dc3d2..10eeff8 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt @@ -1,5 +1,6 @@ package com.casic.xz.meterage.fragment.entrust +import android.graphics.Color import android.graphics.Paint import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R @@ -9,7 +10,6 @@ import com.casic.xz.meterage.model.EntrustDetailModel import com.casic.xz.meterage.vm.DictionaryViewModel import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor import kotlinx.android.synthetic.main.fragment_entrust_basic_information.* class BasicInformationFragment(private val data: EntrustDetailModel.DataModel) : @@ -38,7 +38,7 @@ val textPaint = annexView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - annexView.setTextColor(R.color.themeColor.convertColor(requireContext())) + annexView.setTextColor(Color.BLUE) annexView.setOnClickListener { minioFileName.watchAttachFile(requireContext()) @@ -59,9 +59,9 @@ //加急 if (data.isUrgent == "0") { - RadioButton2.isChecked = true + radioButton2.isChecked = true } else { - RadioButton1.isChecked = true + radioButton1.isChecked = true } //样品 diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/equipment/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/equipment/BasicInformationFragment.kt index 72b523c..7bc3b01 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/equipment/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/equipment/BasicInformationFragment.kt @@ -1,5 +1,6 @@ package com.casic.xz.meterage.fragment.equipment +import android.graphics.Color import android.graphics.Paint import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R @@ -7,7 +8,6 @@ import com.casic.xz.meterage.utils.LoadingDialogHub import com.casic.xz.meterage.vm.EquipmentViewModel import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor import com.pengxh.kt.lite.vm.LoadState import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import kotlinx.android.synthetic.main.fragment_equipment_basic_information.* @@ -74,7 +74,7 @@ val textPaint = instructionsView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - instructionsView.setTextColor(R.color.themeColor.convertColor(requireContext())) + instructionsView.setTextColor(Color.BLUE) val files = ArrayList() data.fileList.forEach { file -> @@ -84,7 +84,7 @@ BottomActionSheet.Builder() .setContext(requireContext()) .setActionItemTitle(files) - .setItemTextColor(R.color.themeColor.convertColor(requireContext())) + .setItemTextColor(Color.BLUE) .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { override fun onActionItemClick(position: Int) { diff --git a/app/src/main/java/com/casic/xz/meterage/model/SampleListModel.java b/app/src/main/java/com/casic/xz/meterage/model/SampleListModel.java new file mode 100644 index 0000000..5784343 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/model/SampleListModel.java @@ -0,0 +1,193 @@ +package com.casic.xz.meterage.model; + +import java.util.List; + +public class SampleListModel { + + private int code; + private DataModel data; + private String message; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataModel getData() { + return data; + } + + public void setData(DataModel data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public static class DataModel { + private List rows; + private int total; + + public List getRows() { + return rows; + } + + public void setRows(List rows) { + this.rows = rows; + } + + public int getTotal() { + return total; + } + + public void setTotal(int total) { + this.total = total; + } + + public static class RowsModel { + private String certificationStatus; + private String customerName; + private String customerNo; + private String id; + private String manufacturingNo; + private String measureLastTime; + private String measurePeriod; + private String orderId; + private String remark; + private String sampleModel; + private String sampleName; + private String sampleNo; + private String sampleSatus; + private String sampleSatusName; + private String validDeadline; + + public String getCertificationStatus() { + return certificationStatus; + } + + public void setCertificationStatus(String certificationStatus) { + this.certificationStatus = certificationStatus; + } + + public String getCustomerName() { + return customerName; + } + + public void setCustomerName(String customerName) { + this.customerName = customerName; + } + + public String getCustomerNo() { + return customerNo; + } + + public void setCustomerNo(String customerNo) { + this.customerNo = customerNo; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getManufacturingNo() { + return manufacturingNo; + } + + public void setManufacturingNo(String manufacturingNo) { + this.manufacturingNo = manufacturingNo; + } + + public String getMeasureLastTime() { + return measureLastTime; + } + + public void setMeasureLastTime(String measureLastTime) { + this.measureLastTime = measureLastTime; + } + + public String getMeasurePeriod() { + return measurePeriod; + } + + public void setMeasurePeriod(String measurePeriod) { + this.measurePeriod = measurePeriod; + } + + public String getOrderId() { + return orderId; + } + + public void setOrderId(String orderId) { + this.orderId = orderId; + } + + public String getRemark() { + return remark; + } + + public void setRemark(String remark) { + this.remark = remark; + } + + public String getSampleModel() { + return sampleModel; + } + + public void setSampleModel(String sampleModel) { + this.sampleModel = sampleModel; + } + + public String getSampleName() { + return sampleName; + } + + public void setSampleName(String sampleName) { + this.sampleName = sampleName; + } + + public String getSampleNo() { + return sampleNo; + } + + public void setSampleNo(String sampleNo) { + this.sampleNo = sampleNo; + } + + public String getSampleSatus() { + return sampleSatus; + } + + public void setSampleSatus(String sampleSatus) { + this.sampleSatus = sampleSatus; + } + + public String getSampleSatusName() { + return sampleSatusName; + } + + public void setSampleSatusName(String sampleSatusName) { + this.sampleSatusName = sampleSatusName; + } + + public String getValidDeadline() { + return validDeadline; + } + + public void setValidDeadline(String validDeadline) { + this.validDeadline = validDeadline; + } + } + } +} diff --git a/app/src/main/java/com/casic/xz/meterage/model/UploadResultModel.java b/app/src/main/java/com/casic/xz/meterage/model/UploadResultModel.java new file mode 100644 index 0000000..f2a6a41 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/model/UploadResultModel.java @@ -0,0 +1,34 @@ +package com.casic.xz.meterage.model; + +import java.util.List; + +public class UploadResultModel { + + private int code; + private List data; + private String message; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public List getData() { + return data; + } + + public void setData(List data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } +} diff --git a/app/src/main/java/com/casic/xz/meterage/utils/FileType.kt b/app/src/main/java/com/casic/xz/meterage/utils/FileType.kt new file mode 100644 index 0000000..17e2bca --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/utils/FileType.kt @@ -0,0 +1,23 @@ +package com.casic.xz.meterage.utils + +sealed class FileType { + /** + * PDF文件 + */ + object PDF : FileType() + + /** + * WORD文件 + */ + object WORD : FileType() + + /** + * IMAGE图片 + */ + object IMAGE : FileType() + + /** + * 未知类型(Excel) + */ + object UNKNOWN : FileType() +} diff --git a/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitService.kt index bc3f8d6..8f4fe44 100644 --- a/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitService.kt @@ -1,5 +1,6 @@ package com.casic.xz.meterage.utils.retrofit +import okhttp3.MultipartBody import okhttp3.RequestBody import retrofit2.http.* @@ -35,6 +36,16 @@ ): String /** + * 上传文件 + */ + @Multipart + @POST("/minio/file/upload") + suspend fun uploadFile( + @Header("token") token: String, + @Part file: MultipartBody.Part + ): String + + /** * 获取通知公告列表 */ @POST("/system/notice/listPage") @@ -209,4 +220,24 @@ @Header("token") token: String, @Body requestBody: RequestBody ): String + + /** + * 获取样品列表 + */ + @POST("/customer/sample/listPage") + suspend fun getSampleList( + @Header("token") token: String, + @Body requestBody: RequestBody, + @QueryMap limit: Map, + @QueryMap offset: Map + ): String + + /** + * 新增委托书 + */ + @POST("/business/order/add") + suspend fun addEntrust( + @Header("token") token: String, + @Body requestBody: RequestBody + ): String } \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 0ae369f..687b02b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -15,7 +15,6 @@ } compileSdkVersion 31 - buildToolsVersion "30.0.3" defaultConfig { applicationId "com.casic.xz.meterage" @@ -84,11 +83,13 @@ implementation 'top.zibin:Luban:1.1.8' //官方Json解析库 implementation 'com.google.code.gson:gson:2.9.0' + //阿里巴巴JSON库 + implementation 'com.alibaba.fastjson2:fastjson2:2.0.24' //Kotlin协程 implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.5.1' //MVVM+LiveData implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.5.1" - implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.0" + implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1" implementation "androidx.lifecycle:lifecycle-extensions:2.2.0" //返回值转换器 implementation 'com.jakewharton.retrofit:retrofit2-kotlin-coroutines-adapter:0.9.2' @@ -109,4 +110,8 @@ implementation 'com.github.barteksc:android-pdf-viewer:2.8.2' //绕过Android 11反射限制 implementation 'com.github.tiann:FreeReflection:3.1.0' + //单项/数字、二三级联动、日期/时间等滚轮选择器 + implementation 'com.github.gzu-liyujiang.AndroidPicker:WheelPicker:4.1.8' + //文件/目录选择器 + implementation 'com.github.gzu-liyujiang.AndroidPicker:FilePicker:4.1.1' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 1ccc12b..0fba91b 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -60,6 +60,8 @@ + + diff --git a/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt b/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt new file mode 100644 index 0000000..21a71d8 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt @@ -0,0 +1,70 @@ +package com.casic.xz.meterage.adapter + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import com.casic.xz.meterage.R +import com.casic.xz.meterage.extensions.toChineseGrade +import com.casic.xz.meterage.model.CustomerListModel + +class SelectCustomerAdapter( + context: Context, private val dataRows: MutableList +) : RecyclerView.Adapter() { + + private var layoutInflater = LayoutInflater.from(context) + + //选择的位置 + private var selectedPosition = 0 + + //临时记录上次选择的位置 + private var temp = -1 + + override fun getItemCount(): Int = dataRows.size + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ItemViewHolder( + layoutInflater.inflate(R.layout.item_select_customer_lv, parent, false) + ) + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + //绑定数据 + val rowsBean = dataRows[position] + holder.agreementLevelView.text = rowsBean.grade.toChineseGrade() + holder.customerNameView.text = rowsBean.customerName + holder.scaleView.text = rowsBean.companySizeName + holder.overallView.text = "公司规模:${rowsBean.evaluationName}" + holder.fullAddressView.text = "公司地址:${rowsBean.fullAddress}" + + holder.itemView.isSelected = holder.layoutPosition == selectedPosition + holder.itemView.setOnClickListener { + itemCheckedListener?.onItemChecked(rowsBean) + + holder.itemView.isSelected = true + temp = selectedPosition + //设置新的位置 + selectedPosition = holder.layoutPosition + //更新旧位置 + notifyItemChanged(temp) + } + } + + inner class ItemViewHolder(view: View) : RecyclerView.ViewHolder(view) { + var agreementLevelView: TextView = view.findViewById(R.id.agreementLevelView) + var customerNameView: TextView = view.findViewById(R.id.customerNameView) + var scaleView: TextView = view.findViewById(R.id.scaleView) + var overallView: TextView = view.findViewById(R.id.overallView) + var fullAddressView: TextView = view.findViewById(R.id.fullAddressView) + } + + private var itemCheckedListener: OnItemCheckedListener? = null + + interface OnItemCheckedListener { + fun onItemChecked(item: CustomerListModel.DataModel.RowsModel) + } + + fun setOnCheckedListener(listener: OnItemCheckedListener?) { + itemCheckedListener = listener + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt b/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt new file mode 100644 index 0000000..c29461e --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt @@ -0,0 +1,68 @@ +package com.casic.xz.meterage.adapter + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import com.casic.xz.meterage.R +import com.casic.xz.meterage.model.SampleListModel + +class SelectSampleAdapter( + context: Context, private val dataRows: MutableList +) : RecyclerView.Adapter() { + + private var layoutInflater = LayoutInflater.from(context) + private var multipleSelected = mutableSetOf() + private var sampleModes = ArrayList() + + override fun getItemCount(): Int = dataRows.size + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ItemViewHolder( + layoutInflater.inflate(R.layout.item_select_sample_lv, parent, false) + ) + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + //绑定数据 + val rowsBean = dataRows[position] + holder.sampleNameView.text = "${rowsBean.sampleName}【${rowsBean.sampleModel}】" + holder.manufacturingCodeView.text = "出厂编号:${rowsBean.manufacturingNo}" + holder.sampleCodeView.text = "样品编号:${rowsBean.sampleNo}" + holder.validDateView.text = "有效期至:${rowsBean.validDeadline}" + + holder.checkImageView.isSelected = multipleSelected.contains(position) + holder.itemView.setOnClickListener { + if (multipleSelected.contains(position)) { + multipleSelected.remove(position) + sampleModes.remove(dataRows[position]) + holder.checkImageView.isSelected = false + } else { + multipleSelected.add(position) + sampleModes.add(dataRows[position]) + holder.checkImageView.isSelected = true + } + + itemCheckedListener?.onItemChecked(sampleModes) + } + } + + inner class ItemViewHolder(view: View) : RecyclerView.ViewHolder(view) { + var sampleNameView: TextView = view.findViewById(R.id.sampleNameView) + var manufacturingCodeView: TextView = view.findViewById(R.id.manufacturingCodeView) + var sampleCodeView: TextView = view.findViewById(R.id.sampleCodeView) + var validDateView: TextView = view.findViewById(R.id.validDateView) + var checkImageView: ImageView = view.findViewById(R.id.checkImageView) + } + + private var itemCheckedListener: OnItemCheckedListener? = null + + interface OnItemCheckedListener { + fun onItemChecked(items: ArrayList) + } + + fun setOnCheckedListener(listener: OnItemCheckedListener?) { + itemCheckedListener = listener + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/callback/DateSelectedCallback.kt b/app/src/main/java/com/casic/xz/meterage/callback/DateSelectedCallback.kt new file mode 100644 index 0000000..8196110 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/callback/DateSelectedCallback.kt @@ -0,0 +1,5 @@ +package com.casic.xz.meterage.callback + +interface DateSelectedCallback { + fun onDateSelected(date: String) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/Activity.kt b/app/src/main/java/com/casic/xz/meterage/extensions/Activity.kt new file mode 100644 index 0000000..e112d1c --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/extensions/Activity.kt @@ -0,0 +1,33 @@ +package com.casic.xz.meterage.extensions + +import android.app.Activity +import com.casic.xz.meterage.R +import com.casic.xz.meterage.callback.DateSelectedCallback +import com.github.gzuliyujiang.wheelpicker.DatePicker +import com.github.gzuliyujiang.wheelpicker.annotation.DateMode +import com.github.gzuliyujiang.wheelpicker.entity.DateEntity +import com.pengxh.kt.lite.extensions.convertColor +import com.pengxh.kt.lite.extensions.sp2px + +fun Activity.showDatePicker(callback: DateSelectedCallback) { + val datePicker = DatePicker(this) + + val layout = datePicker.wheelLayout + layout.setDateMode(DateMode.YEAR_MONTH_DAY) + layout.setDateLabel("年", "月", "日"); + layout.setTextSize(14f.sp2px(this).toFloat()) + layout.setSelectedTextSize(16f.sp2px(this).toFloat()) + layout.setSelectedTextColor(R.color.themeColor.convertColor(this)) + layout.setSelectedTextBold(true) + layout.setResetWhenLinkage(false) + layout.setRange( + DateEntity.today(), + DateEntity.target(2050, 12, 31), + DateEntity.today() + ) + + datePicker.setOnDatePickedListener { year, month, day -> + callback.onDateSelected(String.format("%s-%s-%s", year, month, day)) + } + datePicker.show() +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt b/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt index 016ebcb..cf6bf49 100644 --- a/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt +++ b/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt @@ -4,7 +4,7 @@ * ArrayList扩展方法 */ -//将图片集合格式化成满足上传格式的数据 +//将集合格式化成满足上传格式的数据 fun ArrayList.reformat(): String { if (this.isEmpty()) return "" val builder = StringBuilder() diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt b/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt index 7c57643..aa9b92b 100644 --- a/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt +++ b/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt @@ -1,7 +1,6 @@ package com.casic.xz.meterage.extensions import android.content.Context -import android.util.Log import android.view.ViewGroup import com.casic.xz.meterage.base.BaseApplication import com.pengxh.kt.lite.extensions.dp2px @@ -9,9 +8,8 @@ fun Context.initLayoutImmersionBar(rootView: ViewGroup) { var statusBarHeight = QMUIDisplayHelper.getStatusBarHeight(this) - Log.d("Casic", "状态栏高度: $statusBarHeight") if (statusBarHeight == 0) { - statusBarHeight = 44f.dp2px(BaseApplication.get()) + statusBarHeight = 40f.dp2px(BaseApplication.get()) } rootView.setPadding(0, statusBarHeight, 0, 0) rootView.requestLayout() diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/String.kt b/app/src/main/java/com/casic/xz/meterage/extensions/String.kt index 28f70d8..6234d43 100644 --- a/app/src/main/java/com/casic/xz/meterage/extensions/String.kt +++ b/app/src/main/java/com/casic/xz/meterage/extensions/String.kt @@ -128,9 +128,10 @@ fun String.combineImagePath(): String { if (this.isEmpty()) return this val defaultValue = SaveKeyValues.getValue( - LocaleConstant.DEFAULT_SERVER_CONFIG, LocaleConstant.SERVER_BASE_URL + LocaleConstant.FILE_SERVER_CONFIG, LocaleConstant.File_SERVER_URL ) as String - return "$defaultValue/static/${this.replace("\\", "/")}" + //http://111.198.10.15:21408/test/1677479806059688_1677479806038.jpeg + return "$defaultValue/test/${this.replace("\\", "/")}" } fun String.isEarlier(time: String): Boolean { diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt index 25fa87b..a0e1358 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt @@ -1,18 +1,12 @@ package com.casic.xz.meterage.fragment.customer +import android.graphics.Color import android.graphics.Paint import com.casic.xz.meterage.R -import com.casic.xz.meterage.extensions.combineImagePath import com.casic.xz.meterage.extensions.toChineseGrade +import com.casic.xz.meterage.extensions.watchAttachFile import com.casic.xz.meterage.model.CustomerDetailModel -import com.casic.xz.meterage.view.BigImageActivity -import com.casic.xz.meterage.view.notice.PreviewDocumentActivity -import com.casic.xz.meterage.view.notice.PreviewPdfActivity -import com.casic.xz.meterage.view.notice.PreviewTextActivity import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.extensions.show import kotlinx.android.synthetic.main.fragment_customer_basic_information.* class BasicInformationFragment(private val data: CustomerDetailModel.DataModel) : @@ -48,30 +42,11 @@ val textPaint = minioFileView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - minioFileView.setTextColor(R.color.themeColor.convertColor(requireContext())) + minioFileView.setTextColor(Color.BLUE) minioFileView.setOnClickListener { //查看附件 - if (minioFileName.endsWith("pdf")) { - requireContext().navigatePageTo(minioFileName) - } else if ( - minioFileName.endsWith("doc") || - minioFileName.endsWith("docx") - ) { - requireContext().navigatePageTo(minioFileName) - } else if (minioFileName.endsWith("txt")) { - requireContext().navigatePageTo(minioFileName) - } else if ( - minioFileName.endsWith("png") || - minioFileName.endsWith("jpeg") || - minioFileName.endsWith("jpg") - ) { - val urls = ArrayList() - urls.add(minioFileName.combineImagePath()) - requireContext().navigatePageTo(0, urls) - } else { - "文件类型未知,无法打开附件".show(requireContext()) - } + minioFileName.watchAttachFile(requireContext()) } } } diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt index 77846b4..3a0fe2e 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt @@ -1,5 +1,6 @@ package com.casic.xz.meterage.fragment.device +import android.graphics.Color import android.graphics.Paint import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R @@ -7,7 +8,6 @@ import com.casic.xz.meterage.utils.LoadingDialogHub import com.casic.xz.meterage.vm.EquipmentViewModel import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor import com.pengxh.kt.lite.vm.LoadState import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import kotlinx.android.synthetic.main.fragment_device_basic_information.* @@ -56,7 +56,7 @@ val textPaint = documentsView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - documentsView.setTextColor(R.color.themeColor.convertColor(requireContext())) + documentsView.setTextColor(Color.BLUE) val files = ArrayList() data.fileList.forEach { file -> @@ -66,7 +66,7 @@ BottomActionSheet.Builder() .setContext(requireContext()) .setActionItemTitle(files) - .setItemTextColor(R.color.themeColor.convertColor(requireContext())) + .setItemTextColor(Color.BLUE) .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { override fun onActionItemClick(position: Int) { diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt index 15dc3d2..10eeff8 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt @@ -1,5 +1,6 @@ package com.casic.xz.meterage.fragment.entrust +import android.graphics.Color import android.graphics.Paint import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R @@ -9,7 +10,6 @@ import com.casic.xz.meterage.model.EntrustDetailModel import com.casic.xz.meterage.vm.DictionaryViewModel import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor import kotlinx.android.synthetic.main.fragment_entrust_basic_information.* class BasicInformationFragment(private val data: EntrustDetailModel.DataModel) : @@ -38,7 +38,7 @@ val textPaint = annexView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - annexView.setTextColor(R.color.themeColor.convertColor(requireContext())) + annexView.setTextColor(Color.BLUE) annexView.setOnClickListener { minioFileName.watchAttachFile(requireContext()) @@ -59,9 +59,9 @@ //加急 if (data.isUrgent == "0") { - RadioButton2.isChecked = true + radioButton2.isChecked = true } else { - RadioButton1.isChecked = true + radioButton1.isChecked = true } //样品 diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/equipment/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/equipment/BasicInformationFragment.kt index 72b523c..7bc3b01 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/equipment/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/equipment/BasicInformationFragment.kt @@ -1,5 +1,6 @@ package com.casic.xz.meterage.fragment.equipment +import android.graphics.Color import android.graphics.Paint import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R @@ -7,7 +8,6 @@ import com.casic.xz.meterage.utils.LoadingDialogHub import com.casic.xz.meterage.vm.EquipmentViewModel import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor import com.pengxh.kt.lite.vm.LoadState import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import kotlinx.android.synthetic.main.fragment_equipment_basic_information.* @@ -74,7 +74,7 @@ val textPaint = instructionsView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - instructionsView.setTextColor(R.color.themeColor.convertColor(requireContext())) + instructionsView.setTextColor(Color.BLUE) val files = ArrayList() data.fileList.forEach { file -> @@ -84,7 +84,7 @@ BottomActionSheet.Builder() .setContext(requireContext()) .setActionItemTitle(files) - .setItemTextColor(R.color.themeColor.convertColor(requireContext())) + .setItemTextColor(Color.BLUE) .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { override fun onActionItemClick(position: Int) { diff --git a/app/src/main/java/com/casic/xz/meterage/model/SampleListModel.java b/app/src/main/java/com/casic/xz/meterage/model/SampleListModel.java new file mode 100644 index 0000000..5784343 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/model/SampleListModel.java @@ -0,0 +1,193 @@ +package com.casic.xz.meterage.model; + +import java.util.List; + +public class SampleListModel { + + private int code; + private DataModel data; + private String message; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataModel getData() { + return data; + } + + public void setData(DataModel data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public static class DataModel { + private List rows; + private int total; + + public List getRows() { + return rows; + } + + public void setRows(List rows) { + this.rows = rows; + } + + public int getTotal() { + return total; + } + + public void setTotal(int total) { + this.total = total; + } + + public static class RowsModel { + private String certificationStatus; + private String customerName; + private String customerNo; + private String id; + private String manufacturingNo; + private String measureLastTime; + private String measurePeriod; + private String orderId; + private String remark; + private String sampleModel; + private String sampleName; + private String sampleNo; + private String sampleSatus; + private String sampleSatusName; + private String validDeadline; + + public String getCertificationStatus() { + return certificationStatus; + } + + public void setCertificationStatus(String certificationStatus) { + this.certificationStatus = certificationStatus; + } + + public String getCustomerName() { + return customerName; + } + + public void setCustomerName(String customerName) { + this.customerName = customerName; + } + + public String getCustomerNo() { + return customerNo; + } + + public void setCustomerNo(String customerNo) { + this.customerNo = customerNo; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getManufacturingNo() { + return manufacturingNo; + } + + public void setManufacturingNo(String manufacturingNo) { + this.manufacturingNo = manufacturingNo; + } + + public String getMeasureLastTime() { + return measureLastTime; + } + + public void setMeasureLastTime(String measureLastTime) { + this.measureLastTime = measureLastTime; + } + + public String getMeasurePeriod() { + return measurePeriod; + } + + public void setMeasurePeriod(String measurePeriod) { + this.measurePeriod = measurePeriod; + } + + public String getOrderId() { + return orderId; + } + + public void setOrderId(String orderId) { + this.orderId = orderId; + } + + public String getRemark() { + return remark; + } + + public void setRemark(String remark) { + this.remark = remark; + } + + public String getSampleModel() { + return sampleModel; + } + + public void setSampleModel(String sampleModel) { + this.sampleModel = sampleModel; + } + + public String getSampleName() { + return sampleName; + } + + public void setSampleName(String sampleName) { + this.sampleName = sampleName; + } + + public String getSampleNo() { + return sampleNo; + } + + public void setSampleNo(String sampleNo) { + this.sampleNo = sampleNo; + } + + public String getSampleSatus() { + return sampleSatus; + } + + public void setSampleSatus(String sampleSatus) { + this.sampleSatus = sampleSatus; + } + + public String getSampleSatusName() { + return sampleSatusName; + } + + public void setSampleSatusName(String sampleSatusName) { + this.sampleSatusName = sampleSatusName; + } + + public String getValidDeadline() { + return validDeadline; + } + + public void setValidDeadline(String validDeadline) { + this.validDeadline = validDeadline; + } + } + } +} diff --git a/app/src/main/java/com/casic/xz/meterage/model/UploadResultModel.java b/app/src/main/java/com/casic/xz/meterage/model/UploadResultModel.java new file mode 100644 index 0000000..f2a6a41 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/model/UploadResultModel.java @@ -0,0 +1,34 @@ +package com.casic.xz.meterage.model; + +import java.util.List; + +public class UploadResultModel { + + private int code; + private List data; + private String message; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public List getData() { + return data; + } + + public void setData(List data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } +} diff --git a/app/src/main/java/com/casic/xz/meterage/utils/FileType.kt b/app/src/main/java/com/casic/xz/meterage/utils/FileType.kt new file mode 100644 index 0000000..17e2bca --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/utils/FileType.kt @@ -0,0 +1,23 @@ +package com.casic.xz.meterage.utils + +sealed class FileType { + /** + * PDF文件 + */ + object PDF : FileType() + + /** + * WORD文件 + */ + object WORD : FileType() + + /** + * IMAGE图片 + */ + object IMAGE : FileType() + + /** + * 未知类型(Excel) + */ + object UNKNOWN : FileType() +} diff --git a/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitService.kt index bc3f8d6..8f4fe44 100644 --- a/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitService.kt @@ -1,5 +1,6 @@ package com.casic.xz.meterage.utils.retrofit +import okhttp3.MultipartBody import okhttp3.RequestBody import retrofit2.http.* @@ -35,6 +36,16 @@ ): String /** + * 上传文件 + */ + @Multipart + @POST("/minio/file/upload") + suspend fun uploadFile( + @Header("token") token: String, + @Part file: MultipartBody.Part + ): String + + /** * 获取通知公告列表 */ @POST("/system/notice/listPage") @@ -209,4 +220,24 @@ @Header("token") token: String, @Body requestBody: RequestBody ): String + + /** + * 获取样品列表 + */ + @POST("/customer/sample/listPage") + suspend fun getSampleList( + @Header("token") token: String, + @Body requestBody: RequestBody, + @QueryMap limit: Map, + @QueryMap offset: Map + ): String + + /** + * 新增委托书 + */ + @POST("/business/order/add") + suspend fun addEntrust( + @Header("token") token: String, + @Body requestBody: RequestBody + ): String } \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitServiceManager.kt index cb22e45..90abe5a 100644 --- a/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitServiceManager.kt @@ -1,13 +1,20 @@ package com.casic.xz.meterage.utils.retrofit +import com.alibaba.fastjson2.JSON +import com.alibaba.fastjson2.JSONArray +import com.alibaba.fastjson2.JSONObject +import com.casic.xz.meterage.model.SampleListModel import com.casic.xz.meterage.utils.AuthenticationHelper +import com.casic.xz.meterage.utils.FileType import com.casic.xz.meterage.utils.LocaleConstant import com.pengxh.kt.lite.utils.RetrofitFactory import com.pengxh.kt.lite.utils.SaveKeyValues import okhttp3.MediaType.Companion.toMediaType +import okhttp3.MediaType.Companion.toMediaTypeOrNull +import okhttp3.MultipartBody +import okhttp3.RequestBody.Companion.asRequestBody import okhttp3.RequestBody.Companion.toRequestBody -import org.json.JSONArray -import org.json.JSONObject +import java.io.File object RetrofitServiceManager { @@ -31,9 +38,9 @@ */ suspend fun login(sid: String, account: String, secretKey: String): String { val paramObject = JSONObject() - paramObject.put("sid", sid) - paramObject.put("username", account) - paramObject.put("password", secretKey) + paramObject["sid"] = sid + paramObject["username"] = account + paramObject["password"] = secretKey val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -55,6 +62,20 @@ } /** + * 上传文件 + */ + suspend fun uploadFile(file: File, type: FileType): String { + val requestBody = when (type) { + FileType.PDF -> file.asRequestBody("application/pdf".toMediaTypeOrNull()) + FileType.WORD -> file.asRequestBody("application/msword".toMediaTypeOrNull()) + FileType.IMAGE -> file.asRequestBody("image/png".toMediaTypeOrNull()) + else -> file.asRequestBody("application/vnd.ms-excel".toMediaTypeOrNull()) + } + val filePart = MultipartBody.Part.createFormData("multipartFile", file.name, requestBody) + return api.uploadFile(AuthenticationHelper.token!!, filePart) + } + + /** * 获取通知公告列表 */ suspend fun getNoticeList( @@ -66,11 +87,11 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("noticeNo", noticeNo) - paramObject.put("noticeTitle", noticeTitle) - paramObject.put("noticePublisher", noticePublisher) - paramObject.put("noticeStartTime", noticeStartTime) - paramObject.put("noticeEndTime", noticeEndTime) + paramObject["noticeNo"] = noticeNo + paramObject["noticeTitle"] = noticeTitle + paramObject["noticePublisher"] = noticePublisher + paramObject["noticeStartTime"] = noticeStartTime + paramObject["noticeEndTime"] = noticeEndTime val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -105,26 +126,21 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("equipmentNo", equipmentNo) - paramObject.put("equipmentName", equipmentName) - paramObject.put("mesureType", mesureType) - paramObject.put("managerState", managerState) - paramObject.put("useDept", useDept) - paramObject.put("assetType", assetType) - paramObject.put("equipmentCategory", equipmentCategory) - paramObject.put("isCalibrationTestEquipment", isCalibrationTestEquipment) - paramObject.put("isMeasureAccount", isMeasureAccount) - paramObject.put("isStandardSupportEquipment", isStandardSupportEquipment) - paramObject.put("isFixedAssets", isFixedAssets) - paramObject.put("validStartDate", validStartDate) - paramObject.put("validEndDate", validEndDate) - paramObject.put("abc", abc) - - val jsonArray = JSONArray() - ids.forEach { - jsonArray.put(it) - } - paramObject.put("ids", jsonArray) + paramObject["equipmentNo"] = equipmentNo + paramObject["equipmentName"] = equipmentName + paramObject["mesureType"] = mesureType + paramObject["managerState"] = managerState + paramObject["useDept"] = useDept + paramObject["assetType"] = assetType + paramObject["equipmentCategory"] = equipmentCategory + paramObject["isCalibrationTestEquipment"] = isCalibrationTestEquipment + paramObject["isMeasureAccount"] = isMeasureAccount + paramObject["isStandardSupportEquipment"] = isStandardSupportEquipment + paramObject["isFixedAssets"] = isFixedAssets + paramObject["validStartDate"] = validStartDate + paramObject["validEndDate"] = validEndDate + paramObject["abc"] = abc + paramObject["ids"] = JSONArray.parseArray(JSON.toJSONString(ids)) val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() @@ -143,7 +159,7 @@ */ suspend fun getEquipmentDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -164,13 +180,13 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("standardNo", standardNo) - paramObject.put("standardName", standardName) - paramObject.put("category", category) - paramObject.put("managerState", managerState) - paramObject.put("standardLaboratory", standardLaboratory) - paramObject.put("preparationDate", preparationDate) - paramObject.put("id", id) + paramObject["standardNo"] = standardNo + paramObject["standardName"] = standardName + paramObject["category"] = category + paramObject["managerState"] = managerState + paramObject["standardLaboratory"] = standardLaboratory + paramObject["preparationDate"] = preparationDate + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -193,7 +209,7 @@ */ suspend fun getStandardDeviceDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -212,11 +228,11 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("checkType", checkType) - paramObject.put("priceItem", priceItem) - paramObject.put("priceName", priceName) - paramObject.put("priceNo", priceNo) - paramObject.put("priceType", priceType) + paramObject["checkType"] = checkType + paramObject["priceItem"] = priceItem + paramObject["priceName"] = priceName + paramObject["priceNo"] = priceNo + paramObject["priceType"] = priceType val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -234,7 +250,7 @@ */ suspend fun getCapabilityDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -257,20 +273,15 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("createStartTime", createStartTime) - paramObject.put("createEndTime", createEndTime) - paramObject.put("deptId", deptId) - paramObject.put("director", director) - paramObject.put("effectiveCompany", effectiveCompany) - paramObject.put("trainStartTime", trainStartTime) - paramObject.put("trainEndTime", trainEndTime) - paramObject.put("formId", formId) - - val jsonArray = JSONArray() - ids.forEach { - jsonArray.put(it) - } - paramObject.put("ids", jsonArray) + paramObject["createStartTime"] = createStartTime + paramObject["createEndTime"] = createEndTime + paramObject["deptId"] = deptId + paramObject["director"] = director + paramObject["effectiveCompany"] = effectiveCompany + paramObject["trainStartTime"] = trainStartTime + paramObject["trainEndTime"] = trainEndTime + paramObject["formId"] = formId + paramObject["ids"] = JSONArray.parseArray(JSON.toJSONString(ids)) val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() @@ -294,7 +305,7 @@ */ suspend fun getMeterageTrainDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -308,10 +319,10 @@ bussinessSize: String, customerName: String, customerNo: String, grade: String, offset: Int ): String { val paramObject = JSONObject() - paramObject.put("bussinessSize", bussinessSize) - paramObject.put("customerName", customerName) - paramObject.put("customerNo", customerNo) - paramObject.put("grade", grade) + paramObject["bussinessSize"] = bussinessSize + paramObject["customerName"] = customerName + paramObject["customerNo"] = customerNo + paramObject["grade"] = grade val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() @@ -330,7 +341,7 @@ */ suspend fun getCustomerDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -342,7 +353,7 @@ */ suspend fun getStaffList(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -354,7 +365,7 @@ */ suspend fun getSupportEquipmentList(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -366,7 +377,7 @@ */ suspend fun getVerifyProcedureList(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -389,20 +400,15 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("customerName", customerName) - paramObject.put("customerNo", customerNo) - paramObject.put("deliverer", deliverer) - paramObject.put("orderCode", orderCode) - paramObject.put("startTime", startTime) - paramObject.put("endTime", endTime) - paramObject.put("isUrgent", isUrgent) - paramObject.put("status", status) - - val jsonArray = JSONArray() - ids.forEach { - jsonArray.put(it) - } - paramObject.put("ids", jsonArray) + paramObject["customerName"] = customerName + paramObject["customerNo"] = customerNo + paramObject["deliverer"] = deliverer + paramObject["orderCode"] = orderCode + paramObject["startTime"] = startTime + paramObject["endTime"] = endTime + paramObject["isUrgent"] = isUrgent + paramObject["status"] = status + paramObject["ids"] = JSONArray.parseArray(JSON.toJSONString(ids)) val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() @@ -421,7 +427,7 @@ */ suspend fun getEntrustDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -433,7 +439,7 @@ */ suspend fun acceptEntrust(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -446,10 +452,89 @@ */ suspend fun returnEntrust(id: String, selected: ArrayList): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) return api.returnEntrust(AuthenticationHelper.token!!, requestBody) } + + /** + * 获取样品列表 + */ + suspend fun getSampleList( + customerName: String, + customerNo: String, + startTime: String, + endTime: String, + sampleName: String, + sampleNo: String, + sampleModel: String, + sampleBelong: String, + overtimeStatus: String, + ids: Array, + offset: Int + ): String { + val paramObject = JSONObject() + paramObject["customerName"] = customerName + paramObject["customerNo"] = customerNo + paramObject["startTime"] = startTime + paramObject["endTime"] = endTime + paramObject["sampleName"] = sampleName + paramObject["sampleNo"] = sampleNo + paramObject["sampleModel"] = sampleModel + paramObject["sampleBelong"] = sampleBelong + paramObject["overtimeStatus"] = overtimeStatus + paramObject["ids"] = JSONArray.parseArray(JSON.toJSONString(ids)) + + val requestBody = paramObject.toString().toRequestBody( + "application/json;charset=UTF-8".toMediaType() + ) + + val limitMap = HashMap() + limitMap["limit"] = LocaleConstant.PAGE_LIMIT + + val offsetMap = HashMap() + offsetMap["offset"] = offset + return api.getSampleList(AuthenticationHelper.token!!, requestBody, limitMap, offsetMap) + } + + /** + * 新增委托书 + */ + suspend fun addEntrust( + deliverer: String, + delivererTel: String, + orderTime: String, + planDeliverTime: String, + requireOverTime: String, + customerName: String, + customerPhone: String, + customerAddress: String, + remark: String, + minioFileName: String, + certifications: String, + isUrgent: String, + samples: List + ): String { + val paramObject = JSONObject() + paramObject["deliverer"] = deliverer + paramObject["delivererTel"] = delivererTel + paramObject["orderTime"] = orderTime + paramObject["planDeliverTime"] = planDeliverTime + paramObject["requireOverTime"] = requireOverTime + paramObject["customerName"] = customerName + paramObject["customerPhone"] = customerPhone + paramObject["customerAddress"] = customerAddress + paramObject["remark"] = remark + paramObject["minioFileName"] = minioFileName + paramObject["certifications"] = certifications + paramObject["isUrgent"] = isUrgent + paramObject["customerSampleInfoList"] = JSONArray.parseArray(JSON.toJSONString(samples)) + + val requestBody = paramObject.toString().toRequestBody( + "application/json;charset=UTF-8".toMediaType() + ) + return api.addEntrust(AuthenticationHelper.token!!, requestBody) + } } \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 0ae369f..687b02b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -15,7 +15,6 @@ } compileSdkVersion 31 - buildToolsVersion "30.0.3" defaultConfig { applicationId "com.casic.xz.meterage" @@ -84,11 +83,13 @@ implementation 'top.zibin:Luban:1.1.8' //官方Json解析库 implementation 'com.google.code.gson:gson:2.9.0' + //阿里巴巴JSON库 + implementation 'com.alibaba.fastjson2:fastjson2:2.0.24' //Kotlin协程 implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.5.1' //MVVM+LiveData implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.5.1" - implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.0" + implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1" implementation "androidx.lifecycle:lifecycle-extensions:2.2.0" //返回值转换器 implementation 'com.jakewharton.retrofit:retrofit2-kotlin-coroutines-adapter:0.9.2' @@ -109,4 +110,8 @@ implementation 'com.github.barteksc:android-pdf-viewer:2.8.2' //绕过Android 11反射限制 implementation 'com.github.tiann:FreeReflection:3.1.0' + //单项/数字、二三级联动、日期/时间等滚轮选择器 + implementation 'com.github.gzu-liyujiang.AndroidPicker:WheelPicker:4.1.8' + //文件/目录选择器 + implementation 'com.github.gzu-liyujiang.AndroidPicker:FilePicker:4.1.1' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 1ccc12b..0fba91b 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -60,6 +60,8 @@ + + diff --git a/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt b/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt new file mode 100644 index 0000000..21a71d8 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt @@ -0,0 +1,70 @@ +package com.casic.xz.meterage.adapter + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import com.casic.xz.meterage.R +import com.casic.xz.meterage.extensions.toChineseGrade +import com.casic.xz.meterage.model.CustomerListModel + +class SelectCustomerAdapter( + context: Context, private val dataRows: MutableList +) : RecyclerView.Adapter() { + + private var layoutInflater = LayoutInflater.from(context) + + //选择的位置 + private var selectedPosition = 0 + + //临时记录上次选择的位置 + private var temp = -1 + + override fun getItemCount(): Int = dataRows.size + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ItemViewHolder( + layoutInflater.inflate(R.layout.item_select_customer_lv, parent, false) + ) + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + //绑定数据 + val rowsBean = dataRows[position] + holder.agreementLevelView.text = rowsBean.grade.toChineseGrade() + holder.customerNameView.text = rowsBean.customerName + holder.scaleView.text = rowsBean.companySizeName + holder.overallView.text = "公司规模:${rowsBean.evaluationName}" + holder.fullAddressView.text = "公司地址:${rowsBean.fullAddress}" + + holder.itemView.isSelected = holder.layoutPosition == selectedPosition + holder.itemView.setOnClickListener { + itemCheckedListener?.onItemChecked(rowsBean) + + holder.itemView.isSelected = true + temp = selectedPosition + //设置新的位置 + selectedPosition = holder.layoutPosition + //更新旧位置 + notifyItemChanged(temp) + } + } + + inner class ItemViewHolder(view: View) : RecyclerView.ViewHolder(view) { + var agreementLevelView: TextView = view.findViewById(R.id.agreementLevelView) + var customerNameView: TextView = view.findViewById(R.id.customerNameView) + var scaleView: TextView = view.findViewById(R.id.scaleView) + var overallView: TextView = view.findViewById(R.id.overallView) + var fullAddressView: TextView = view.findViewById(R.id.fullAddressView) + } + + private var itemCheckedListener: OnItemCheckedListener? = null + + interface OnItemCheckedListener { + fun onItemChecked(item: CustomerListModel.DataModel.RowsModel) + } + + fun setOnCheckedListener(listener: OnItemCheckedListener?) { + itemCheckedListener = listener + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt b/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt new file mode 100644 index 0000000..c29461e --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt @@ -0,0 +1,68 @@ +package com.casic.xz.meterage.adapter + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import com.casic.xz.meterage.R +import com.casic.xz.meterage.model.SampleListModel + +class SelectSampleAdapter( + context: Context, private val dataRows: MutableList +) : RecyclerView.Adapter() { + + private var layoutInflater = LayoutInflater.from(context) + private var multipleSelected = mutableSetOf() + private var sampleModes = ArrayList() + + override fun getItemCount(): Int = dataRows.size + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ItemViewHolder( + layoutInflater.inflate(R.layout.item_select_sample_lv, parent, false) + ) + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + //绑定数据 + val rowsBean = dataRows[position] + holder.sampleNameView.text = "${rowsBean.sampleName}【${rowsBean.sampleModel}】" + holder.manufacturingCodeView.text = "出厂编号:${rowsBean.manufacturingNo}" + holder.sampleCodeView.text = "样品编号:${rowsBean.sampleNo}" + holder.validDateView.text = "有效期至:${rowsBean.validDeadline}" + + holder.checkImageView.isSelected = multipleSelected.contains(position) + holder.itemView.setOnClickListener { + if (multipleSelected.contains(position)) { + multipleSelected.remove(position) + sampleModes.remove(dataRows[position]) + holder.checkImageView.isSelected = false + } else { + multipleSelected.add(position) + sampleModes.add(dataRows[position]) + holder.checkImageView.isSelected = true + } + + itemCheckedListener?.onItemChecked(sampleModes) + } + } + + inner class ItemViewHolder(view: View) : RecyclerView.ViewHolder(view) { + var sampleNameView: TextView = view.findViewById(R.id.sampleNameView) + var manufacturingCodeView: TextView = view.findViewById(R.id.manufacturingCodeView) + var sampleCodeView: TextView = view.findViewById(R.id.sampleCodeView) + var validDateView: TextView = view.findViewById(R.id.validDateView) + var checkImageView: ImageView = view.findViewById(R.id.checkImageView) + } + + private var itemCheckedListener: OnItemCheckedListener? = null + + interface OnItemCheckedListener { + fun onItemChecked(items: ArrayList) + } + + fun setOnCheckedListener(listener: OnItemCheckedListener?) { + itemCheckedListener = listener + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/callback/DateSelectedCallback.kt b/app/src/main/java/com/casic/xz/meterage/callback/DateSelectedCallback.kt new file mode 100644 index 0000000..8196110 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/callback/DateSelectedCallback.kt @@ -0,0 +1,5 @@ +package com.casic.xz.meterage.callback + +interface DateSelectedCallback { + fun onDateSelected(date: String) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/Activity.kt b/app/src/main/java/com/casic/xz/meterage/extensions/Activity.kt new file mode 100644 index 0000000..e112d1c --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/extensions/Activity.kt @@ -0,0 +1,33 @@ +package com.casic.xz.meterage.extensions + +import android.app.Activity +import com.casic.xz.meterage.R +import com.casic.xz.meterage.callback.DateSelectedCallback +import com.github.gzuliyujiang.wheelpicker.DatePicker +import com.github.gzuliyujiang.wheelpicker.annotation.DateMode +import com.github.gzuliyujiang.wheelpicker.entity.DateEntity +import com.pengxh.kt.lite.extensions.convertColor +import com.pengxh.kt.lite.extensions.sp2px + +fun Activity.showDatePicker(callback: DateSelectedCallback) { + val datePicker = DatePicker(this) + + val layout = datePicker.wheelLayout + layout.setDateMode(DateMode.YEAR_MONTH_DAY) + layout.setDateLabel("年", "月", "日"); + layout.setTextSize(14f.sp2px(this).toFloat()) + layout.setSelectedTextSize(16f.sp2px(this).toFloat()) + layout.setSelectedTextColor(R.color.themeColor.convertColor(this)) + layout.setSelectedTextBold(true) + layout.setResetWhenLinkage(false) + layout.setRange( + DateEntity.today(), + DateEntity.target(2050, 12, 31), + DateEntity.today() + ) + + datePicker.setOnDatePickedListener { year, month, day -> + callback.onDateSelected(String.format("%s-%s-%s", year, month, day)) + } + datePicker.show() +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt b/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt index 016ebcb..cf6bf49 100644 --- a/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt +++ b/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt @@ -4,7 +4,7 @@ * ArrayList扩展方法 */ -//将图片集合格式化成满足上传格式的数据 +//将集合格式化成满足上传格式的数据 fun ArrayList.reformat(): String { if (this.isEmpty()) return "" val builder = StringBuilder() diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt b/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt index 7c57643..aa9b92b 100644 --- a/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt +++ b/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt @@ -1,7 +1,6 @@ package com.casic.xz.meterage.extensions import android.content.Context -import android.util.Log import android.view.ViewGroup import com.casic.xz.meterage.base.BaseApplication import com.pengxh.kt.lite.extensions.dp2px @@ -9,9 +8,8 @@ fun Context.initLayoutImmersionBar(rootView: ViewGroup) { var statusBarHeight = QMUIDisplayHelper.getStatusBarHeight(this) - Log.d("Casic", "状态栏高度: $statusBarHeight") if (statusBarHeight == 0) { - statusBarHeight = 44f.dp2px(BaseApplication.get()) + statusBarHeight = 40f.dp2px(BaseApplication.get()) } rootView.setPadding(0, statusBarHeight, 0, 0) rootView.requestLayout() diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/String.kt b/app/src/main/java/com/casic/xz/meterage/extensions/String.kt index 28f70d8..6234d43 100644 --- a/app/src/main/java/com/casic/xz/meterage/extensions/String.kt +++ b/app/src/main/java/com/casic/xz/meterage/extensions/String.kt @@ -128,9 +128,10 @@ fun String.combineImagePath(): String { if (this.isEmpty()) return this val defaultValue = SaveKeyValues.getValue( - LocaleConstant.DEFAULT_SERVER_CONFIG, LocaleConstant.SERVER_BASE_URL + LocaleConstant.FILE_SERVER_CONFIG, LocaleConstant.File_SERVER_URL ) as String - return "$defaultValue/static/${this.replace("\\", "/")}" + //http://111.198.10.15:21408/test/1677479806059688_1677479806038.jpeg + return "$defaultValue/test/${this.replace("\\", "/")}" } fun String.isEarlier(time: String): Boolean { diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt index 25fa87b..a0e1358 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt @@ -1,18 +1,12 @@ package com.casic.xz.meterage.fragment.customer +import android.graphics.Color import android.graphics.Paint import com.casic.xz.meterage.R -import com.casic.xz.meterage.extensions.combineImagePath import com.casic.xz.meterage.extensions.toChineseGrade +import com.casic.xz.meterage.extensions.watchAttachFile import com.casic.xz.meterage.model.CustomerDetailModel -import com.casic.xz.meterage.view.BigImageActivity -import com.casic.xz.meterage.view.notice.PreviewDocumentActivity -import com.casic.xz.meterage.view.notice.PreviewPdfActivity -import com.casic.xz.meterage.view.notice.PreviewTextActivity import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.extensions.show import kotlinx.android.synthetic.main.fragment_customer_basic_information.* class BasicInformationFragment(private val data: CustomerDetailModel.DataModel) : @@ -48,30 +42,11 @@ val textPaint = minioFileView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - minioFileView.setTextColor(R.color.themeColor.convertColor(requireContext())) + minioFileView.setTextColor(Color.BLUE) minioFileView.setOnClickListener { //查看附件 - if (minioFileName.endsWith("pdf")) { - requireContext().navigatePageTo(minioFileName) - } else if ( - minioFileName.endsWith("doc") || - minioFileName.endsWith("docx") - ) { - requireContext().navigatePageTo(minioFileName) - } else if (minioFileName.endsWith("txt")) { - requireContext().navigatePageTo(minioFileName) - } else if ( - minioFileName.endsWith("png") || - minioFileName.endsWith("jpeg") || - minioFileName.endsWith("jpg") - ) { - val urls = ArrayList() - urls.add(minioFileName.combineImagePath()) - requireContext().navigatePageTo(0, urls) - } else { - "文件类型未知,无法打开附件".show(requireContext()) - } + minioFileName.watchAttachFile(requireContext()) } } } diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt index 77846b4..3a0fe2e 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt @@ -1,5 +1,6 @@ package com.casic.xz.meterage.fragment.device +import android.graphics.Color import android.graphics.Paint import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R @@ -7,7 +8,6 @@ import com.casic.xz.meterage.utils.LoadingDialogHub import com.casic.xz.meterage.vm.EquipmentViewModel import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor import com.pengxh.kt.lite.vm.LoadState import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import kotlinx.android.synthetic.main.fragment_device_basic_information.* @@ -56,7 +56,7 @@ val textPaint = documentsView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - documentsView.setTextColor(R.color.themeColor.convertColor(requireContext())) + documentsView.setTextColor(Color.BLUE) val files = ArrayList() data.fileList.forEach { file -> @@ -66,7 +66,7 @@ BottomActionSheet.Builder() .setContext(requireContext()) .setActionItemTitle(files) - .setItemTextColor(R.color.themeColor.convertColor(requireContext())) + .setItemTextColor(Color.BLUE) .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { override fun onActionItemClick(position: Int) { diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt index 15dc3d2..10eeff8 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt @@ -1,5 +1,6 @@ package com.casic.xz.meterage.fragment.entrust +import android.graphics.Color import android.graphics.Paint import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R @@ -9,7 +10,6 @@ import com.casic.xz.meterage.model.EntrustDetailModel import com.casic.xz.meterage.vm.DictionaryViewModel import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor import kotlinx.android.synthetic.main.fragment_entrust_basic_information.* class BasicInformationFragment(private val data: EntrustDetailModel.DataModel) : @@ -38,7 +38,7 @@ val textPaint = annexView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - annexView.setTextColor(R.color.themeColor.convertColor(requireContext())) + annexView.setTextColor(Color.BLUE) annexView.setOnClickListener { minioFileName.watchAttachFile(requireContext()) @@ -59,9 +59,9 @@ //加急 if (data.isUrgent == "0") { - RadioButton2.isChecked = true + radioButton2.isChecked = true } else { - RadioButton1.isChecked = true + radioButton1.isChecked = true } //样品 diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/equipment/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/equipment/BasicInformationFragment.kt index 72b523c..7bc3b01 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/equipment/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/equipment/BasicInformationFragment.kt @@ -1,5 +1,6 @@ package com.casic.xz.meterage.fragment.equipment +import android.graphics.Color import android.graphics.Paint import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R @@ -7,7 +8,6 @@ import com.casic.xz.meterage.utils.LoadingDialogHub import com.casic.xz.meterage.vm.EquipmentViewModel import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor import com.pengxh.kt.lite.vm.LoadState import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import kotlinx.android.synthetic.main.fragment_equipment_basic_information.* @@ -74,7 +74,7 @@ val textPaint = instructionsView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - instructionsView.setTextColor(R.color.themeColor.convertColor(requireContext())) + instructionsView.setTextColor(Color.BLUE) val files = ArrayList() data.fileList.forEach { file -> @@ -84,7 +84,7 @@ BottomActionSheet.Builder() .setContext(requireContext()) .setActionItemTitle(files) - .setItemTextColor(R.color.themeColor.convertColor(requireContext())) + .setItemTextColor(Color.BLUE) .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { override fun onActionItemClick(position: Int) { diff --git a/app/src/main/java/com/casic/xz/meterage/model/SampleListModel.java b/app/src/main/java/com/casic/xz/meterage/model/SampleListModel.java new file mode 100644 index 0000000..5784343 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/model/SampleListModel.java @@ -0,0 +1,193 @@ +package com.casic.xz.meterage.model; + +import java.util.List; + +public class SampleListModel { + + private int code; + private DataModel data; + private String message; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataModel getData() { + return data; + } + + public void setData(DataModel data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public static class DataModel { + private List rows; + private int total; + + public List getRows() { + return rows; + } + + public void setRows(List rows) { + this.rows = rows; + } + + public int getTotal() { + return total; + } + + public void setTotal(int total) { + this.total = total; + } + + public static class RowsModel { + private String certificationStatus; + private String customerName; + private String customerNo; + private String id; + private String manufacturingNo; + private String measureLastTime; + private String measurePeriod; + private String orderId; + private String remark; + private String sampleModel; + private String sampleName; + private String sampleNo; + private String sampleSatus; + private String sampleSatusName; + private String validDeadline; + + public String getCertificationStatus() { + return certificationStatus; + } + + public void setCertificationStatus(String certificationStatus) { + this.certificationStatus = certificationStatus; + } + + public String getCustomerName() { + return customerName; + } + + public void setCustomerName(String customerName) { + this.customerName = customerName; + } + + public String getCustomerNo() { + return customerNo; + } + + public void setCustomerNo(String customerNo) { + this.customerNo = customerNo; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getManufacturingNo() { + return manufacturingNo; + } + + public void setManufacturingNo(String manufacturingNo) { + this.manufacturingNo = manufacturingNo; + } + + public String getMeasureLastTime() { + return measureLastTime; + } + + public void setMeasureLastTime(String measureLastTime) { + this.measureLastTime = measureLastTime; + } + + public String getMeasurePeriod() { + return measurePeriod; + } + + public void setMeasurePeriod(String measurePeriod) { + this.measurePeriod = measurePeriod; + } + + public String getOrderId() { + return orderId; + } + + public void setOrderId(String orderId) { + this.orderId = orderId; + } + + public String getRemark() { + return remark; + } + + public void setRemark(String remark) { + this.remark = remark; + } + + public String getSampleModel() { + return sampleModel; + } + + public void setSampleModel(String sampleModel) { + this.sampleModel = sampleModel; + } + + public String getSampleName() { + return sampleName; + } + + public void setSampleName(String sampleName) { + this.sampleName = sampleName; + } + + public String getSampleNo() { + return sampleNo; + } + + public void setSampleNo(String sampleNo) { + this.sampleNo = sampleNo; + } + + public String getSampleSatus() { + return sampleSatus; + } + + public void setSampleSatus(String sampleSatus) { + this.sampleSatus = sampleSatus; + } + + public String getSampleSatusName() { + return sampleSatusName; + } + + public void setSampleSatusName(String sampleSatusName) { + this.sampleSatusName = sampleSatusName; + } + + public String getValidDeadline() { + return validDeadline; + } + + public void setValidDeadline(String validDeadline) { + this.validDeadline = validDeadline; + } + } + } +} diff --git a/app/src/main/java/com/casic/xz/meterage/model/UploadResultModel.java b/app/src/main/java/com/casic/xz/meterage/model/UploadResultModel.java new file mode 100644 index 0000000..f2a6a41 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/model/UploadResultModel.java @@ -0,0 +1,34 @@ +package com.casic.xz.meterage.model; + +import java.util.List; + +public class UploadResultModel { + + private int code; + private List data; + private String message; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public List getData() { + return data; + } + + public void setData(List data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } +} diff --git a/app/src/main/java/com/casic/xz/meterage/utils/FileType.kt b/app/src/main/java/com/casic/xz/meterage/utils/FileType.kt new file mode 100644 index 0000000..17e2bca --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/utils/FileType.kt @@ -0,0 +1,23 @@ +package com.casic.xz.meterage.utils + +sealed class FileType { + /** + * PDF文件 + */ + object PDF : FileType() + + /** + * WORD文件 + */ + object WORD : FileType() + + /** + * IMAGE图片 + */ + object IMAGE : FileType() + + /** + * 未知类型(Excel) + */ + object UNKNOWN : FileType() +} diff --git a/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitService.kt index bc3f8d6..8f4fe44 100644 --- a/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitService.kt @@ -1,5 +1,6 @@ package com.casic.xz.meterage.utils.retrofit +import okhttp3.MultipartBody import okhttp3.RequestBody import retrofit2.http.* @@ -35,6 +36,16 @@ ): String /** + * 上传文件 + */ + @Multipart + @POST("/minio/file/upload") + suspend fun uploadFile( + @Header("token") token: String, + @Part file: MultipartBody.Part + ): String + + /** * 获取通知公告列表 */ @POST("/system/notice/listPage") @@ -209,4 +220,24 @@ @Header("token") token: String, @Body requestBody: RequestBody ): String + + /** + * 获取样品列表 + */ + @POST("/customer/sample/listPage") + suspend fun getSampleList( + @Header("token") token: String, + @Body requestBody: RequestBody, + @QueryMap limit: Map, + @QueryMap offset: Map + ): String + + /** + * 新增委托书 + */ + @POST("/business/order/add") + suspend fun addEntrust( + @Header("token") token: String, + @Body requestBody: RequestBody + ): String } \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitServiceManager.kt index cb22e45..90abe5a 100644 --- a/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitServiceManager.kt @@ -1,13 +1,20 @@ package com.casic.xz.meterage.utils.retrofit +import com.alibaba.fastjson2.JSON +import com.alibaba.fastjson2.JSONArray +import com.alibaba.fastjson2.JSONObject +import com.casic.xz.meterage.model.SampleListModel import com.casic.xz.meterage.utils.AuthenticationHelper +import com.casic.xz.meterage.utils.FileType import com.casic.xz.meterage.utils.LocaleConstant import com.pengxh.kt.lite.utils.RetrofitFactory import com.pengxh.kt.lite.utils.SaveKeyValues import okhttp3.MediaType.Companion.toMediaType +import okhttp3.MediaType.Companion.toMediaTypeOrNull +import okhttp3.MultipartBody +import okhttp3.RequestBody.Companion.asRequestBody import okhttp3.RequestBody.Companion.toRequestBody -import org.json.JSONArray -import org.json.JSONObject +import java.io.File object RetrofitServiceManager { @@ -31,9 +38,9 @@ */ suspend fun login(sid: String, account: String, secretKey: String): String { val paramObject = JSONObject() - paramObject.put("sid", sid) - paramObject.put("username", account) - paramObject.put("password", secretKey) + paramObject["sid"] = sid + paramObject["username"] = account + paramObject["password"] = secretKey val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -55,6 +62,20 @@ } /** + * 上传文件 + */ + suspend fun uploadFile(file: File, type: FileType): String { + val requestBody = when (type) { + FileType.PDF -> file.asRequestBody("application/pdf".toMediaTypeOrNull()) + FileType.WORD -> file.asRequestBody("application/msword".toMediaTypeOrNull()) + FileType.IMAGE -> file.asRequestBody("image/png".toMediaTypeOrNull()) + else -> file.asRequestBody("application/vnd.ms-excel".toMediaTypeOrNull()) + } + val filePart = MultipartBody.Part.createFormData("multipartFile", file.name, requestBody) + return api.uploadFile(AuthenticationHelper.token!!, filePart) + } + + /** * 获取通知公告列表 */ suspend fun getNoticeList( @@ -66,11 +87,11 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("noticeNo", noticeNo) - paramObject.put("noticeTitle", noticeTitle) - paramObject.put("noticePublisher", noticePublisher) - paramObject.put("noticeStartTime", noticeStartTime) - paramObject.put("noticeEndTime", noticeEndTime) + paramObject["noticeNo"] = noticeNo + paramObject["noticeTitle"] = noticeTitle + paramObject["noticePublisher"] = noticePublisher + paramObject["noticeStartTime"] = noticeStartTime + paramObject["noticeEndTime"] = noticeEndTime val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -105,26 +126,21 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("equipmentNo", equipmentNo) - paramObject.put("equipmentName", equipmentName) - paramObject.put("mesureType", mesureType) - paramObject.put("managerState", managerState) - paramObject.put("useDept", useDept) - paramObject.put("assetType", assetType) - paramObject.put("equipmentCategory", equipmentCategory) - paramObject.put("isCalibrationTestEquipment", isCalibrationTestEquipment) - paramObject.put("isMeasureAccount", isMeasureAccount) - paramObject.put("isStandardSupportEquipment", isStandardSupportEquipment) - paramObject.put("isFixedAssets", isFixedAssets) - paramObject.put("validStartDate", validStartDate) - paramObject.put("validEndDate", validEndDate) - paramObject.put("abc", abc) - - val jsonArray = JSONArray() - ids.forEach { - jsonArray.put(it) - } - paramObject.put("ids", jsonArray) + paramObject["equipmentNo"] = equipmentNo + paramObject["equipmentName"] = equipmentName + paramObject["mesureType"] = mesureType + paramObject["managerState"] = managerState + paramObject["useDept"] = useDept + paramObject["assetType"] = assetType + paramObject["equipmentCategory"] = equipmentCategory + paramObject["isCalibrationTestEquipment"] = isCalibrationTestEquipment + paramObject["isMeasureAccount"] = isMeasureAccount + paramObject["isStandardSupportEquipment"] = isStandardSupportEquipment + paramObject["isFixedAssets"] = isFixedAssets + paramObject["validStartDate"] = validStartDate + paramObject["validEndDate"] = validEndDate + paramObject["abc"] = abc + paramObject["ids"] = JSONArray.parseArray(JSON.toJSONString(ids)) val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() @@ -143,7 +159,7 @@ */ suspend fun getEquipmentDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -164,13 +180,13 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("standardNo", standardNo) - paramObject.put("standardName", standardName) - paramObject.put("category", category) - paramObject.put("managerState", managerState) - paramObject.put("standardLaboratory", standardLaboratory) - paramObject.put("preparationDate", preparationDate) - paramObject.put("id", id) + paramObject["standardNo"] = standardNo + paramObject["standardName"] = standardName + paramObject["category"] = category + paramObject["managerState"] = managerState + paramObject["standardLaboratory"] = standardLaboratory + paramObject["preparationDate"] = preparationDate + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -193,7 +209,7 @@ */ suspend fun getStandardDeviceDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -212,11 +228,11 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("checkType", checkType) - paramObject.put("priceItem", priceItem) - paramObject.put("priceName", priceName) - paramObject.put("priceNo", priceNo) - paramObject.put("priceType", priceType) + paramObject["checkType"] = checkType + paramObject["priceItem"] = priceItem + paramObject["priceName"] = priceName + paramObject["priceNo"] = priceNo + paramObject["priceType"] = priceType val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -234,7 +250,7 @@ */ suspend fun getCapabilityDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -257,20 +273,15 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("createStartTime", createStartTime) - paramObject.put("createEndTime", createEndTime) - paramObject.put("deptId", deptId) - paramObject.put("director", director) - paramObject.put("effectiveCompany", effectiveCompany) - paramObject.put("trainStartTime", trainStartTime) - paramObject.put("trainEndTime", trainEndTime) - paramObject.put("formId", formId) - - val jsonArray = JSONArray() - ids.forEach { - jsonArray.put(it) - } - paramObject.put("ids", jsonArray) + paramObject["createStartTime"] = createStartTime + paramObject["createEndTime"] = createEndTime + paramObject["deptId"] = deptId + paramObject["director"] = director + paramObject["effectiveCompany"] = effectiveCompany + paramObject["trainStartTime"] = trainStartTime + paramObject["trainEndTime"] = trainEndTime + paramObject["formId"] = formId + paramObject["ids"] = JSONArray.parseArray(JSON.toJSONString(ids)) val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() @@ -294,7 +305,7 @@ */ suspend fun getMeterageTrainDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -308,10 +319,10 @@ bussinessSize: String, customerName: String, customerNo: String, grade: String, offset: Int ): String { val paramObject = JSONObject() - paramObject.put("bussinessSize", bussinessSize) - paramObject.put("customerName", customerName) - paramObject.put("customerNo", customerNo) - paramObject.put("grade", grade) + paramObject["bussinessSize"] = bussinessSize + paramObject["customerName"] = customerName + paramObject["customerNo"] = customerNo + paramObject["grade"] = grade val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() @@ -330,7 +341,7 @@ */ suspend fun getCustomerDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -342,7 +353,7 @@ */ suspend fun getStaffList(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -354,7 +365,7 @@ */ suspend fun getSupportEquipmentList(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -366,7 +377,7 @@ */ suspend fun getVerifyProcedureList(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -389,20 +400,15 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("customerName", customerName) - paramObject.put("customerNo", customerNo) - paramObject.put("deliverer", deliverer) - paramObject.put("orderCode", orderCode) - paramObject.put("startTime", startTime) - paramObject.put("endTime", endTime) - paramObject.put("isUrgent", isUrgent) - paramObject.put("status", status) - - val jsonArray = JSONArray() - ids.forEach { - jsonArray.put(it) - } - paramObject.put("ids", jsonArray) + paramObject["customerName"] = customerName + paramObject["customerNo"] = customerNo + paramObject["deliverer"] = deliverer + paramObject["orderCode"] = orderCode + paramObject["startTime"] = startTime + paramObject["endTime"] = endTime + paramObject["isUrgent"] = isUrgent + paramObject["status"] = status + paramObject["ids"] = JSONArray.parseArray(JSON.toJSONString(ids)) val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() @@ -421,7 +427,7 @@ */ suspend fun getEntrustDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -433,7 +439,7 @@ */ suspend fun acceptEntrust(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -446,10 +452,89 @@ */ suspend fun returnEntrust(id: String, selected: ArrayList): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) return api.returnEntrust(AuthenticationHelper.token!!, requestBody) } + + /** + * 获取样品列表 + */ + suspend fun getSampleList( + customerName: String, + customerNo: String, + startTime: String, + endTime: String, + sampleName: String, + sampleNo: String, + sampleModel: String, + sampleBelong: String, + overtimeStatus: String, + ids: Array, + offset: Int + ): String { + val paramObject = JSONObject() + paramObject["customerName"] = customerName + paramObject["customerNo"] = customerNo + paramObject["startTime"] = startTime + paramObject["endTime"] = endTime + paramObject["sampleName"] = sampleName + paramObject["sampleNo"] = sampleNo + paramObject["sampleModel"] = sampleModel + paramObject["sampleBelong"] = sampleBelong + paramObject["overtimeStatus"] = overtimeStatus + paramObject["ids"] = JSONArray.parseArray(JSON.toJSONString(ids)) + + val requestBody = paramObject.toString().toRequestBody( + "application/json;charset=UTF-8".toMediaType() + ) + + val limitMap = HashMap() + limitMap["limit"] = LocaleConstant.PAGE_LIMIT + + val offsetMap = HashMap() + offsetMap["offset"] = offset + return api.getSampleList(AuthenticationHelper.token!!, requestBody, limitMap, offsetMap) + } + + /** + * 新增委托书 + */ + suspend fun addEntrust( + deliverer: String, + delivererTel: String, + orderTime: String, + planDeliverTime: String, + requireOverTime: String, + customerName: String, + customerPhone: String, + customerAddress: String, + remark: String, + minioFileName: String, + certifications: String, + isUrgent: String, + samples: List + ): String { + val paramObject = JSONObject() + paramObject["deliverer"] = deliverer + paramObject["delivererTel"] = delivererTel + paramObject["orderTime"] = orderTime + paramObject["planDeliverTime"] = planDeliverTime + paramObject["requireOverTime"] = requireOverTime + paramObject["customerName"] = customerName + paramObject["customerPhone"] = customerPhone + paramObject["customerAddress"] = customerAddress + paramObject["remark"] = remark + paramObject["minioFileName"] = minioFileName + paramObject["certifications"] = certifications + paramObject["isUrgent"] = isUrgent + paramObject["customerSampleInfoList"] = JSONArray.parseArray(JSON.toJSONString(samples)) + + val requestBody = paramObject.toString().toRequestBody( + "application/json;charset=UTF-8".toMediaType() + ) + return api.addEntrust(AuthenticationHelper.token!!, requestBody) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/view/home/EntrustAddActivity.kt b/app/src/main/java/com/casic/xz/meterage/view/home/EntrustAddActivity.kt index 3e30095..9c8d27b 100644 --- a/app/src/main/java/com/casic/xz/meterage/view/home/EntrustAddActivity.kt +++ b/app/src/main/java/com/casic/xz/meterage/view/home/EntrustAddActivity.kt @@ -1,52 +1,211 @@ package com.casic.xz.meterage.view.home +import android.app.Activity +import android.content.Context +import android.content.Intent +import android.graphics.Color +import android.graphics.Paint import android.util.Log +import androidx.activity.result.ActivityResult +import androidx.activity.result.ActivityResultCallback +import androidx.activity.result.contract.ActivityResultContracts import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R import com.casic.xz.meterage.adapter.CertificateTypeAdapter2 -import com.casic.xz.meterage.extensions.initLayoutImmersionBar +import com.casic.xz.meterage.adapter.CustomerSampleAdapter +import com.casic.xz.meterage.callback.DateSelectedCallback +import com.casic.xz.meterage.callback.OnImageCompressListener +import com.casic.xz.meterage.extensions.* +import com.casic.xz.meterage.model.EntrustDetailModel +import com.casic.xz.meterage.model.SampleListModel +import com.casic.xz.meterage.utils.FileType +import com.casic.xz.meterage.utils.GlideLoadEngine +import com.casic.xz.meterage.utils.LoadingDialogHub import com.casic.xz.meterage.vm.DictionaryViewModel +import com.casic.xz.meterage.vm.EntrustViewModel +import com.casic.xz.meterage.vm.FileUploadViewModel +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken import com.gyf.immersionbar.ImmersionBar +import com.luck.picture.lib.basic.PictureSelector +import com.luck.picture.lib.config.SelectMimeType +import com.luck.picture.lib.entity.LocalMedia +import com.luck.picture.lib.interfaces.OnResultCallbackListener import com.pengxh.kt.lite.base.KotlinBaseActivity -import com.pengxh.kt.lite.extensions.toJson +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.vm.LoadState +import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import kotlinx.android.synthetic.main.activity_entrust_add.* +import java.io.File + class EntrustAddActivity : KotlinBaseActivity() { + private val context: Context = this@EntrustAddActivity + private val gson by lazy { Gson() } private lateinit var dictionaryViewModel: DictionaryViewModel - private var checkedItems = ArrayList() + private lateinit var fileUploadViewModel: FileUploadViewModel + private lateinit var entrustViewModel: EntrustViewModel + private lateinit var sampleAdapter: CustomerSampleAdapter + private var checkedItems = ArrayList() + private var isUrgent = "0" + private var sampleModels: ArrayList? = null + private var dataBeans = ArrayList() override fun initData() { //证书 dictionaryViewModel = ViewModelProvider(this)[DictionaryViewModel::class.java] dictionaryViewModel.getDictionaryByCode("certificationClass") - dictionaryViewModel.dictionary.observe(this) { dic -> - if (dic.code == 200) { - val typeAdapter2 = CertificateTypeAdapter2(this, dic.data) + dictionaryViewModel.dictionary.observe(this) { + if (it.code == 200) { + val typeAdapter2 = CertificateTypeAdapter2(this, it.data) typeRecyclerView.adapter = typeAdapter2 typeAdapter2.setOnItemCheckedListener(object : CertificateTypeAdapter2.OnItemCheckedListener { override fun onItemChecked(position: Int, isChecked: Boolean) { if (isChecked) { - checkedItems.add(position) + checkedItems.add(position.toString()) } else { - checkedItems.remove(position) + checkedItems.remove(position.toString()) } } }) } } + + fileUploadViewModel = ViewModelProvider(this)[FileUploadViewModel::class.java] + fileUploadViewModel.resultModel.observe(this) { + if (it.code == 200) { + val annexName = it.data[0] + annexView.text = annexName + val textPaint = annexView.paint + textPaint.flags = Paint.UNDERLINE_TEXT_FLAG + textPaint.isAntiAlias = true + annexView.setTextColor(Color.BLUE) + + annexView.setOnClickListener { + annexName.watchAttachFile(this) + } + } + } + + entrustViewModel = ViewModelProvider(this)[EntrustViewModel::class.java] + entrustViewModel.addResult.observe(this) { + if (it.code == 200) { + finish() + } + } + + //样品列表 + sampleAdapter = CustomerSampleAdapter(this, dataBeans) + sampleRecyclerView.adapter = sampleAdapter } + private val selectCustomerLauncher = + registerForActivityResult(ActivityResultContracts.StartActivityForResult(), + object : ActivityResultCallback { + override fun onActivityResult(result: ActivityResult?) { + if (result?.resultCode == Activity.RESULT_OK) { + val data = result.data ?: return + + entrustNameView.text = data.getStringExtra("entrustName") + entrustContactView.text = data.getStringExtra("entrustContact") + entrustAddressView.text = data.getStringExtra("entrustAddress") + } + } + }) + + private val selectSampleLauncher = + registerForActivityResult(ActivityResultContracts.StartActivityForResult(), + object : ActivityResultCallback { + override fun onActivityResult(result: ActivityResult?) { + if (result?.resultCode == Activity.RESULT_OK) { + val data = result.data ?: return + + val modelsJson = data.getStringExtra("sampleModels") + if (!modelsJson.isNullOrBlank()) { + sampleModels = gson.fromJson( + modelsJson, + object : + TypeToken>() {}.type + ) + } + + //刷新列表 + dataBeans.clear() + sampleModels?.forEach { + val model = + EntrustDetailModel.DataModel.CustomerSampleInfoListModel() + + model.customerName = it.customerName + model.customerNo = it.customerNo + model.id = it.id + model.manufacturingNo = it.manufacturingNo + model.measureLastTime = it.measureLastTime + model.measurePeriod = it.measurePeriod + model.orderId = it.orderId + model.remark = it.remark + model.sampleModel = it.sampleModel + model.sampleName = it.sampleName + model.sampleNo = it.sampleNo + model.validDeadline = it.validDeadline + + dataBeans.add(model) + } + sampleAdapter.notifyDataSetChanged() + } + } + }) + override fun initEvent() { + leftBackView.setOnClickListener { finish() } + + estimateTimeView.setOnClickListener { + showDatePicker(object : DateSelectedCallback { + override fun onDateSelected(date: String) { + estimateTimeView.text = date + } + }) + } + + completedView.setOnClickListener { + showDatePicker(object : DateSelectedCallback { + override fun onDateSelected(date: String) { + completedView.text = date + } + }) + } + + entrustNameView.setOnClickListener { + selectCustomerLauncher.launch(Intent(this, SelectCustomerActivity::class.java)) + } + //上传附件 uploadFileButton.setOnClickListener { + BottomActionSheet.Builder() + .setContext(this) + .setItemTextColor(Color.BLUE) + .setActionItemTitle(listOf("文件", "图片")) + .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { + override fun onActionItemClick(position: Int) { + when (position) { + 0 -> uploadFile() + 1 -> uploadImage() + } + } + }).build().show() + } + radioGroup.setOnCheckedChangeListener { _, checkedId -> + when (checkedId) { + R.id.radioButton1 -> isUrgent = "1" + R.id.radioButton2 -> isUrgent = "0" + } } //选择样品 selectSampleButton.setOnClickListener { - + selectSampleLauncher.launch(Intent(this, SelectSampleActivity::class.java)) } //写入样品信息 @@ -55,14 +214,68 @@ } pushEntrustView.setOnClickListener { - Log.d("Casic", "EntrustAddActivity => initEvent: ${checkedItems.toJson()}") + val sender = senderView.text.toString() + if (sender.isBlank()) { + "请填写送样人名字".show(this) + return@setOnClickListener + } + + val contact = contactView.text.toString() + if (contact.isBlank()) { + "请填写送样人联系方式".show(this) + return@setOnClickListener + } + + val estimateTime = estimateTimeView.text.toString() + if (estimateTime.isBlank()) { + "请选择预计送到的时间".show(this) + return@setOnClickListener + } + + val entrustName = entrustNameView.text.toString() + if (entrustName.isBlank()) { + "请选择委托方".show(this) + return@setOnClickListener + } + + if (sampleModels == null) { + "请选择样品".show(this) + return@setOnClickListener + } + entrustViewModel.addEntrust( + sender, + contact, + createEntrustDateView.text.toString(), + estimateTime, + completedView.text.toString(), + entrustName, + entrustContactView.text.toString(), + entrustAddressView.text.toString(), + remarkView.text.toString(), + annexView.text.toString(), + checkedItems.reformat(), + isUrgent, + sampleModels!! + ) } } override fun initLayoutView(): Int = R.layout.activity_entrust_add override fun observeRequestState() { + fileUploadViewModel.loadState.observe(this) { + when (it) { + LoadState.Loading -> LoadingDialogHub.show(this, "文件上传中,请稍后...") + else -> LoadingDialogHub.dismiss() + } + } + entrustViewModel.loadState.observe(this) { + when (it) { + LoadState.Loading -> LoadingDialogHub.show(this, "委托创建中,请稍后...") + else -> LoadingDialogHub.dismiss() + } + } } override fun setupTopBarLayout() { @@ -70,4 +283,62 @@ initLayoutImmersionBar(rootView) titleView.text = "委托需求" } + + private fun uploadFile() { +// val explorer = FileExplorer(this) +// explorer.setInitDir(ExplorerMode.FILE, Environment.getExternalStorageDirectory()) +// explorer.setShowHomeDir(true) +// explorer.setShowUpDir(true) +// explorer.setShowHideDir(true) +// explorer.setAllowExtensions(arrayOf(".doc", ".docx", ".xls", ".xlsx", ".pdf")) +// explorer.setOnFileClickedListener { +// val type = if (it.name.endsWith(".doc") || it.name.endsWith(".docx")) { +// FileType.WORD +// } else if (it.name.endsWith(".pdf")) { +// FileType.PDF +// } else { +// FileType.UNKNOWN +// } +// +// Log.d("Casic", "EntrustAddActivity => uploadFile: ${it.absolutePath}") +// fileUploadViewModel.uploadFile(it, type) +// } + } + + private fun uploadImage() { + PictureSelector.create(this) + .openGallery(SelectMimeType.ofImage()) + .isGif(false) + .isMaxSelectEnabledMask(true) + .setFilterMinFileSize(100) + .setMaxSelectNum(1) + .isDisplayCamera(false) + .setImageEngine(GlideLoadEngine.instance) + .forResult(object : OnResultCallbackListener { + override fun onResult(result: ArrayList?) { + if (result == null) { + "选择照片失败,请重试".show(context) + return + } + result[0].realPath.compressImage(context, object : OnImageCompressListener { + override fun onSuccess(file: File) { + Log.d( + "Casic", "EntrustAddActivity => onSuccess: ${file.absolutePath}" + ) + ///storage/emulated/0/Android/data/com.casic.xz.meterage/files/Pictures/CompressImage/1677478115391211.jpeg + //上传图片 + fileUploadViewModel.uploadFile(file, FileType.IMAGE) + } + + override fun onError(e: Throwable) { + e.printStackTrace() + } + }) + } + + override fun onCancel() { + + } + }) + } } \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 0ae369f..687b02b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -15,7 +15,6 @@ } compileSdkVersion 31 - buildToolsVersion "30.0.3" defaultConfig { applicationId "com.casic.xz.meterage" @@ -84,11 +83,13 @@ implementation 'top.zibin:Luban:1.1.8' //官方Json解析库 implementation 'com.google.code.gson:gson:2.9.0' + //阿里巴巴JSON库 + implementation 'com.alibaba.fastjson2:fastjson2:2.0.24' //Kotlin协程 implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.5.1' //MVVM+LiveData implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.5.1" - implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.0" + implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1" implementation "androidx.lifecycle:lifecycle-extensions:2.2.0" //返回值转换器 implementation 'com.jakewharton.retrofit:retrofit2-kotlin-coroutines-adapter:0.9.2' @@ -109,4 +110,8 @@ implementation 'com.github.barteksc:android-pdf-viewer:2.8.2' //绕过Android 11反射限制 implementation 'com.github.tiann:FreeReflection:3.1.0' + //单项/数字、二三级联动、日期/时间等滚轮选择器 + implementation 'com.github.gzu-liyujiang.AndroidPicker:WheelPicker:4.1.8' + //文件/目录选择器 + implementation 'com.github.gzu-liyujiang.AndroidPicker:FilePicker:4.1.1' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 1ccc12b..0fba91b 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -60,6 +60,8 @@ + + diff --git a/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt b/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt new file mode 100644 index 0000000..21a71d8 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt @@ -0,0 +1,70 @@ +package com.casic.xz.meterage.adapter + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import com.casic.xz.meterage.R +import com.casic.xz.meterage.extensions.toChineseGrade +import com.casic.xz.meterage.model.CustomerListModel + +class SelectCustomerAdapter( + context: Context, private val dataRows: MutableList +) : RecyclerView.Adapter() { + + private var layoutInflater = LayoutInflater.from(context) + + //选择的位置 + private var selectedPosition = 0 + + //临时记录上次选择的位置 + private var temp = -1 + + override fun getItemCount(): Int = dataRows.size + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ItemViewHolder( + layoutInflater.inflate(R.layout.item_select_customer_lv, parent, false) + ) + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + //绑定数据 + val rowsBean = dataRows[position] + holder.agreementLevelView.text = rowsBean.grade.toChineseGrade() + holder.customerNameView.text = rowsBean.customerName + holder.scaleView.text = rowsBean.companySizeName + holder.overallView.text = "公司规模:${rowsBean.evaluationName}" + holder.fullAddressView.text = "公司地址:${rowsBean.fullAddress}" + + holder.itemView.isSelected = holder.layoutPosition == selectedPosition + holder.itemView.setOnClickListener { + itemCheckedListener?.onItemChecked(rowsBean) + + holder.itemView.isSelected = true + temp = selectedPosition + //设置新的位置 + selectedPosition = holder.layoutPosition + //更新旧位置 + notifyItemChanged(temp) + } + } + + inner class ItemViewHolder(view: View) : RecyclerView.ViewHolder(view) { + var agreementLevelView: TextView = view.findViewById(R.id.agreementLevelView) + var customerNameView: TextView = view.findViewById(R.id.customerNameView) + var scaleView: TextView = view.findViewById(R.id.scaleView) + var overallView: TextView = view.findViewById(R.id.overallView) + var fullAddressView: TextView = view.findViewById(R.id.fullAddressView) + } + + private var itemCheckedListener: OnItemCheckedListener? = null + + interface OnItemCheckedListener { + fun onItemChecked(item: CustomerListModel.DataModel.RowsModel) + } + + fun setOnCheckedListener(listener: OnItemCheckedListener?) { + itemCheckedListener = listener + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt b/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt new file mode 100644 index 0000000..c29461e --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt @@ -0,0 +1,68 @@ +package com.casic.xz.meterage.adapter + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import com.casic.xz.meterage.R +import com.casic.xz.meterage.model.SampleListModel + +class SelectSampleAdapter( + context: Context, private val dataRows: MutableList +) : RecyclerView.Adapter() { + + private var layoutInflater = LayoutInflater.from(context) + private var multipleSelected = mutableSetOf() + private var sampleModes = ArrayList() + + override fun getItemCount(): Int = dataRows.size + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ItemViewHolder( + layoutInflater.inflate(R.layout.item_select_sample_lv, parent, false) + ) + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + //绑定数据 + val rowsBean = dataRows[position] + holder.sampleNameView.text = "${rowsBean.sampleName}【${rowsBean.sampleModel}】" + holder.manufacturingCodeView.text = "出厂编号:${rowsBean.manufacturingNo}" + holder.sampleCodeView.text = "样品编号:${rowsBean.sampleNo}" + holder.validDateView.text = "有效期至:${rowsBean.validDeadline}" + + holder.checkImageView.isSelected = multipleSelected.contains(position) + holder.itemView.setOnClickListener { + if (multipleSelected.contains(position)) { + multipleSelected.remove(position) + sampleModes.remove(dataRows[position]) + holder.checkImageView.isSelected = false + } else { + multipleSelected.add(position) + sampleModes.add(dataRows[position]) + holder.checkImageView.isSelected = true + } + + itemCheckedListener?.onItemChecked(sampleModes) + } + } + + inner class ItemViewHolder(view: View) : RecyclerView.ViewHolder(view) { + var sampleNameView: TextView = view.findViewById(R.id.sampleNameView) + var manufacturingCodeView: TextView = view.findViewById(R.id.manufacturingCodeView) + var sampleCodeView: TextView = view.findViewById(R.id.sampleCodeView) + var validDateView: TextView = view.findViewById(R.id.validDateView) + var checkImageView: ImageView = view.findViewById(R.id.checkImageView) + } + + private var itemCheckedListener: OnItemCheckedListener? = null + + interface OnItemCheckedListener { + fun onItemChecked(items: ArrayList) + } + + fun setOnCheckedListener(listener: OnItemCheckedListener?) { + itemCheckedListener = listener + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/callback/DateSelectedCallback.kt b/app/src/main/java/com/casic/xz/meterage/callback/DateSelectedCallback.kt new file mode 100644 index 0000000..8196110 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/callback/DateSelectedCallback.kt @@ -0,0 +1,5 @@ +package com.casic.xz.meterage.callback + +interface DateSelectedCallback { + fun onDateSelected(date: String) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/Activity.kt b/app/src/main/java/com/casic/xz/meterage/extensions/Activity.kt new file mode 100644 index 0000000..e112d1c --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/extensions/Activity.kt @@ -0,0 +1,33 @@ +package com.casic.xz.meterage.extensions + +import android.app.Activity +import com.casic.xz.meterage.R +import com.casic.xz.meterage.callback.DateSelectedCallback +import com.github.gzuliyujiang.wheelpicker.DatePicker +import com.github.gzuliyujiang.wheelpicker.annotation.DateMode +import com.github.gzuliyujiang.wheelpicker.entity.DateEntity +import com.pengxh.kt.lite.extensions.convertColor +import com.pengxh.kt.lite.extensions.sp2px + +fun Activity.showDatePicker(callback: DateSelectedCallback) { + val datePicker = DatePicker(this) + + val layout = datePicker.wheelLayout + layout.setDateMode(DateMode.YEAR_MONTH_DAY) + layout.setDateLabel("年", "月", "日"); + layout.setTextSize(14f.sp2px(this).toFloat()) + layout.setSelectedTextSize(16f.sp2px(this).toFloat()) + layout.setSelectedTextColor(R.color.themeColor.convertColor(this)) + layout.setSelectedTextBold(true) + layout.setResetWhenLinkage(false) + layout.setRange( + DateEntity.today(), + DateEntity.target(2050, 12, 31), + DateEntity.today() + ) + + datePicker.setOnDatePickedListener { year, month, day -> + callback.onDateSelected(String.format("%s-%s-%s", year, month, day)) + } + datePicker.show() +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt b/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt index 016ebcb..cf6bf49 100644 --- a/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt +++ b/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt @@ -4,7 +4,7 @@ * ArrayList扩展方法 */ -//将图片集合格式化成满足上传格式的数据 +//将集合格式化成满足上传格式的数据 fun ArrayList.reformat(): String { if (this.isEmpty()) return "" val builder = StringBuilder() diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt b/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt index 7c57643..aa9b92b 100644 --- a/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt +++ b/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt @@ -1,7 +1,6 @@ package com.casic.xz.meterage.extensions import android.content.Context -import android.util.Log import android.view.ViewGroup import com.casic.xz.meterage.base.BaseApplication import com.pengxh.kt.lite.extensions.dp2px @@ -9,9 +8,8 @@ fun Context.initLayoutImmersionBar(rootView: ViewGroup) { var statusBarHeight = QMUIDisplayHelper.getStatusBarHeight(this) - Log.d("Casic", "状态栏高度: $statusBarHeight") if (statusBarHeight == 0) { - statusBarHeight = 44f.dp2px(BaseApplication.get()) + statusBarHeight = 40f.dp2px(BaseApplication.get()) } rootView.setPadding(0, statusBarHeight, 0, 0) rootView.requestLayout() diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/String.kt b/app/src/main/java/com/casic/xz/meterage/extensions/String.kt index 28f70d8..6234d43 100644 --- a/app/src/main/java/com/casic/xz/meterage/extensions/String.kt +++ b/app/src/main/java/com/casic/xz/meterage/extensions/String.kt @@ -128,9 +128,10 @@ fun String.combineImagePath(): String { if (this.isEmpty()) return this val defaultValue = SaveKeyValues.getValue( - LocaleConstant.DEFAULT_SERVER_CONFIG, LocaleConstant.SERVER_BASE_URL + LocaleConstant.FILE_SERVER_CONFIG, LocaleConstant.File_SERVER_URL ) as String - return "$defaultValue/static/${this.replace("\\", "/")}" + //http://111.198.10.15:21408/test/1677479806059688_1677479806038.jpeg + return "$defaultValue/test/${this.replace("\\", "/")}" } fun String.isEarlier(time: String): Boolean { diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt index 25fa87b..a0e1358 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt @@ -1,18 +1,12 @@ package com.casic.xz.meterage.fragment.customer +import android.graphics.Color import android.graphics.Paint import com.casic.xz.meterage.R -import com.casic.xz.meterage.extensions.combineImagePath import com.casic.xz.meterage.extensions.toChineseGrade +import com.casic.xz.meterage.extensions.watchAttachFile import com.casic.xz.meterage.model.CustomerDetailModel -import com.casic.xz.meterage.view.BigImageActivity -import com.casic.xz.meterage.view.notice.PreviewDocumentActivity -import com.casic.xz.meterage.view.notice.PreviewPdfActivity -import com.casic.xz.meterage.view.notice.PreviewTextActivity import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.extensions.show import kotlinx.android.synthetic.main.fragment_customer_basic_information.* class BasicInformationFragment(private val data: CustomerDetailModel.DataModel) : @@ -48,30 +42,11 @@ val textPaint = minioFileView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - minioFileView.setTextColor(R.color.themeColor.convertColor(requireContext())) + minioFileView.setTextColor(Color.BLUE) minioFileView.setOnClickListener { //查看附件 - if (minioFileName.endsWith("pdf")) { - requireContext().navigatePageTo(minioFileName) - } else if ( - minioFileName.endsWith("doc") || - minioFileName.endsWith("docx") - ) { - requireContext().navigatePageTo(minioFileName) - } else if (minioFileName.endsWith("txt")) { - requireContext().navigatePageTo(minioFileName) - } else if ( - minioFileName.endsWith("png") || - minioFileName.endsWith("jpeg") || - minioFileName.endsWith("jpg") - ) { - val urls = ArrayList() - urls.add(minioFileName.combineImagePath()) - requireContext().navigatePageTo(0, urls) - } else { - "文件类型未知,无法打开附件".show(requireContext()) - } + minioFileName.watchAttachFile(requireContext()) } } } diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt index 77846b4..3a0fe2e 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt @@ -1,5 +1,6 @@ package com.casic.xz.meterage.fragment.device +import android.graphics.Color import android.graphics.Paint import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R @@ -7,7 +8,6 @@ import com.casic.xz.meterage.utils.LoadingDialogHub import com.casic.xz.meterage.vm.EquipmentViewModel import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor import com.pengxh.kt.lite.vm.LoadState import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import kotlinx.android.synthetic.main.fragment_device_basic_information.* @@ -56,7 +56,7 @@ val textPaint = documentsView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - documentsView.setTextColor(R.color.themeColor.convertColor(requireContext())) + documentsView.setTextColor(Color.BLUE) val files = ArrayList() data.fileList.forEach { file -> @@ -66,7 +66,7 @@ BottomActionSheet.Builder() .setContext(requireContext()) .setActionItemTitle(files) - .setItemTextColor(R.color.themeColor.convertColor(requireContext())) + .setItemTextColor(Color.BLUE) .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { override fun onActionItemClick(position: Int) { diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt index 15dc3d2..10eeff8 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt @@ -1,5 +1,6 @@ package com.casic.xz.meterage.fragment.entrust +import android.graphics.Color import android.graphics.Paint import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R @@ -9,7 +10,6 @@ import com.casic.xz.meterage.model.EntrustDetailModel import com.casic.xz.meterage.vm.DictionaryViewModel import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor import kotlinx.android.synthetic.main.fragment_entrust_basic_information.* class BasicInformationFragment(private val data: EntrustDetailModel.DataModel) : @@ -38,7 +38,7 @@ val textPaint = annexView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - annexView.setTextColor(R.color.themeColor.convertColor(requireContext())) + annexView.setTextColor(Color.BLUE) annexView.setOnClickListener { minioFileName.watchAttachFile(requireContext()) @@ -59,9 +59,9 @@ //加急 if (data.isUrgent == "0") { - RadioButton2.isChecked = true + radioButton2.isChecked = true } else { - RadioButton1.isChecked = true + radioButton1.isChecked = true } //样品 diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/equipment/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/equipment/BasicInformationFragment.kt index 72b523c..7bc3b01 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/equipment/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/equipment/BasicInformationFragment.kt @@ -1,5 +1,6 @@ package com.casic.xz.meterage.fragment.equipment +import android.graphics.Color import android.graphics.Paint import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R @@ -7,7 +8,6 @@ import com.casic.xz.meterage.utils.LoadingDialogHub import com.casic.xz.meterage.vm.EquipmentViewModel import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor import com.pengxh.kt.lite.vm.LoadState import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import kotlinx.android.synthetic.main.fragment_equipment_basic_information.* @@ -74,7 +74,7 @@ val textPaint = instructionsView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - instructionsView.setTextColor(R.color.themeColor.convertColor(requireContext())) + instructionsView.setTextColor(Color.BLUE) val files = ArrayList() data.fileList.forEach { file -> @@ -84,7 +84,7 @@ BottomActionSheet.Builder() .setContext(requireContext()) .setActionItemTitle(files) - .setItemTextColor(R.color.themeColor.convertColor(requireContext())) + .setItemTextColor(Color.BLUE) .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { override fun onActionItemClick(position: Int) { diff --git a/app/src/main/java/com/casic/xz/meterage/model/SampleListModel.java b/app/src/main/java/com/casic/xz/meterage/model/SampleListModel.java new file mode 100644 index 0000000..5784343 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/model/SampleListModel.java @@ -0,0 +1,193 @@ +package com.casic.xz.meterage.model; + +import java.util.List; + +public class SampleListModel { + + private int code; + private DataModel data; + private String message; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataModel getData() { + return data; + } + + public void setData(DataModel data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public static class DataModel { + private List rows; + private int total; + + public List getRows() { + return rows; + } + + public void setRows(List rows) { + this.rows = rows; + } + + public int getTotal() { + return total; + } + + public void setTotal(int total) { + this.total = total; + } + + public static class RowsModel { + private String certificationStatus; + private String customerName; + private String customerNo; + private String id; + private String manufacturingNo; + private String measureLastTime; + private String measurePeriod; + private String orderId; + private String remark; + private String sampleModel; + private String sampleName; + private String sampleNo; + private String sampleSatus; + private String sampleSatusName; + private String validDeadline; + + public String getCertificationStatus() { + return certificationStatus; + } + + public void setCertificationStatus(String certificationStatus) { + this.certificationStatus = certificationStatus; + } + + public String getCustomerName() { + return customerName; + } + + public void setCustomerName(String customerName) { + this.customerName = customerName; + } + + public String getCustomerNo() { + return customerNo; + } + + public void setCustomerNo(String customerNo) { + this.customerNo = customerNo; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getManufacturingNo() { + return manufacturingNo; + } + + public void setManufacturingNo(String manufacturingNo) { + this.manufacturingNo = manufacturingNo; + } + + public String getMeasureLastTime() { + return measureLastTime; + } + + public void setMeasureLastTime(String measureLastTime) { + this.measureLastTime = measureLastTime; + } + + public String getMeasurePeriod() { + return measurePeriod; + } + + public void setMeasurePeriod(String measurePeriod) { + this.measurePeriod = measurePeriod; + } + + public String getOrderId() { + return orderId; + } + + public void setOrderId(String orderId) { + this.orderId = orderId; + } + + public String getRemark() { + return remark; + } + + public void setRemark(String remark) { + this.remark = remark; + } + + public String getSampleModel() { + return sampleModel; + } + + public void setSampleModel(String sampleModel) { + this.sampleModel = sampleModel; + } + + public String getSampleName() { + return sampleName; + } + + public void setSampleName(String sampleName) { + this.sampleName = sampleName; + } + + public String getSampleNo() { + return sampleNo; + } + + public void setSampleNo(String sampleNo) { + this.sampleNo = sampleNo; + } + + public String getSampleSatus() { + return sampleSatus; + } + + public void setSampleSatus(String sampleSatus) { + this.sampleSatus = sampleSatus; + } + + public String getSampleSatusName() { + return sampleSatusName; + } + + public void setSampleSatusName(String sampleSatusName) { + this.sampleSatusName = sampleSatusName; + } + + public String getValidDeadline() { + return validDeadline; + } + + public void setValidDeadline(String validDeadline) { + this.validDeadline = validDeadline; + } + } + } +} diff --git a/app/src/main/java/com/casic/xz/meterage/model/UploadResultModel.java b/app/src/main/java/com/casic/xz/meterage/model/UploadResultModel.java new file mode 100644 index 0000000..f2a6a41 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/model/UploadResultModel.java @@ -0,0 +1,34 @@ +package com.casic.xz.meterage.model; + +import java.util.List; + +public class UploadResultModel { + + private int code; + private List data; + private String message; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public List getData() { + return data; + } + + public void setData(List data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } +} diff --git a/app/src/main/java/com/casic/xz/meterage/utils/FileType.kt b/app/src/main/java/com/casic/xz/meterage/utils/FileType.kt new file mode 100644 index 0000000..17e2bca --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/utils/FileType.kt @@ -0,0 +1,23 @@ +package com.casic.xz.meterage.utils + +sealed class FileType { + /** + * PDF文件 + */ + object PDF : FileType() + + /** + * WORD文件 + */ + object WORD : FileType() + + /** + * IMAGE图片 + */ + object IMAGE : FileType() + + /** + * 未知类型(Excel) + */ + object UNKNOWN : FileType() +} diff --git a/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitService.kt index bc3f8d6..8f4fe44 100644 --- a/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitService.kt @@ -1,5 +1,6 @@ package com.casic.xz.meterage.utils.retrofit +import okhttp3.MultipartBody import okhttp3.RequestBody import retrofit2.http.* @@ -35,6 +36,16 @@ ): String /** + * 上传文件 + */ + @Multipart + @POST("/minio/file/upload") + suspend fun uploadFile( + @Header("token") token: String, + @Part file: MultipartBody.Part + ): String + + /** * 获取通知公告列表 */ @POST("/system/notice/listPage") @@ -209,4 +220,24 @@ @Header("token") token: String, @Body requestBody: RequestBody ): String + + /** + * 获取样品列表 + */ + @POST("/customer/sample/listPage") + suspend fun getSampleList( + @Header("token") token: String, + @Body requestBody: RequestBody, + @QueryMap limit: Map, + @QueryMap offset: Map + ): String + + /** + * 新增委托书 + */ + @POST("/business/order/add") + suspend fun addEntrust( + @Header("token") token: String, + @Body requestBody: RequestBody + ): String } \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitServiceManager.kt index cb22e45..90abe5a 100644 --- a/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitServiceManager.kt @@ -1,13 +1,20 @@ package com.casic.xz.meterage.utils.retrofit +import com.alibaba.fastjson2.JSON +import com.alibaba.fastjson2.JSONArray +import com.alibaba.fastjson2.JSONObject +import com.casic.xz.meterage.model.SampleListModel import com.casic.xz.meterage.utils.AuthenticationHelper +import com.casic.xz.meterage.utils.FileType import com.casic.xz.meterage.utils.LocaleConstant import com.pengxh.kt.lite.utils.RetrofitFactory import com.pengxh.kt.lite.utils.SaveKeyValues import okhttp3.MediaType.Companion.toMediaType +import okhttp3.MediaType.Companion.toMediaTypeOrNull +import okhttp3.MultipartBody +import okhttp3.RequestBody.Companion.asRequestBody import okhttp3.RequestBody.Companion.toRequestBody -import org.json.JSONArray -import org.json.JSONObject +import java.io.File object RetrofitServiceManager { @@ -31,9 +38,9 @@ */ suspend fun login(sid: String, account: String, secretKey: String): String { val paramObject = JSONObject() - paramObject.put("sid", sid) - paramObject.put("username", account) - paramObject.put("password", secretKey) + paramObject["sid"] = sid + paramObject["username"] = account + paramObject["password"] = secretKey val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -55,6 +62,20 @@ } /** + * 上传文件 + */ + suspend fun uploadFile(file: File, type: FileType): String { + val requestBody = when (type) { + FileType.PDF -> file.asRequestBody("application/pdf".toMediaTypeOrNull()) + FileType.WORD -> file.asRequestBody("application/msword".toMediaTypeOrNull()) + FileType.IMAGE -> file.asRequestBody("image/png".toMediaTypeOrNull()) + else -> file.asRequestBody("application/vnd.ms-excel".toMediaTypeOrNull()) + } + val filePart = MultipartBody.Part.createFormData("multipartFile", file.name, requestBody) + return api.uploadFile(AuthenticationHelper.token!!, filePart) + } + + /** * 获取通知公告列表 */ suspend fun getNoticeList( @@ -66,11 +87,11 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("noticeNo", noticeNo) - paramObject.put("noticeTitle", noticeTitle) - paramObject.put("noticePublisher", noticePublisher) - paramObject.put("noticeStartTime", noticeStartTime) - paramObject.put("noticeEndTime", noticeEndTime) + paramObject["noticeNo"] = noticeNo + paramObject["noticeTitle"] = noticeTitle + paramObject["noticePublisher"] = noticePublisher + paramObject["noticeStartTime"] = noticeStartTime + paramObject["noticeEndTime"] = noticeEndTime val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -105,26 +126,21 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("equipmentNo", equipmentNo) - paramObject.put("equipmentName", equipmentName) - paramObject.put("mesureType", mesureType) - paramObject.put("managerState", managerState) - paramObject.put("useDept", useDept) - paramObject.put("assetType", assetType) - paramObject.put("equipmentCategory", equipmentCategory) - paramObject.put("isCalibrationTestEquipment", isCalibrationTestEquipment) - paramObject.put("isMeasureAccount", isMeasureAccount) - paramObject.put("isStandardSupportEquipment", isStandardSupportEquipment) - paramObject.put("isFixedAssets", isFixedAssets) - paramObject.put("validStartDate", validStartDate) - paramObject.put("validEndDate", validEndDate) - paramObject.put("abc", abc) - - val jsonArray = JSONArray() - ids.forEach { - jsonArray.put(it) - } - paramObject.put("ids", jsonArray) + paramObject["equipmentNo"] = equipmentNo + paramObject["equipmentName"] = equipmentName + paramObject["mesureType"] = mesureType + paramObject["managerState"] = managerState + paramObject["useDept"] = useDept + paramObject["assetType"] = assetType + paramObject["equipmentCategory"] = equipmentCategory + paramObject["isCalibrationTestEquipment"] = isCalibrationTestEquipment + paramObject["isMeasureAccount"] = isMeasureAccount + paramObject["isStandardSupportEquipment"] = isStandardSupportEquipment + paramObject["isFixedAssets"] = isFixedAssets + paramObject["validStartDate"] = validStartDate + paramObject["validEndDate"] = validEndDate + paramObject["abc"] = abc + paramObject["ids"] = JSONArray.parseArray(JSON.toJSONString(ids)) val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() @@ -143,7 +159,7 @@ */ suspend fun getEquipmentDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -164,13 +180,13 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("standardNo", standardNo) - paramObject.put("standardName", standardName) - paramObject.put("category", category) - paramObject.put("managerState", managerState) - paramObject.put("standardLaboratory", standardLaboratory) - paramObject.put("preparationDate", preparationDate) - paramObject.put("id", id) + paramObject["standardNo"] = standardNo + paramObject["standardName"] = standardName + paramObject["category"] = category + paramObject["managerState"] = managerState + paramObject["standardLaboratory"] = standardLaboratory + paramObject["preparationDate"] = preparationDate + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -193,7 +209,7 @@ */ suspend fun getStandardDeviceDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -212,11 +228,11 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("checkType", checkType) - paramObject.put("priceItem", priceItem) - paramObject.put("priceName", priceName) - paramObject.put("priceNo", priceNo) - paramObject.put("priceType", priceType) + paramObject["checkType"] = checkType + paramObject["priceItem"] = priceItem + paramObject["priceName"] = priceName + paramObject["priceNo"] = priceNo + paramObject["priceType"] = priceType val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -234,7 +250,7 @@ */ suspend fun getCapabilityDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -257,20 +273,15 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("createStartTime", createStartTime) - paramObject.put("createEndTime", createEndTime) - paramObject.put("deptId", deptId) - paramObject.put("director", director) - paramObject.put("effectiveCompany", effectiveCompany) - paramObject.put("trainStartTime", trainStartTime) - paramObject.put("trainEndTime", trainEndTime) - paramObject.put("formId", formId) - - val jsonArray = JSONArray() - ids.forEach { - jsonArray.put(it) - } - paramObject.put("ids", jsonArray) + paramObject["createStartTime"] = createStartTime + paramObject["createEndTime"] = createEndTime + paramObject["deptId"] = deptId + paramObject["director"] = director + paramObject["effectiveCompany"] = effectiveCompany + paramObject["trainStartTime"] = trainStartTime + paramObject["trainEndTime"] = trainEndTime + paramObject["formId"] = formId + paramObject["ids"] = JSONArray.parseArray(JSON.toJSONString(ids)) val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() @@ -294,7 +305,7 @@ */ suspend fun getMeterageTrainDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -308,10 +319,10 @@ bussinessSize: String, customerName: String, customerNo: String, grade: String, offset: Int ): String { val paramObject = JSONObject() - paramObject.put("bussinessSize", bussinessSize) - paramObject.put("customerName", customerName) - paramObject.put("customerNo", customerNo) - paramObject.put("grade", grade) + paramObject["bussinessSize"] = bussinessSize + paramObject["customerName"] = customerName + paramObject["customerNo"] = customerNo + paramObject["grade"] = grade val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() @@ -330,7 +341,7 @@ */ suspend fun getCustomerDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -342,7 +353,7 @@ */ suspend fun getStaffList(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -354,7 +365,7 @@ */ suspend fun getSupportEquipmentList(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -366,7 +377,7 @@ */ suspend fun getVerifyProcedureList(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -389,20 +400,15 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("customerName", customerName) - paramObject.put("customerNo", customerNo) - paramObject.put("deliverer", deliverer) - paramObject.put("orderCode", orderCode) - paramObject.put("startTime", startTime) - paramObject.put("endTime", endTime) - paramObject.put("isUrgent", isUrgent) - paramObject.put("status", status) - - val jsonArray = JSONArray() - ids.forEach { - jsonArray.put(it) - } - paramObject.put("ids", jsonArray) + paramObject["customerName"] = customerName + paramObject["customerNo"] = customerNo + paramObject["deliverer"] = deliverer + paramObject["orderCode"] = orderCode + paramObject["startTime"] = startTime + paramObject["endTime"] = endTime + paramObject["isUrgent"] = isUrgent + paramObject["status"] = status + paramObject["ids"] = JSONArray.parseArray(JSON.toJSONString(ids)) val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() @@ -421,7 +427,7 @@ */ suspend fun getEntrustDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -433,7 +439,7 @@ */ suspend fun acceptEntrust(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -446,10 +452,89 @@ */ suspend fun returnEntrust(id: String, selected: ArrayList): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) return api.returnEntrust(AuthenticationHelper.token!!, requestBody) } + + /** + * 获取样品列表 + */ + suspend fun getSampleList( + customerName: String, + customerNo: String, + startTime: String, + endTime: String, + sampleName: String, + sampleNo: String, + sampleModel: String, + sampleBelong: String, + overtimeStatus: String, + ids: Array, + offset: Int + ): String { + val paramObject = JSONObject() + paramObject["customerName"] = customerName + paramObject["customerNo"] = customerNo + paramObject["startTime"] = startTime + paramObject["endTime"] = endTime + paramObject["sampleName"] = sampleName + paramObject["sampleNo"] = sampleNo + paramObject["sampleModel"] = sampleModel + paramObject["sampleBelong"] = sampleBelong + paramObject["overtimeStatus"] = overtimeStatus + paramObject["ids"] = JSONArray.parseArray(JSON.toJSONString(ids)) + + val requestBody = paramObject.toString().toRequestBody( + "application/json;charset=UTF-8".toMediaType() + ) + + val limitMap = HashMap() + limitMap["limit"] = LocaleConstant.PAGE_LIMIT + + val offsetMap = HashMap() + offsetMap["offset"] = offset + return api.getSampleList(AuthenticationHelper.token!!, requestBody, limitMap, offsetMap) + } + + /** + * 新增委托书 + */ + suspend fun addEntrust( + deliverer: String, + delivererTel: String, + orderTime: String, + planDeliverTime: String, + requireOverTime: String, + customerName: String, + customerPhone: String, + customerAddress: String, + remark: String, + minioFileName: String, + certifications: String, + isUrgent: String, + samples: List + ): String { + val paramObject = JSONObject() + paramObject["deliverer"] = deliverer + paramObject["delivererTel"] = delivererTel + paramObject["orderTime"] = orderTime + paramObject["planDeliverTime"] = planDeliverTime + paramObject["requireOverTime"] = requireOverTime + paramObject["customerName"] = customerName + paramObject["customerPhone"] = customerPhone + paramObject["customerAddress"] = customerAddress + paramObject["remark"] = remark + paramObject["minioFileName"] = minioFileName + paramObject["certifications"] = certifications + paramObject["isUrgent"] = isUrgent + paramObject["customerSampleInfoList"] = JSONArray.parseArray(JSON.toJSONString(samples)) + + val requestBody = paramObject.toString().toRequestBody( + "application/json;charset=UTF-8".toMediaType() + ) + return api.addEntrust(AuthenticationHelper.token!!, requestBody) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/view/home/EntrustAddActivity.kt b/app/src/main/java/com/casic/xz/meterage/view/home/EntrustAddActivity.kt index 3e30095..9c8d27b 100644 --- a/app/src/main/java/com/casic/xz/meterage/view/home/EntrustAddActivity.kt +++ b/app/src/main/java/com/casic/xz/meterage/view/home/EntrustAddActivity.kt @@ -1,52 +1,211 @@ package com.casic.xz.meterage.view.home +import android.app.Activity +import android.content.Context +import android.content.Intent +import android.graphics.Color +import android.graphics.Paint import android.util.Log +import androidx.activity.result.ActivityResult +import androidx.activity.result.ActivityResultCallback +import androidx.activity.result.contract.ActivityResultContracts import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R import com.casic.xz.meterage.adapter.CertificateTypeAdapter2 -import com.casic.xz.meterage.extensions.initLayoutImmersionBar +import com.casic.xz.meterage.adapter.CustomerSampleAdapter +import com.casic.xz.meterage.callback.DateSelectedCallback +import com.casic.xz.meterage.callback.OnImageCompressListener +import com.casic.xz.meterage.extensions.* +import com.casic.xz.meterage.model.EntrustDetailModel +import com.casic.xz.meterage.model.SampleListModel +import com.casic.xz.meterage.utils.FileType +import com.casic.xz.meterage.utils.GlideLoadEngine +import com.casic.xz.meterage.utils.LoadingDialogHub import com.casic.xz.meterage.vm.DictionaryViewModel +import com.casic.xz.meterage.vm.EntrustViewModel +import com.casic.xz.meterage.vm.FileUploadViewModel +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken import com.gyf.immersionbar.ImmersionBar +import com.luck.picture.lib.basic.PictureSelector +import com.luck.picture.lib.config.SelectMimeType +import com.luck.picture.lib.entity.LocalMedia +import com.luck.picture.lib.interfaces.OnResultCallbackListener import com.pengxh.kt.lite.base.KotlinBaseActivity -import com.pengxh.kt.lite.extensions.toJson +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.vm.LoadState +import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import kotlinx.android.synthetic.main.activity_entrust_add.* +import java.io.File + class EntrustAddActivity : KotlinBaseActivity() { + private val context: Context = this@EntrustAddActivity + private val gson by lazy { Gson() } private lateinit var dictionaryViewModel: DictionaryViewModel - private var checkedItems = ArrayList() + private lateinit var fileUploadViewModel: FileUploadViewModel + private lateinit var entrustViewModel: EntrustViewModel + private lateinit var sampleAdapter: CustomerSampleAdapter + private var checkedItems = ArrayList() + private var isUrgent = "0" + private var sampleModels: ArrayList? = null + private var dataBeans = ArrayList() override fun initData() { //证书 dictionaryViewModel = ViewModelProvider(this)[DictionaryViewModel::class.java] dictionaryViewModel.getDictionaryByCode("certificationClass") - dictionaryViewModel.dictionary.observe(this) { dic -> - if (dic.code == 200) { - val typeAdapter2 = CertificateTypeAdapter2(this, dic.data) + dictionaryViewModel.dictionary.observe(this) { + if (it.code == 200) { + val typeAdapter2 = CertificateTypeAdapter2(this, it.data) typeRecyclerView.adapter = typeAdapter2 typeAdapter2.setOnItemCheckedListener(object : CertificateTypeAdapter2.OnItemCheckedListener { override fun onItemChecked(position: Int, isChecked: Boolean) { if (isChecked) { - checkedItems.add(position) + checkedItems.add(position.toString()) } else { - checkedItems.remove(position) + checkedItems.remove(position.toString()) } } }) } } + + fileUploadViewModel = ViewModelProvider(this)[FileUploadViewModel::class.java] + fileUploadViewModel.resultModel.observe(this) { + if (it.code == 200) { + val annexName = it.data[0] + annexView.text = annexName + val textPaint = annexView.paint + textPaint.flags = Paint.UNDERLINE_TEXT_FLAG + textPaint.isAntiAlias = true + annexView.setTextColor(Color.BLUE) + + annexView.setOnClickListener { + annexName.watchAttachFile(this) + } + } + } + + entrustViewModel = ViewModelProvider(this)[EntrustViewModel::class.java] + entrustViewModel.addResult.observe(this) { + if (it.code == 200) { + finish() + } + } + + //样品列表 + sampleAdapter = CustomerSampleAdapter(this, dataBeans) + sampleRecyclerView.adapter = sampleAdapter } + private val selectCustomerLauncher = + registerForActivityResult(ActivityResultContracts.StartActivityForResult(), + object : ActivityResultCallback { + override fun onActivityResult(result: ActivityResult?) { + if (result?.resultCode == Activity.RESULT_OK) { + val data = result.data ?: return + + entrustNameView.text = data.getStringExtra("entrustName") + entrustContactView.text = data.getStringExtra("entrustContact") + entrustAddressView.text = data.getStringExtra("entrustAddress") + } + } + }) + + private val selectSampleLauncher = + registerForActivityResult(ActivityResultContracts.StartActivityForResult(), + object : ActivityResultCallback { + override fun onActivityResult(result: ActivityResult?) { + if (result?.resultCode == Activity.RESULT_OK) { + val data = result.data ?: return + + val modelsJson = data.getStringExtra("sampleModels") + if (!modelsJson.isNullOrBlank()) { + sampleModels = gson.fromJson( + modelsJson, + object : + TypeToken>() {}.type + ) + } + + //刷新列表 + dataBeans.clear() + sampleModels?.forEach { + val model = + EntrustDetailModel.DataModel.CustomerSampleInfoListModel() + + model.customerName = it.customerName + model.customerNo = it.customerNo + model.id = it.id + model.manufacturingNo = it.manufacturingNo + model.measureLastTime = it.measureLastTime + model.measurePeriod = it.measurePeriod + model.orderId = it.orderId + model.remark = it.remark + model.sampleModel = it.sampleModel + model.sampleName = it.sampleName + model.sampleNo = it.sampleNo + model.validDeadline = it.validDeadline + + dataBeans.add(model) + } + sampleAdapter.notifyDataSetChanged() + } + } + }) + override fun initEvent() { + leftBackView.setOnClickListener { finish() } + + estimateTimeView.setOnClickListener { + showDatePicker(object : DateSelectedCallback { + override fun onDateSelected(date: String) { + estimateTimeView.text = date + } + }) + } + + completedView.setOnClickListener { + showDatePicker(object : DateSelectedCallback { + override fun onDateSelected(date: String) { + completedView.text = date + } + }) + } + + entrustNameView.setOnClickListener { + selectCustomerLauncher.launch(Intent(this, SelectCustomerActivity::class.java)) + } + //上传附件 uploadFileButton.setOnClickListener { + BottomActionSheet.Builder() + .setContext(this) + .setItemTextColor(Color.BLUE) + .setActionItemTitle(listOf("文件", "图片")) + .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { + override fun onActionItemClick(position: Int) { + when (position) { + 0 -> uploadFile() + 1 -> uploadImage() + } + } + }).build().show() + } + radioGroup.setOnCheckedChangeListener { _, checkedId -> + when (checkedId) { + R.id.radioButton1 -> isUrgent = "1" + R.id.radioButton2 -> isUrgent = "0" + } } //选择样品 selectSampleButton.setOnClickListener { - + selectSampleLauncher.launch(Intent(this, SelectSampleActivity::class.java)) } //写入样品信息 @@ -55,14 +214,68 @@ } pushEntrustView.setOnClickListener { - Log.d("Casic", "EntrustAddActivity => initEvent: ${checkedItems.toJson()}") + val sender = senderView.text.toString() + if (sender.isBlank()) { + "请填写送样人名字".show(this) + return@setOnClickListener + } + + val contact = contactView.text.toString() + if (contact.isBlank()) { + "请填写送样人联系方式".show(this) + return@setOnClickListener + } + + val estimateTime = estimateTimeView.text.toString() + if (estimateTime.isBlank()) { + "请选择预计送到的时间".show(this) + return@setOnClickListener + } + + val entrustName = entrustNameView.text.toString() + if (entrustName.isBlank()) { + "请选择委托方".show(this) + return@setOnClickListener + } + + if (sampleModels == null) { + "请选择样品".show(this) + return@setOnClickListener + } + entrustViewModel.addEntrust( + sender, + contact, + createEntrustDateView.text.toString(), + estimateTime, + completedView.text.toString(), + entrustName, + entrustContactView.text.toString(), + entrustAddressView.text.toString(), + remarkView.text.toString(), + annexView.text.toString(), + checkedItems.reformat(), + isUrgent, + sampleModels!! + ) } } override fun initLayoutView(): Int = R.layout.activity_entrust_add override fun observeRequestState() { + fileUploadViewModel.loadState.observe(this) { + when (it) { + LoadState.Loading -> LoadingDialogHub.show(this, "文件上传中,请稍后...") + else -> LoadingDialogHub.dismiss() + } + } + entrustViewModel.loadState.observe(this) { + when (it) { + LoadState.Loading -> LoadingDialogHub.show(this, "委托创建中,请稍后...") + else -> LoadingDialogHub.dismiss() + } + } } override fun setupTopBarLayout() { @@ -70,4 +283,62 @@ initLayoutImmersionBar(rootView) titleView.text = "委托需求" } + + private fun uploadFile() { +// val explorer = FileExplorer(this) +// explorer.setInitDir(ExplorerMode.FILE, Environment.getExternalStorageDirectory()) +// explorer.setShowHomeDir(true) +// explorer.setShowUpDir(true) +// explorer.setShowHideDir(true) +// explorer.setAllowExtensions(arrayOf(".doc", ".docx", ".xls", ".xlsx", ".pdf")) +// explorer.setOnFileClickedListener { +// val type = if (it.name.endsWith(".doc") || it.name.endsWith(".docx")) { +// FileType.WORD +// } else if (it.name.endsWith(".pdf")) { +// FileType.PDF +// } else { +// FileType.UNKNOWN +// } +// +// Log.d("Casic", "EntrustAddActivity => uploadFile: ${it.absolutePath}") +// fileUploadViewModel.uploadFile(it, type) +// } + } + + private fun uploadImage() { + PictureSelector.create(this) + .openGallery(SelectMimeType.ofImage()) + .isGif(false) + .isMaxSelectEnabledMask(true) + .setFilterMinFileSize(100) + .setMaxSelectNum(1) + .isDisplayCamera(false) + .setImageEngine(GlideLoadEngine.instance) + .forResult(object : OnResultCallbackListener { + override fun onResult(result: ArrayList?) { + if (result == null) { + "选择照片失败,请重试".show(context) + return + } + result[0].realPath.compressImage(context, object : OnImageCompressListener { + override fun onSuccess(file: File) { + Log.d( + "Casic", "EntrustAddActivity => onSuccess: ${file.absolutePath}" + ) + ///storage/emulated/0/Android/data/com.casic.xz.meterage/files/Pictures/CompressImage/1677478115391211.jpeg + //上传图片 + fileUploadViewModel.uploadFile(file, FileType.IMAGE) + } + + override fun onError(e: Throwable) { + e.printStackTrace() + } + }) + } + + override fun onCancel() { + + } + }) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/view/home/SelectCustomerActivity.kt b/app/src/main/java/com/casic/xz/meterage/view/home/SelectCustomerActivity.kt new file mode 100644 index 0000000..9bf6a1a --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/view/home/SelectCustomerActivity.kt @@ -0,0 +1,158 @@ +package com.casic.xz.meterage.view.home + +import android.content.Intent +import android.os.Handler +import androidx.lifecycle.ViewModelProvider +import androidx.recyclerview.widget.DefaultItemAnimator +import androidx.recyclerview.widget.DividerItemDecoration +import com.casic.xz.meterage.R +import com.casic.xz.meterage.adapter.SelectCustomerAdapter +import com.casic.xz.meterage.extensions.initLayoutImmersionBar +import com.casic.xz.meterage.extensions.showEmptyPage +import com.casic.xz.meterage.model.CustomerListModel +import com.casic.xz.meterage.utils.LoadingDialogHub +import com.casic.xz.meterage.vm.CustomerViewModel +import com.gyf.immersionbar.ImmersionBar +import com.pengxh.kt.lite.base.KotlinBaseActivity +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.utils.WeakReferenceHandler +import com.pengxh.kt.lite.vm.LoadState +import kotlinx.android.synthetic.main.activity_select_customer.* +import kotlinx.android.synthetic.main.include_base_title.* +import kotlinx.android.synthetic.main.include_empty_view.* + +class SelectCustomerActivity : KotlinBaseActivity() { + + private lateinit var weakReferenceHandler: WeakReferenceHandler + private lateinit var customerViewModel: CustomerViewModel + private lateinit var selectCustomerAdapter: SelectCustomerAdapter + private var dataBeans: MutableList = ArrayList() + private var pageIndex = 1 + private var isRefresh = false + private var isLoadMore = false + private var customerModel: CustomerListModel.DataModel.RowsModel? = null + + override fun initData() { + weakReferenceHandler = WeakReferenceHandler(callback) + customerViewModel = ViewModelProvider(this)[CustomerViewModel::class.java] + customerViewModel.customerList.observe(this) { + if (it.code == 200) { + val dataRows = it.data?.rows!! + when { + isRefresh -> { + dataBeans.clear() + dataBeans = dataRows + customerLayout.finishRefresh() + isRefresh = false + } + isLoadMore -> { + if (dataRows.size == 0) { + "到底了,别拉了".show(this) + } + dataBeans.addAll(dataRows) + customerLayout.finishLoadMore() + isLoadMore = false + } + else -> { + dataBeans = dataRows + } + } + weakReferenceHandler.sendEmptyMessage(2023022701) + } + } + } + + override fun initEvent() { + leftBackView.setOnClickListener { + if (customerModel == null) { + "请选择委托方".show(this) + return@setOnClickListener + } + val intent = Intent() + intent.putExtra("entrustName", customerModel!!.customerName) + intent.putExtra("entrustContact", customerModel!!.phone) + intent.putExtra("entrustAddress", customerModel!!.fullAddress) + setResult(RESULT_OK, intent) + finish() + } + + customerLayout.setOnRefreshListener { + isRefresh = true + //刷新之后页码重置 + pageIndex = 1 + getCustomerList() + } + + customerLayout.setOnLoadMoreListener { + isLoadMore = true + pageIndex++ + getCustomerList() + } + } + + override fun initLayoutView(): Int = R.layout.activity_select_customer + + override fun observeRequestState() { + customerViewModel.loadState.observe(this) { + when (it) { + LoadState.Loading -> LoadingDialogHub.show(this, "数据加载中...") + else -> LoadingDialogHub.dismiss() + } + } + } + + override fun setupTopBarLayout() { + ImmersionBar.with(this).statusBarDarkFont(true).init() + initLayoutImmersionBar(rootView) + titleView.text = "客户列表" + } + + override fun onResume() { + super.onResume() + pageIndex = 1 + getCustomerList() + } + + private fun getCustomerList() { + customerViewModel.getCustomerList( + "", + "", + "", + "", + pageIndex + ) + } + + private val callback = Handler.Callback { + when (it.what) { + 2023022701 -> { + if (isRefresh || isLoadMore) { + selectCustomerAdapter.notifyDataSetChanged() + } else { + if (dataBeans.size == 0) { + emptyView!!.showEmptyPage("无客户数据") { + pageIndex = 1 + getCustomerList() + } + } else { + emptyView!!.hide() + selectCustomerAdapter = SelectCustomerAdapter(this, dataBeans) + customerRecyclerView.addItemDecoration( + DividerItemDecoration(this, DividerItemDecoration.VERTICAL) + ) + (customerRecyclerView.itemAnimator as DefaultItemAnimator).supportsChangeAnimations = + false + customerRecyclerView.adapter = selectCustomerAdapter + selectCustomerAdapter.setOnCheckedListener(object : + SelectCustomerAdapter.OnItemCheckedListener { + override fun onItemChecked(item: CustomerListModel.DataModel.RowsModel) { + customerModel = item + } + }) + } + } + } + } + true + } +} \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 0ae369f..687b02b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -15,7 +15,6 @@ } compileSdkVersion 31 - buildToolsVersion "30.0.3" defaultConfig { applicationId "com.casic.xz.meterage" @@ -84,11 +83,13 @@ implementation 'top.zibin:Luban:1.1.8' //官方Json解析库 implementation 'com.google.code.gson:gson:2.9.0' + //阿里巴巴JSON库 + implementation 'com.alibaba.fastjson2:fastjson2:2.0.24' //Kotlin协程 implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.5.1' //MVVM+LiveData implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.5.1" - implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.0" + implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1" implementation "androidx.lifecycle:lifecycle-extensions:2.2.0" //返回值转换器 implementation 'com.jakewharton.retrofit:retrofit2-kotlin-coroutines-adapter:0.9.2' @@ -109,4 +110,8 @@ implementation 'com.github.barteksc:android-pdf-viewer:2.8.2' //绕过Android 11反射限制 implementation 'com.github.tiann:FreeReflection:3.1.0' + //单项/数字、二三级联动、日期/时间等滚轮选择器 + implementation 'com.github.gzu-liyujiang.AndroidPicker:WheelPicker:4.1.8' + //文件/目录选择器 + implementation 'com.github.gzu-liyujiang.AndroidPicker:FilePicker:4.1.1' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 1ccc12b..0fba91b 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -60,6 +60,8 @@ + + diff --git a/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt b/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt new file mode 100644 index 0000000..21a71d8 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt @@ -0,0 +1,70 @@ +package com.casic.xz.meterage.adapter + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import com.casic.xz.meterage.R +import com.casic.xz.meterage.extensions.toChineseGrade +import com.casic.xz.meterage.model.CustomerListModel + +class SelectCustomerAdapter( + context: Context, private val dataRows: MutableList +) : RecyclerView.Adapter() { + + private var layoutInflater = LayoutInflater.from(context) + + //选择的位置 + private var selectedPosition = 0 + + //临时记录上次选择的位置 + private var temp = -1 + + override fun getItemCount(): Int = dataRows.size + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ItemViewHolder( + layoutInflater.inflate(R.layout.item_select_customer_lv, parent, false) + ) + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + //绑定数据 + val rowsBean = dataRows[position] + holder.agreementLevelView.text = rowsBean.grade.toChineseGrade() + holder.customerNameView.text = rowsBean.customerName + holder.scaleView.text = rowsBean.companySizeName + holder.overallView.text = "公司规模:${rowsBean.evaluationName}" + holder.fullAddressView.text = "公司地址:${rowsBean.fullAddress}" + + holder.itemView.isSelected = holder.layoutPosition == selectedPosition + holder.itemView.setOnClickListener { + itemCheckedListener?.onItemChecked(rowsBean) + + holder.itemView.isSelected = true + temp = selectedPosition + //设置新的位置 + selectedPosition = holder.layoutPosition + //更新旧位置 + notifyItemChanged(temp) + } + } + + inner class ItemViewHolder(view: View) : RecyclerView.ViewHolder(view) { + var agreementLevelView: TextView = view.findViewById(R.id.agreementLevelView) + var customerNameView: TextView = view.findViewById(R.id.customerNameView) + var scaleView: TextView = view.findViewById(R.id.scaleView) + var overallView: TextView = view.findViewById(R.id.overallView) + var fullAddressView: TextView = view.findViewById(R.id.fullAddressView) + } + + private var itemCheckedListener: OnItemCheckedListener? = null + + interface OnItemCheckedListener { + fun onItemChecked(item: CustomerListModel.DataModel.RowsModel) + } + + fun setOnCheckedListener(listener: OnItemCheckedListener?) { + itemCheckedListener = listener + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt b/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt new file mode 100644 index 0000000..c29461e --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt @@ -0,0 +1,68 @@ +package com.casic.xz.meterage.adapter + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import com.casic.xz.meterage.R +import com.casic.xz.meterage.model.SampleListModel + +class SelectSampleAdapter( + context: Context, private val dataRows: MutableList +) : RecyclerView.Adapter() { + + private var layoutInflater = LayoutInflater.from(context) + private var multipleSelected = mutableSetOf() + private var sampleModes = ArrayList() + + override fun getItemCount(): Int = dataRows.size + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ItemViewHolder( + layoutInflater.inflate(R.layout.item_select_sample_lv, parent, false) + ) + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + //绑定数据 + val rowsBean = dataRows[position] + holder.sampleNameView.text = "${rowsBean.sampleName}【${rowsBean.sampleModel}】" + holder.manufacturingCodeView.text = "出厂编号:${rowsBean.manufacturingNo}" + holder.sampleCodeView.text = "样品编号:${rowsBean.sampleNo}" + holder.validDateView.text = "有效期至:${rowsBean.validDeadline}" + + holder.checkImageView.isSelected = multipleSelected.contains(position) + holder.itemView.setOnClickListener { + if (multipleSelected.contains(position)) { + multipleSelected.remove(position) + sampleModes.remove(dataRows[position]) + holder.checkImageView.isSelected = false + } else { + multipleSelected.add(position) + sampleModes.add(dataRows[position]) + holder.checkImageView.isSelected = true + } + + itemCheckedListener?.onItemChecked(sampleModes) + } + } + + inner class ItemViewHolder(view: View) : RecyclerView.ViewHolder(view) { + var sampleNameView: TextView = view.findViewById(R.id.sampleNameView) + var manufacturingCodeView: TextView = view.findViewById(R.id.manufacturingCodeView) + var sampleCodeView: TextView = view.findViewById(R.id.sampleCodeView) + var validDateView: TextView = view.findViewById(R.id.validDateView) + var checkImageView: ImageView = view.findViewById(R.id.checkImageView) + } + + private var itemCheckedListener: OnItemCheckedListener? = null + + interface OnItemCheckedListener { + fun onItemChecked(items: ArrayList) + } + + fun setOnCheckedListener(listener: OnItemCheckedListener?) { + itemCheckedListener = listener + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/callback/DateSelectedCallback.kt b/app/src/main/java/com/casic/xz/meterage/callback/DateSelectedCallback.kt new file mode 100644 index 0000000..8196110 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/callback/DateSelectedCallback.kt @@ -0,0 +1,5 @@ +package com.casic.xz.meterage.callback + +interface DateSelectedCallback { + fun onDateSelected(date: String) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/Activity.kt b/app/src/main/java/com/casic/xz/meterage/extensions/Activity.kt new file mode 100644 index 0000000..e112d1c --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/extensions/Activity.kt @@ -0,0 +1,33 @@ +package com.casic.xz.meterage.extensions + +import android.app.Activity +import com.casic.xz.meterage.R +import com.casic.xz.meterage.callback.DateSelectedCallback +import com.github.gzuliyujiang.wheelpicker.DatePicker +import com.github.gzuliyujiang.wheelpicker.annotation.DateMode +import com.github.gzuliyujiang.wheelpicker.entity.DateEntity +import com.pengxh.kt.lite.extensions.convertColor +import com.pengxh.kt.lite.extensions.sp2px + +fun Activity.showDatePicker(callback: DateSelectedCallback) { + val datePicker = DatePicker(this) + + val layout = datePicker.wheelLayout + layout.setDateMode(DateMode.YEAR_MONTH_DAY) + layout.setDateLabel("年", "月", "日"); + layout.setTextSize(14f.sp2px(this).toFloat()) + layout.setSelectedTextSize(16f.sp2px(this).toFloat()) + layout.setSelectedTextColor(R.color.themeColor.convertColor(this)) + layout.setSelectedTextBold(true) + layout.setResetWhenLinkage(false) + layout.setRange( + DateEntity.today(), + DateEntity.target(2050, 12, 31), + DateEntity.today() + ) + + datePicker.setOnDatePickedListener { year, month, day -> + callback.onDateSelected(String.format("%s-%s-%s", year, month, day)) + } + datePicker.show() +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt b/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt index 016ebcb..cf6bf49 100644 --- a/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt +++ b/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt @@ -4,7 +4,7 @@ * ArrayList扩展方法 */ -//将图片集合格式化成满足上传格式的数据 +//将集合格式化成满足上传格式的数据 fun ArrayList.reformat(): String { if (this.isEmpty()) return "" val builder = StringBuilder() diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt b/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt index 7c57643..aa9b92b 100644 --- a/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt +++ b/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt @@ -1,7 +1,6 @@ package com.casic.xz.meterage.extensions import android.content.Context -import android.util.Log import android.view.ViewGroup import com.casic.xz.meterage.base.BaseApplication import com.pengxh.kt.lite.extensions.dp2px @@ -9,9 +8,8 @@ fun Context.initLayoutImmersionBar(rootView: ViewGroup) { var statusBarHeight = QMUIDisplayHelper.getStatusBarHeight(this) - Log.d("Casic", "状态栏高度: $statusBarHeight") if (statusBarHeight == 0) { - statusBarHeight = 44f.dp2px(BaseApplication.get()) + statusBarHeight = 40f.dp2px(BaseApplication.get()) } rootView.setPadding(0, statusBarHeight, 0, 0) rootView.requestLayout() diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/String.kt b/app/src/main/java/com/casic/xz/meterage/extensions/String.kt index 28f70d8..6234d43 100644 --- a/app/src/main/java/com/casic/xz/meterage/extensions/String.kt +++ b/app/src/main/java/com/casic/xz/meterage/extensions/String.kt @@ -128,9 +128,10 @@ fun String.combineImagePath(): String { if (this.isEmpty()) return this val defaultValue = SaveKeyValues.getValue( - LocaleConstant.DEFAULT_SERVER_CONFIG, LocaleConstant.SERVER_BASE_URL + LocaleConstant.FILE_SERVER_CONFIG, LocaleConstant.File_SERVER_URL ) as String - return "$defaultValue/static/${this.replace("\\", "/")}" + //http://111.198.10.15:21408/test/1677479806059688_1677479806038.jpeg + return "$defaultValue/test/${this.replace("\\", "/")}" } fun String.isEarlier(time: String): Boolean { diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt index 25fa87b..a0e1358 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt @@ -1,18 +1,12 @@ package com.casic.xz.meterage.fragment.customer +import android.graphics.Color import android.graphics.Paint import com.casic.xz.meterage.R -import com.casic.xz.meterage.extensions.combineImagePath import com.casic.xz.meterage.extensions.toChineseGrade +import com.casic.xz.meterage.extensions.watchAttachFile import com.casic.xz.meterage.model.CustomerDetailModel -import com.casic.xz.meterage.view.BigImageActivity -import com.casic.xz.meterage.view.notice.PreviewDocumentActivity -import com.casic.xz.meterage.view.notice.PreviewPdfActivity -import com.casic.xz.meterage.view.notice.PreviewTextActivity import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.extensions.show import kotlinx.android.synthetic.main.fragment_customer_basic_information.* class BasicInformationFragment(private val data: CustomerDetailModel.DataModel) : @@ -48,30 +42,11 @@ val textPaint = minioFileView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - minioFileView.setTextColor(R.color.themeColor.convertColor(requireContext())) + minioFileView.setTextColor(Color.BLUE) minioFileView.setOnClickListener { //查看附件 - if (minioFileName.endsWith("pdf")) { - requireContext().navigatePageTo(minioFileName) - } else if ( - minioFileName.endsWith("doc") || - minioFileName.endsWith("docx") - ) { - requireContext().navigatePageTo(minioFileName) - } else if (minioFileName.endsWith("txt")) { - requireContext().navigatePageTo(minioFileName) - } else if ( - minioFileName.endsWith("png") || - minioFileName.endsWith("jpeg") || - minioFileName.endsWith("jpg") - ) { - val urls = ArrayList() - urls.add(minioFileName.combineImagePath()) - requireContext().navigatePageTo(0, urls) - } else { - "文件类型未知,无法打开附件".show(requireContext()) - } + minioFileName.watchAttachFile(requireContext()) } } } diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt index 77846b4..3a0fe2e 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt @@ -1,5 +1,6 @@ package com.casic.xz.meterage.fragment.device +import android.graphics.Color import android.graphics.Paint import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R @@ -7,7 +8,6 @@ import com.casic.xz.meterage.utils.LoadingDialogHub import com.casic.xz.meterage.vm.EquipmentViewModel import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor import com.pengxh.kt.lite.vm.LoadState import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import kotlinx.android.synthetic.main.fragment_device_basic_information.* @@ -56,7 +56,7 @@ val textPaint = documentsView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - documentsView.setTextColor(R.color.themeColor.convertColor(requireContext())) + documentsView.setTextColor(Color.BLUE) val files = ArrayList() data.fileList.forEach { file -> @@ -66,7 +66,7 @@ BottomActionSheet.Builder() .setContext(requireContext()) .setActionItemTitle(files) - .setItemTextColor(R.color.themeColor.convertColor(requireContext())) + .setItemTextColor(Color.BLUE) .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { override fun onActionItemClick(position: Int) { diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt index 15dc3d2..10eeff8 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt @@ -1,5 +1,6 @@ package com.casic.xz.meterage.fragment.entrust +import android.graphics.Color import android.graphics.Paint import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R @@ -9,7 +10,6 @@ import com.casic.xz.meterage.model.EntrustDetailModel import com.casic.xz.meterage.vm.DictionaryViewModel import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor import kotlinx.android.synthetic.main.fragment_entrust_basic_information.* class BasicInformationFragment(private val data: EntrustDetailModel.DataModel) : @@ -38,7 +38,7 @@ val textPaint = annexView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - annexView.setTextColor(R.color.themeColor.convertColor(requireContext())) + annexView.setTextColor(Color.BLUE) annexView.setOnClickListener { minioFileName.watchAttachFile(requireContext()) @@ -59,9 +59,9 @@ //加急 if (data.isUrgent == "0") { - RadioButton2.isChecked = true + radioButton2.isChecked = true } else { - RadioButton1.isChecked = true + radioButton1.isChecked = true } //样品 diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/equipment/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/equipment/BasicInformationFragment.kt index 72b523c..7bc3b01 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/equipment/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/equipment/BasicInformationFragment.kt @@ -1,5 +1,6 @@ package com.casic.xz.meterage.fragment.equipment +import android.graphics.Color import android.graphics.Paint import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R @@ -7,7 +8,6 @@ import com.casic.xz.meterage.utils.LoadingDialogHub import com.casic.xz.meterage.vm.EquipmentViewModel import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor import com.pengxh.kt.lite.vm.LoadState import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import kotlinx.android.synthetic.main.fragment_equipment_basic_information.* @@ -74,7 +74,7 @@ val textPaint = instructionsView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - instructionsView.setTextColor(R.color.themeColor.convertColor(requireContext())) + instructionsView.setTextColor(Color.BLUE) val files = ArrayList() data.fileList.forEach { file -> @@ -84,7 +84,7 @@ BottomActionSheet.Builder() .setContext(requireContext()) .setActionItemTitle(files) - .setItemTextColor(R.color.themeColor.convertColor(requireContext())) + .setItemTextColor(Color.BLUE) .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { override fun onActionItemClick(position: Int) { diff --git a/app/src/main/java/com/casic/xz/meterage/model/SampleListModel.java b/app/src/main/java/com/casic/xz/meterage/model/SampleListModel.java new file mode 100644 index 0000000..5784343 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/model/SampleListModel.java @@ -0,0 +1,193 @@ +package com.casic.xz.meterage.model; + +import java.util.List; + +public class SampleListModel { + + private int code; + private DataModel data; + private String message; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataModel getData() { + return data; + } + + public void setData(DataModel data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public static class DataModel { + private List rows; + private int total; + + public List getRows() { + return rows; + } + + public void setRows(List rows) { + this.rows = rows; + } + + public int getTotal() { + return total; + } + + public void setTotal(int total) { + this.total = total; + } + + public static class RowsModel { + private String certificationStatus; + private String customerName; + private String customerNo; + private String id; + private String manufacturingNo; + private String measureLastTime; + private String measurePeriod; + private String orderId; + private String remark; + private String sampleModel; + private String sampleName; + private String sampleNo; + private String sampleSatus; + private String sampleSatusName; + private String validDeadline; + + public String getCertificationStatus() { + return certificationStatus; + } + + public void setCertificationStatus(String certificationStatus) { + this.certificationStatus = certificationStatus; + } + + public String getCustomerName() { + return customerName; + } + + public void setCustomerName(String customerName) { + this.customerName = customerName; + } + + public String getCustomerNo() { + return customerNo; + } + + public void setCustomerNo(String customerNo) { + this.customerNo = customerNo; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getManufacturingNo() { + return manufacturingNo; + } + + public void setManufacturingNo(String manufacturingNo) { + this.manufacturingNo = manufacturingNo; + } + + public String getMeasureLastTime() { + return measureLastTime; + } + + public void setMeasureLastTime(String measureLastTime) { + this.measureLastTime = measureLastTime; + } + + public String getMeasurePeriod() { + return measurePeriod; + } + + public void setMeasurePeriod(String measurePeriod) { + this.measurePeriod = measurePeriod; + } + + public String getOrderId() { + return orderId; + } + + public void setOrderId(String orderId) { + this.orderId = orderId; + } + + public String getRemark() { + return remark; + } + + public void setRemark(String remark) { + this.remark = remark; + } + + public String getSampleModel() { + return sampleModel; + } + + public void setSampleModel(String sampleModel) { + this.sampleModel = sampleModel; + } + + public String getSampleName() { + return sampleName; + } + + public void setSampleName(String sampleName) { + this.sampleName = sampleName; + } + + public String getSampleNo() { + return sampleNo; + } + + public void setSampleNo(String sampleNo) { + this.sampleNo = sampleNo; + } + + public String getSampleSatus() { + return sampleSatus; + } + + public void setSampleSatus(String sampleSatus) { + this.sampleSatus = sampleSatus; + } + + public String getSampleSatusName() { + return sampleSatusName; + } + + public void setSampleSatusName(String sampleSatusName) { + this.sampleSatusName = sampleSatusName; + } + + public String getValidDeadline() { + return validDeadline; + } + + public void setValidDeadline(String validDeadline) { + this.validDeadline = validDeadline; + } + } + } +} diff --git a/app/src/main/java/com/casic/xz/meterage/model/UploadResultModel.java b/app/src/main/java/com/casic/xz/meterage/model/UploadResultModel.java new file mode 100644 index 0000000..f2a6a41 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/model/UploadResultModel.java @@ -0,0 +1,34 @@ +package com.casic.xz.meterage.model; + +import java.util.List; + +public class UploadResultModel { + + private int code; + private List data; + private String message; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public List getData() { + return data; + } + + public void setData(List data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } +} diff --git a/app/src/main/java/com/casic/xz/meterage/utils/FileType.kt b/app/src/main/java/com/casic/xz/meterage/utils/FileType.kt new file mode 100644 index 0000000..17e2bca --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/utils/FileType.kt @@ -0,0 +1,23 @@ +package com.casic.xz.meterage.utils + +sealed class FileType { + /** + * PDF文件 + */ + object PDF : FileType() + + /** + * WORD文件 + */ + object WORD : FileType() + + /** + * IMAGE图片 + */ + object IMAGE : FileType() + + /** + * 未知类型(Excel) + */ + object UNKNOWN : FileType() +} diff --git a/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitService.kt index bc3f8d6..8f4fe44 100644 --- a/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitService.kt @@ -1,5 +1,6 @@ package com.casic.xz.meterage.utils.retrofit +import okhttp3.MultipartBody import okhttp3.RequestBody import retrofit2.http.* @@ -35,6 +36,16 @@ ): String /** + * 上传文件 + */ + @Multipart + @POST("/minio/file/upload") + suspend fun uploadFile( + @Header("token") token: String, + @Part file: MultipartBody.Part + ): String + + /** * 获取通知公告列表 */ @POST("/system/notice/listPage") @@ -209,4 +220,24 @@ @Header("token") token: String, @Body requestBody: RequestBody ): String + + /** + * 获取样品列表 + */ + @POST("/customer/sample/listPage") + suspend fun getSampleList( + @Header("token") token: String, + @Body requestBody: RequestBody, + @QueryMap limit: Map, + @QueryMap offset: Map + ): String + + /** + * 新增委托书 + */ + @POST("/business/order/add") + suspend fun addEntrust( + @Header("token") token: String, + @Body requestBody: RequestBody + ): String } \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitServiceManager.kt index cb22e45..90abe5a 100644 --- a/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitServiceManager.kt @@ -1,13 +1,20 @@ package com.casic.xz.meterage.utils.retrofit +import com.alibaba.fastjson2.JSON +import com.alibaba.fastjson2.JSONArray +import com.alibaba.fastjson2.JSONObject +import com.casic.xz.meterage.model.SampleListModel import com.casic.xz.meterage.utils.AuthenticationHelper +import com.casic.xz.meterage.utils.FileType import com.casic.xz.meterage.utils.LocaleConstant import com.pengxh.kt.lite.utils.RetrofitFactory import com.pengxh.kt.lite.utils.SaveKeyValues import okhttp3.MediaType.Companion.toMediaType +import okhttp3.MediaType.Companion.toMediaTypeOrNull +import okhttp3.MultipartBody +import okhttp3.RequestBody.Companion.asRequestBody import okhttp3.RequestBody.Companion.toRequestBody -import org.json.JSONArray -import org.json.JSONObject +import java.io.File object RetrofitServiceManager { @@ -31,9 +38,9 @@ */ suspend fun login(sid: String, account: String, secretKey: String): String { val paramObject = JSONObject() - paramObject.put("sid", sid) - paramObject.put("username", account) - paramObject.put("password", secretKey) + paramObject["sid"] = sid + paramObject["username"] = account + paramObject["password"] = secretKey val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -55,6 +62,20 @@ } /** + * 上传文件 + */ + suspend fun uploadFile(file: File, type: FileType): String { + val requestBody = when (type) { + FileType.PDF -> file.asRequestBody("application/pdf".toMediaTypeOrNull()) + FileType.WORD -> file.asRequestBody("application/msword".toMediaTypeOrNull()) + FileType.IMAGE -> file.asRequestBody("image/png".toMediaTypeOrNull()) + else -> file.asRequestBody("application/vnd.ms-excel".toMediaTypeOrNull()) + } + val filePart = MultipartBody.Part.createFormData("multipartFile", file.name, requestBody) + return api.uploadFile(AuthenticationHelper.token!!, filePart) + } + + /** * 获取通知公告列表 */ suspend fun getNoticeList( @@ -66,11 +87,11 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("noticeNo", noticeNo) - paramObject.put("noticeTitle", noticeTitle) - paramObject.put("noticePublisher", noticePublisher) - paramObject.put("noticeStartTime", noticeStartTime) - paramObject.put("noticeEndTime", noticeEndTime) + paramObject["noticeNo"] = noticeNo + paramObject["noticeTitle"] = noticeTitle + paramObject["noticePublisher"] = noticePublisher + paramObject["noticeStartTime"] = noticeStartTime + paramObject["noticeEndTime"] = noticeEndTime val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -105,26 +126,21 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("equipmentNo", equipmentNo) - paramObject.put("equipmentName", equipmentName) - paramObject.put("mesureType", mesureType) - paramObject.put("managerState", managerState) - paramObject.put("useDept", useDept) - paramObject.put("assetType", assetType) - paramObject.put("equipmentCategory", equipmentCategory) - paramObject.put("isCalibrationTestEquipment", isCalibrationTestEquipment) - paramObject.put("isMeasureAccount", isMeasureAccount) - paramObject.put("isStandardSupportEquipment", isStandardSupportEquipment) - paramObject.put("isFixedAssets", isFixedAssets) - paramObject.put("validStartDate", validStartDate) - paramObject.put("validEndDate", validEndDate) - paramObject.put("abc", abc) - - val jsonArray = JSONArray() - ids.forEach { - jsonArray.put(it) - } - paramObject.put("ids", jsonArray) + paramObject["equipmentNo"] = equipmentNo + paramObject["equipmentName"] = equipmentName + paramObject["mesureType"] = mesureType + paramObject["managerState"] = managerState + paramObject["useDept"] = useDept + paramObject["assetType"] = assetType + paramObject["equipmentCategory"] = equipmentCategory + paramObject["isCalibrationTestEquipment"] = isCalibrationTestEquipment + paramObject["isMeasureAccount"] = isMeasureAccount + paramObject["isStandardSupportEquipment"] = isStandardSupportEquipment + paramObject["isFixedAssets"] = isFixedAssets + paramObject["validStartDate"] = validStartDate + paramObject["validEndDate"] = validEndDate + paramObject["abc"] = abc + paramObject["ids"] = JSONArray.parseArray(JSON.toJSONString(ids)) val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() @@ -143,7 +159,7 @@ */ suspend fun getEquipmentDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -164,13 +180,13 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("standardNo", standardNo) - paramObject.put("standardName", standardName) - paramObject.put("category", category) - paramObject.put("managerState", managerState) - paramObject.put("standardLaboratory", standardLaboratory) - paramObject.put("preparationDate", preparationDate) - paramObject.put("id", id) + paramObject["standardNo"] = standardNo + paramObject["standardName"] = standardName + paramObject["category"] = category + paramObject["managerState"] = managerState + paramObject["standardLaboratory"] = standardLaboratory + paramObject["preparationDate"] = preparationDate + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -193,7 +209,7 @@ */ suspend fun getStandardDeviceDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -212,11 +228,11 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("checkType", checkType) - paramObject.put("priceItem", priceItem) - paramObject.put("priceName", priceName) - paramObject.put("priceNo", priceNo) - paramObject.put("priceType", priceType) + paramObject["checkType"] = checkType + paramObject["priceItem"] = priceItem + paramObject["priceName"] = priceName + paramObject["priceNo"] = priceNo + paramObject["priceType"] = priceType val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -234,7 +250,7 @@ */ suspend fun getCapabilityDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -257,20 +273,15 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("createStartTime", createStartTime) - paramObject.put("createEndTime", createEndTime) - paramObject.put("deptId", deptId) - paramObject.put("director", director) - paramObject.put("effectiveCompany", effectiveCompany) - paramObject.put("trainStartTime", trainStartTime) - paramObject.put("trainEndTime", trainEndTime) - paramObject.put("formId", formId) - - val jsonArray = JSONArray() - ids.forEach { - jsonArray.put(it) - } - paramObject.put("ids", jsonArray) + paramObject["createStartTime"] = createStartTime + paramObject["createEndTime"] = createEndTime + paramObject["deptId"] = deptId + paramObject["director"] = director + paramObject["effectiveCompany"] = effectiveCompany + paramObject["trainStartTime"] = trainStartTime + paramObject["trainEndTime"] = trainEndTime + paramObject["formId"] = formId + paramObject["ids"] = JSONArray.parseArray(JSON.toJSONString(ids)) val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() @@ -294,7 +305,7 @@ */ suspend fun getMeterageTrainDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -308,10 +319,10 @@ bussinessSize: String, customerName: String, customerNo: String, grade: String, offset: Int ): String { val paramObject = JSONObject() - paramObject.put("bussinessSize", bussinessSize) - paramObject.put("customerName", customerName) - paramObject.put("customerNo", customerNo) - paramObject.put("grade", grade) + paramObject["bussinessSize"] = bussinessSize + paramObject["customerName"] = customerName + paramObject["customerNo"] = customerNo + paramObject["grade"] = grade val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() @@ -330,7 +341,7 @@ */ suspend fun getCustomerDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -342,7 +353,7 @@ */ suspend fun getStaffList(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -354,7 +365,7 @@ */ suspend fun getSupportEquipmentList(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -366,7 +377,7 @@ */ suspend fun getVerifyProcedureList(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -389,20 +400,15 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("customerName", customerName) - paramObject.put("customerNo", customerNo) - paramObject.put("deliverer", deliverer) - paramObject.put("orderCode", orderCode) - paramObject.put("startTime", startTime) - paramObject.put("endTime", endTime) - paramObject.put("isUrgent", isUrgent) - paramObject.put("status", status) - - val jsonArray = JSONArray() - ids.forEach { - jsonArray.put(it) - } - paramObject.put("ids", jsonArray) + paramObject["customerName"] = customerName + paramObject["customerNo"] = customerNo + paramObject["deliverer"] = deliverer + paramObject["orderCode"] = orderCode + paramObject["startTime"] = startTime + paramObject["endTime"] = endTime + paramObject["isUrgent"] = isUrgent + paramObject["status"] = status + paramObject["ids"] = JSONArray.parseArray(JSON.toJSONString(ids)) val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() @@ -421,7 +427,7 @@ */ suspend fun getEntrustDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -433,7 +439,7 @@ */ suspend fun acceptEntrust(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -446,10 +452,89 @@ */ suspend fun returnEntrust(id: String, selected: ArrayList): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) return api.returnEntrust(AuthenticationHelper.token!!, requestBody) } + + /** + * 获取样品列表 + */ + suspend fun getSampleList( + customerName: String, + customerNo: String, + startTime: String, + endTime: String, + sampleName: String, + sampleNo: String, + sampleModel: String, + sampleBelong: String, + overtimeStatus: String, + ids: Array, + offset: Int + ): String { + val paramObject = JSONObject() + paramObject["customerName"] = customerName + paramObject["customerNo"] = customerNo + paramObject["startTime"] = startTime + paramObject["endTime"] = endTime + paramObject["sampleName"] = sampleName + paramObject["sampleNo"] = sampleNo + paramObject["sampleModel"] = sampleModel + paramObject["sampleBelong"] = sampleBelong + paramObject["overtimeStatus"] = overtimeStatus + paramObject["ids"] = JSONArray.parseArray(JSON.toJSONString(ids)) + + val requestBody = paramObject.toString().toRequestBody( + "application/json;charset=UTF-8".toMediaType() + ) + + val limitMap = HashMap() + limitMap["limit"] = LocaleConstant.PAGE_LIMIT + + val offsetMap = HashMap() + offsetMap["offset"] = offset + return api.getSampleList(AuthenticationHelper.token!!, requestBody, limitMap, offsetMap) + } + + /** + * 新增委托书 + */ + suspend fun addEntrust( + deliverer: String, + delivererTel: String, + orderTime: String, + planDeliverTime: String, + requireOverTime: String, + customerName: String, + customerPhone: String, + customerAddress: String, + remark: String, + minioFileName: String, + certifications: String, + isUrgent: String, + samples: List + ): String { + val paramObject = JSONObject() + paramObject["deliverer"] = deliverer + paramObject["delivererTel"] = delivererTel + paramObject["orderTime"] = orderTime + paramObject["planDeliverTime"] = planDeliverTime + paramObject["requireOverTime"] = requireOverTime + paramObject["customerName"] = customerName + paramObject["customerPhone"] = customerPhone + paramObject["customerAddress"] = customerAddress + paramObject["remark"] = remark + paramObject["minioFileName"] = minioFileName + paramObject["certifications"] = certifications + paramObject["isUrgent"] = isUrgent + paramObject["customerSampleInfoList"] = JSONArray.parseArray(JSON.toJSONString(samples)) + + val requestBody = paramObject.toString().toRequestBody( + "application/json;charset=UTF-8".toMediaType() + ) + return api.addEntrust(AuthenticationHelper.token!!, requestBody) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/view/home/EntrustAddActivity.kt b/app/src/main/java/com/casic/xz/meterage/view/home/EntrustAddActivity.kt index 3e30095..9c8d27b 100644 --- a/app/src/main/java/com/casic/xz/meterage/view/home/EntrustAddActivity.kt +++ b/app/src/main/java/com/casic/xz/meterage/view/home/EntrustAddActivity.kt @@ -1,52 +1,211 @@ package com.casic.xz.meterage.view.home +import android.app.Activity +import android.content.Context +import android.content.Intent +import android.graphics.Color +import android.graphics.Paint import android.util.Log +import androidx.activity.result.ActivityResult +import androidx.activity.result.ActivityResultCallback +import androidx.activity.result.contract.ActivityResultContracts import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R import com.casic.xz.meterage.adapter.CertificateTypeAdapter2 -import com.casic.xz.meterage.extensions.initLayoutImmersionBar +import com.casic.xz.meterage.adapter.CustomerSampleAdapter +import com.casic.xz.meterage.callback.DateSelectedCallback +import com.casic.xz.meterage.callback.OnImageCompressListener +import com.casic.xz.meterage.extensions.* +import com.casic.xz.meterage.model.EntrustDetailModel +import com.casic.xz.meterage.model.SampleListModel +import com.casic.xz.meterage.utils.FileType +import com.casic.xz.meterage.utils.GlideLoadEngine +import com.casic.xz.meterage.utils.LoadingDialogHub import com.casic.xz.meterage.vm.DictionaryViewModel +import com.casic.xz.meterage.vm.EntrustViewModel +import com.casic.xz.meterage.vm.FileUploadViewModel +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken import com.gyf.immersionbar.ImmersionBar +import com.luck.picture.lib.basic.PictureSelector +import com.luck.picture.lib.config.SelectMimeType +import com.luck.picture.lib.entity.LocalMedia +import com.luck.picture.lib.interfaces.OnResultCallbackListener import com.pengxh.kt.lite.base.KotlinBaseActivity -import com.pengxh.kt.lite.extensions.toJson +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.vm.LoadState +import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import kotlinx.android.synthetic.main.activity_entrust_add.* +import java.io.File + class EntrustAddActivity : KotlinBaseActivity() { + private val context: Context = this@EntrustAddActivity + private val gson by lazy { Gson() } private lateinit var dictionaryViewModel: DictionaryViewModel - private var checkedItems = ArrayList() + private lateinit var fileUploadViewModel: FileUploadViewModel + private lateinit var entrustViewModel: EntrustViewModel + private lateinit var sampleAdapter: CustomerSampleAdapter + private var checkedItems = ArrayList() + private var isUrgent = "0" + private var sampleModels: ArrayList? = null + private var dataBeans = ArrayList() override fun initData() { //证书 dictionaryViewModel = ViewModelProvider(this)[DictionaryViewModel::class.java] dictionaryViewModel.getDictionaryByCode("certificationClass") - dictionaryViewModel.dictionary.observe(this) { dic -> - if (dic.code == 200) { - val typeAdapter2 = CertificateTypeAdapter2(this, dic.data) + dictionaryViewModel.dictionary.observe(this) { + if (it.code == 200) { + val typeAdapter2 = CertificateTypeAdapter2(this, it.data) typeRecyclerView.adapter = typeAdapter2 typeAdapter2.setOnItemCheckedListener(object : CertificateTypeAdapter2.OnItemCheckedListener { override fun onItemChecked(position: Int, isChecked: Boolean) { if (isChecked) { - checkedItems.add(position) + checkedItems.add(position.toString()) } else { - checkedItems.remove(position) + checkedItems.remove(position.toString()) } } }) } } + + fileUploadViewModel = ViewModelProvider(this)[FileUploadViewModel::class.java] + fileUploadViewModel.resultModel.observe(this) { + if (it.code == 200) { + val annexName = it.data[0] + annexView.text = annexName + val textPaint = annexView.paint + textPaint.flags = Paint.UNDERLINE_TEXT_FLAG + textPaint.isAntiAlias = true + annexView.setTextColor(Color.BLUE) + + annexView.setOnClickListener { + annexName.watchAttachFile(this) + } + } + } + + entrustViewModel = ViewModelProvider(this)[EntrustViewModel::class.java] + entrustViewModel.addResult.observe(this) { + if (it.code == 200) { + finish() + } + } + + //样品列表 + sampleAdapter = CustomerSampleAdapter(this, dataBeans) + sampleRecyclerView.adapter = sampleAdapter } + private val selectCustomerLauncher = + registerForActivityResult(ActivityResultContracts.StartActivityForResult(), + object : ActivityResultCallback { + override fun onActivityResult(result: ActivityResult?) { + if (result?.resultCode == Activity.RESULT_OK) { + val data = result.data ?: return + + entrustNameView.text = data.getStringExtra("entrustName") + entrustContactView.text = data.getStringExtra("entrustContact") + entrustAddressView.text = data.getStringExtra("entrustAddress") + } + } + }) + + private val selectSampleLauncher = + registerForActivityResult(ActivityResultContracts.StartActivityForResult(), + object : ActivityResultCallback { + override fun onActivityResult(result: ActivityResult?) { + if (result?.resultCode == Activity.RESULT_OK) { + val data = result.data ?: return + + val modelsJson = data.getStringExtra("sampleModels") + if (!modelsJson.isNullOrBlank()) { + sampleModels = gson.fromJson( + modelsJson, + object : + TypeToken>() {}.type + ) + } + + //刷新列表 + dataBeans.clear() + sampleModels?.forEach { + val model = + EntrustDetailModel.DataModel.CustomerSampleInfoListModel() + + model.customerName = it.customerName + model.customerNo = it.customerNo + model.id = it.id + model.manufacturingNo = it.manufacturingNo + model.measureLastTime = it.measureLastTime + model.measurePeriod = it.measurePeriod + model.orderId = it.orderId + model.remark = it.remark + model.sampleModel = it.sampleModel + model.sampleName = it.sampleName + model.sampleNo = it.sampleNo + model.validDeadline = it.validDeadline + + dataBeans.add(model) + } + sampleAdapter.notifyDataSetChanged() + } + } + }) + override fun initEvent() { + leftBackView.setOnClickListener { finish() } + + estimateTimeView.setOnClickListener { + showDatePicker(object : DateSelectedCallback { + override fun onDateSelected(date: String) { + estimateTimeView.text = date + } + }) + } + + completedView.setOnClickListener { + showDatePicker(object : DateSelectedCallback { + override fun onDateSelected(date: String) { + completedView.text = date + } + }) + } + + entrustNameView.setOnClickListener { + selectCustomerLauncher.launch(Intent(this, SelectCustomerActivity::class.java)) + } + //上传附件 uploadFileButton.setOnClickListener { + BottomActionSheet.Builder() + .setContext(this) + .setItemTextColor(Color.BLUE) + .setActionItemTitle(listOf("文件", "图片")) + .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { + override fun onActionItemClick(position: Int) { + when (position) { + 0 -> uploadFile() + 1 -> uploadImage() + } + } + }).build().show() + } + radioGroup.setOnCheckedChangeListener { _, checkedId -> + when (checkedId) { + R.id.radioButton1 -> isUrgent = "1" + R.id.radioButton2 -> isUrgent = "0" + } } //选择样品 selectSampleButton.setOnClickListener { - + selectSampleLauncher.launch(Intent(this, SelectSampleActivity::class.java)) } //写入样品信息 @@ -55,14 +214,68 @@ } pushEntrustView.setOnClickListener { - Log.d("Casic", "EntrustAddActivity => initEvent: ${checkedItems.toJson()}") + val sender = senderView.text.toString() + if (sender.isBlank()) { + "请填写送样人名字".show(this) + return@setOnClickListener + } + + val contact = contactView.text.toString() + if (contact.isBlank()) { + "请填写送样人联系方式".show(this) + return@setOnClickListener + } + + val estimateTime = estimateTimeView.text.toString() + if (estimateTime.isBlank()) { + "请选择预计送到的时间".show(this) + return@setOnClickListener + } + + val entrustName = entrustNameView.text.toString() + if (entrustName.isBlank()) { + "请选择委托方".show(this) + return@setOnClickListener + } + + if (sampleModels == null) { + "请选择样品".show(this) + return@setOnClickListener + } + entrustViewModel.addEntrust( + sender, + contact, + createEntrustDateView.text.toString(), + estimateTime, + completedView.text.toString(), + entrustName, + entrustContactView.text.toString(), + entrustAddressView.text.toString(), + remarkView.text.toString(), + annexView.text.toString(), + checkedItems.reformat(), + isUrgent, + sampleModels!! + ) } } override fun initLayoutView(): Int = R.layout.activity_entrust_add override fun observeRequestState() { + fileUploadViewModel.loadState.observe(this) { + when (it) { + LoadState.Loading -> LoadingDialogHub.show(this, "文件上传中,请稍后...") + else -> LoadingDialogHub.dismiss() + } + } + entrustViewModel.loadState.observe(this) { + when (it) { + LoadState.Loading -> LoadingDialogHub.show(this, "委托创建中,请稍后...") + else -> LoadingDialogHub.dismiss() + } + } } override fun setupTopBarLayout() { @@ -70,4 +283,62 @@ initLayoutImmersionBar(rootView) titleView.text = "委托需求" } + + private fun uploadFile() { +// val explorer = FileExplorer(this) +// explorer.setInitDir(ExplorerMode.FILE, Environment.getExternalStorageDirectory()) +// explorer.setShowHomeDir(true) +// explorer.setShowUpDir(true) +// explorer.setShowHideDir(true) +// explorer.setAllowExtensions(arrayOf(".doc", ".docx", ".xls", ".xlsx", ".pdf")) +// explorer.setOnFileClickedListener { +// val type = if (it.name.endsWith(".doc") || it.name.endsWith(".docx")) { +// FileType.WORD +// } else if (it.name.endsWith(".pdf")) { +// FileType.PDF +// } else { +// FileType.UNKNOWN +// } +// +// Log.d("Casic", "EntrustAddActivity => uploadFile: ${it.absolutePath}") +// fileUploadViewModel.uploadFile(it, type) +// } + } + + private fun uploadImage() { + PictureSelector.create(this) + .openGallery(SelectMimeType.ofImage()) + .isGif(false) + .isMaxSelectEnabledMask(true) + .setFilterMinFileSize(100) + .setMaxSelectNum(1) + .isDisplayCamera(false) + .setImageEngine(GlideLoadEngine.instance) + .forResult(object : OnResultCallbackListener { + override fun onResult(result: ArrayList?) { + if (result == null) { + "选择照片失败,请重试".show(context) + return + } + result[0].realPath.compressImage(context, object : OnImageCompressListener { + override fun onSuccess(file: File) { + Log.d( + "Casic", "EntrustAddActivity => onSuccess: ${file.absolutePath}" + ) + ///storage/emulated/0/Android/data/com.casic.xz.meterage/files/Pictures/CompressImage/1677478115391211.jpeg + //上传图片 + fileUploadViewModel.uploadFile(file, FileType.IMAGE) + } + + override fun onError(e: Throwable) { + e.printStackTrace() + } + }) + } + + override fun onCancel() { + + } + }) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/view/home/SelectCustomerActivity.kt b/app/src/main/java/com/casic/xz/meterage/view/home/SelectCustomerActivity.kt new file mode 100644 index 0000000..9bf6a1a --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/view/home/SelectCustomerActivity.kt @@ -0,0 +1,158 @@ +package com.casic.xz.meterage.view.home + +import android.content.Intent +import android.os.Handler +import androidx.lifecycle.ViewModelProvider +import androidx.recyclerview.widget.DefaultItemAnimator +import androidx.recyclerview.widget.DividerItemDecoration +import com.casic.xz.meterage.R +import com.casic.xz.meterage.adapter.SelectCustomerAdapter +import com.casic.xz.meterage.extensions.initLayoutImmersionBar +import com.casic.xz.meterage.extensions.showEmptyPage +import com.casic.xz.meterage.model.CustomerListModel +import com.casic.xz.meterage.utils.LoadingDialogHub +import com.casic.xz.meterage.vm.CustomerViewModel +import com.gyf.immersionbar.ImmersionBar +import com.pengxh.kt.lite.base.KotlinBaseActivity +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.utils.WeakReferenceHandler +import com.pengxh.kt.lite.vm.LoadState +import kotlinx.android.synthetic.main.activity_select_customer.* +import kotlinx.android.synthetic.main.include_base_title.* +import kotlinx.android.synthetic.main.include_empty_view.* + +class SelectCustomerActivity : KotlinBaseActivity() { + + private lateinit var weakReferenceHandler: WeakReferenceHandler + private lateinit var customerViewModel: CustomerViewModel + private lateinit var selectCustomerAdapter: SelectCustomerAdapter + private var dataBeans: MutableList = ArrayList() + private var pageIndex = 1 + private var isRefresh = false + private var isLoadMore = false + private var customerModel: CustomerListModel.DataModel.RowsModel? = null + + override fun initData() { + weakReferenceHandler = WeakReferenceHandler(callback) + customerViewModel = ViewModelProvider(this)[CustomerViewModel::class.java] + customerViewModel.customerList.observe(this) { + if (it.code == 200) { + val dataRows = it.data?.rows!! + when { + isRefresh -> { + dataBeans.clear() + dataBeans = dataRows + customerLayout.finishRefresh() + isRefresh = false + } + isLoadMore -> { + if (dataRows.size == 0) { + "到底了,别拉了".show(this) + } + dataBeans.addAll(dataRows) + customerLayout.finishLoadMore() + isLoadMore = false + } + else -> { + dataBeans = dataRows + } + } + weakReferenceHandler.sendEmptyMessage(2023022701) + } + } + } + + override fun initEvent() { + leftBackView.setOnClickListener { + if (customerModel == null) { + "请选择委托方".show(this) + return@setOnClickListener + } + val intent = Intent() + intent.putExtra("entrustName", customerModel!!.customerName) + intent.putExtra("entrustContact", customerModel!!.phone) + intent.putExtra("entrustAddress", customerModel!!.fullAddress) + setResult(RESULT_OK, intent) + finish() + } + + customerLayout.setOnRefreshListener { + isRefresh = true + //刷新之后页码重置 + pageIndex = 1 + getCustomerList() + } + + customerLayout.setOnLoadMoreListener { + isLoadMore = true + pageIndex++ + getCustomerList() + } + } + + override fun initLayoutView(): Int = R.layout.activity_select_customer + + override fun observeRequestState() { + customerViewModel.loadState.observe(this) { + when (it) { + LoadState.Loading -> LoadingDialogHub.show(this, "数据加载中...") + else -> LoadingDialogHub.dismiss() + } + } + } + + override fun setupTopBarLayout() { + ImmersionBar.with(this).statusBarDarkFont(true).init() + initLayoutImmersionBar(rootView) + titleView.text = "客户列表" + } + + override fun onResume() { + super.onResume() + pageIndex = 1 + getCustomerList() + } + + private fun getCustomerList() { + customerViewModel.getCustomerList( + "", + "", + "", + "", + pageIndex + ) + } + + private val callback = Handler.Callback { + when (it.what) { + 2023022701 -> { + if (isRefresh || isLoadMore) { + selectCustomerAdapter.notifyDataSetChanged() + } else { + if (dataBeans.size == 0) { + emptyView!!.showEmptyPage("无客户数据") { + pageIndex = 1 + getCustomerList() + } + } else { + emptyView!!.hide() + selectCustomerAdapter = SelectCustomerAdapter(this, dataBeans) + customerRecyclerView.addItemDecoration( + DividerItemDecoration(this, DividerItemDecoration.VERTICAL) + ) + (customerRecyclerView.itemAnimator as DefaultItemAnimator).supportsChangeAnimations = + false + customerRecyclerView.adapter = selectCustomerAdapter + selectCustomerAdapter.setOnCheckedListener(object : + SelectCustomerAdapter.OnItemCheckedListener { + override fun onItemChecked(item: CustomerListModel.DataModel.RowsModel) { + customerModel = item + } + }) + } + } + } + } + true + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/view/home/SelectSampleActivity.kt b/app/src/main/java/com/casic/xz/meterage/view/home/SelectSampleActivity.kt new file mode 100644 index 0000000..f85cb44 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/view/home/SelectSampleActivity.kt @@ -0,0 +1,152 @@ +package com.casic.xz.meterage.view.home + +import android.content.Intent +import android.os.Handler +import androidx.lifecycle.ViewModelProvider +import androidx.recyclerview.widget.DefaultItemAnimator +import androidx.recyclerview.widget.DividerItemDecoration +import com.casic.xz.meterage.R +import com.casic.xz.meterage.adapter.SelectSampleAdapter +import com.casic.xz.meterage.extensions.initLayoutImmersionBar +import com.casic.xz.meterage.extensions.showEmptyPage +import com.casic.xz.meterage.model.SampleListModel +import com.casic.xz.meterage.vm.SampleViewModel +import com.gyf.immersionbar.ImmersionBar +import com.pengxh.kt.lite.base.KotlinBaseActivity +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.extensions.toJson +import com.pengxh.kt.lite.utils.WeakReferenceHandler +import kotlinx.android.synthetic.main.activity_select_sample.* +import kotlinx.android.synthetic.main.include_base_title.* +import kotlinx.android.synthetic.main.include_empty_view.* + +class SelectSampleActivity : KotlinBaseActivity() { + + private lateinit var weakReferenceHandler: WeakReferenceHandler + private lateinit var sampleViewModel: SampleViewModel + private lateinit var selectSampleAdapter: SelectSampleAdapter + private var dataBeans: MutableList = ArrayList() + private var pageIndex = 1 + private var isRefresh = false + private var isLoadMore = false + private var sampleModels = ArrayList() + + override fun initData() { + weakReferenceHandler = WeakReferenceHandler(callback) + sampleViewModel = ViewModelProvider(this)[SampleViewModel::class.java] + sampleViewModel.sampleList.observe(this) { + if (it.code == 200) { + val dataRows = it.data?.rows!! + when { + isRefresh -> { + dataBeans.clear() + dataBeans = dataRows + sampleLayout.finishRefresh() + isRefresh = false + } + isLoadMore -> { + if (dataRows.size == 0) { + "到底了,别拉了".show(this) + } + dataBeans.addAll(dataRows) + sampleLayout.finishLoadMore() + isLoadMore = false + } + else -> { + dataBeans = dataRows + } + } + weakReferenceHandler.sendEmptyMessage(2023030101) + } + } + } + + override fun initEvent() { + leftBackView.setOnClickListener { + val intent = Intent() + intent.putExtra("sampleModels", sampleModels.toJson()) + setResult(RESULT_OK, intent) + finish() + } + + sampleLayout.setOnRefreshListener { + isRefresh = true + //刷新之后页码重置 + pageIndex = 1 + getSampleList() + } + + sampleLayout.setOnLoadMoreListener { + isLoadMore = true + pageIndex++ + getSampleList() + } + } + + override fun initLayoutView(): Int = R.layout.activity_select_sample + + override fun observeRequestState() { + + } + + override fun setupTopBarLayout() { + ImmersionBar.with(this).statusBarDarkFont(true).init() + initLayoutImmersionBar(rootView) + titleView.text = "样品列表" + } + + override fun onResume() { + super.onResume() + pageIndex = 1 + getSampleList() + } + + private fun getSampleList() { + sampleViewModel.getSampleList( + "", + "", + "", + "", + "", + "", + "", + "", + "", + arrayOf(), + pageIndex + ) + } + + private val callback = Handler.Callback { + when (it.what) { + 2023030101 -> { + if (isRefresh || isLoadMore) { + selectSampleAdapter.notifyDataSetChanged() + } else { + if (dataBeans.size == 0) { + emptyView!!.showEmptyPage("无样品数据") { + pageIndex = 1 + getSampleList() + } + } else { + emptyView!!.hide() + selectSampleAdapter = SelectSampleAdapter(this, dataBeans) + sampleRecyclerView.addItemDecoration( + DividerItemDecoration(this, DividerItemDecoration.VERTICAL) + ) + (sampleRecyclerView.itemAnimator as DefaultItemAnimator).supportsChangeAnimations = + false + sampleRecyclerView.adapter = selectSampleAdapter + selectSampleAdapter.setOnCheckedListener(object : + SelectSampleAdapter.OnItemCheckedListener { + override fun onItemChecked(items: ArrayList) { + sampleModels = items + } + }) + } + } + } + } + true + } +} \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 0ae369f..687b02b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -15,7 +15,6 @@ } compileSdkVersion 31 - buildToolsVersion "30.0.3" defaultConfig { applicationId "com.casic.xz.meterage" @@ -84,11 +83,13 @@ implementation 'top.zibin:Luban:1.1.8' //官方Json解析库 implementation 'com.google.code.gson:gson:2.9.0' + //阿里巴巴JSON库 + implementation 'com.alibaba.fastjson2:fastjson2:2.0.24' //Kotlin协程 implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.5.1' //MVVM+LiveData implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.5.1" - implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.0" + implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1" implementation "androidx.lifecycle:lifecycle-extensions:2.2.0" //返回值转换器 implementation 'com.jakewharton.retrofit:retrofit2-kotlin-coroutines-adapter:0.9.2' @@ -109,4 +110,8 @@ implementation 'com.github.barteksc:android-pdf-viewer:2.8.2' //绕过Android 11反射限制 implementation 'com.github.tiann:FreeReflection:3.1.0' + //单项/数字、二三级联动、日期/时间等滚轮选择器 + implementation 'com.github.gzu-liyujiang.AndroidPicker:WheelPicker:4.1.8' + //文件/目录选择器 + implementation 'com.github.gzu-liyujiang.AndroidPicker:FilePicker:4.1.1' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 1ccc12b..0fba91b 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -60,6 +60,8 @@ + + diff --git a/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt b/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt new file mode 100644 index 0000000..21a71d8 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt @@ -0,0 +1,70 @@ +package com.casic.xz.meterage.adapter + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import com.casic.xz.meterage.R +import com.casic.xz.meterage.extensions.toChineseGrade +import com.casic.xz.meterage.model.CustomerListModel + +class SelectCustomerAdapter( + context: Context, private val dataRows: MutableList +) : RecyclerView.Adapter() { + + private var layoutInflater = LayoutInflater.from(context) + + //选择的位置 + private var selectedPosition = 0 + + //临时记录上次选择的位置 + private var temp = -1 + + override fun getItemCount(): Int = dataRows.size + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ItemViewHolder( + layoutInflater.inflate(R.layout.item_select_customer_lv, parent, false) + ) + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + //绑定数据 + val rowsBean = dataRows[position] + holder.agreementLevelView.text = rowsBean.grade.toChineseGrade() + holder.customerNameView.text = rowsBean.customerName + holder.scaleView.text = rowsBean.companySizeName + holder.overallView.text = "公司规模:${rowsBean.evaluationName}" + holder.fullAddressView.text = "公司地址:${rowsBean.fullAddress}" + + holder.itemView.isSelected = holder.layoutPosition == selectedPosition + holder.itemView.setOnClickListener { + itemCheckedListener?.onItemChecked(rowsBean) + + holder.itemView.isSelected = true + temp = selectedPosition + //设置新的位置 + selectedPosition = holder.layoutPosition + //更新旧位置 + notifyItemChanged(temp) + } + } + + inner class ItemViewHolder(view: View) : RecyclerView.ViewHolder(view) { + var agreementLevelView: TextView = view.findViewById(R.id.agreementLevelView) + var customerNameView: TextView = view.findViewById(R.id.customerNameView) + var scaleView: TextView = view.findViewById(R.id.scaleView) + var overallView: TextView = view.findViewById(R.id.overallView) + var fullAddressView: TextView = view.findViewById(R.id.fullAddressView) + } + + private var itemCheckedListener: OnItemCheckedListener? = null + + interface OnItemCheckedListener { + fun onItemChecked(item: CustomerListModel.DataModel.RowsModel) + } + + fun setOnCheckedListener(listener: OnItemCheckedListener?) { + itemCheckedListener = listener + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt b/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt new file mode 100644 index 0000000..c29461e --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt @@ -0,0 +1,68 @@ +package com.casic.xz.meterage.adapter + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import com.casic.xz.meterage.R +import com.casic.xz.meterage.model.SampleListModel + +class SelectSampleAdapter( + context: Context, private val dataRows: MutableList +) : RecyclerView.Adapter() { + + private var layoutInflater = LayoutInflater.from(context) + private var multipleSelected = mutableSetOf() + private var sampleModes = ArrayList() + + override fun getItemCount(): Int = dataRows.size + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ItemViewHolder( + layoutInflater.inflate(R.layout.item_select_sample_lv, parent, false) + ) + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + //绑定数据 + val rowsBean = dataRows[position] + holder.sampleNameView.text = "${rowsBean.sampleName}【${rowsBean.sampleModel}】" + holder.manufacturingCodeView.text = "出厂编号:${rowsBean.manufacturingNo}" + holder.sampleCodeView.text = "样品编号:${rowsBean.sampleNo}" + holder.validDateView.text = "有效期至:${rowsBean.validDeadline}" + + holder.checkImageView.isSelected = multipleSelected.contains(position) + holder.itemView.setOnClickListener { + if (multipleSelected.contains(position)) { + multipleSelected.remove(position) + sampleModes.remove(dataRows[position]) + holder.checkImageView.isSelected = false + } else { + multipleSelected.add(position) + sampleModes.add(dataRows[position]) + holder.checkImageView.isSelected = true + } + + itemCheckedListener?.onItemChecked(sampleModes) + } + } + + inner class ItemViewHolder(view: View) : RecyclerView.ViewHolder(view) { + var sampleNameView: TextView = view.findViewById(R.id.sampleNameView) + var manufacturingCodeView: TextView = view.findViewById(R.id.manufacturingCodeView) + var sampleCodeView: TextView = view.findViewById(R.id.sampleCodeView) + var validDateView: TextView = view.findViewById(R.id.validDateView) + var checkImageView: ImageView = view.findViewById(R.id.checkImageView) + } + + private var itemCheckedListener: OnItemCheckedListener? = null + + interface OnItemCheckedListener { + fun onItemChecked(items: ArrayList) + } + + fun setOnCheckedListener(listener: OnItemCheckedListener?) { + itemCheckedListener = listener + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/callback/DateSelectedCallback.kt b/app/src/main/java/com/casic/xz/meterage/callback/DateSelectedCallback.kt new file mode 100644 index 0000000..8196110 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/callback/DateSelectedCallback.kt @@ -0,0 +1,5 @@ +package com.casic.xz.meterage.callback + +interface DateSelectedCallback { + fun onDateSelected(date: String) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/Activity.kt b/app/src/main/java/com/casic/xz/meterage/extensions/Activity.kt new file mode 100644 index 0000000..e112d1c --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/extensions/Activity.kt @@ -0,0 +1,33 @@ +package com.casic.xz.meterage.extensions + +import android.app.Activity +import com.casic.xz.meterage.R +import com.casic.xz.meterage.callback.DateSelectedCallback +import com.github.gzuliyujiang.wheelpicker.DatePicker +import com.github.gzuliyujiang.wheelpicker.annotation.DateMode +import com.github.gzuliyujiang.wheelpicker.entity.DateEntity +import com.pengxh.kt.lite.extensions.convertColor +import com.pengxh.kt.lite.extensions.sp2px + +fun Activity.showDatePicker(callback: DateSelectedCallback) { + val datePicker = DatePicker(this) + + val layout = datePicker.wheelLayout + layout.setDateMode(DateMode.YEAR_MONTH_DAY) + layout.setDateLabel("年", "月", "日"); + layout.setTextSize(14f.sp2px(this).toFloat()) + layout.setSelectedTextSize(16f.sp2px(this).toFloat()) + layout.setSelectedTextColor(R.color.themeColor.convertColor(this)) + layout.setSelectedTextBold(true) + layout.setResetWhenLinkage(false) + layout.setRange( + DateEntity.today(), + DateEntity.target(2050, 12, 31), + DateEntity.today() + ) + + datePicker.setOnDatePickedListener { year, month, day -> + callback.onDateSelected(String.format("%s-%s-%s", year, month, day)) + } + datePicker.show() +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt b/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt index 016ebcb..cf6bf49 100644 --- a/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt +++ b/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt @@ -4,7 +4,7 @@ * ArrayList扩展方法 */ -//将图片集合格式化成满足上传格式的数据 +//将集合格式化成满足上传格式的数据 fun ArrayList.reformat(): String { if (this.isEmpty()) return "" val builder = StringBuilder() diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt b/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt index 7c57643..aa9b92b 100644 --- a/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt +++ b/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt @@ -1,7 +1,6 @@ package com.casic.xz.meterage.extensions import android.content.Context -import android.util.Log import android.view.ViewGroup import com.casic.xz.meterage.base.BaseApplication import com.pengxh.kt.lite.extensions.dp2px @@ -9,9 +8,8 @@ fun Context.initLayoutImmersionBar(rootView: ViewGroup) { var statusBarHeight = QMUIDisplayHelper.getStatusBarHeight(this) - Log.d("Casic", "状态栏高度: $statusBarHeight") if (statusBarHeight == 0) { - statusBarHeight = 44f.dp2px(BaseApplication.get()) + statusBarHeight = 40f.dp2px(BaseApplication.get()) } rootView.setPadding(0, statusBarHeight, 0, 0) rootView.requestLayout() diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/String.kt b/app/src/main/java/com/casic/xz/meterage/extensions/String.kt index 28f70d8..6234d43 100644 --- a/app/src/main/java/com/casic/xz/meterage/extensions/String.kt +++ b/app/src/main/java/com/casic/xz/meterage/extensions/String.kt @@ -128,9 +128,10 @@ fun String.combineImagePath(): String { if (this.isEmpty()) return this val defaultValue = SaveKeyValues.getValue( - LocaleConstant.DEFAULT_SERVER_CONFIG, LocaleConstant.SERVER_BASE_URL + LocaleConstant.FILE_SERVER_CONFIG, LocaleConstant.File_SERVER_URL ) as String - return "$defaultValue/static/${this.replace("\\", "/")}" + //http://111.198.10.15:21408/test/1677479806059688_1677479806038.jpeg + return "$defaultValue/test/${this.replace("\\", "/")}" } fun String.isEarlier(time: String): Boolean { diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt index 25fa87b..a0e1358 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt @@ -1,18 +1,12 @@ package com.casic.xz.meterage.fragment.customer +import android.graphics.Color import android.graphics.Paint import com.casic.xz.meterage.R -import com.casic.xz.meterage.extensions.combineImagePath import com.casic.xz.meterage.extensions.toChineseGrade +import com.casic.xz.meterage.extensions.watchAttachFile import com.casic.xz.meterage.model.CustomerDetailModel -import com.casic.xz.meterage.view.BigImageActivity -import com.casic.xz.meterage.view.notice.PreviewDocumentActivity -import com.casic.xz.meterage.view.notice.PreviewPdfActivity -import com.casic.xz.meterage.view.notice.PreviewTextActivity import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.extensions.show import kotlinx.android.synthetic.main.fragment_customer_basic_information.* class BasicInformationFragment(private val data: CustomerDetailModel.DataModel) : @@ -48,30 +42,11 @@ val textPaint = minioFileView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - minioFileView.setTextColor(R.color.themeColor.convertColor(requireContext())) + minioFileView.setTextColor(Color.BLUE) minioFileView.setOnClickListener { //查看附件 - if (minioFileName.endsWith("pdf")) { - requireContext().navigatePageTo(minioFileName) - } else if ( - minioFileName.endsWith("doc") || - minioFileName.endsWith("docx") - ) { - requireContext().navigatePageTo(minioFileName) - } else if (minioFileName.endsWith("txt")) { - requireContext().navigatePageTo(minioFileName) - } else if ( - minioFileName.endsWith("png") || - minioFileName.endsWith("jpeg") || - minioFileName.endsWith("jpg") - ) { - val urls = ArrayList() - urls.add(minioFileName.combineImagePath()) - requireContext().navigatePageTo(0, urls) - } else { - "文件类型未知,无法打开附件".show(requireContext()) - } + minioFileName.watchAttachFile(requireContext()) } } } diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt index 77846b4..3a0fe2e 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt @@ -1,5 +1,6 @@ package com.casic.xz.meterage.fragment.device +import android.graphics.Color import android.graphics.Paint import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R @@ -7,7 +8,6 @@ import com.casic.xz.meterage.utils.LoadingDialogHub import com.casic.xz.meterage.vm.EquipmentViewModel import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor import com.pengxh.kt.lite.vm.LoadState import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import kotlinx.android.synthetic.main.fragment_device_basic_information.* @@ -56,7 +56,7 @@ val textPaint = documentsView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - documentsView.setTextColor(R.color.themeColor.convertColor(requireContext())) + documentsView.setTextColor(Color.BLUE) val files = ArrayList() data.fileList.forEach { file -> @@ -66,7 +66,7 @@ BottomActionSheet.Builder() .setContext(requireContext()) .setActionItemTitle(files) - .setItemTextColor(R.color.themeColor.convertColor(requireContext())) + .setItemTextColor(Color.BLUE) .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { override fun onActionItemClick(position: Int) { diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt index 15dc3d2..10eeff8 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt @@ -1,5 +1,6 @@ package com.casic.xz.meterage.fragment.entrust +import android.graphics.Color import android.graphics.Paint import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R @@ -9,7 +10,6 @@ import com.casic.xz.meterage.model.EntrustDetailModel import com.casic.xz.meterage.vm.DictionaryViewModel import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor import kotlinx.android.synthetic.main.fragment_entrust_basic_information.* class BasicInformationFragment(private val data: EntrustDetailModel.DataModel) : @@ -38,7 +38,7 @@ val textPaint = annexView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - annexView.setTextColor(R.color.themeColor.convertColor(requireContext())) + annexView.setTextColor(Color.BLUE) annexView.setOnClickListener { minioFileName.watchAttachFile(requireContext()) @@ -59,9 +59,9 @@ //加急 if (data.isUrgent == "0") { - RadioButton2.isChecked = true + radioButton2.isChecked = true } else { - RadioButton1.isChecked = true + radioButton1.isChecked = true } //样品 diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/equipment/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/equipment/BasicInformationFragment.kt index 72b523c..7bc3b01 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/equipment/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/equipment/BasicInformationFragment.kt @@ -1,5 +1,6 @@ package com.casic.xz.meterage.fragment.equipment +import android.graphics.Color import android.graphics.Paint import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R @@ -7,7 +8,6 @@ import com.casic.xz.meterage.utils.LoadingDialogHub import com.casic.xz.meterage.vm.EquipmentViewModel import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor import com.pengxh.kt.lite.vm.LoadState import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import kotlinx.android.synthetic.main.fragment_equipment_basic_information.* @@ -74,7 +74,7 @@ val textPaint = instructionsView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - instructionsView.setTextColor(R.color.themeColor.convertColor(requireContext())) + instructionsView.setTextColor(Color.BLUE) val files = ArrayList() data.fileList.forEach { file -> @@ -84,7 +84,7 @@ BottomActionSheet.Builder() .setContext(requireContext()) .setActionItemTitle(files) - .setItemTextColor(R.color.themeColor.convertColor(requireContext())) + .setItemTextColor(Color.BLUE) .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { override fun onActionItemClick(position: Int) { diff --git a/app/src/main/java/com/casic/xz/meterage/model/SampleListModel.java b/app/src/main/java/com/casic/xz/meterage/model/SampleListModel.java new file mode 100644 index 0000000..5784343 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/model/SampleListModel.java @@ -0,0 +1,193 @@ +package com.casic.xz.meterage.model; + +import java.util.List; + +public class SampleListModel { + + private int code; + private DataModel data; + private String message; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataModel getData() { + return data; + } + + public void setData(DataModel data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public static class DataModel { + private List rows; + private int total; + + public List getRows() { + return rows; + } + + public void setRows(List rows) { + this.rows = rows; + } + + public int getTotal() { + return total; + } + + public void setTotal(int total) { + this.total = total; + } + + public static class RowsModel { + private String certificationStatus; + private String customerName; + private String customerNo; + private String id; + private String manufacturingNo; + private String measureLastTime; + private String measurePeriod; + private String orderId; + private String remark; + private String sampleModel; + private String sampleName; + private String sampleNo; + private String sampleSatus; + private String sampleSatusName; + private String validDeadline; + + public String getCertificationStatus() { + return certificationStatus; + } + + public void setCertificationStatus(String certificationStatus) { + this.certificationStatus = certificationStatus; + } + + public String getCustomerName() { + return customerName; + } + + public void setCustomerName(String customerName) { + this.customerName = customerName; + } + + public String getCustomerNo() { + return customerNo; + } + + public void setCustomerNo(String customerNo) { + this.customerNo = customerNo; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getManufacturingNo() { + return manufacturingNo; + } + + public void setManufacturingNo(String manufacturingNo) { + this.manufacturingNo = manufacturingNo; + } + + public String getMeasureLastTime() { + return measureLastTime; + } + + public void setMeasureLastTime(String measureLastTime) { + this.measureLastTime = measureLastTime; + } + + public String getMeasurePeriod() { + return measurePeriod; + } + + public void setMeasurePeriod(String measurePeriod) { + this.measurePeriod = measurePeriod; + } + + public String getOrderId() { + return orderId; + } + + public void setOrderId(String orderId) { + this.orderId = orderId; + } + + public String getRemark() { + return remark; + } + + public void setRemark(String remark) { + this.remark = remark; + } + + public String getSampleModel() { + return sampleModel; + } + + public void setSampleModel(String sampleModel) { + this.sampleModel = sampleModel; + } + + public String getSampleName() { + return sampleName; + } + + public void setSampleName(String sampleName) { + this.sampleName = sampleName; + } + + public String getSampleNo() { + return sampleNo; + } + + public void setSampleNo(String sampleNo) { + this.sampleNo = sampleNo; + } + + public String getSampleSatus() { + return sampleSatus; + } + + public void setSampleSatus(String sampleSatus) { + this.sampleSatus = sampleSatus; + } + + public String getSampleSatusName() { + return sampleSatusName; + } + + public void setSampleSatusName(String sampleSatusName) { + this.sampleSatusName = sampleSatusName; + } + + public String getValidDeadline() { + return validDeadline; + } + + public void setValidDeadline(String validDeadline) { + this.validDeadline = validDeadline; + } + } + } +} diff --git a/app/src/main/java/com/casic/xz/meterage/model/UploadResultModel.java b/app/src/main/java/com/casic/xz/meterage/model/UploadResultModel.java new file mode 100644 index 0000000..f2a6a41 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/model/UploadResultModel.java @@ -0,0 +1,34 @@ +package com.casic.xz.meterage.model; + +import java.util.List; + +public class UploadResultModel { + + private int code; + private List data; + private String message; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public List getData() { + return data; + } + + public void setData(List data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } +} diff --git a/app/src/main/java/com/casic/xz/meterage/utils/FileType.kt b/app/src/main/java/com/casic/xz/meterage/utils/FileType.kt new file mode 100644 index 0000000..17e2bca --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/utils/FileType.kt @@ -0,0 +1,23 @@ +package com.casic.xz.meterage.utils + +sealed class FileType { + /** + * PDF文件 + */ + object PDF : FileType() + + /** + * WORD文件 + */ + object WORD : FileType() + + /** + * IMAGE图片 + */ + object IMAGE : FileType() + + /** + * 未知类型(Excel) + */ + object UNKNOWN : FileType() +} diff --git a/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitService.kt index bc3f8d6..8f4fe44 100644 --- a/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitService.kt @@ -1,5 +1,6 @@ package com.casic.xz.meterage.utils.retrofit +import okhttp3.MultipartBody import okhttp3.RequestBody import retrofit2.http.* @@ -35,6 +36,16 @@ ): String /** + * 上传文件 + */ + @Multipart + @POST("/minio/file/upload") + suspend fun uploadFile( + @Header("token") token: String, + @Part file: MultipartBody.Part + ): String + + /** * 获取通知公告列表 */ @POST("/system/notice/listPage") @@ -209,4 +220,24 @@ @Header("token") token: String, @Body requestBody: RequestBody ): String + + /** + * 获取样品列表 + */ + @POST("/customer/sample/listPage") + suspend fun getSampleList( + @Header("token") token: String, + @Body requestBody: RequestBody, + @QueryMap limit: Map, + @QueryMap offset: Map + ): String + + /** + * 新增委托书 + */ + @POST("/business/order/add") + suspend fun addEntrust( + @Header("token") token: String, + @Body requestBody: RequestBody + ): String } \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitServiceManager.kt index cb22e45..90abe5a 100644 --- a/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitServiceManager.kt @@ -1,13 +1,20 @@ package com.casic.xz.meterage.utils.retrofit +import com.alibaba.fastjson2.JSON +import com.alibaba.fastjson2.JSONArray +import com.alibaba.fastjson2.JSONObject +import com.casic.xz.meterage.model.SampleListModel import com.casic.xz.meterage.utils.AuthenticationHelper +import com.casic.xz.meterage.utils.FileType import com.casic.xz.meterage.utils.LocaleConstant import com.pengxh.kt.lite.utils.RetrofitFactory import com.pengxh.kt.lite.utils.SaveKeyValues import okhttp3.MediaType.Companion.toMediaType +import okhttp3.MediaType.Companion.toMediaTypeOrNull +import okhttp3.MultipartBody +import okhttp3.RequestBody.Companion.asRequestBody import okhttp3.RequestBody.Companion.toRequestBody -import org.json.JSONArray -import org.json.JSONObject +import java.io.File object RetrofitServiceManager { @@ -31,9 +38,9 @@ */ suspend fun login(sid: String, account: String, secretKey: String): String { val paramObject = JSONObject() - paramObject.put("sid", sid) - paramObject.put("username", account) - paramObject.put("password", secretKey) + paramObject["sid"] = sid + paramObject["username"] = account + paramObject["password"] = secretKey val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -55,6 +62,20 @@ } /** + * 上传文件 + */ + suspend fun uploadFile(file: File, type: FileType): String { + val requestBody = when (type) { + FileType.PDF -> file.asRequestBody("application/pdf".toMediaTypeOrNull()) + FileType.WORD -> file.asRequestBody("application/msword".toMediaTypeOrNull()) + FileType.IMAGE -> file.asRequestBody("image/png".toMediaTypeOrNull()) + else -> file.asRequestBody("application/vnd.ms-excel".toMediaTypeOrNull()) + } + val filePart = MultipartBody.Part.createFormData("multipartFile", file.name, requestBody) + return api.uploadFile(AuthenticationHelper.token!!, filePart) + } + + /** * 获取通知公告列表 */ suspend fun getNoticeList( @@ -66,11 +87,11 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("noticeNo", noticeNo) - paramObject.put("noticeTitle", noticeTitle) - paramObject.put("noticePublisher", noticePublisher) - paramObject.put("noticeStartTime", noticeStartTime) - paramObject.put("noticeEndTime", noticeEndTime) + paramObject["noticeNo"] = noticeNo + paramObject["noticeTitle"] = noticeTitle + paramObject["noticePublisher"] = noticePublisher + paramObject["noticeStartTime"] = noticeStartTime + paramObject["noticeEndTime"] = noticeEndTime val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -105,26 +126,21 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("equipmentNo", equipmentNo) - paramObject.put("equipmentName", equipmentName) - paramObject.put("mesureType", mesureType) - paramObject.put("managerState", managerState) - paramObject.put("useDept", useDept) - paramObject.put("assetType", assetType) - paramObject.put("equipmentCategory", equipmentCategory) - paramObject.put("isCalibrationTestEquipment", isCalibrationTestEquipment) - paramObject.put("isMeasureAccount", isMeasureAccount) - paramObject.put("isStandardSupportEquipment", isStandardSupportEquipment) - paramObject.put("isFixedAssets", isFixedAssets) - paramObject.put("validStartDate", validStartDate) - paramObject.put("validEndDate", validEndDate) - paramObject.put("abc", abc) - - val jsonArray = JSONArray() - ids.forEach { - jsonArray.put(it) - } - paramObject.put("ids", jsonArray) + paramObject["equipmentNo"] = equipmentNo + paramObject["equipmentName"] = equipmentName + paramObject["mesureType"] = mesureType + paramObject["managerState"] = managerState + paramObject["useDept"] = useDept + paramObject["assetType"] = assetType + paramObject["equipmentCategory"] = equipmentCategory + paramObject["isCalibrationTestEquipment"] = isCalibrationTestEquipment + paramObject["isMeasureAccount"] = isMeasureAccount + paramObject["isStandardSupportEquipment"] = isStandardSupportEquipment + paramObject["isFixedAssets"] = isFixedAssets + paramObject["validStartDate"] = validStartDate + paramObject["validEndDate"] = validEndDate + paramObject["abc"] = abc + paramObject["ids"] = JSONArray.parseArray(JSON.toJSONString(ids)) val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() @@ -143,7 +159,7 @@ */ suspend fun getEquipmentDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -164,13 +180,13 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("standardNo", standardNo) - paramObject.put("standardName", standardName) - paramObject.put("category", category) - paramObject.put("managerState", managerState) - paramObject.put("standardLaboratory", standardLaboratory) - paramObject.put("preparationDate", preparationDate) - paramObject.put("id", id) + paramObject["standardNo"] = standardNo + paramObject["standardName"] = standardName + paramObject["category"] = category + paramObject["managerState"] = managerState + paramObject["standardLaboratory"] = standardLaboratory + paramObject["preparationDate"] = preparationDate + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -193,7 +209,7 @@ */ suspend fun getStandardDeviceDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -212,11 +228,11 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("checkType", checkType) - paramObject.put("priceItem", priceItem) - paramObject.put("priceName", priceName) - paramObject.put("priceNo", priceNo) - paramObject.put("priceType", priceType) + paramObject["checkType"] = checkType + paramObject["priceItem"] = priceItem + paramObject["priceName"] = priceName + paramObject["priceNo"] = priceNo + paramObject["priceType"] = priceType val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -234,7 +250,7 @@ */ suspend fun getCapabilityDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -257,20 +273,15 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("createStartTime", createStartTime) - paramObject.put("createEndTime", createEndTime) - paramObject.put("deptId", deptId) - paramObject.put("director", director) - paramObject.put("effectiveCompany", effectiveCompany) - paramObject.put("trainStartTime", trainStartTime) - paramObject.put("trainEndTime", trainEndTime) - paramObject.put("formId", formId) - - val jsonArray = JSONArray() - ids.forEach { - jsonArray.put(it) - } - paramObject.put("ids", jsonArray) + paramObject["createStartTime"] = createStartTime + paramObject["createEndTime"] = createEndTime + paramObject["deptId"] = deptId + paramObject["director"] = director + paramObject["effectiveCompany"] = effectiveCompany + paramObject["trainStartTime"] = trainStartTime + paramObject["trainEndTime"] = trainEndTime + paramObject["formId"] = formId + paramObject["ids"] = JSONArray.parseArray(JSON.toJSONString(ids)) val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() @@ -294,7 +305,7 @@ */ suspend fun getMeterageTrainDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -308,10 +319,10 @@ bussinessSize: String, customerName: String, customerNo: String, grade: String, offset: Int ): String { val paramObject = JSONObject() - paramObject.put("bussinessSize", bussinessSize) - paramObject.put("customerName", customerName) - paramObject.put("customerNo", customerNo) - paramObject.put("grade", grade) + paramObject["bussinessSize"] = bussinessSize + paramObject["customerName"] = customerName + paramObject["customerNo"] = customerNo + paramObject["grade"] = grade val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() @@ -330,7 +341,7 @@ */ suspend fun getCustomerDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -342,7 +353,7 @@ */ suspend fun getStaffList(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -354,7 +365,7 @@ */ suspend fun getSupportEquipmentList(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -366,7 +377,7 @@ */ suspend fun getVerifyProcedureList(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -389,20 +400,15 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("customerName", customerName) - paramObject.put("customerNo", customerNo) - paramObject.put("deliverer", deliverer) - paramObject.put("orderCode", orderCode) - paramObject.put("startTime", startTime) - paramObject.put("endTime", endTime) - paramObject.put("isUrgent", isUrgent) - paramObject.put("status", status) - - val jsonArray = JSONArray() - ids.forEach { - jsonArray.put(it) - } - paramObject.put("ids", jsonArray) + paramObject["customerName"] = customerName + paramObject["customerNo"] = customerNo + paramObject["deliverer"] = deliverer + paramObject["orderCode"] = orderCode + paramObject["startTime"] = startTime + paramObject["endTime"] = endTime + paramObject["isUrgent"] = isUrgent + paramObject["status"] = status + paramObject["ids"] = JSONArray.parseArray(JSON.toJSONString(ids)) val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() @@ -421,7 +427,7 @@ */ suspend fun getEntrustDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -433,7 +439,7 @@ */ suspend fun acceptEntrust(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -446,10 +452,89 @@ */ suspend fun returnEntrust(id: String, selected: ArrayList): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) return api.returnEntrust(AuthenticationHelper.token!!, requestBody) } + + /** + * 获取样品列表 + */ + suspend fun getSampleList( + customerName: String, + customerNo: String, + startTime: String, + endTime: String, + sampleName: String, + sampleNo: String, + sampleModel: String, + sampleBelong: String, + overtimeStatus: String, + ids: Array, + offset: Int + ): String { + val paramObject = JSONObject() + paramObject["customerName"] = customerName + paramObject["customerNo"] = customerNo + paramObject["startTime"] = startTime + paramObject["endTime"] = endTime + paramObject["sampleName"] = sampleName + paramObject["sampleNo"] = sampleNo + paramObject["sampleModel"] = sampleModel + paramObject["sampleBelong"] = sampleBelong + paramObject["overtimeStatus"] = overtimeStatus + paramObject["ids"] = JSONArray.parseArray(JSON.toJSONString(ids)) + + val requestBody = paramObject.toString().toRequestBody( + "application/json;charset=UTF-8".toMediaType() + ) + + val limitMap = HashMap() + limitMap["limit"] = LocaleConstant.PAGE_LIMIT + + val offsetMap = HashMap() + offsetMap["offset"] = offset + return api.getSampleList(AuthenticationHelper.token!!, requestBody, limitMap, offsetMap) + } + + /** + * 新增委托书 + */ + suspend fun addEntrust( + deliverer: String, + delivererTel: String, + orderTime: String, + planDeliverTime: String, + requireOverTime: String, + customerName: String, + customerPhone: String, + customerAddress: String, + remark: String, + minioFileName: String, + certifications: String, + isUrgent: String, + samples: List + ): String { + val paramObject = JSONObject() + paramObject["deliverer"] = deliverer + paramObject["delivererTel"] = delivererTel + paramObject["orderTime"] = orderTime + paramObject["planDeliverTime"] = planDeliverTime + paramObject["requireOverTime"] = requireOverTime + paramObject["customerName"] = customerName + paramObject["customerPhone"] = customerPhone + paramObject["customerAddress"] = customerAddress + paramObject["remark"] = remark + paramObject["minioFileName"] = minioFileName + paramObject["certifications"] = certifications + paramObject["isUrgent"] = isUrgent + paramObject["customerSampleInfoList"] = JSONArray.parseArray(JSON.toJSONString(samples)) + + val requestBody = paramObject.toString().toRequestBody( + "application/json;charset=UTF-8".toMediaType() + ) + return api.addEntrust(AuthenticationHelper.token!!, requestBody) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/view/home/EntrustAddActivity.kt b/app/src/main/java/com/casic/xz/meterage/view/home/EntrustAddActivity.kt index 3e30095..9c8d27b 100644 --- a/app/src/main/java/com/casic/xz/meterage/view/home/EntrustAddActivity.kt +++ b/app/src/main/java/com/casic/xz/meterage/view/home/EntrustAddActivity.kt @@ -1,52 +1,211 @@ package com.casic.xz.meterage.view.home +import android.app.Activity +import android.content.Context +import android.content.Intent +import android.graphics.Color +import android.graphics.Paint import android.util.Log +import androidx.activity.result.ActivityResult +import androidx.activity.result.ActivityResultCallback +import androidx.activity.result.contract.ActivityResultContracts import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R import com.casic.xz.meterage.adapter.CertificateTypeAdapter2 -import com.casic.xz.meterage.extensions.initLayoutImmersionBar +import com.casic.xz.meterage.adapter.CustomerSampleAdapter +import com.casic.xz.meterage.callback.DateSelectedCallback +import com.casic.xz.meterage.callback.OnImageCompressListener +import com.casic.xz.meterage.extensions.* +import com.casic.xz.meterage.model.EntrustDetailModel +import com.casic.xz.meterage.model.SampleListModel +import com.casic.xz.meterage.utils.FileType +import com.casic.xz.meterage.utils.GlideLoadEngine +import com.casic.xz.meterage.utils.LoadingDialogHub import com.casic.xz.meterage.vm.DictionaryViewModel +import com.casic.xz.meterage.vm.EntrustViewModel +import com.casic.xz.meterage.vm.FileUploadViewModel +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken import com.gyf.immersionbar.ImmersionBar +import com.luck.picture.lib.basic.PictureSelector +import com.luck.picture.lib.config.SelectMimeType +import com.luck.picture.lib.entity.LocalMedia +import com.luck.picture.lib.interfaces.OnResultCallbackListener import com.pengxh.kt.lite.base.KotlinBaseActivity -import com.pengxh.kt.lite.extensions.toJson +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.vm.LoadState +import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import kotlinx.android.synthetic.main.activity_entrust_add.* +import java.io.File + class EntrustAddActivity : KotlinBaseActivity() { + private val context: Context = this@EntrustAddActivity + private val gson by lazy { Gson() } private lateinit var dictionaryViewModel: DictionaryViewModel - private var checkedItems = ArrayList() + private lateinit var fileUploadViewModel: FileUploadViewModel + private lateinit var entrustViewModel: EntrustViewModel + private lateinit var sampleAdapter: CustomerSampleAdapter + private var checkedItems = ArrayList() + private var isUrgent = "0" + private var sampleModels: ArrayList? = null + private var dataBeans = ArrayList() override fun initData() { //证书 dictionaryViewModel = ViewModelProvider(this)[DictionaryViewModel::class.java] dictionaryViewModel.getDictionaryByCode("certificationClass") - dictionaryViewModel.dictionary.observe(this) { dic -> - if (dic.code == 200) { - val typeAdapter2 = CertificateTypeAdapter2(this, dic.data) + dictionaryViewModel.dictionary.observe(this) { + if (it.code == 200) { + val typeAdapter2 = CertificateTypeAdapter2(this, it.data) typeRecyclerView.adapter = typeAdapter2 typeAdapter2.setOnItemCheckedListener(object : CertificateTypeAdapter2.OnItemCheckedListener { override fun onItemChecked(position: Int, isChecked: Boolean) { if (isChecked) { - checkedItems.add(position) + checkedItems.add(position.toString()) } else { - checkedItems.remove(position) + checkedItems.remove(position.toString()) } } }) } } + + fileUploadViewModel = ViewModelProvider(this)[FileUploadViewModel::class.java] + fileUploadViewModel.resultModel.observe(this) { + if (it.code == 200) { + val annexName = it.data[0] + annexView.text = annexName + val textPaint = annexView.paint + textPaint.flags = Paint.UNDERLINE_TEXT_FLAG + textPaint.isAntiAlias = true + annexView.setTextColor(Color.BLUE) + + annexView.setOnClickListener { + annexName.watchAttachFile(this) + } + } + } + + entrustViewModel = ViewModelProvider(this)[EntrustViewModel::class.java] + entrustViewModel.addResult.observe(this) { + if (it.code == 200) { + finish() + } + } + + //样品列表 + sampleAdapter = CustomerSampleAdapter(this, dataBeans) + sampleRecyclerView.adapter = sampleAdapter } + private val selectCustomerLauncher = + registerForActivityResult(ActivityResultContracts.StartActivityForResult(), + object : ActivityResultCallback { + override fun onActivityResult(result: ActivityResult?) { + if (result?.resultCode == Activity.RESULT_OK) { + val data = result.data ?: return + + entrustNameView.text = data.getStringExtra("entrustName") + entrustContactView.text = data.getStringExtra("entrustContact") + entrustAddressView.text = data.getStringExtra("entrustAddress") + } + } + }) + + private val selectSampleLauncher = + registerForActivityResult(ActivityResultContracts.StartActivityForResult(), + object : ActivityResultCallback { + override fun onActivityResult(result: ActivityResult?) { + if (result?.resultCode == Activity.RESULT_OK) { + val data = result.data ?: return + + val modelsJson = data.getStringExtra("sampleModels") + if (!modelsJson.isNullOrBlank()) { + sampleModels = gson.fromJson( + modelsJson, + object : + TypeToken>() {}.type + ) + } + + //刷新列表 + dataBeans.clear() + sampleModels?.forEach { + val model = + EntrustDetailModel.DataModel.CustomerSampleInfoListModel() + + model.customerName = it.customerName + model.customerNo = it.customerNo + model.id = it.id + model.manufacturingNo = it.manufacturingNo + model.measureLastTime = it.measureLastTime + model.measurePeriod = it.measurePeriod + model.orderId = it.orderId + model.remark = it.remark + model.sampleModel = it.sampleModel + model.sampleName = it.sampleName + model.sampleNo = it.sampleNo + model.validDeadline = it.validDeadline + + dataBeans.add(model) + } + sampleAdapter.notifyDataSetChanged() + } + } + }) + override fun initEvent() { + leftBackView.setOnClickListener { finish() } + + estimateTimeView.setOnClickListener { + showDatePicker(object : DateSelectedCallback { + override fun onDateSelected(date: String) { + estimateTimeView.text = date + } + }) + } + + completedView.setOnClickListener { + showDatePicker(object : DateSelectedCallback { + override fun onDateSelected(date: String) { + completedView.text = date + } + }) + } + + entrustNameView.setOnClickListener { + selectCustomerLauncher.launch(Intent(this, SelectCustomerActivity::class.java)) + } + //上传附件 uploadFileButton.setOnClickListener { + BottomActionSheet.Builder() + .setContext(this) + .setItemTextColor(Color.BLUE) + .setActionItemTitle(listOf("文件", "图片")) + .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { + override fun onActionItemClick(position: Int) { + when (position) { + 0 -> uploadFile() + 1 -> uploadImage() + } + } + }).build().show() + } + radioGroup.setOnCheckedChangeListener { _, checkedId -> + when (checkedId) { + R.id.radioButton1 -> isUrgent = "1" + R.id.radioButton2 -> isUrgent = "0" + } } //选择样品 selectSampleButton.setOnClickListener { - + selectSampleLauncher.launch(Intent(this, SelectSampleActivity::class.java)) } //写入样品信息 @@ -55,14 +214,68 @@ } pushEntrustView.setOnClickListener { - Log.d("Casic", "EntrustAddActivity => initEvent: ${checkedItems.toJson()}") + val sender = senderView.text.toString() + if (sender.isBlank()) { + "请填写送样人名字".show(this) + return@setOnClickListener + } + + val contact = contactView.text.toString() + if (contact.isBlank()) { + "请填写送样人联系方式".show(this) + return@setOnClickListener + } + + val estimateTime = estimateTimeView.text.toString() + if (estimateTime.isBlank()) { + "请选择预计送到的时间".show(this) + return@setOnClickListener + } + + val entrustName = entrustNameView.text.toString() + if (entrustName.isBlank()) { + "请选择委托方".show(this) + return@setOnClickListener + } + + if (sampleModels == null) { + "请选择样品".show(this) + return@setOnClickListener + } + entrustViewModel.addEntrust( + sender, + contact, + createEntrustDateView.text.toString(), + estimateTime, + completedView.text.toString(), + entrustName, + entrustContactView.text.toString(), + entrustAddressView.text.toString(), + remarkView.text.toString(), + annexView.text.toString(), + checkedItems.reformat(), + isUrgent, + sampleModels!! + ) } } override fun initLayoutView(): Int = R.layout.activity_entrust_add override fun observeRequestState() { + fileUploadViewModel.loadState.observe(this) { + when (it) { + LoadState.Loading -> LoadingDialogHub.show(this, "文件上传中,请稍后...") + else -> LoadingDialogHub.dismiss() + } + } + entrustViewModel.loadState.observe(this) { + when (it) { + LoadState.Loading -> LoadingDialogHub.show(this, "委托创建中,请稍后...") + else -> LoadingDialogHub.dismiss() + } + } } override fun setupTopBarLayout() { @@ -70,4 +283,62 @@ initLayoutImmersionBar(rootView) titleView.text = "委托需求" } + + private fun uploadFile() { +// val explorer = FileExplorer(this) +// explorer.setInitDir(ExplorerMode.FILE, Environment.getExternalStorageDirectory()) +// explorer.setShowHomeDir(true) +// explorer.setShowUpDir(true) +// explorer.setShowHideDir(true) +// explorer.setAllowExtensions(arrayOf(".doc", ".docx", ".xls", ".xlsx", ".pdf")) +// explorer.setOnFileClickedListener { +// val type = if (it.name.endsWith(".doc") || it.name.endsWith(".docx")) { +// FileType.WORD +// } else if (it.name.endsWith(".pdf")) { +// FileType.PDF +// } else { +// FileType.UNKNOWN +// } +// +// Log.d("Casic", "EntrustAddActivity => uploadFile: ${it.absolutePath}") +// fileUploadViewModel.uploadFile(it, type) +// } + } + + private fun uploadImage() { + PictureSelector.create(this) + .openGallery(SelectMimeType.ofImage()) + .isGif(false) + .isMaxSelectEnabledMask(true) + .setFilterMinFileSize(100) + .setMaxSelectNum(1) + .isDisplayCamera(false) + .setImageEngine(GlideLoadEngine.instance) + .forResult(object : OnResultCallbackListener { + override fun onResult(result: ArrayList?) { + if (result == null) { + "选择照片失败,请重试".show(context) + return + } + result[0].realPath.compressImage(context, object : OnImageCompressListener { + override fun onSuccess(file: File) { + Log.d( + "Casic", "EntrustAddActivity => onSuccess: ${file.absolutePath}" + ) + ///storage/emulated/0/Android/data/com.casic.xz.meterage/files/Pictures/CompressImage/1677478115391211.jpeg + //上传图片 + fileUploadViewModel.uploadFile(file, FileType.IMAGE) + } + + override fun onError(e: Throwable) { + e.printStackTrace() + } + }) + } + + override fun onCancel() { + + } + }) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/view/home/SelectCustomerActivity.kt b/app/src/main/java/com/casic/xz/meterage/view/home/SelectCustomerActivity.kt new file mode 100644 index 0000000..9bf6a1a --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/view/home/SelectCustomerActivity.kt @@ -0,0 +1,158 @@ +package com.casic.xz.meterage.view.home + +import android.content.Intent +import android.os.Handler +import androidx.lifecycle.ViewModelProvider +import androidx.recyclerview.widget.DefaultItemAnimator +import androidx.recyclerview.widget.DividerItemDecoration +import com.casic.xz.meterage.R +import com.casic.xz.meterage.adapter.SelectCustomerAdapter +import com.casic.xz.meterage.extensions.initLayoutImmersionBar +import com.casic.xz.meterage.extensions.showEmptyPage +import com.casic.xz.meterage.model.CustomerListModel +import com.casic.xz.meterage.utils.LoadingDialogHub +import com.casic.xz.meterage.vm.CustomerViewModel +import com.gyf.immersionbar.ImmersionBar +import com.pengxh.kt.lite.base.KotlinBaseActivity +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.utils.WeakReferenceHandler +import com.pengxh.kt.lite.vm.LoadState +import kotlinx.android.synthetic.main.activity_select_customer.* +import kotlinx.android.synthetic.main.include_base_title.* +import kotlinx.android.synthetic.main.include_empty_view.* + +class SelectCustomerActivity : KotlinBaseActivity() { + + private lateinit var weakReferenceHandler: WeakReferenceHandler + private lateinit var customerViewModel: CustomerViewModel + private lateinit var selectCustomerAdapter: SelectCustomerAdapter + private var dataBeans: MutableList = ArrayList() + private var pageIndex = 1 + private var isRefresh = false + private var isLoadMore = false + private var customerModel: CustomerListModel.DataModel.RowsModel? = null + + override fun initData() { + weakReferenceHandler = WeakReferenceHandler(callback) + customerViewModel = ViewModelProvider(this)[CustomerViewModel::class.java] + customerViewModel.customerList.observe(this) { + if (it.code == 200) { + val dataRows = it.data?.rows!! + when { + isRefresh -> { + dataBeans.clear() + dataBeans = dataRows + customerLayout.finishRefresh() + isRefresh = false + } + isLoadMore -> { + if (dataRows.size == 0) { + "到底了,别拉了".show(this) + } + dataBeans.addAll(dataRows) + customerLayout.finishLoadMore() + isLoadMore = false + } + else -> { + dataBeans = dataRows + } + } + weakReferenceHandler.sendEmptyMessage(2023022701) + } + } + } + + override fun initEvent() { + leftBackView.setOnClickListener { + if (customerModel == null) { + "请选择委托方".show(this) + return@setOnClickListener + } + val intent = Intent() + intent.putExtra("entrustName", customerModel!!.customerName) + intent.putExtra("entrustContact", customerModel!!.phone) + intent.putExtra("entrustAddress", customerModel!!.fullAddress) + setResult(RESULT_OK, intent) + finish() + } + + customerLayout.setOnRefreshListener { + isRefresh = true + //刷新之后页码重置 + pageIndex = 1 + getCustomerList() + } + + customerLayout.setOnLoadMoreListener { + isLoadMore = true + pageIndex++ + getCustomerList() + } + } + + override fun initLayoutView(): Int = R.layout.activity_select_customer + + override fun observeRequestState() { + customerViewModel.loadState.observe(this) { + when (it) { + LoadState.Loading -> LoadingDialogHub.show(this, "数据加载中...") + else -> LoadingDialogHub.dismiss() + } + } + } + + override fun setupTopBarLayout() { + ImmersionBar.with(this).statusBarDarkFont(true).init() + initLayoutImmersionBar(rootView) + titleView.text = "客户列表" + } + + override fun onResume() { + super.onResume() + pageIndex = 1 + getCustomerList() + } + + private fun getCustomerList() { + customerViewModel.getCustomerList( + "", + "", + "", + "", + pageIndex + ) + } + + private val callback = Handler.Callback { + when (it.what) { + 2023022701 -> { + if (isRefresh || isLoadMore) { + selectCustomerAdapter.notifyDataSetChanged() + } else { + if (dataBeans.size == 0) { + emptyView!!.showEmptyPage("无客户数据") { + pageIndex = 1 + getCustomerList() + } + } else { + emptyView!!.hide() + selectCustomerAdapter = SelectCustomerAdapter(this, dataBeans) + customerRecyclerView.addItemDecoration( + DividerItemDecoration(this, DividerItemDecoration.VERTICAL) + ) + (customerRecyclerView.itemAnimator as DefaultItemAnimator).supportsChangeAnimations = + false + customerRecyclerView.adapter = selectCustomerAdapter + selectCustomerAdapter.setOnCheckedListener(object : + SelectCustomerAdapter.OnItemCheckedListener { + override fun onItemChecked(item: CustomerListModel.DataModel.RowsModel) { + customerModel = item + } + }) + } + } + } + } + true + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/view/home/SelectSampleActivity.kt b/app/src/main/java/com/casic/xz/meterage/view/home/SelectSampleActivity.kt new file mode 100644 index 0000000..f85cb44 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/view/home/SelectSampleActivity.kt @@ -0,0 +1,152 @@ +package com.casic.xz.meterage.view.home + +import android.content.Intent +import android.os.Handler +import androidx.lifecycle.ViewModelProvider +import androidx.recyclerview.widget.DefaultItemAnimator +import androidx.recyclerview.widget.DividerItemDecoration +import com.casic.xz.meterage.R +import com.casic.xz.meterage.adapter.SelectSampleAdapter +import com.casic.xz.meterage.extensions.initLayoutImmersionBar +import com.casic.xz.meterage.extensions.showEmptyPage +import com.casic.xz.meterage.model.SampleListModel +import com.casic.xz.meterage.vm.SampleViewModel +import com.gyf.immersionbar.ImmersionBar +import com.pengxh.kt.lite.base.KotlinBaseActivity +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.extensions.toJson +import com.pengxh.kt.lite.utils.WeakReferenceHandler +import kotlinx.android.synthetic.main.activity_select_sample.* +import kotlinx.android.synthetic.main.include_base_title.* +import kotlinx.android.synthetic.main.include_empty_view.* + +class SelectSampleActivity : KotlinBaseActivity() { + + private lateinit var weakReferenceHandler: WeakReferenceHandler + private lateinit var sampleViewModel: SampleViewModel + private lateinit var selectSampleAdapter: SelectSampleAdapter + private var dataBeans: MutableList = ArrayList() + private var pageIndex = 1 + private var isRefresh = false + private var isLoadMore = false + private var sampleModels = ArrayList() + + override fun initData() { + weakReferenceHandler = WeakReferenceHandler(callback) + sampleViewModel = ViewModelProvider(this)[SampleViewModel::class.java] + sampleViewModel.sampleList.observe(this) { + if (it.code == 200) { + val dataRows = it.data?.rows!! + when { + isRefresh -> { + dataBeans.clear() + dataBeans = dataRows + sampleLayout.finishRefresh() + isRefresh = false + } + isLoadMore -> { + if (dataRows.size == 0) { + "到底了,别拉了".show(this) + } + dataBeans.addAll(dataRows) + sampleLayout.finishLoadMore() + isLoadMore = false + } + else -> { + dataBeans = dataRows + } + } + weakReferenceHandler.sendEmptyMessage(2023030101) + } + } + } + + override fun initEvent() { + leftBackView.setOnClickListener { + val intent = Intent() + intent.putExtra("sampleModels", sampleModels.toJson()) + setResult(RESULT_OK, intent) + finish() + } + + sampleLayout.setOnRefreshListener { + isRefresh = true + //刷新之后页码重置 + pageIndex = 1 + getSampleList() + } + + sampleLayout.setOnLoadMoreListener { + isLoadMore = true + pageIndex++ + getSampleList() + } + } + + override fun initLayoutView(): Int = R.layout.activity_select_sample + + override fun observeRequestState() { + + } + + override fun setupTopBarLayout() { + ImmersionBar.with(this).statusBarDarkFont(true).init() + initLayoutImmersionBar(rootView) + titleView.text = "样品列表" + } + + override fun onResume() { + super.onResume() + pageIndex = 1 + getSampleList() + } + + private fun getSampleList() { + sampleViewModel.getSampleList( + "", + "", + "", + "", + "", + "", + "", + "", + "", + arrayOf(), + pageIndex + ) + } + + private val callback = Handler.Callback { + when (it.what) { + 2023030101 -> { + if (isRefresh || isLoadMore) { + selectSampleAdapter.notifyDataSetChanged() + } else { + if (dataBeans.size == 0) { + emptyView!!.showEmptyPage("无样品数据") { + pageIndex = 1 + getSampleList() + } + } else { + emptyView!!.hide() + selectSampleAdapter = SelectSampleAdapter(this, dataBeans) + sampleRecyclerView.addItemDecoration( + DividerItemDecoration(this, DividerItemDecoration.VERTICAL) + ) + (sampleRecyclerView.itemAnimator as DefaultItemAnimator).supportsChangeAnimations = + false + sampleRecyclerView.adapter = selectSampleAdapter + selectSampleAdapter.setOnCheckedListener(object : + SelectSampleAdapter.OnItemCheckedListener { + override fun onItemChecked(items: ArrayList) { + sampleModels = items + } + }) + } + } + } + } + true + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/view/notice/NoticeDetailActivity.kt b/app/src/main/java/com/casic/xz/meterage/view/notice/NoticeDetailActivity.kt index a9d9422..9596985 100644 --- a/app/src/main/java/com/casic/xz/meterage/view/notice/NoticeDetailActivity.kt +++ b/app/src/main/java/com/casic/xz/meterage/view/notice/NoticeDetailActivity.kt @@ -1,6 +1,7 @@ package com.casic.xz.meterage.view.notice import android.annotation.SuppressLint +import android.graphics.Color import android.graphics.Paint import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R @@ -10,7 +11,6 @@ import com.casic.xz.meterage.vm.NoticeViewModel import com.gyf.immersionbar.ImmersionBar import com.pengxh.kt.lite.base.KotlinBaseActivity -import com.pengxh.kt.lite.extensions.convertColor import com.pengxh.kt.lite.extensions.obtainScreenWidth import com.pengxh.kt.lite.utils.Constant import kotlinx.android.synthetic.main.activity_notice_detail.* @@ -54,7 +54,7 @@ val textPaint = minioFileView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - minioFileView.setTextColor(R.color.themeColor.convertColor(this)) + minioFileView.setTextColor(Color.BLUE) minioFileView.setOnClickListener { minioFileName.watchAttachFile(this) diff --git a/app/build.gradle b/app/build.gradle index 0ae369f..687b02b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -15,7 +15,6 @@ } compileSdkVersion 31 - buildToolsVersion "30.0.3" defaultConfig { applicationId "com.casic.xz.meterage" @@ -84,11 +83,13 @@ implementation 'top.zibin:Luban:1.1.8' //官方Json解析库 implementation 'com.google.code.gson:gson:2.9.0' + //阿里巴巴JSON库 + implementation 'com.alibaba.fastjson2:fastjson2:2.0.24' //Kotlin协程 implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.5.1' //MVVM+LiveData implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.5.1" - implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.0" + implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1" implementation "androidx.lifecycle:lifecycle-extensions:2.2.0" //返回值转换器 implementation 'com.jakewharton.retrofit:retrofit2-kotlin-coroutines-adapter:0.9.2' @@ -109,4 +110,8 @@ implementation 'com.github.barteksc:android-pdf-viewer:2.8.2' //绕过Android 11反射限制 implementation 'com.github.tiann:FreeReflection:3.1.0' + //单项/数字、二三级联动、日期/时间等滚轮选择器 + implementation 'com.github.gzu-liyujiang.AndroidPicker:WheelPicker:4.1.8' + //文件/目录选择器 + implementation 'com.github.gzu-liyujiang.AndroidPicker:FilePicker:4.1.1' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 1ccc12b..0fba91b 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -60,6 +60,8 @@ + + diff --git a/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt b/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt new file mode 100644 index 0000000..21a71d8 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt @@ -0,0 +1,70 @@ +package com.casic.xz.meterage.adapter + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import com.casic.xz.meterage.R +import com.casic.xz.meterage.extensions.toChineseGrade +import com.casic.xz.meterage.model.CustomerListModel + +class SelectCustomerAdapter( + context: Context, private val dataRows: MutableList +) : RecyclerView.Adapter() { + + private var layoutInflater = LayoutInflater.from(context) + + //选择的位置 + private var selectedPosition = 0 + + //临时记录上次选择的位置 + private var temp = -1 + + override fun getItemCount(): Int = dataRows.size + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ItemViewHolder( + layoutInflater.inflate(R.layout.item_select_customer_lv, parent, false) + ) + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + //绑定数据 + val rowsBean = dataRows[position] + holder.agreementLevelView.text = rowsBean.grade.toChineseGrade() + holder.customerNameView.text = rowsBean.customerName + holder.scaleView.text = rowsBean.companySizeName + holder.overallView.text = "公司规模:${rowsBean.evaluationName}" + holder.fullAddressView.text = "公司地址:${rowsBean.fullAddress}" + + holder.itemView.isSelected = holder.layoutPosition == selectedPosition + holder.itemView.setOnClickListener { + itemCheckedListener?.onItemChecked(rowsBean) + + holder.itemView.isSelected = true + temp = selectedPosition + //设置新的位置 + selectedPosition = holder.layoutPosition + //更新旧位置 + notifyItemChanged(temp) + } + } + + inner class ItemViewHolder(view: View) : RecyclerView.ViewHolder(view) { + var agreementLevelView: TextView = view.findViewById(R.id.agreementLevelView) + var customerNameView: TextView = view.findViewById(R.id.customerNameView) + var scaleView: TextView = view.findViewById(R.id.scaleView) + var overallView: TextView = view.findViewById(R.id.overallView) + var fullAddressView: TextView = view.findViewById(R.id.fullAddressView) + } + + private var itemCheckedListener: OnItemCheckedListener? = null + + interface OnItemCheckedListener { + fun onItemChecked(item: CustomerListModel.DataModel.RowsModel) + } + + fun setOnCheckedListener(listener: OnItemCheckedListener?) { + itemCheckedListener = listener + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt b/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt new file mode 100644 index 0000000..c29461e --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt @@ -0,0 +1,68 @@ +package com.casic.xz.meterage.adapter + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import com.casic.xz.meterage.R +import com.casic.xz.meterage.model.SampleListModel + +class SelectSampleAdapter( + context: Context, private val dataRows: MutableList +) : RecyclerView.Adapter() { + + private var layoutInflater = LayoutInflater.from(context) + private var multipleSelected = mutableSetOf() + private var sampleModes = ArrayList() + + override fun getItemCount(): Int = dataRows.size + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ItemViewHolder( + layoutInflater.inflate(R.layout.item_select_sample_lv, parent, false) + ) + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + //绑定数据 + val rowsBean = dataRows[position] + holder.sampleNameView.text = "${rowsBean.sampleName}【${rowsBean.sampleModel}】" + holder.manufacturingCodeView.text = "出厂编号:${rowsBean.manufacturingNo}" + holder.sampleCodeView.text = "样品编号:${rowsBean.sampleNo}" + holder.validDateView.text = "有效期至:${rowsBean.validDeadline}" + + holder.checkImageView.isSelected = multipleSelected.contains(position) + holder.itemView.setOnClickListener { + if (multipleSelected.contains(position)) { + multipleSelected.remove(position) + sampleModes.remove(dataRows[position]) + holder.checkImageView.isSelected = false + } else { + multipleSelected.add(position) + sampleModes.add(dataRows[position]) + holder.checkImageView.isSelected = true + } + + itemCheckedListener?.onItemChecked(sampleModes) + } + } + + inner class ItemViewHolder(view: View) : RecyclerView.ViewHolder(view) { + var sampleNameView: TextView = view.findViewById(R.id.sampleNameView) + var manufacturingCodeView: TextView = view.findViewById(R.id.manufacturingCodeView) + var sampleCodeView: TextView = view.findViewById(R.id.sampleCodeView) + var validDateView: TextView = view.findViewById(R.id.validDateView) + var checkImageView: ImageView = view.findViewById(R.id.checkImageView) + } + + private var itemCheckedListener: OnItemCheckedListener? = null + + interface OnItemCheckedListener { + fun onItemChecked(items: ArrayList) + } + + fun setOnCheckedListener(listener: OnItemCheckedListener?) { + itemCheckedListener = listener + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/callback/DateSelectedCallback.kt b/app/src/main/java/com/casic/xz/meterage/callback/DateSelectedCallback.kt new file mode 100644 index 0000000..8196110 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/callback/DateSelectedCallback.kt @@ -0,0 +1,5 @@ +package com.casic.xz.meterage.callback + +interface DateSelectedCallback { + fun onDateSelected(date: String) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/Activity.kt b/app/src/main/java/com/casic/xz/meterage/extensions/Activity.kt new file mode 100644 index 0000000..e112d1c --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/extensions/Activity.kt @@ -0,0 +1,33 @@ +package com.casic.xz.meterage.extensions + +import android.app.Activity +import com.casic.xz.meterage.R +import com.casic.xz.meterage.callback.DateSelectedCallback +import com.github.gzuliyujiang.wheelpicker.DatePicker +import com.github.gzuliyujiang.wheelpicker.annotation.DateMode +import com.github.gzuliyujiang.wheelpicker.entity.DateEntity +import com.pengxh.kt.lite.extensions.convertColor +import com.pengxh.kt.lite.extensions.sp2px + +fun Activity.showDatePicker(callback: DateSelectedCallback) { + val datePicker = DatePicker(this) + + val layout = datePicker.wheelLayout + layout.setDateMode(DateMode.YEAR_MONTH_DAY) + layout.setDateLabel("年", "月", "日"); + layout.setTextSize(14f.sp2px(this).toFloat()) + layout.setSelectedTextSize(16f.sp2px(this).toFloat()) + layout.setSelectedTextColor(R.color.themeColor.convertColor(this)) + layout.setSelectedTextBold(true) + layout.setResetWhenLinkage(false) + layout.setRange( + DateEntity.today(), + DateEntity.target(2050, 12, 31), + DateEntity.today() + ) + + datePicker.setOnDatePickedListener { year, month, day -> + callback.onDateSelected(String.format("%s-%s-%s", year, month, day)) + } + datePicker.show() +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt b/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt index 016ebcb..cf6bf49 100644 --- a/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt +++ b/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt @@ -4,7 +4,7 @@ * ArrayList扩展方法 */ -//将图片集合格式化成满足上传格式的数据 +//将集合格式化成满足上传格式的数据 fun ArrayList.reformat(): String { if (this.isEmpty()) return "" val builder = StringBuilder() diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt b/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt index 7c57643..aa9b92b 100644 --- a/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt +++ b/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt @@ -1,7 +1,6 @@ package com.casic.xz.meterage.extensions import android.content.Context -import android.util.Log import android.view.ViewGroup import com.casic.xz.meterage.base.BaseApplication import com.pengxh.kt.lite.extensions.dp2px @@ -9,9 +8,8 @@ fun Context.initLayoutImmersionBar(rootView: ViewGroup) { var statusBarHeight = QMUIDisplayHelper.getStatusBarHeight(this) - Log.d("Casic", "状态栏高度: $statusBarHeight") if (statusBarHeight == 0) { - statusBarHeight = 44f.dp2px(BaseApplication.get()) + statusBarHeight = 40f.dp2px(BaseApplication.get()) } rootView.setPadding(0, statusBarHeight, 0, 0) rootView.requestLayout() diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/String.kt b/app/src/main/java/com/casic/xz/meterage/extensions/String.kt index 28f70d8..6234d43 100644 --- a/app/src/main/java/com/casic/xz/meterage/extensions/String.kt +++ b/app/src/main/java/com/casic/xz/meterage/extensions/String.kt @@ -128,9 +128,10 @@ fun String.combineImagePath(): String { if (this.isEmpty()) return this val defaultValue = SaveKeyValues.getValue( - LocaleConstant.DEFAULT_SERVER_CONFIG, LocaleConstant.SERVER_BASE_URL + LocaleConstant.FILE_SERVER_CONFIG, LocaleConstant.File_SERVER_URL ) as String - return "$defaultValue/static/${this.replace("\\", "/")}" + //http://111.198.10.15:21408/test/1677479806059688_1677479806038.jpeg + return "$defaultValue/test/${this.replace("\\", "/")}" } fun String.isEarlier(time: String): Boolean { diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt index 25fa87b..a0e1358 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt @@ -1,18 +1,12 @@ package com.casic.xz.meterage.fragment.customer +import android.graphics.Color import android.graphics.Paint import com.casic.xz.meterage.R -import com.casic.xz.meterage.extensions.combineImagePath import com.casic.xz.meterage.extensions.toChineseGrade +import com.casic.xz.meterage.extensions.watchAttachFile import com.casic.xz.meterage.model.CustomerDetailModel -import com.casic.xz.meterage.view.BigImageActivity -import com.casic.xz.meterage.view.notice.PreviewDocumentActivity -import com.casic.xz.meterage.view.notice.PreviewPdfActivity -import com.casic.xz.meterage.view.notice.PreviewTextActivity import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.extensions.show import kotlinx.android.synthetic.main.fragment_customer_basic_information.* class BasicInformationFragment(private val data: CustomerDetailModel.DataModel) : @@ -48,30 +42,11 @@ val textPaint = minioFileView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - minioFileView.setTextColor(R.color.themeColor.convertColor(requireContext())) + minioFileView.setTextColor(Color.BLUE) minioFileView.setOnClickListener { //查看附件 - if (minioFileName.endsWith("pdf")) { - requireContext().navigatePageTo(minioFileName) - } else if ( - minioFileName.endsWith("doc") || - minioFileName.endsWith("docx") - ) { - requireContext().navigatePageTo(minioFileName) - } else if (minioFileName.endsWith("txt")) { - requireContext().navigatePageTo(minioFileName) - } else if ( - minioFileName.endsWith("png") || - minioFileName.endsWith("jpeg") || - minioFileName.endsWith("jpg") - ) { - val urls = ArrayList() - urls.add(minioFileName.combineImagePath()) - requireContext().navigatePageTo(0, urls) - } else { - "文件类型未知,无法打开附件".show(requireContext()) - } + minioFileName.watchAttachFile(requireContext()) } } } diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt index 77846b4..3a0fe2e 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt @@ -1,5 +1,6 @@ package com.casic.xz.meterage.fragment.device +import android.graphics.Color import android.graphics.Paint import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R @@ -7,7 +8,6 @@ import com.casic.xz.meterage.utils.LoadingDialogHub import com.casic.xz.meterage.vm.EquipmentViewModel import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor import com.pengxh.kt.lite.vm.LoadState import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import kotlinx.android.synthetic.main.fragment_device_basic_information.* @@ -56,7 +56,7 @@ val textPaint = documentsView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - documentsView.setTextColor(R.color.themeColor.convertColor(requireContext())) + documentsView.setTextColor(Color.BLUE) val files = ArrayList() data.fileList.forEach { file -> @@ -66,7 +66,7 @@ BottomActionSheet.Builder() .setContext(requireContext()) .setActionItemTitle(files) - .setItemTextColor(R.color.themeColor.convertColor(requireContext())) + .setItemTextColor(Color.BLUE) .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { override fun onActionItemClick(position: Int) { diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt index 15dc3d2..10eeff8 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt @@ -1,5 +1,6 @@ package com.casic.xz.meterage.fragment.entrust +import android.graphics.Color import android.graphics.Paint import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R @@ -9,7 +10,6 @@ import com.casic.xz.meterage.model.EntrustDetailModel import com.casic.xz.meterage.vm.DictionaryViewModel import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor import kotlinx.android.synthetic.main.fragment_entrust_basic_information.* class BasicInformationFragment(private val data: EntrustDetailModel.DataModel) : @@ -38,7 +38,7 @@ val textPaint = annexView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - annexView.setTextColor(R.color.themeColor.convertColor(requireContext())) + annexView.setTextColor(Color.BLUE) annexView.setOnClickListener { minioFileName.watchAttachFile(requireContext()) @@ -59,9 +59,9 @@ //加急 if (data.isUrgent == "0") { - RadioButton2.isChecked = true + radioButton2.isChecked = true } else { - RadioButton1.isChecked = true + radioButton1.isChecked = true } //样品 diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/equipment/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/equipment/BasicInformationFragment.kt index 72b523c..7bc3b01 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/equipment/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/equipment/BasicInformationFragment.kt @@ -1,5 +1,6 @@ package com.casic.xz.meterage.fragment.equipment +import android.graphics.Color import android.graphics.Paint import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R @@ -7,7 +8,6 @@ import com.casic.xz.meterage.utils.LoadingDialogHub import com.casic.xz.meterage.vm.EquipmentViewModel import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor import com.pengxh.kt.lite.vm.LoadState import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import kotlinx.android.synthetic.main.fragment_equipment_basic_information.* @@ -74,7 +74,7 @@ val textPaint = instructionsView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - instructionsView.setTextColor(R.color.themeColor.convertColor(requireContext())) + instructionsView.setTextColor(Color.BLUE) val files = ArrayList() data.fileList.forEach { file -> @@ -84,7 +84,7 @@ BottomActionSheet.Builder() .setContext(requireContext()) .setActionItemTitle(files) - .setItemTextColor(R.color.themeColor.convertColor(requireContext())) + .setItemTextColor(Color.BLUE) .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { override fun onActionItemClick(position: Int) { diff --git a/app/src/main/java/com/casic/xz/meterage/model/SampleListModel.java b/app/src/main/java/com/casic/xz/meterage/model/SampleListModel.java new file mode 100644 index 0000000..5784343 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/model/SampleListModel.java @@ -0,0 +1,193 @@ +package com.casic.xz.meterage.model; + +import java.util.List; + +public class SampleListModel { + + private int code; + private DataModel data; + private String message; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataModel getData() { + return data; + } + + public void setData(DataModel data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public static class DataModel { + private List rows; + private int total; + + public List getRows() { + return rows; + } + + public void setRows(List rows) { + this.rows = rows; + } + + public int getTotal() { + return total; + } + + public void setTotal(int total) { + this.total = total; + } + + public static class RowsModel { + private String certificationStatus; + private String customerName; + private String customerNo; + private String id; + private String manufacturingNo; + private String measureLastTime; + private String measurePeriod; + private String orderId; + private String remark; + private String sampleModel; + private String sampleName; + private String sampleNo; + private String sampleSatus; + private String sampleSatusName; + private String validDeadline; + + public String getCertificationStatus() { + return certificationStatus; + } + + public void setCertificationStatus(String certificationStatus) { + this.certificationStatus = certificationStatus; + } + + public String getCustomerName() { + return customerName; + } + + public void setCustomerName(String customerName) { + this.customerName = customerName; + } + + public String getCustomerNo() { + return customerNo; + } + + public void setCustomerNo(String customerNo) { + this.customerNo = customerNo; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getManufacturingNo() { + return manufacturingNo; + } + + public void setManufacturingNo(String manufacturingNo) { + this.manufacturingNo = manufacturingNo; + } + + public String getMeasureLastTime() { + return measureLastTime; + } + + public void setMeasureLastTime(String measureLastTime) { + this.measureLastTime = measureLastTime; + } + + public String getMeasurePeriod() { + return measurePeriod; + } + + public void setMeasurePeriod(String measurePeriod) { + this.measurePeriod = measurePeriod; + } + + public String getOrderId() { + return orderId; + } + + public void setOrderId(String orderId) { + this.orderId = orderId; + } + + public String getRemark() { + return remark; + } + + public void setRemark(String remark) { + this.remark = remark; + } + + public String getSampleModel() { + return sampleModel; + } + + public void setSampleModel(String sampleModel) { + this.sampleModel = sampleModel; + } + + public String getSampleName() { + return sampleName; + } + + public void setSampleName(String sampleName) { + this.sampleName = sampleName; + } + + public String getSampleNo() { + return sampleNo; + } + + public void setSampleNo(String sampleNo) { + this.sampleNo = sampleNo; + } + + public String getSampleSatus() { + return sampleSatus; + } + + public void setSampleSatus(String sampleSatus) { + this.sampleSatus = sampleSatus; + } + + public String getSampleSatusName() { + return sampleSatusName; + } + + public void setSampleSatusName(String sampleSatusName) { + this.sampleSatusName = sampleSatusName; + } + + public String getValidDeadline() { + return validDeadline; + } + + public void setValidDeadline(String validDeadline) { + this.validDeadline = validDeadline; + } + } + } +} diff --git a/app/src/main/java/com/casic/xz/meterage/model/UploadResultModel.java b/app/src/main/java/com/casic/xz/meterage/model/UploadResultModel.java new file mode 100644 index 0000000..f2a6a41 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/model/UploadResultModel.java @@ -0,0 +1,34 @@ +package com.casic.xz.meterage.model; + +import java.util.List; + +public class UploadResultModel { + + private int code; + private List data; + private String message; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public List getData() { + return data; + } + + public void setData(List data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } +} diff --git a/app/src/main/java/com/casic/xz/meterage/utils/FileType.kt b/app/src/main/java/com/casic/xz/meterage/utils/FileType.kt new file mode 100644 index 0000000..17e2bca --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/utils/FileType.kt @@ -0,0 +1,23 @@ +package com.casic.xz.meterage.utils + +sealed class FileType { + /** + * PDF文件 + */ + object PDF : FileType() + + /** + * WORD文件 + */ + object WORD : FileType() + + /** + * IMAGE图片 + */ + object IMAGE : FileType() + + /** + * 未知类型(Excel) + */ + object UNKNOWN : FileType() +} diff --git a/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitService.kt index bc3f8d6..8f4fe44 100644 --- a/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitService.kt @@ -1,5 +1,6 @@ package com.casic.xz.meterage.utils.retrofit +import okhttp3.MultipartBody import okhttp3.RequestBody import retrofit2.http.* @@ -35,6 +36,16 @@ ): String /** + * 上传文件 + */ + @Multipart + @POST("/minio/file/upload") + suspend fun uploadFile( + @Header("token") token: String, + @Part file: MultipartBody.Part + ): String + + /** * 获取通知公告列表 */ @POST("/system/notice/listPage") @@ -209,4 +220,24 @@ @Header("token") token: String, @Body requestBody: RequestBody ): String + + /** + * 获取样品列表 + */ + @POST("/customer/sample/listPage") + suspend fun getSampleList( + @Header("token") token: String, + @Body requestBody: RequestBody, + @QueryMap limit: Map, + @QueryMap offset: Map + ): String + + /** + * 新增委托书 + */ + @POST("/business/order/add") + suspend fun addEntrust( + @Header("token") token: String, + @Body requestBody: RequestBody + ): String } \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitServiceManager.kt index cb22e45..90abe5a 100644 --- a/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitServiceManager.kt @@ -1,13 +1,20 @@ package com.casic.xz.meterage.utils.retrofit +import com.alibaba.fastjson2.JSON +import com.alibaba.fastjson2.JSONArray +import com.alibaba.fastjson2.JSONObject +import com.casic.xz.meterage.model.SampleListModel import com.casic.xz.meterage.utils.AuthenticationHelper +import com.casic.xz.meterage.utils.FileType import com.casic.xz.meterage.utils.LocaleConstant import com.pengxh.kt.lite.utils.RetrofitFactory import com.pengxh.kt.lite.utils.SaveKeyValues import okhttp3.MediaType.Companion.toMediaType +import okhttp3.MediaType.Companion.toMediaTypeOrNull +import okhttp3.MultipartBody +import okhttp3.RequestBody.Companion.asRequestBody import okhttp3.RequestBody.Companion.toRequestBody -import org.json.JSONArray -import org.json.JSONObject +import java.io.File object RetrofitServiceManager { @@ -31,9 +38,9 @@ */ suspend fun login(sid: String, account: String, secretKey: String): String { val paramObject = JSONObject() - paramObject.put("sid", sid) - paramObject.put("username", account) - paramObject.put("password", secretKey) + paramObject["sid"] = sid + paramObject["username"] = account + paramObject["password"] = secretKey val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -55,6 +62,20 @@ } /** + * 上传文件 + */ + suspend fun uploadFile(file: File, type: FileType): String { + val requestBody = when (type) { + FileType.PDF -> file.asRequestBody("application/pdf".toMediaTypeOrNull()) + FileType.WORD -> file.asRequestBody("application/msword".toMediaTypeOrNull()) + FileType.IMAGE -> file.asRequestBody("image/png".toMediaTypeOrNull()) + else -> file.asRequestBody("application/vnd.ms-excel".toMediaTypeOrNull()) + } + val filePart = MultipartBody.Part.createFormData("multipartFile", file.name, requestBody) + return api.uploadFile(AuthenticationHelper.token!!, filePart) + } + + /** * 获取通知公告列表 */ suspend fun getNoticeList( @@ -66,11 +87,11 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("noticeNo", noticeNo) - paramObject.put("noticeTitle", noticeTitle) - paramObject.put("noticePublisher", noticePublisher) - paramObject.put("noticeStartTime", noticeStartTime) - paramObject.put("noticeEndTime", noticeEndTime) + paramObject["noticeNo"] = noticeNo + paramObject["noticeTitle"] = noticeTitle + paramObject["noticePublisher"] = noticePublisher + paramObject["noticeStartTime"] = noticeStartTime + paramObject["noticeEndTime"] = noticeEndTime val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -105,26 +126,21 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("equipmentNo", equipmentNo) - paramObject.put("equipmentName", equipmentName) - paramObject.put("mesureType", mesureType) - paramObject.put("managerState", managerState) - paramObject.put("useDept", useDept) - paramObject.put("assetType", assetType) - paramObject.put("equipmentCategory", equipmentCategory) - paramObject.put("isCalibrationTestEquipment", isCalibrationTestEquipment) - paramObject.put("isMeasureAccount", isMeasureAccount) - paramObject.put("isStandardSupportEquipment", isStandardSupportEquipment) - paramObject.put("isFixedAssets", isFixedAssets) - paramObject.put("validStartDate", validStartDate) - paramObject.put("validEndDate", validEndDate) - paramObject.put("abc", abc) - - val jsonArray = JSONArray() - ids.forEach { - jsonArray.put(it) - } - paramObject.put("ids", jsonArray) + paramObject["equipmentNo"] = equipmentNo + paramObject["equipmentName"] = equipmentName + paramObject["mesureType"] = mesureType + paramObject["managerState"] = managerState + paramObject["useDept"] = useDept + paramObject["assetType"] = assetType + paramObject["equipmentCategory"] = equipmentCategory + paramObject["isCalibrationTestEquipment"] = isCalibrationTestEquipment + paramObject["isMeasureAccount"] = isMeasureAccount + paramObject["isStandardSupportEquipment"] = isStandardSupportEquipment + paramObject["isFixedAssets"] = isFixedAssets + paramObject["validStartDate"] = validStartDate + paramObject["validEndDate"] = validEndDate + paramObject["abc"] = abc + paramObject["ids"] = JSONArray.parseArray(JSON.toJSONString(ids)) val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() @@ -143,7 +159,7 @@ */ suspend fun getEquipmentDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -164,13 +180,13 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("standardNo", standardNo) - paramObject.put("standardName", standardName) - paramObject.put("category", category) - paramObject.put("managerState", managerState) - paramObject.put("standardLaboratory", standardLaboratory) - paramObject.put("preparationDate", preparationDate) - paramObject.put("id", id) + paramObject["standardNo"] = standardNo + paramObject["standardName"] = standardName + paramObject["category"] = category + paramObject["managerState"] = managerState + paramObject["standardLaboratory"] = standardLaboratory + paramObject["preparationDate"] = preparationDate + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -193,7 +209,7 @@ */ suspend fun getStandardDeviceDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -212,11 +228,11 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("checkType", checkType) - paramObject.put("priceItem", priceItem) - paramObject.put("priceName", priceName) - paramObject.put("priceNo", priceNo) - paramObject.put("priceType", priceType) + paramObject["checkType"] = checkType + paramObject["priceItem"] = priceItem + paramObject["priceName"] = priceName + paramObject["priceNo"] = priceNo + paramObject["priceType"] = priceType val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -234,7 +250,7 @@ */ suspend fun getCapabilityDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -257,20 +273,15 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("createStartTime", createStartTime) - paramObject.put("createEndTime", createEndTime) - paramObject.put("deptId", deptId) - paramObject.put("director", director) - paramObject.put("effectiveCompany", effectiveCompany) - paramObject.put("trainStartTime", trainStartTime) - paramObject.put("trainEndTime", trainEndTime) - paramObject.put("formId", formId) - - val jsonArray = JSONArray() - ids.forEach { - jsonArray.put(it) - } - paramObject.put("ids", jsonArray) + paramObject["createStartTime"] = createStartTime + paramObject["createEndTime"] = createEndTime + paramObject["deptId"] = deptId + paramObject["director"] = director + paramObject["effectiveCompany"] = effectiveCompany + paramObject["trainStartTime"] = trainStartTime + paramObject["trainEndTime"] = trainEndTime + paramObject["formId"] = formId + paramObject["ids"] = JSONArray.parseArray(JSON.toJSONString(ids)) val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() @@ -294,7 +305,7 @@ */ suspend fun getMeterageTrainDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -308,10 +319,10 @@ bussinessSize: String, customerName: String, customerNo: String, grade: String, offset: Int ): String { val paramObject = JSONObject() - paramObject.put("bussinessSize", bussinessSize) - paramObject.put("customerName", customerName) - paramObject.put("customerNo", customerNo) - paramObject.put("grade", grade) + paramObject["bussinessSize"] = bussinessSize + paramObject["customerName"] = customerName + paramObject["customerNo"] = customerNo + paramObject["grade"] = grade val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() @@ -330,7 +341,7 @@ */ suspend fun getCustomerDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -342,7 +353,7 @@ */ suspend fun getStaffList(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -354,7 +365,7 @@ */ suspend fun getSupportEquipmentList(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -366,7 +377,7 @@ */ suspend fun getVerifyProcedureList(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -389,20 +400,15 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("customerName", customerName) - paramObject.put("customerNo", customerNo) - paramObject.put("deliverer", deliverer) - paramObject.put("orderCode", orderCode) - paramObject.put("startTime", startTime) - paramObject.put("endTime", endTime) - paramObject.put("isUrgent", isUrgent) - paramObject.put("status", status) - - val jsonArray = JSONArray() - ids.forEach { - jsonArray.put(it) - } - paramObject.put("ids", jsonArray) + paramObject["customerName"] = customerName + paramObject["customerNo"] = customerNo + paramObject["deliverer"] = deliverer + paramObject["orderCode"] = orderCode + paramObject["startTime"] = startTime + paramObject["endTime"] = endTime + paramObject["isUrgent"] = isUrgent + paramObject["status"] = status + paramObject["ids"] = JSONArray.parseArray(JSON.toJSONString(ids)) val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() @@ -421,7 +427,7 @@ */ suspend fun getEntrustDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -433,7 +439,7 @@ */ suspend fun acceptEntrust(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -446,10 +452,89 @@ */ suspend fun returnEntrust(id: String, selected: ArrayList): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) return api.returnEntrust(AuthenticationHelper.token!!, requestBody) } + + /** + * 获取样品列表 + */ + suspend fun getSampleList( + customerName: String, + customerNo: String, + startTime: String, + endTime: String, + sampleName: String, + sampleNo: String, + sampleModel: String, + sampleBelong: String, + overtimeStatus: String, + ids: Array, + offset: Int + ): String { + val paramObject = JSONObject() + paramObject["customerName"] = customerName + paramObject["customerNo"] = customerNo + paramObject["startTime"] = startTime + paramObject["endTime"] = endTime + paramObject["sampleName"] = sampleName + paramObject["sampleNo"] = sampleNo + paramObject["sampleModel"] = sampleModel + paramObject["sampleBelong"] = sampleBelong + paramObject["overtimeStatus"] = overtimeStatus + paramObject["ids"] = JSONArray.parseArray(JSON.toJSONString(ids)) + + val requestBody = paramObject.toString().toRequestBody( + "application/json;charset=UTF-8".toMediaType() + ) + + val limitMap = HashMap() + limitMap["limit"] = LocaleConstant.PAGE_LIMIT + + val offsetMap = HashMap() + offsetMap["offset"] = offset + return api.getSampleList(AuthenticationHelper.token!!, requestBody, limitMap, offsetMap) + } + + /** + * 新增委托书 + */ + suspend fun addEntrust( + deliverer: String, + delivererTel: String, + orderTime: String, + planDeliverTime: String, + requireOverTime: String, + customerName: String, + customerPhone: String, + customerAddress: String, + remark: String, + minioFileName: String, + certifications: String, + isUrgent: String, + samples: List + ): String { + val paramObject = JSONObject() + paramObject["deliverer"] = deliverer + paramObject["delivererTel"] = delivererTel + paramObject["orderTime"] = orderTime + paramObject["planDeliverTime"] = planDeliverTime + paramObject["requireOverTime"] = requireOverTime + paramObject["customerName"] = customerName + paramObject["customerPhone"] = customerPhone + paramObject["customerAddress"] = customerAddress + paramObject["remark"] = remark + paramObject["minioFileName"] = minioFileName + paramObject["certifications"] = certifications + paramObject["isUrgent"] = isUrgent + paramObject["customerSampleInfoList"] = JSONArray.parseArray(JSON.toJSONString(samples)) + + val requestBody = paramObject.toString().toRequestBody( + "application/json;charset=UTF-8".toMediaType() + ) + return api.addEntrust(AuthenticationHelper.token!!, requestBody) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/view/home/EntrustAddActivity.kt b/app/src/main/java/com/casic/xz/meterage/view/home/EntrustAddActivity.kt index 3e30095..9c8d27b 100644 --- a/app/src/main/java/com/casic/xz/meterage/view/home/EntrustAddActivity.kt +++ b/app/src/main/java/com/casic/xz/meterage/view/home/EntrustAddActivity.kt @@ -1,52 +1,211 @@ package com.casic.xz.meterage.view.home +import android.app.Activity +import android.content.Context +import android.content.Intent +import android.graphics.Color +import android.graphics.Paint import android.util.Log +import androidx.activity.result.ActivityResult +import androidx.activity.result.ActivityResultCallback +import androidx.activity.result.contract.ActivityResultContracts import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R import com.casic.xz.meterage.adapter.CertificateTypeAdapter2 -import com.casic.xz.meterage.extensions.initLayoutImmersionBar +import com.casic.xz.meterage.adapter.CustomerSampleAdapter +import com.casic.xz.meterage.callback.DateSelectedCallback +import com.casic.xz.meterage.callback.OnImageCompressListener +import com.casic.xz.meterage.extensions.* +import com.casic.xz.meterage.model.EntrustDetailModel +import com.casic.xz.meterage.model.SampleListModel +import com.casic.xz.meterage.utils.FileType +import com.casic.xz.meterage.utils.GlideLoadEngine +import com.casic.xz.meterage.utils.LoadingDialogHub import com.casic.xz.meterage.vm.DictionaryViewModel +import com.casic.xz.meterage.vm.EntrustViewModel +import com.casic.xz.meterage.vm.FileUploadViewModel +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken import com.gyf.immersionbar.ImmersionBar +import com.luck.picture.lib.basic.PictureSelector +import com.luck.picture.lib.config.SelectMimeType +import com.luck.picture.lib.entity.LocalMedia +import com.luck.picture.lib.interfaces.OnResultCallbackListener import com.pengxh.kt.lite.base.KotlinBaseActivity -import com.pengxh.kt.lite.extensions.toJson +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.vm.LoadState +import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import kotlinx.android.synthetic.main.activity_entrust_add.* +import java.io.File + class EntrustAddActivity : KotlinBaseActivity() { + private val context: Context = this@EntrustAddActivity + private val gson by lazy { Gson() } private lateinit var dictionaryViewModel: DictionaryViewModel - private var checkedItems = ArrayList() + private lateinit var fileUploadViewModel: FileUploadViewModel + private lateinit var entrustViewModel: EntrustViewModel + private lateinit var sampleAdapter: CustomerSampleAdapter + private var checkedItems = ArrayList() + private var isUrgent = "0" + private var sampleModels: ArrayList? = null + private var dataBeans = ArrayList() override fun initData() { //证书 dictionaryViewModel = ViewModelProvider(this)[DictionaryViewModel::class.java] dictionaryViewModel.getDictionaryByCode("certificationClass") - dictionaryViewModel.dictionary.observe(this) { dic -> - if (dic.code == 200) { - val typeAdapter2 = CertificateTypeAdapter2(this, dic.data) + dictionaryViewModel.dictionary.observe(this) { + if (it.code == 200) { + val typeAdapter2 = CertificateTypeAdapter2(this, it.data) typeRecyclerView.adapter = typeAdapter2 typeAdapter2.setOnItemCheckedListener(object : CertificateTypeAdapter2.OnItemCheckedListener { override fun onItemChecked(position: Int, isChecked: Boolean) { if (isChecked) { - checkedItems.add(position) + checkedItems.add(position.toString()) } else { - checkedItems.remove(position) + checkedItems.remove(position.toString()) } } }) } } + + fileUploadViewModel = ViewModelProvider(this)[FileUploadViewModel::class.java] + fileUploadViewModel.resultModel.observe(this) { + if (it.code == 200) { + val annexName = it.data[0] + annexView.text = annexName + val textPaint = annexView.paint + textPaint.flags = Paint.UNDERLINE_TEXT_FLAG + textPaint.isAntiAlias = true + annexView.setTextColor(Color.BLUE) + + annexView.setOnClickListener { + annexName.watchAttachFile(this) + } + } + } + + entrustViewModel = ViewModelProvider(this)[EntrustViewModel::class.java] + entrustViewModel.addResult.observe(this) { + if (it.code == 200) { + finish() + } + } + + //样品列表 + sampleAdapter = CustomerSampleAdapter(this, dataBeans) + sampleRecyclerView.adapter = sampleAdapter } + private val selectCustomerLauncher = + registerForActivityResult(ActivityResultContracts.StartActivityForResult(), + object : ActivityResultCallback { + override fun onActivityResult(result: ActivityResult?) { + if (result?.resultCode == Activity.RESULT_OK) { + val data = result.data ?: return + + entrustNameView.text = data.getStringExtra("entrustName") + entrustContactView.text = data.getStringExtra("entrustContact") + entrustAddressView.text = data.getStringExtra("entrustAddress") + } + } + }) + + private val selectSampleLauncher = + registerForActivityResult(ActivityResultContracts.StartActivityForResult(), + object : ActivityResultCallback { + override fun onActivityResult(result: ActivityResult?) { + if (result?.resultCode == Activity.RESULT_OK) { + val data = result.data ?: return + + val modelsJson = data.getStringExtra("sampleModels") + if (!modelsJson.isNullOrBlank()) { + sampleModels = gson.fromJson( + modelsJson, + object : + TypeToken>() {}.type + ) + } + + //刷新列表 + dataBeans.clear() + sampleModels?.forEach { + val model = + EntrustDetailModel.DataModel.CustomerSampleInfoListModel() + + model.customerName = it.customerName + model.customerNo = it.customerNo + model.id = it.id + model.manufacturingNo = it.manufacturingNo + model.measureLastTime = it.measureLastTime + model.measurePeriod = it.measurePeriod + model.orderId = it.orderId + model.remark = it.remark + model.sampleModel = it.sampleModel + model.sampleName = it.sampleName + model.sampleNo = it.sampleNo + model.validDeadline = it.validDeadline + + dataBeans.add(model) + } + sampleAdapter.notifyDataSetChanged() + } + } + }) + override fun initEvent() { + leftBackView.setOnClickListener { finish() } + + estimateTimeView.setOnClickListener { + showDatePicker(object : DateSelectedCallback { + override fun onDateSelected(date: String) { + estimateTimeView.text = date + } + }) + } + + completedView.setOnClickListener { + showDatePicker(object : DateSelectedCallback { + override fun onDateSelected(date: String) { + completedView.text = date + } + }) + } + + entrustNameView.setOnClickListener { + selectCustomerLauncher.launch(Intent(this, SelectCustomerActivity::class.java)) + } + //上传附件 uploadFileButton.setOnClickListener { + BottomActionSheet.Builder() + .setContext(this) + .setItemTextColor(Color.BLUE) + .setActionItemTitle(listOf("文件", "图片")) + .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { + override fun onActionItemClick(position: Int) { + when (position) { + 0 -> uploadFile() + 1 -> uploadImage() + } + } + }).build().show() + } + radioGroup.setOnCheckedChangeListener { _, checkedId -> + when (checkedId) { + R.id.radioButton1 -> isUrgent = "1" + R.id.radioButton2 -> isUrgent = "0" + } } //选择样品 selectSampleButton.setOnClickListener { - + selectSampleLauncher.launch(Intent(this, SelectSampleActivity::class.java)) } //写入样品信息 @@ -55,14 +214,68 @@ } pushEntrustView.setOnClickListener { - Log.d("Casic", "EntrustAddActivity => initEvent: ${checkedItems.toJson()}") + val sender = senderView.text.toString() + if (sender.isBlank()) { + "请填写送样人名字".show(this) + return@setOnClickListener + } + + val contact = contactView.text.toString() + if (contact.isBlank()) { + "请填写送样人联系方式".show(this) + return@setOnClickListener + } + + val estimateTime = estimateTimeView.text.toString() + if (estimateTime.isBlank()) { + "请选择预计送到的时间".show(this) + return@setOnClickListener + } + + val entrustName = entrustNameView.text.toString() + if (entrustName.isBlank()) { + "请选择委托方".show(this) + return@setOnClickListener + } + + if (sampleModels == null) { + "请选择样品".show(this) + return@setOnClickListener + } + entrustViewModel.addEntrust( + sender, + contact, + createEntrustDateView.text.toString(), + estimateTime, + completedView.text.toString(), + entrustName, + entrustContactView.text.toString(), + entrustAddressView.text.toString(), + remarkView.text.toString(), + annexView.text.toString(), + checkedItems.reformat(), + isUrgent, + sampleModels!! + ) } } override fun initLayoutView(): Int = R.layout.activity_entrust_add override fun observeRequestState() { + fileUploadViewModel.loadState.observe(this) { + when (it) { + LoadState.Loading -> LoadingDialogHub.show(this, "文件上传中,请稍后...") + else -> LoadingDialogHub.dismiss() + } + } + entrustViewModel.loadState.observe(this) { + when (it) { + LoadState.Loading -> LoadingDialogHub.show(this, "委托创建中,请稍后...") + else -> LoadingDialogHub.dismiss() + } + } } override fun setupTopBarLayout() { @@ -70,4 +283,62 @@ initLayoutImmersionBar(rootView) titleView.text = "委托需求" } + + private fun uploadFile() { +// val explorer = FileExplorer(this) +// explorer.setInitDir(ExplorerMode.FILE, Environment.getExternalStorageDirectory()) +// explorer.setShowHomeDir(true) +// explorer.setShowUpDir(true) +// explorer.setShowHideDir(true) +// explorer.setAllowExtensions(arrayOf(".doc", ".docx", ".xls", ".xlsx", ".pdf")) +// explorer.setOnFileClickedListener { +// val type = if (it.name.endsWith(".doc") || it.name.endsWith(".docx")) { +// FileType.WORD +// } else if (it.name.endsWith(".pdf")) { +// FileType.PDF +// } else { +// FileType.UNKNOWN +// } +// +// Log.d("Casic", "EntrustAddActivity => uploadFile: ${it.absolutePath}") +// fileUploadViewModel.uploadFile(it, type) +// } + } + + private fun uploadImage() { + PictureSelector.create(this) + .openGallery(SelectMimeType.ofImage()) + .isGif(false) + .isMaxSelectEnabledMask(true) + .setFilterMinFileSize(100) + .setMaxSelectNum(1) + .isDisplayCamera(false) + .setImageEngine(GlideLoadEngine.instance) + .forResult(object : OnResultCallbackListener { + override fun onResult(result: ArrayList?) { + if (result == null) { + "选择照片失败,请重试".show(context) + return + } + result[0].realPath.compressImage(context, object : OnImageCompressListener { + override fun onSuccess(file: File) { + Log.d( + "Casic", "EntrustAddActivity => onSuccess: ${file.absolutePath}" + ) + ///storage/emulated/0/Android/data/com.casic.xz.meterage/files/Pictures/CompressImage/1677478115391211.jpeg + //上传图片 + fileUploadViewModel.uploadFile(file, FileType.IMAGE) + } + + override fun onError(e: Throwable) { + e.printStackTrace() + } + }) + } + + override fun onCancel() { + + } + }) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/view/home/SelectCustomerActivity.kt b/app/src/main/java/com/casic/xz/meterage/view/home/SelectCustomerActivity.kt new file mode 100644 index 0000000..9bf6a1a --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/view/home/SelectCustomerActivity.kt @@ -0,0 +1,158 @@ +package com.casic.xz.meterage.view.home + +import android.content.Intent +import android.os.Handler +import androidx.lifecycle.ViewModelProvider +import androidx.recyclerview.widget.DefaultItemAnimator +import androidx.recyclerview.widget.DividerItemDecoration +import com.casic.xz.meterage.R +import com.casic.xz.meterage.adapter.SelectCustomerAdapter +import com.casic.xz.meterage.extensions.initLayoutImmersionBar +import com.casic.xz.meterage.extensions.showEmptyPage +import com.casic.xz.meterage.model.CustomerListModel +import com.casic.xz.meterage.utils.LoadingDialogHub +import com.casic.xz.meterage.vm.CustomerViewModel +import com.gyf.immersionbar.ImmersionBar +import com.pengxh.kt.lite.base.KotlinBaseActivity +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.utils.WeakReferenceHandler +import com.pengxh.kt.lite.vm.LoadState +import kotlinx.android.synthetic.main.activity_select_customer.* +import kotlinx.android.synthetic.main.include_base_title.* +import kotlinx.android.synthetic.main.include_empty_view.* + +class SelectCustomerActivity : KotlinBaseActivity() { + + private lateinit var weakReferenceHandler: WeakReferenceHandler + private lateinit var customerViewModel: CustomerViewModel + private lateinit var selectCustomerAdapter: SelectCustomerAdapter + private var dataBeans: MutableList = ArrayList() + private var pageIndex = 1 + private var isRefresh = false + private var isLoadMore = false + private var customerModel: CustomerListModel.DataModel.RowsModel? = null + + override fun initData() { + weakReferenceHandler = WeakReferenceHandler(callback) + customerViewModel = ViewModelProvider(this)[CustomerViewModel::class.java] + customerViewModel.customerList.observe(this) { + if (it.code == 200) { + val dataRows = it.data?.rows!! + when { + isRefresh -> { + dataBeans.clear() + dataBeans = dataRows + customerLayout.finishRefresh() + isRefresh = false + } + isLoadMore -> { + if (dataRows.size == 0) { + "到底了,别拉了".show(this) + } + dataBeans.addAll(dataRows) + customerLayout.finishLoadMore() + isLoadMore = false + } + else -> { + dataBeans = dataRows + } + } + weakReferenceHandler.sendEmptyMessage(2023022701) + } + } + } + + override fun initEvent() { + leftBackView.setOnClickListener { + if (customerModel == null) { + "请选择委托方".show(this) + return@setOnClickListener + } + val intent = Intent() + intent.putExtra("entrustName", customerModel!!.customerName) + intent.putExtra("entrustContact", customerModel!!.phone) + intent.putExtra("entrustAddress", customerModel!!.fullAddress) + setResult(RESULT_OK, intent) + finish() + } + + customerLayout.setOnRefreshListener { + isRefresh = true + //刷新之后页码重置 + pageIndex = 1 + getCustomerList() + } + + customerLayout.setOnLoadMoreListener { + isLoadMore = true + pageIndex++ + getCustomerList() + } + } + + override fun initLayoutView(): Int = R.layout.activity_select_customer + + override fun observeRequestState() { + customerViewModel.loadState.observe(this) { + when (it) { + LoadState.Loading -> LoadingDialogHub.show(this, "数据加载中...") + else -> LoadingDialogHub.dismiss() + } + } + } + + override fun setupTopBarLayout() { + ImmersionBar.with(this).statusBarDarkFont(true).init() + initLayoutImmersionBar(rootView) + titleView.text = "客户列表" + } + + override fun onResume() { + super.onResume() + pageIndex = 1 + getCustomerList() + } + + private fun getCustomerList() { + customerViewModel.getCustomerList( + "", + "", + "", + "", + pageIndex + ) + } + + private val callback = Handler.Callback { + when (it.what) { + 2023022701 -> { + if (isRefresh || isLoadMore) { + selectCustomerAdapter.notifyDataSetChanged() + } else { + if (dataBeans.size == 0) { + emptyView!!.showEmptyPage("无客户数据") { + pageIndex = 1 + getCustomerList() + } + } else { + emptyView!!.hide() + selectCustomerAdapter = SelectCustomerAdapter(this, dataBeans) + customerRecyclerView.addItemDecoration( + DividerItemDecoration(this, DividerItemDecoration.VERTICAL) + ) + (customerRecyclerView.itemAnimator as DefaultItemAnimator).supportsChangeAnimations = + false + customerRecyclerView.adapter = selectCustomerAdapter + selectCustomerAdapter.setOnCheckedListener(object : + SelectCustomerAdapter.OnItemCheckedListener { + override fun onItemChecked(item: CustomerListModel.DataModel.RowsModel) { + customerModel = item + } + }) + } + } + } + } + true + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/view/home/SelectSampleActivity.kt b/app/src/main/java/com/casic/xz/meterage/view/home/SelectSampleActivity.kt new file mode 100644 index 0000000..f85cb44 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/view/home/SelectSampleActivity.kt @@ -0,0 +1,152 @@ +package com.casic.xz.meterage.view.home + +import android.content.Intent +import android.os.Handler +import androidx.lifecycle.ViewModelProvider +import androidx.recyclerview.widget.DefaultItemAnimator +import androidx.recyclerview.widget.DividerItemDecoration +import com.casic.xz.meterage.R +import com.casic.xz.meterage.adapter.SelectSampleAdapter +import com.casic.xz.meterage.extensions.initLayoutImmersionBar +import com.casic.xz.meterage.extensions.showEmptyPage +import com.casic.xz.meterage.model.SampleListModel +import com.casic.xz.meterage.vm.SampleViewModel +import com.gyf.immersionbar.ImmersionBar +import com.pengxh.kt.lite.base.KotlinBaseActivity +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.extensions.toJson +import com.pengxh.kt.lite.utils.WeakReferenceHandler +import kotlinx.android.synthetic.main.activity_select_sample.* +import kotlinx.android.synthetic.main.include_base_title.* +import kotlinx.android.synthetic.main.include_empty_view.* + +class SelectSampleActivity : KotlinBaseActivity() { + + private lateinit var weakReferenceHandler: WeakReferenceHandler + private lateinit var sampleViewModel: SampleViewModel + private lateinit var selectSampleAdapter: SelectSampleAdapter + private var dataBeans: MutableList = ArrayList() + private var pageIndex = 1 + private var isRefresh = false + private var isLoadMore = false + private var sampleModels = ArrayList() + + override fun initData() { + weakReferenceHandler = WeakReferenceHandler(callback) + sampleViewModel = ViewModelProvider(this)[SampleViewModel::class.java] + sampleViewModel.sampleList.observe(this) { + if (it.code == 200) { + val dataRows = it.data?.rows!! + when { + isRefresh -> { + dataBeans.clear() + dataBeans = dataRows + sampleLayout.finishRefresh() + isRefresh = false + } + isLoadMore -> { + if (dataRows.size == 0) { + "到底了,别拉了".show(this) + } + dataBeans.addAll(dataRows) + sampleLayout.finishLoadMore() + isLoadMore = false + } + else -> { + dataBeans = dataRows + } + } + weakReferenceHandler.sendEmptyMessage(2023030101) + } + } + } + + override fun initEvent() { + leftBackView.setOnClickListener { + val intent = Intent() + intent.putExtra("sampleModels", sampleModels.toJson()) + setResult(RESULT_OK, intent) + finish() + } + + sampleLayout.setOnRefreshListener { + isRefresh = true + //刷新之后页码重置 + pageIndex = 1 + getSampleList() + } + + sampleLayout.setOnLoadMoreListener { + isLoadMore = true + pageIndex++ + getSampleList() + } + } + + override fun initLayoutView(): Int = R.layout.activity_select_sample + + override fun observeRequestState() { + + } + + override fun setupTopBarLayout() { + ImmersionBar.with(this).statusBarDarkFont(true).init() + initLayoutImmersionBar(rootView) + titleView.text = "样品列表" + } + + override fun onResume() { + super.onResume() + pageIndex = 1 + getSampleList() + } + + private fun getSampleList() { + sampleViewModel.getSampleList( + "", + "", + "", + "", + "", + "", + "", + "", + "", + arrayOf(), + pageIndex + ) + } + + private val callback = Handler.Callback { + when (it.what) { + 2023030101 -> { + if (isRefresh || isLoadMore) { + selectSampleAdapter.notifyDataSetChanged() + } else { + if (dataBeans.size == 0) { + emptyView!!.showEmptyPage("无样品数据") { + pageIndex = 1 + getSampleList() + } + } else { + emptyView!!.hide() + selectSampleAdapter = SelectSampleAdapter(this, dataBeans) + sampleRecyclerView.addItemDecoration( + DividerItemDecoration(this, DividerItemDecoration.VERTICAL) + ) + (sampleRecyclerView.itemAnimator as DefaultItemAnimator).supportsChangeAnimations = + false + sampleRecyclerView.adapter = selectSampleAdapter + selectSampleAdapter.setOnCheckedListener(object : + SelectSampleAdapter.OnItemCheckedListener { + override fun onItemChecked(items: ArrayList) { + sampleModels = items + } + }) + } + } + } + } + true + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/view/notice/NoticeDetailActivity.kt b/app/src/main/java/com/casic/xz/meterage/view/notice/NoticeDetailActivity.kt index a9d9422..9596985 100644 --- a/app/src/main/java/com/casic/xz/meterage/view/notice/NoticeDetailActivity.kt +++ b/app/src/main/java/com/casic/xz/meterage/view/notice/NoticeDetailActivity.kt @@ -1,6 +1,7 @@ package com.casic.xz.meterage.view.notice import android.annotation.SuppressLint +import android.graphics.Color import android.graphics.Paint import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R @@ -10,7 +11,6 @@ import com.casic.xz.meterage.vm.NoticeViewModel import com.gyf.immersionbar.ImmersionBar import com.pengxh.kt.lite.base.KotlinBaseActivity -import com.pengxh.kt.lite.extensions.convertColor import com.pengxh.kt.lite.extensions.obtainScreenWidth import com.pengxh.kt.lite.utils.Constant import kotlinx.android.synthetic.main.activity_notice_detail.* @@ -54,7 +54,7 @@ val textPaint = minioFileView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - minioFileView.setTextColor(R.color.themeColor.convertColor(this)) + minioFileView.setTextColor(Color.BLUE) minioFileView.setOnClickListener { minioFileName.watchAttachFile(this) diff --git a/app/src/main/java/com/casic/xz/meterage/vm/EntrustViewModel.kt b/app/src/main/java/com/casic/xz/meterage/vm/EntrustViewModel.kt index 2280f88..103c002 100644 --- a/app/src/main/java/com/casic/xz/meterage/vm/EntrustViewModel.kt +++ b/app/src/main/java/com/casic/xz/meterage/vm/EntrustViewModel.kt @@ -7,6 +7,7 @@ import com.casic.xz.meterage.model.ActionResultModel import com.casic.xz.meterage.model.EntrustDetailModel import com.casic.xz.meterage.model.EntrustListModel +import com.casic.xz.meterage.model.SampleListModel import com.casic.xz.meterage.utils.retrofit.RetrofitServiceManager import com.google.gson.Gson import com.google.gson.reflect.TypeToken @@ -25,6 +26,7 @@ val entrustDetail = MutableLiveData() val acceptResult = MutableLiveData() val returnResult = MutableLiveData() + val addResult = MutableLiveData() fun getEntrustList( customerName: String, @@ -119,4 +121,50 @@ loadState.value = LoadState.Fail it.cause.toString().show(BaseApplication.get()) }) + + fun addEntrust( + deliverer: String, + delivererTel: String, + orderTime: String, + planDeliverTime: String, + requireOverTime: String, + customerName: String, + customerPhone: String, + customerAddress: String, + remark: String, + minioFileName: String, + certifications: String, + isUrgent: String, + samples: List + ) = launch({ + loadState.value = LoadState.Loading + val response = RetrofitServiceManager.addEntrust( + deliverer, + delivererTel, + orderTime, + planDeliverTime, + requireOverTime, + customerName, + customerPhone, + customerAddress, + remark, + minioFileName, + certifications, + isUrgent, + samples + ) + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + loadState.value = LoadState.Success + addResult.value = gson.fromJson( + response, object : TypeToken() {}.type + ) + } else { + loadState.value = LoadState.Fail + response.toErrorMessage().show(BaseApplication.get()) + } + }, { + loadState.value = LoadState.Fail + it.cause.toString().show(BaseApplication.get()) + }) } \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 0ae369f..687b02b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -15,7 +15,6 @@ } compileSdkVersion 31 - buildToolsVersion "30.0.3" defaultConfig { applicationId "com.casic.xz.meterage" @@ -84,11 +83,13 @@ implementation 'top.zibin:Luban:1.1.8' //官方Json解析库 implementation 'com.google.code.gson:gson:2.9.0' + //阿里巴巴JSON库 + implementation 'com.alibaba.fastjson2:fastjson2:2.0.24' //Kotlin协程 implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.5.1' //MVVM+LiveData implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.5.1" - implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.0" + implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1" implementation "androidx.lifecycle:lifecycle-extensions:2.2.0" //返回值转换器 implementation 'com.jakewharton.retrofit:retrofit2-kotlin-coroutines-adapter:0.9.2' @@ -109,4 +110,8 @@ implementation 'com.github.barteksc:android-pdf-viewer:2.8.2' //绕过Android 11反射限制 implementation 'com.github.tiann:FreeReflection:3.1.0' + //单项/数字、二三级联动、日期/时间等滚轮选择器 + implementation 'com.github.gzu-liyujiang.AndroidPicker:WheelPicker:4.1.8' + //文件/目录选择器 + implementation 'com.github.gzu-liyujiang.AndroidPicker:FilePicker:4.1.1' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 1ccc12b..0fba91b 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -60,6 +60,8 @@ + + diff --git a/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt b/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt new file mode 100644 index 0000000..21a71d8 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt @@ -0,0 +1,70 @@ +package com.casic.xz.meterage.adapter + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import com.casic.xz.meterage.R +import com.casic.xz.meterage.extensions.toChineseGrade +import com.casic.xz.meterage.model.CustomerListModel + +class SelectCustomerAdapter( + context: Context, private val dataRows: MutableList +) : RecyclerView.Adapter() { + + private var layoutInflater = LayoutInflater.from(context) + + //选择的位置 + private var selectedPosition = 0 + + //临时记录上次选择的位置 + private var temp = -1 + + override fun getItemCount(): Int = dataRows.size + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ItemViewHolder( + layoutInflater.inflate(R.layout.item_select_customer_lv, parent, false) + ) + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + //绑定数据 + val rowsBean = dataRows[position] + holder.agreementLevelView.text = rowsBean.grade.toChineseGrade() + holder.customerNameView.text = rowsBean.customerName + holder.scaleView.text = rowsBean.companySizeName + holder.overallView.text = "公司规模:${rowsBean.evaluationName}" + holder.fullAddressView.text = "公司地址:${rowsBean.fullAddress}" + + holder.itemView.isSelected = holder.layoutPosition == selectedPosition + holder.itemView.setOnClickListener { + itemCheckedListener?.onItemChecked(rowsBean) + + holder.itemView.isSelected = true + temp = selectedPosition + //设置新的位置 + selectedPosition = holder.layoutPosition + //更新旧位置 + notifyItemChanged(temp) + } + } + + inner class ItemViewHolder(view: View) : RecyclerView.ViewHolder(view) { + var agreementLevelView: TextView = view.findViewById(R.id.agreementLevelView) + var customerNameView: TextView = view.findViewById(R.id.customerNameView) + var scaleView: TextView = view.findViewById(R.id.scaleView) + var overallView: TextView = view.findViewById(R.id.overallView) + var fullAddressView: TextView = view.findViewById(R.id.fullAddressView) + } + + private var itemCheckedListener: OnItemCheckedListener? = null + + interface OnItemCheckedListener { + fun onItemChecked(item: CustomerListModel.DataModel.RowsModel) + } + + fun setOnCheckedListener(listener: OnItemCheckedListener?) { + itemCheckedListener = listener + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt b/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt new file mode 100644 index 0000000..c29461e --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt @@ -0,0 +1,68 @@ +package com.casic.xz.meterage.adapter + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import com.casic.xz.meterage.R +import com.casic.xz.meterage.model.SampleListModel + +class SelectSampleAdapter( + context: Context, private val dataRows: MutableList +) : RecyclerView.Adapter() { + + private var layoutInflater = LayoutInflater.from(context) + private var multipleSelected = mutableSetOf() + private var sampleModes = ArrayList() + + override fun getItemCount(): Int = dataRows.size + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ItemViewHolder( + layoutInflater.inflate(R.layout.item_select_sample_lv, parent, false) + ) + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + //绑定数据 + val rowsBean = dataRows[position] + holder.sampleNameView.text = "${rowsBean.sampleName}【${rowsBean.sampleModel}】" + holder.manufacturingCodeView.text = "出厂编号:${rowsBean.manufacturingNo}" + holder.sampleCodeView.text = "样品编号:${rowsBean.sampleNo}" + holder.validDateView.text = "有效期至:${rowsBean.validDeadline}" + + holder.checkImageView.isSelected = multipleSelected.contains(position) + holder.itemView.setOnClickListener { + if (multipleSelected.contains(position)) { + multipleSelected.remove(position) + sampleModes.remove(dataRows[position]) + holder.checkImageView.isSelected = false + } else { + multipleSelected.add(position) + sampleModes.add(dataRows[position]) + holder.checkImageView.isSelected = true + } + + itemCheckedListener?.onItemChecked(sampleModes) + } + } + + inner class ItemViewHolder(view: View) : RecyclerView.ViewHolder(view) { + var sampleNameView: TextView = view.findViewById(R.id.sampleNameView) + var manufacturingCodeView: TextView = view.findViewById(R.id.manufacturingCodeView) + var sampleCodeView: TextView = view.findViewById(R.id.sampleCodeView) + var validDateView: TextView = view.findViewById(R.id.validDateView) + var checkImageView: ImageView = view.findViewById(R.id.checkImageView) + } + + private var itemCheckedListener: OnItemCheckedListener? = null + + interface OnItemCheckedListener { + fun onItemChecked(items: ArrayList) + } + + fun setOnCheckedListener(listener: OnItemCheckedListener?) { + itemCheckedListener = listener + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/callback/DateSelectedCallback.kt b/app/src/main/java/com/casic/xz/meterage/callback/DateSelectedCallback.kt new file mode 100644 index 0000000..8196110 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/callback/DateSelectedCallback.kt @@ -0,0 +1,5 @@ +package com.casic.xz.meterage.callback + +interface DateSelectedCallback { + fun onDateSelected(date: String) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/Activity.kt b/app/src/main/java/com/casic/xz/meterage/extensions/Activity.kt new file mode 100644 index 0000000..e112d1c --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/extensions/Activity.kt @@ -0,0 +1,33 @@ +package com.casic.xz.meterage.extensions + +import android.app.Activity +import com.casic.xz.meterage.R +import com.casic.xz.meterage.callback.DateSelectedCallback +import com.github.gzuliyujiang.wheelpicker.DatePicker +import com.github.gzuliyujiang.wheelpicker.annotation.DateMode +import com.github.gzuliyujiang.wheelpicker.entity.DateEntity +import com.pengxh.kt.lite.extensions.convertColor +import com.pengxh.kt.lite.extensions.sp2px + +fun Activity.showDatePicker(callback: DateSelectedCallback) { + val datePicker = DatePicker(this) + + val layout = datePicker.wheelLayout + layout.setDateMode(DateMode.YEAR_MONTH_DAY) + layout.setDateLabel("年", "月", "日"); + layout.setTextSize(14f.sp2px(this).toFloat()) + layout.setSelectedTextSize(16f.sp2px(this).toFloat()) + layout.setSelectedTextColor(R.color.themeColor.convertColor(this)) + layout.setSelectedTextBold(true) + layout.setResetWhenLinkage(false) + layout.setRange( + DateEntity.today(), + DateEntity.target(2050, 12, 31), + DateEntity.today() + ) + + datePicker.setOnDatePickedListener { year, month, day -> + callback.onDateSelected(String.format("%s-%s-%s", year, month, day)) + } + datePicker.show() +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt b/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt index 016ebcb..cf6bf49 100644 --- a/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt +++ b/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt @@ -4,7 +4,7 @@ * ArrayList扩展方法 */ -//将图片集合格式化成满足上传格式的数据 +//将集合格式化成满足上传格式的数据 fun ArrayList.reformat(): String { if (this.isEmpty()) return "" val builder = StringBuilder() diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt b/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt index 7c57643..aa9b92b 100644 --- a/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt +++ b/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt @@ -1,7 +1,6 @@ package com.casic.xz.meterage.extensions import android.content.Context -import android.util.Log import android.view.ViewGroup import com.casic.xz.meterage.base.BaseApplication import com.pengxh.kt.lite.extensions.dp2px @@ -9,9 +8,8 @@ fun Context.initLayoutImmersionBar(rootView: ViewGroup) { var statusBarHeight = QMUIDisplayHelper.getStatusBarHeight(this) - Log.d("Casic", "状态栏高度: $statusBarHeight") if (statusBarHeight == 0) { - statusBarHeight = 44f.dp2px(BaseApplication.get()) + statusBarHeight = 40f.dp2px(BaseApplication.get()) } rootView.setPadding(0, statusBarHeight, 0, 0) rootView.requestLayout() diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/String.kt b/app/src/main/java/com/casic/xz/meterage/extensions/String.kt index 28f70d8..6234d43 100644 --- a/app/src/main/java/com/casic/xz/meterage/extensions/String.kt +++ b/app/src/main/java/com/casic/xz/meterage/extensions/String.kt @@ -128,9 +128,10 @@ fun String.combineImagePath(): String { if (this.isEmpty()) return this val defaultValue = SaveKeyValues.getValue( - LocaleConstant.DEFAULT_SERVER_CONFIG, LocaleConstant.SERVER_BASE_URL + LocaleConstant.FILE_SERVER_CONFIG, LocaleConstant.File_SERVER_URL ) as String - return "$defaultValue/static/${this.replace("\\", "/")}" + //http://111.198.10.15:21408/test/1677479806059688_1677479806038.jpeg + return "$defaultValue/test/${this.replace("\\", "/")}" } fun String.isEarlier(time: String): Boolean { diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt index 25fa87b..a0e1358 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt @@ -1,18 +1,12 @@ package com.casic.xz.meterage.fragment.customer +import android.graphics.Color import android.graphics.Paint import com.casic.xz.meterage.R -import com.casic.xz.meterage.extensions.combineImagePath import com.casic.xz.meterage.extensions.toChineseGrade +import com.casic.xz.meterage.extensions.watchAttachFile import com.casic.xz.meterage.model.CustomerDetailModel -import com.casic.xz.meterage.view.BigImageActivity -import com.casic.xz.meterage.view.notice.PreviewDocumentActivity -import com.casic.xz.meterage.view.notice.PreviewPdfActivity -import com.casic.xz.meterage.view.notice.PreviewTextActivity import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.extensions.show import kotlinx.android.synthetic.main.fragment_customer_basic_information.* class BasicInformationFragment(private val data: CustomerDetailModel.DataModel) : @@ -48,30 +42,11 @@ val textPaint = minioFileView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - minioFileView.setTextColor(R.color.themeColor.convertColor(requireContext())) + minioFileView.setTextColor(Color.BLUE) minioFileView.setOnClickListener { //查看附件 - if (minioFileName.endsWith("pdf")) { - requireContext().navigatePageTo(minioFileName) - } else if ( - minioFileName.endsWith("doc") || - minioFileName.endsWith("docx") - ) { - requireContext().navigatePageTo(minioFileName) - } else if (minioFileName.endsWith("txt")) { - requireContext().navigatePageTo(minioFileName) - } else if ( - minioFileName.endsWith("png") || - minioFileName.endsWith("jpeg") || - minioFileName.endsWith("jpg") - ) { - val urls = ArrayList() - urls.add(minioFileName.combineImagePath()) - requireContext().navigatePageTo(0, urls) - } else { - "文件类型未知,无法打开附件".show(requireContext()) - } + minioFileName.watchAttachFile(requireContext()) } } } diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt index 77846b4..3a0fe2e 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt @@ -1,5 +1,6 @@ package com.casic.xz.meterage.fragment.device +import android.graphics.Color import android.graphics.Paint import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R @@ -7,7 +8,6 @@ import com.casic.xz.meterage.utils.LoadingDialogHub import com.casic.xz.meterage.vm.EquipmentViewModel import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor import com.pengxh.kt.lite.vm.LoadState import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import kotlinx.android.synthetic.main.fragment_device_basic_information.* @@ -56,7 +56,7 @@ val textPaint = documentsView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - documentsView.setTextColor(R.color.themeColor.convertColor(requireContext())) + documentsView.setTextColor(Color.BLUE) val files = ArrayList() data.fileList.forEach { file -> @@ -66,7 +66,7 @@ BottomActionSheet.Builder() .setContext(requireContext()) .setActionItemTitle(files) - .setItemTextColor(R.color.themeColor.convertColor(requireContext())) + .setItemTextColor(Color.BLUE) .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { override fun onActionItemClick(position: Int) { diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt index 15dc3d2..10eeff8 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt @@ -1,5 +1,6 @@ package com.casic.xz.meterage.fragment.entrust +import android.graphics.Color import android.graphics.Paint import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R @@ -9,7 +10,6 @@ import com.casic.xz.meterage.model.EntrustDetailModel import com.casic.xz.meterage.vm.DictionaryViewModel import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor import kotlinx.android.synthetic.main.fragment_entrust_basic_information.* class BasicInformationFragment(private val data: EntrustDetailModel.DataModel) : @@ -38,7 +38,7 @@ val textPaint = annexView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - annexView.setTextColor(R.color.themeColor.convertColor(requireContext())) + annexView.setTextColor(Color.BLUE) annexView.setOnClickListener { minioFileName.watchAttachFile(requireContext()) @@ -59,9 +59,9 @@ //加急 if (data.isUrgent == "0") { - RadioButton2.isChecked = true + radioButton2.isChecked = true } else { - RadioButton1.isChecked = true + radioButton1.isChecked = true } //样品 diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/equipment/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/equipment/BasicInformationFragment.kt index 72b523c..7bc3b01 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/equipment/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/equipment/BasicInformationFragment.kt @@ -1,5 +1,6 @@ package com.casic.xz.meterage.fragment.equipment +import android.graphics.Color import android.graphics.Paint import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R @@ -7,7 +8,6 @@ import com.casic.xz.meterage.utils.LoadingDialogHub import com.casic.xz.meterage.vm.EquipmentViewModel import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor import com.pengxh.kt.lite.vm.LoadState import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import kotlinx.android.synthetic.main.fragment_equipment_basic_information.* @@ -74,7 +74,7 @@ val textPaint = instructionsView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - instructionsView.setTextColor(R.color.themeColor.convertColor(requireContext())) + instructionsView.setTextColor(Color.BLUE) val files = ArrayList() data.fileList.forEach { file -> @@ -84,7 +84,7 @@ BottomActionSheet.Builder() .setContext(requireContext()) .setActionItemTitle(files) - .setItemTextColor(R.color.themeColor.convertColor(requireContext())) + .setItemTextColor(Color.BLUE) .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { override fun onActionItemClick(position: Int) { diff --git a/app/src/main/java/com/casic/xz/meterage/model/SampleListModel.java b/app/src/main/java/com/casic/xz/meterage/model/SampleListModel.java new file mode 100644 index 0000000..5784343 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/model/SampleListModel.java @@ -0,0 +1,193 @@ +package com.casic.xz.meterage.model; + +import java.util.List; + +public class SampleListModel { + + private int code; + private DataModel data; + private String message; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataModel getData() { + return data; + } + + public void setData(DataModel data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public static class DataModel { + private List rows; + private int total; + + public List getRows() { + return rows; + } + + public void setRows(List rows) { + this.rows = rows; + } + + public int getTotal() { + return total; + } + + public void setTotal(int total) { + this.total = total; + } + + public static class RowsModel { + private String certificationStatus; + private String customerName; + private String customerNo; + private String id; + private String manufacturingNo; + private String measureLastTime; + private String measurePeriod; + private String orderId; + private String remark; + private String sampleModel; + private String sampleName; + private String sampleNo; + private String sampleSatus; + private String sampleSatusName; + private String validDeadline; + + public String getCertificationStatus() { + return certificationStatus; + } + + public void setCertificationStatus(String certificationStatus) { + this.certificationStatus = certificationStatus; + } + + public String getCustomerName() { + return customerName; + } + + public void setCustomerName(String customerName) { + this.customerName = customerName; + } + + public String getCustomerNo() { + return customerNo; + } + + public void setCustomerNo(String customerNo) { + this.customerNo = customerNo; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getManufacturingNo() { + return manufacturingNo; + } + + public void setManufacturingNo(String manufacturingNo) { + this.manufacturingNo = manufacturingNo; + } + + public String getMeasureLastTime() { + return measureLastTime; + } + + public void setMeasureLastTime(String measureLastTime) { + this.measureLastTime = measureLastTime; + } + + public String getMeasurePeriod() { + return measurePeriod; + } + + public void setMeasurePeriod(String measurePeriod) { + this.measurePeriod = measurePeriod; + } + + public String getOrderId() { + return orderId; + } + + public void setOrderId(String orderId) { + this.orderId = orderId; + } + + public String getRemark() { + return remark; + } + + public void setRemark(String remark) { + this.remark = remark; + } + + public String getSampleModel() { + return sampleModel; + } + + public void setSampleModel(String sampleModel) { + this.sampleModel = sampleModel; + } + + public String getSampleName() { + return sampleName; + } + + public void setSampleName(String sampleName) { + this.sampleName = sampleName; + } + + public String getSampleNo() { + return sampleNo; + } + + public void setSampleNo(String sampleNo) { + this.sampleNo = sampleNo; + } + + public String getSampleSatus() { + return sampleSatus; + } + + public void setSampleSatus(String sampleSatus) { + this.sampleSatus = sampleSatus; + } + + public String getSampleSatusName() { + return sampleSatusName; + } + + public void setSampleSatusName(String sampleSatusName) { + this.sampleSatusName = sampleSatusName; + } + + public String getValidDeadline() { + return validDeadline; + } + + public void setValidDeadline(String validDeadline) { + this.validDeadline = validDeadline; + } + } + } +} diff --git a/app/src/main/java/com/casic/xz/meterage/model/UploadResultModel.java b/app/src/main/java/com/casic/xz/meterage/model/UploadResultModel.java new file mode 100644 index 0000000..f2a6a41 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/model/UploadResultModel.java @@ -0,0 +1,34 @@ +package com.casic.xz.meterage.model; + +import java.util.List; + +public class UploadResultModel { + + private int code; + private List data; + private String message; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public List getData() { + return data; + } + + public void setData(List data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } +} diff --git a/app/src/main/java/com/casic/xz/meterage/utils/FileType.kt b/app/src/main/java/com/casic/xz/meterage/utils/FileType.kt new file mode 100644 index 0000000..17e2bca --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/utils/FileType.kt @@ -0,0 +1,23 @@ +package com.casic.xz.meterage.utils + +sealed class FileType { + /** + * PDF文件 + */ + object PDF : FileType() + + /** + * WORD文件 + */ + object WORD : FileType() + + /** + * IMAGE图片 + */ + object IMAGE : FileType() + + /** + * 未知类型(Excel) + */ + object UNKNOWN : FileType() +} diff --git a/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitService.kt index bc3f8d6..8f4fe44 100644 --- a/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitService.kt @@ -1,5 +1,6 @@ package com.casic.xz.meterage.utils.retrofit +import okhttp3.MultipartBody import okhttp3.RequestBody import retrofit2.http.* @@ -35,6 +36,16 @@ ): String /** + * 上传文件 + */ + @Multipart + @POST("/minio/file/upload") + suspend fun uploadFile( + @Header("token") token: String, + @Part file: MultipartBody.Part + ): String + + /** * 获取通知公告列表 */ @POST("/system/notice/listPage") @@ -209,4 +220,24 @@ @Header("token") token: String, @Body requestBody: RequestBody ): String + + /** + * 获取样品列表 + */ + @POST("/customer/sample/listPage") + suspend fun getSampleList( + @Header("token") token: String, + @Body requestBody: RequestBody, + @QueryMap limit: Map, + @QueryMap offset: Map + ): String + + /** + * 新增委托书 + */ + @POST("/business/order/add") + suspend fun addEntrust( + @Header("token") token: String, + @Body requestBody: RequestBody + ): String } \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitServiceManager.kt index cb22e45..90abe5a 100644 --- a/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitServiceManager.kt @@ -1,13 +1,20 @@ package com.casic.xz.meterage.utils.retrofit +import com.alibaba.fastjson2.JSON +import com.alibaba.fastjson2.JSONArray +import com.alibaba.fastjson2.JSONObject +import com.casic.xz.meterage.model.SampleListModel import com.casic.xz.meterage.utils.AuthenticationHelper +import com.casic.xz.meterage.utils.FileType import com.casic.xz.meterage.utils.LocaleConstant import com.pengxh.kt.lite.utils.RetrofitFactory import com.pengxh.kt.lite.utils.SaveKeyValues import okhttp3.MediaType.Companion.toMediaType +import okhttp3.MediaType.Companion.toMediaTypeOrNull +import okhttp3.MultipartBody +import okhttp3.RequestBody.Companion.asRequestBody import okhttp3.RequestBody.Companion.toRequestBody -import org.json.JSONArray -import org.json.JSONObject +import java.io.File object RetrofitServiceManager { @@ -31,9 +38,9 @@ */ suspend fun login(sid: String, account: String, secretKey: String): String { val paramObject = JSONObject() - paramObject.put("sid", sid) - paramObject.put("username", account) - paramObject.put("password", secretKey) + paramObject["sid"] = sid + paramObject["username"] = account + paramObject["password"] = secretKey val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -55,6 +62,20 @@ } /** + * 上传文件 + */ + suspend fun uploadFile(file: File, type: FileType): String { + val requestBody = when (type) { + FileType.PDF -> file.asRequestBody("application/pdf".toMediaTypeOrNull()) + FileType.WORD -> file.asRequestBody("application/msword".toMediaTypeOrNull()) + FileType.IMAGE -> file.asRequestBody("image/png".toMediaTypeOrNull()) + else -> file.asRequestBody("application/vnd.ms-excel".toMediaTypeOrNull()) + } + val filePart = MultipartBody.Part.createFormData("multipartFile", file.name, requestBody) + return api.uploadFile(AuthenticationHelper.token!!, filePart) + } + + /** * 获取通知公告列表 */ suspend fun getNoticeList( @@ -66,11 +87,11 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("noticeNo", noticeNo) - paramObject.put("noticeTitle", noticeTitle) - paramObject.put("noticePublisher", noticePublisher) - paramObject.put("noticeStartTime", noticeStartTime) - paramObject.put("noticeEndTime", noticeEndTime) + paramObject["noticeNo"] = noticeNo + paramObject["noticeTitle"] = noticeTitle + paramObject["noticePublisher"] = noticePublisher + paramObject["noticeStartTime"] = noticeStartTime + paramObject["noticeEndTime"] = noticeEndTime val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -105,26 +126,21 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("equipmentNo", equipmentNo) - paramObject.put("equipmentName", equipmentName) - paramObject.put("mesureType", mesureType) - paramObject.put("managerState", managerState) - paramObject.put("useDept", useDept) - paramObject.put("assetType", assetType) - paramObject.put("equipmentCategory", equipmentCategory) - paramObject.put("isCalibrationTestEquipment", isCalibrationTestEquipment) - paramObject.put("isMeasureAccount", isMeasureAccount) - paramObject.put("isStandardSupportEquipment", isStandardSupportEquipment) - paramObject.put("isFixedAssets", isFixedAssets) - paramObject.put("validStartDate", validStartDate) - paramObject.put("validEndDate", validEndDate) - paramObject.put("abc", abc) - - val jsonArray = JSONArray() - ids.forEach { - jsonArray.put(it) - } - paramObject.put("ids", jsonArray) + paramObject["equipmentNo"] = equipmentNo + paramObject["equipmentName"] = equipmentName + paramObject["mesureType"] = mesureType + paramObject["managerState"] = managerState + paramObject["useDept"] = useDept + paramObject["assetType"] = assetType + paramObject["equipmentCategory"] = equipmentCategory + paramObject["isCalibrationTestEquipment"] = isCalibrationTestEquipment + paramObject["isMeasureAccount"] = isMeasureAccount + paramObject["isStandardSupportEquipment"] = isStandardSupportEquipment + paramObject["isFixedAssets"] = isFixedAssets + paramObject["validStartDate"] = validStartDate + paramObject["validEndDate"] = validEndDate + paramObject["abc"] = abc + paramObject["ids"] = JSONArray.parseArray(JSON.toJSONString(ids)) val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() @@ -143,7 +159,7 @@ */ suspend fun getEquipmentDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -164,13 +180,13 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("standardNo", standardNo) - paramObject.put("standardName", standardName) - paramObject.put("category", category) - paramObject.put("managerState", managerState) - paramObject.put("standardLaboratory", standardLaboratory) - paramObject.put("preparationDate", preparationDate) - paramObject.put("id", id) + paramObject["standardNo"] = standardNo + paramObject["standardName"] = standardName + paramObject["category"] = category + paramObject["managerState"] = managerState + paramObject["standardLaboratory"] = standardLaboratory + paramObject["preparationDate"] = preparationDate + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -193,7 +209,7 @@ */ suspend fun getStandardDeviceDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -212,11 +228,11 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("checkType", checkType) - paramObject.put("priceItem", priceItem) - paramObject.put("priceName", priceName) - paramObject.put("priceNo", priceNo) - paramObject.put("priceType", priceType) + paramObject["checkType"] = checkType + paramObject["priceItem"] = priceItem + paramObject["priceName"] = priceName + paramObject["priceNo"] = priceNo + paramObject["priceType"] = priceType val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -234,7 +250,7 @@ */ suspend fun getCapabilityDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -257,20 +273,15 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("createStartTime", createStartTime) - paramObject.put("createEndTime", createEndTime) - paramObject.put("deptId", deptId) - paramObject.put("director", director) - paramObject.put("effectiveCompany", effectiveCompany) - paramObject.put("trainStartTime", trainStartTime) - paramObject.put("trainEndTime", trainEndTime) - paramObject.put("formId", formId) - - val jsonArray = JSONArray() - ids.forEach { - jsonArray.put(it) - } - paramObject.put("ids", jsonArray) + paramObject["createStartTime"] = createStartTime + paramObject["createEndTime"] = createEndTime + paramObject["deptId"] = deptId + paramObject["director"] = director + paramObject["effectiveCompany"] = effectiveCompany + paramObject["trainStartTime"] = trainStartTime + paramObject["trainEndTime"] = trainEndTime + paramObject["formId"] = formId + paramObject["ids"] = JSONArray.parseArray(JSON.toJSONString(ids)) val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() @@ -294,7 +305,7 @@ */ suspend fun getMeterageTrainDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -308,10 +319,10 @@ bussinessSize: String, customerName: String, customerNo: String, grade: String, offset: Int ): String { val paramObject = JSONObject() - paramObject.put("bussinessSize", bussinessSize) - paramObject.put("customerName", customerName) - paramObject.put("customerNo", customerNo) - paramObject.put("grade", grade) + paramObject["bussinessSize"] = bussinessSize + paramObject["customerName"] = customerName + paramObject["customerNo"] = customerNo + paramObject["grade"] = grade val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() @@ -330,7 +341,7 @@ */ suspend fun getCustomerDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -342,7 +353,7 @@ */ suspend fun getStaffList(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -354,7 +365,7 @@ */ suspend fun getSupportEquipmentList(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -366,7 +377,7 @@ */ suspend fun getVerifyProcedureList(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -389,20 +400,15 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("customerName", customerName) - paramObject.put("customerNo", customerNo) - paramObject.put("deliverer", deliverer) - paramObject.put("orderCode", orderCode) - paramObject.put("startTime", startTime) - paramObject.put("endTime", endTime) - paramObject.put("isUrgent", isUrgent) - paramObject.put("status", status) - - val jsonArray = JSONArray() - ids.forEach { - jsonArray.put(it) - } - paramObject.put("ids", jsonArray) + paramObject["customerName"] = customerName + paramObject["customerNo"] = customerNo + paramObject["deliverer"] = deliverer + paramObject["orderCode"] = orderCode + paramObject["startTime"] = startTime + paramObject["endTime"] = endTime + paramObject["isUrgent"] = isUrgent + paramObject["status"] = status + paramObject["ids"] = JSONArray.parseArray(JSON.toJSONString(ids)) val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() @@ -421,7 +427,7 @@ */ suspend fun getEntrustDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -433,7 +439,7 @@ */ suspend fun acceptEntrust(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -446,10 +452,89 @@ */ suspend fun returnEntrust(id: String, selected: ArrayList): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) return api.returnEntrust(AuthenticationHelper.token!!, requestBody) } + + /** + * 获取样品列表 + */ + suspend fun getSampleList( + customerName: String, + customerNo: String, + startTime: String, + endTime: String, + sampleName: String, + sampleNo: String, + sampleModel: String, + sampleBelong: String, + overtimeStatus: String, + ids: Array, + offset: Int + ): String { + val paramObject = JSONObject() + paramObject["customerName"] = customerName + paramObject["customerNo"] = customerNo + paramObject["startTime"] = startTime + paramObject["endTime"] = endTime + paramObject["sampleName"] = sampleName + paramObject["sampleNo"] = sampleNo + paramObject["sampleModel"] = sampleModel + paramObject["sampleBelong"] = sampleBelong + paramObject["overtimeStatus"] = overtimeStatus + paramObject["ids"] = JSONArray.parseArray(JSON.toJSONString(ids)) + + val requestBody = paramObject.toString().toRequestBody( + "application/json;charset=UTF-8".toMediaType() + ) + + val limitMap = HashMap() + limitMap["limit"] = LocaleConstant.PAGE_LIMIT + + val offsetMap = HashMap() + offsetMap["offset"] = offset + return api.getSampleList(AuthenticationHelper.token!!, requestBody, limitMap, offsetMap) + } + + /** + * 新增委托书 + */ + suspend fun addEntrust( + deliverer: String, + delivererTel: String, + orderTime: String, + planDeliverTime: String, + requireOverTime: String, + customerName: String, + customerPhone: String, + customerAddress: String, + remark: String, + minioFileName: String, + certifications: String, + isUrgent: String, + samples: List + ): String { + val paramObject = JSONObject() + paramObject["deliverer"] = deliverer + paramObject["delivererTel"] = delivererTel + paramObject["orderTime"] = orderTime + paramObject["planDeliverTime"] = planDeliverTime + paramObject["requireOverTime"] = requireOverTime + paramObject["customerName"] = customerName + paramObject["customerPhone"] = customerPhone + paramObject["customerAddress"] = customerAddress + paramObject["remark"] = remark + paramObject["minioFileName"] = minioFileName + paramObject["certifications"] = certifications + paramObject["isUrgent"] = isUrgent + paramObject["customerSampleInfoList"] = JSONArray.parseArray(JSON.toJSONString(samples)) + + val requestBody = paramObject.toString().toRequestBody( + "application/json;charset=UTF-8".toMediaType() + ) + return api.addEntrust(AuthenticationHelper.token!!, requestBody) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/view/home/EntrustAddActivity.kt b/app/src/main/java/com/casic/xz/meterage/view/home/EntrustAddActivity.kt index 3e30095..9c8d27b 100644 --- a/app/src/main/java/com/casic/xz/meterage/view/home/EntrustAddActivity.kt +++ b/app/src/main/java/com/casic/xz/meterage/view/home/EntrustAddActivity.kt @@ -1,52 +1,211 @@ package com.casic.xz.meterage.view.home +import android.app.Activity +import android.content.Context +import android.content.Intent +import android.graphics.Color +import android.graphics.Paint import android.util.Log +import androidx.activity.result.ActivityResult +import androidx.activity.result.ActivityResultCallback +import androidx.activity.result.contract.ActivityResultContracts import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R import com.casic.xz.meterage.adapter.CertificateTypeAdapter2 -import com.casic.xz.meterage.extensions.initLayoutImmersionBar +import com.casic.xz.meterage.adapter.CustomerSampleAdapter +import com.casic.xz.meterage.callback.DateSelectedCallback +import com.casic.xz.meterage.callback.OnImageCompressListener +import com.casic.xz.meterage.extensions.* +import com.casic.xz.meterage.model.EntrustDetailModel +import com.casic.xz.meterage.model.SampleListModel +import com.casic.xz.meterage.utils.FileType +import com.casic.xz.meterage.utils.GlideLoadEngine +import com.casic.xz.meterage.utils.LoadingDialogHub import com.casic.xz.meterage.vm.DictionaryViewModel +import com.casic.xz.meterage.vm.EntrustViewModel +import com.casic.xz.meterage.vm.FileUploadViewModel +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken import com.gyf.immersionbar.ImmersionBar +import com.luck.picture.lib.basic.PictureSelector +import com.luck.picture.lib.config.SelectMimeType +import com.luck.picture.lib.entity.LocalMedia +import com.luck.picture.lib.interfaces.OnResultCallbackListener import com.pengxh.kt.lite.base.KotlinBaseActivity -import com.pengxh.kt.lite.extensions.toJson +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.vm.LoadState +import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import kotlinx.android.synthetic.main.activity_entrust_add.* +import java.io.File + class EntrustAddActivity : KotlinBaseActivity() { + private val context: Context = this@EntrustAddActivity + private val gson by lazy { Gson() } private lateinit var dictionaryViewModel: DictionaryViewModel - private var checkedItems = ArrayList() + private lateinit var fileUploadViewModel: FileUploadViewModel + private lateinit var entrustViewModel: EntrustViewModel + private lateinit var sampleAdapter: CustomerSampleAdapter + private var checkedItems = ArrayList() + private var isUrgent = "0" + private var sampleModels: ArrayList? = null + private var dataBeans = ArrayList() override fun initData() { //证书 dictionaryViewModel = ViewModelProvider(this)[DictionaryViewModel::class.java] dictionaryViewModel.getDictionaryByCode("certificationClass") - dictionaryViewModel.dictionary.observe(this) { dic -> - if (dic.code == 200) { - val typeAdapter2 = CertificateTypeAdapter2(this, dic.data) + dictionaryViewModel.dictionary.observe(this) { + if (it.code == 200) { + val typeAdapter2 = CertificateTypeAdapter2(this, it.data) typeRecyclerView.adapter = typeAdapter2 typeAdapter2.setOnItemCheckedListener(object : CertificateTypeAdapter2.OnItemCheckedListener { override fun onItemChecked(position: Int, isChecked: Boolean) { if (isChecked) { - checkedItems.add(position) + checkedItems.add(position.toString()) } else { - checkedItems.remove(position) + checkedItems.remove(position.toString()) } } }) } } + + fileUploadViewModel = ViewModelProvider(this)[FileUploadViewModel::class.java] + fileUploadViewModel.resultModel.observe(this) { + if (it.code == 200) { + val annexName = it.data[0] + annexView.text = annexName + val textPaint = annexView.paint + textPaint.flags = Paint.UNDERLINE_TEXT_FLAG + textPaint.isAntiAlias = true + annexView.setTextColor(Color.BLUE) + + annexView.setOnClickListener { + annexName.watchAttachFile(this) + } + } + } + + entrustViewModel = ViewModelProvider(this)[EntrustViewModel::class.java] + entrustViewModel.addResult.observe(this) { + if (it.code == 200) { + finish() + } + } + + //样品列表 + sampleAdapter = CustomerSampleAdapter(this, dataBeans) + sampleRecyclerView.adapter = sampleAdapter } + private val selectCustomerLauncher = + registerForActivityResult(ActivityResultContracts.StartActivityForResult(), + object : ActivityResultCallback { + override fun onActivityResult(result: ActivityResult?) { + if (result?.resultCode == Activity.RESULT_OK) { + val data = result.data ?: return + + entrustNameView.text = data.getStringExtra("entrustName") + entrustContactView.text = data.getStringExtra("entrustContact") + entrustAddressView.text = data.getStringExtra("entrustAddress") + } + } + }) + + private val selectSampleLauncher = + registerForActivityResult(ActivityResultContracts.StartActivityForResult(), + object : ActivityResultCallback { + override fun onActivityResult(result: ActivityResult?) { + if (result?.resultCode == Activity.RESULT_OK) { + val data = result.data ?: return + + val modelsJson = data.getStringExtra("sampleModels") + if (!modelsJson.isNullOrBlank()) { + sampleModels = gson.fromJson( + modelsJson, + object : + TypeToken>() {}.type + ) + } + + //刷新列表 + dataBeans.clear() + sampleModels?.forEach { + val model = + EntrustDetailModel.DataModel.CustomerSampleInfoListModel() + + model.customerName = it.customerName + model.customerNo = it.customerNo + model.id = it.id + model.manufacturingNo = it.manufacturingNo + model.measureLastTime = it.measureLastTime + model.measurePeriod = it.measurePeriod + model.orderId = it.orderId + model.remark = it.remark + model.sampleModel = it.sampleModel + model.sampleName = it.sampleName + model.sampleNo = it.sampleNo + model.validDeadline = it.validDeadline + + dataBeans.add(model) + } + sampleAdapter.notifyDataSetChanged() + } + } + }) + override fun initEvent() { + leftBackView.setOnClickListener { finish() } + + estimateTimeView.setOnClickListener { + showDatePicker(object : DateSelectedCallback { + override fun onDateSelected(date: String) { + estimateTimeView.text = date + } + }) + } + + completedView.setOnClickListener { + showDatePicker(object : DateSelectedCallback { + override fun onDateSelected(date: String) { + completedView.text = date + } + }) + } + + entrustNameView.setOnClickListener { + selectCustomerLauncher.launch(Intent(this, SelectCustomerActivity::class.java)) + } + //上传附件 uploadFileButton.setOnClickListener { + BottomActionSheet.Builder() + .setContext(this) + .setItemTextColor(Color.BLUE) + .setActionItemTitle(listOf("文件", "图片")) + .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { + override fun onActionItemClick(position: Int) { + when (position) { + 0 -> uploadFile() + 1 -> uploadImage() + } + } + }).build().show() + } + radioGroup.setOnCheckedChangeListener { _, checkedId -> + when (checkedId) { + R.id.radioButton1 -> isUrgent = "1" + R.id.radioButton2 -> isUrgent = "0" + } } //选择样品 selectSampleButton.setOnClickListener { - + selectSampleLauncher.launch(Intent(this, SelectSampleActivity::class.java)) } //写入样品信息 @@ -55,14 +214,68 @@ } pushEntrustView.setOnClickListener { - Log.d("Casic", "EntrustAddActivity => initEvent: ${checkedItems.toJson()}") + val sender = senderView.text.toString() + if (sender.isBlank()) { + "请填写送样人名字".show(this) + return@setOnClickListener + } + + val contact = contactView.text.toString() + if (contact.isBlank()) { + "请填写送样人联系方式".show(this) + return@setOnClickListener + } + + val estimateTime = estimateTimeView.text.toString() + if (estimateTime.isBlank()) { + "请选择预计送到的时间".show(this) + return@setOnClickListener + } + + val entrustName = entrustNameView.text.toString() + if (entrustName.isBlank()) { + "请选择委托方".show(this) + return@setOnClickListener + } + + if (sampleModels == null) { + "请选择样品".show(this) + return@setOnClickListener + } + entrustViewModel.addEntrust( + sender, + contact, + createEntrustDateView.text.toString(), + estimateTime, + completedView.text.toString(), + entrustName, + entrustContactView.text.toString(), + entrustAddressView.text.toString(), + remarkView.text.toString(), + annexView.text.toString(), + checkedItems.reformat(), + isUrgent, + sampleModels!! + ) } } override fun initLayoutView(): Int = R.layout.activity_entrust_add override fun observeRequestState() { + fileUploadViewModel.loadState.observe(this) { + when (it) { + LoadState.Loading -> LoadingDialogHub.show(this, "文件上传中,请稍后...") + else -> LoadingDialogHub.dismiss() + } + } + entrustViewModel.loadState.observe(this) { + when (it) { + LoadState.Loading -> LoadingDialogHub.show(this, "委托创建中,请稍后...") + else -> LoadingDialogHub.dismiss() + } + } } override fun setupTopBarLayout() { @@ -70,4 +283,62 @@ initLayoutImmersionBar(rootView) titleView.text = "委托需求" } + + private fun uploadFile() { +// val explorer = FileExplorer(this) +// explorer.setInitDir(ExplorerMode.FILE, Environment.getExternalStorageDirectory()) +// explorer.setShowHomeDir(true) +// explorer.setShowUpDir(true) +// explorer.setShowHideDir(true) +// explorer.setAllowExtensions(arrayOf(".doc", ".docx", ".xls", ".xlsx", ".pdf")) +// explorer.setOnFileClickedListener { +// val type = if (it.name.endsWith(".doc") || it.name.endsWith(".docx")) { +// FileType.WORD +// } else if (it.name.endsWith(".pdf")) { +// FileType.PDF +// } else { +// FileType.UNKNOWN +// } +// +// Log.d("Casic", "EntrustAddActivity => uploadFile: ${it.absolutePath}") +// fileUploadViewModel.uploadFile(it, type) +// } + } + + private fun uploadImage() { + PictureSelector.create(this) + .openGallery(SelectMimeType.ofImage()) + .isGif(false) + .isMaxSelectEnabledMask(true) + .setFilterMinFileSize(100) + .setMaxSelectNum(1) + .isDisplayCamera(false) + .setImageEngine(GlideLoadEngine.instance) + .forResult(object : OnResultCallbackListener { + override fun onResult(result: ArrayList?) { + if (result == null) { + "选择照片失败,请重试".show(context) + return + } + result[0].realPath.compressImage(context, object : OnImageCompressListener { + override fun onSuccess(file: File) { + Log.d( + "Casic", "EntrustAddActivity => onSuccess: ${file.absolutePath}" + ) + ///storage/emulated/0/Android/data/com.casic.xz.meterage/files/Pictures/CompressImage/1677478115391211.jpeg + //上传图片 + fileUploadViewModel.uploadFile(file, FileType.IMAGE) + } + + override fun onError(e: Throwable) { + e.printStackTrace() + } + }) + } + + override fun onCancel() { + + } + }) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/view/home/SelectCustomerActivity.kt b/app/src/main/java/com/casic/xz/meterage/view/home/SelectCustomerActivity.kt new file mode 100644 index 0000000..9bf6a1a --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/view/home/SelectCustomerActivity.kt @@ -0,0 +1,158 @@ +package com.casic.xz.meterage.view.home + +import android.content.Intent +import android.os.Handler +import androidx.lifecycle.ViewModelProvider +import androidx.recyclerview.widget.DefaultItemAnimator +import androidx.recyclerview.widget.DividerItemDecoration +import com.casic.xz.meterage.R +import com.casic.xz.meterage.adapter.SelectCustomerAdapter +import com.casic.xz.meterage.extensions.initLayoutImmersionBar +import com.casic.xz.meterage.extensions.showEmptyPage +import com.casic.xz.meterage.model.CustomerListModel +import com.casic.xz.meterage.utils.LoadingDialogHub +import com.casic.xz.meterage.vm.CustomerViewModel +import com.gyf.immersionbar.ImmersionBar +import com.pengxh.kt.lite.base.KotlinBaseActivity +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.utils.WeakReferenceHandler +import com.pengxh.kt.lite.vm.LoadState +import kotlinx.android.synthetic.main.activity_select_customer.* +import kotlinx.android.synthetic.main.include_base_title.* +import kotlinx.android.synthetic.main.include_empty_view.* + +class SelectCustomerActivity : KotlinBaseActivity() { + + private lateinit var weakReferenceHandler: WeakReferenceHandler + private lateinit var customerViewModel: CustomerViewModel + private lateinit var selectCustomerAdapter: SelectCustomerAdapter + private var dataBeans: MutableList = ArrayList() + private var pageIndex = 1 + private var isRefresh = false + private var isLoadMore = false + private var customerModel: CustomerListModel.DataModel.RowsModel? = null + + override fun initData() { + weakReferenceHandler = WeakReferenceHandler(callback) + customerViewModel = ViewModelProvider(this)[CustomerViewModel::class.java] + customerViewModel.customerList.observe(this) { + if (it.code == 200) { + val dataRows = it.data?.rows!! + when { + isRefresh -> { + dataBeans.clear() + dataBeans = dataRows + customerLayout.finishRefresh() + isRefresh = false + } + isLoadMore -> { + if (dataRows.size == 0) { + "到底了,别拉了".show(this) + } + dataBeans.addAll(dataRows) + customerLayout.finishLoadMore() + isLoadMore = false + } + else -> { + dataBeans = dataRows + } + } + weakReferenceHandler.sendEmptyMessage(2023022701) + } + } + } + + override fun initEvent() { + leftBackView.setOnClickListener { + if (customerModel == null) { + "请选择委托方".show(this) + return@setOnClickListener + } + val intent = Intent() + intent.putExtra("entrustName", customerModel!!.customerName) + intent.putExtra("entrustContact", customerModel!!.phone) + intent.putExtra("entrustAddress", customerModel!!.fullAddress) + setResult(RESULT_OK, intent) + finish() + } + + customerLayout.setOnRefreshListener { + isRefresh = true + //刷新之后页码重置 + pageIndex = 1 + getCustomerList() + } + + customerLayout.setOnLoadMoreListener { + isLoadMore = true + pageIndex++ + getCustomerList() + } + } + + override fun initLayoutView(): Int = R.layout.activity_select_customer + + override fun observeRequestState() { + customerViewModel.loadState.observe(this) { + when (it) { + LoadState.Loading -> LoadingDialogHub.show(this, "数据加载中...") + else -> LoadingDialogHub.dismiss() + } + } + } + + override fun setupTopBarLayout() { + ImmersionBar.with(this).statusBarDarkFont(true).init() + initLayoutImmersionBar(rootView) + titleView.text = "客户列表" + } + + override fun onResume() { + super.onResume() + pageIndex = 1 + getCustomerList() + } + + private fun getCustomerList() { + customerViewModel.getCustomerList( + "", + "", + "", + "", + pageIndex + ) + } + + private val callback = Handler.Callback { + when (it.what) { + 2023022701 -> { + if (isRefresh || isLoadMore) { + selectCustomerAdapter.notifyDataSetChanged() + } else { + if (dataBeans.size == 0) { + emptyView!!.showEmptyPage("无客户数据") { + pageIndex = 1 + getCustomerList() + } + } else { + emptyView!!.hide() + selectCustomerAdapter = SelectCustomerAdapter(this, dataBeans) + customerRecyclerView.addItemDecoration( + DividerItemDecoration(this, DividerItemDecoration.VERTICAL) + ) + (customerRecyclerView.itemAnimator as DefaultItemAnimator).supportsChangeAnimations = + false + customerRecyclerView.adapter = selectCustomerAdapter + selectCustomerAdapter.setOnCheckedListener(object : + SelectCustomerAdapter.OnItemCheckedListener { + override fun onItemChecked(item: CustomerListModel.DataModel.RowsModel) { + customerModel = item + } + }) + } + } + } + } + true + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/view/home/SelectSampleActivity.kt b/app/src/main/java/com/casic/xz/meterage/view/home/SelectSampleActivity.kt new file mode 100644 index 0000000..f85cb44 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/view/home/SelectSampleActivity.kt @@ -0,0 +1,152 @@ +package com.casic.xz.meterage.view.home + +import android.content.Intent +import android.os.Handler +import androidx.lifecycle.ViewModelProvider +import androidx.recyclerview.widget.DefaultItemAnimator +import androidx.recyclerview.widget.DividerItemDecoration +import com.casic.xz.meterage.R +import com.casic.xz.meterage.adapter.SelectSampleAdapter +import com.casic.xz.meterage.extensions.initLayoutImmersionBar +import com.casic.xz.meterage.extensions.showEmptyPage +import com.casic.xz.meterage.model.SampleListModel +import com.casic.xz.meterage.vm.SampleViewModel +import com.gyf.immersionbar.ImmersionBar +import com.pengxh.kt.lite.base.KotlinBaseActivity +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.extensions.toJson +import com.pengxh.kt.lite.utils.WeakReferenceHandler +import kotlinx.android.synthetic.main.activity_select_sample.* +import kotlinx.android.synthetic.main.include_base_title.* +import kotlinx.android.synthetic.main.include_empty_view.* + +class SelectSampleActivity : KotlinBaseActivity() { + + private lateinit var weakReferenceHandler: WeakReferenceHandler + private lateinit var sampleViewModel: SampleViewModel + private lateinit var selectSampleAdapter: SelectSampleAdapter + private var dataBeans: MutableList = ArrayList() + private var pageIndex = 1 + private var isRefresh = false + private var isLoadMore = false + private var sampleModels = ArrayList() + + override fun initData() { + weakReferenceHandler = WeakReferenceHandler(callback) + sampleViewModel = ViewModelProvider(this)[SampleViewModel::class.java] + sampleViewModel.sampleList.observe(this) { + if (it.code == 200) { + val dataRows = it.data?.rows!! + when { + isRefresh -> { + dataBeans.clear() + dataBeans = dataRows + sampleLayout.finishRefresh() + isRefresh = false + } + isLoadMore -> { + if (dataRows.size == 0) { + "到底了,别拉了".show(this) + } + dataBeans.addAll(dataRows) + sampleLayout.finishLoadMore() + isLoadMore = false + } + else -> { + dataBeans = dataRows + } + } + weakReferenceHandler.sendEmptyMessage(2023030101) + } + } + } + + override fun initEvent() { + leftBackView.setOnClickListener { + val intent = Intent() + intent.putExtra("sampleModels", sampleModels.toJson()) + setResult(RESULT_OK, intent) + finish() + } + + sampleLayout.setOnRefreshListener { + isRefresh = true + //刷新之后页码重置 + pageIndex = 1 + getSampleList() + } + + sampleLayout.setOnLoadMoreListener { + isLoadMore = true + pageIndex++ + getSampleList() + } + } + + override fun initLayoutView(): Int = R.layout.activity_select_sample + + override fun observeRequestState() { + + } + + override fun setupTopBarLayout() { + ImmersionBar.with(this).statusBarDarkFont(true).init() + initLayoutImmersionBar(rootView) + titleView.text = "样品列表" + } + + override fun onResume() { + super.onResume() + pageIndex = 1 + getSampleList() + } + + private fun getSampleList() { + sampleViewModel.getSampleList( + "", + "", + "", + "", + "", + "", + "", + "", + "", + arrayOf(), + pageIndex + ) + } + + private val callback = Handler.Callback { + when (it.what) { + 2023030101 -> { + if (isRefresh || isLoadMore) { + selectSampleAdapter.notifyDataSetChanged() + } else { + if (dataBeans.size == 0) { + emptyView!!.showEmptyPage("无样品数据") { + pageIndex = 1 + getSampleList() + } + } else { + emptyView!!.hide() + selectSampleAdapter = SelectSampleAdapter(this, dataBeans) + sampleRecyclerView.addItemDecoration( + DividerItemDecoration(this, DividerItemDecoration.VERTICAL) + ) + (sampleRecyclerView.itemAnimator as DefaultItemAnimator).supportsChangeAnimations = + false + sampleRecyclerView.adapter = selectSampleAdapter + selectSampleAdapter.setOnCheckedListener(object : + SelectSampleAdapter.OnItemCheckedListener { + override fun onItemChecked(items: ArrayList) { + sampleModels = items + } + }) + } + } + } + } + true + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/view/notice/NoticeDetailActivity.kt b/app/src/main/java/com/casic/xz/meterage/view/notice/NoticeDetailActivity.kt index a9d9422..9596985 100644 --- a/app/src/main/java/com/casic/xz/meterage/view/notice/NoticeDetailActivity.kt +++ b/app/src/main/java/com/casic/xz/meterage/view/notice/NoticeDetailActivity.kt @@ -1,6 +1,7 @@ package com.casic.xz.meterage.view.notice import android.annotation.SuppressLint +import android.graphics.Color import android.graphics.Paint import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R @@ -10,7 +11,6 @@ import com.casic.xz.meterage.vm.NoticeViewModel import com.gyf.immersionbar.ImmersionBar import com.pengxh.kt.lite.base.KotlinBaseActivity -import com.pengxh.kt.lite.extensions.convertColor import com.pengxh.kt.lite.extensions.obtainScreenWidth import com.pengxh.kt.lite.utils.Constant import kotlinx.android.synthetic.main.activity_notice_detail.* @@ -54,7 +54,7 @@ val textPaint = minioFileView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - minioFileView.setTextColor(R.color.themeColor.convertColor(this)) + minioFileView.setTextColor(Color.BLUE) minioFileView.setOnClickListener { minioFileName.watchAttachFile(this) diff --git a/app/src/main/java/com/casic/xz/meterage/vm/EntrustViewModel.kt b/app/src/main/java/com/casic/xz/meterage/vm/EntrustViewModel.kt index 2280f88..103c002 100644 --- a/app/src/main/java/com/casic/xz/meterage/vm/EntrustViewModel.kt +++ b/app/src/main/java/com/casic/xz/meterage/vm/EntrustViewModel.kt @@ -7,6 +7,7 @@ import com.casic.xz.meterage.model.ActionResultModel import com.casic.xz.meterage.model.EntrustDetailModel import com.casic.xz.meterage.model.EntrustListModel +import com.casic.xz.meterage.model.SampleListModel import com.casic.xz.meterage.utils.retrofit.RetrofitServiceManager import com.google.gson.Gson import com.google.gson.reflect.TypeToken @@ -25,6 +26,7 @@ val entrustDetail = MutableLiveData() val acceptResult = MutableLiveData() val returnResult = MutableLiveData() + val addResult = MutableLiveData() fun getEntrustList( customerName: String, @@ -119,4 +121,50 @@ loadState.value = LoadState.Fail it.cause.toString().show(BaseApplication.get()) }) + + fun addEntrust( + deliverer: String, + delivererTel: String, + orderTime: String, + planDeliverTime: String, + requireOverTime: String, + customerName: String, + customerPhone: String, + customerAddress: String, + remark: String, + minioFileName: String, + certifications: String, + isUrgent: String, + samples: List + ) = launch({ + loadState.value = LoadState.Loading + val response = RetrofitServiceManager.addEntrust( + deliverer, + delivererTel, + orderTime, + planDeliverTime, + requireOverTime, + customerName, + customerPhone, + customerAddress, + remark, + minioFileName, + certifications, + isUrgent, + samples + ) + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + loadState.value = LoadState.Success + addResult.value = gson.fromJson( + response, object : TypeToken() {}.type + ) + } else { + loadState.value = LoadState.Fail + response.toErrorMessage().show(BaseApplication.get()) + } + }, { + loadState.value = LoadState.Fail + it.cause.toString().show(BaseApplication.get()) + }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/vm/FileUploadViewModel.kt b/app/src/main/java/com/casic/xz/meterage/vm/FileUploadViewModel.kt new file mode 100644 index 0000000..b16c1c7 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/vm/FileUploadViewModel.kt @@ -0,0 +1,40 @@ +package com.casic.xz.meterage.vm + +import androidx.lifecycle.MutableLiveData +import com.casic.xz.meterage.base.BaseApplication +import com.casic.xz.meterage.extensions.separateResponseCode +import com.casic.xz.meterage.extensions.toErrorMessage +import com.casic.xz.meterage.model.UploadResultModel +import com.casic.xz.meterage.utils.FileType +import com.casic.xz.meterage.utils.retrofit.RetrofitServiceManager +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken +import com.pengxh.kt.lite.extensions.launch +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.vm.BaseViewModel +import com.pengxh.kt.lite.vm.LoadState +import java.io.File + +class FileUploadViewModel : BaseViewModel() { + + private val gson by lazy { Gson() } + val resultModel = MutableLiveData() + + fun uploadFile(file: File, type: FileType) = launch({ + loadState.value = LoadState.Loading + val response = RetrofitServiceManager.uploadFile(file, type) + 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(BaseApplication.get()) + } + }, { + loadState.value = LoadState.Fail + it.cause.toString().show(BaseApplication.get()) + }) +} \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 0ae369f..687b02b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -15,7 +15,6 @@ } compileSdkVersion 31 - buildToolsVersion "30.0.3" defaultConfig { applicationId "com.casic.xz.meterage" @@ -84,11 +83,13 @@ implementation 'top.zibin:Luban:1.1.8' //官方Json解析库 implementation 'com.google.code.gson:gson:2.9.0' + //阿里巴巴JSON库 + implementation 'com.alibaba.fastjson2:fastjson2:2.0.24' //Kotlin协程 implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.5.1' //MVVM+LiveData implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.5.1" - implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.0" + implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1" implementation "androidx.lifecycle:lifecycle-extensions:2.2.0" //返回值转换器 implementation 'com.jakewharton.retrofit:retrofit2-kotlin-coroutines-adapter:0.9.2' @@ -109,4 +110,8 @@ implementation 'com.github.barteksc:android-pdf-viewer:2.8.2' //绕过Android 11反射限制 implementation 'com.github.tiann:FreeReflection:3.1.0' + //单项/数字、二三级联动、日期/时间等滚轮选择器 + implementation 'com.github.gzu-liyujiang.AndroidPicker:WheelPicker:4.1.8' + //文件/目录选择器 + implementation 'com.github.gzu-liyujiang.AndroidPicker:FilePicker:4.1.1' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 1ccc12b..0fba91b 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -60,6 +60,8 @@ + + diff --git a/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt b/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt new file mode 100644 index 0000000..21a71d8 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt @@ -0,0 +1,70 @@ +package com.casic.xz.meterage.adapter + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import com.casic.xz.meterage.R +import com.casic.xz.meterage.extensions.toChineseGrade +import com.casic.xz.meterage.model.CustomerListModel + +class SelectCustomerAdapter( + context: Context, private val dataRows: MutableList +) : RecyclerView.Adapter() { + + private var layoutInflater = LayoutInflater.from(context) + + //选择的位置 + private var selectedPosition = 0 + + //临时记录上次选择的位置 + private var temp = -1 + + override fun getItemCount(): Int = dataRows.size + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ItemViewHolder( + layoutInflater.inflate(R.layout.item_select_customer_lv, parent, false) + ) + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + //绑定数据 + val rowsBean = dataRows[position] + holder.agreementLevelView.text = rowsBean.grade.toChineseGrade() + holder.customerNameView.text = rowsBean.customerName + holder.scaleView.text = rowsBean.companySizeName + holder.overallView.text = "公司规模:${rowsBean.evaluationName}" + holder.fullAddressView.text = "公司地址:${rowsBean.fullAddress}" + + holder.itemView.isSelected = holder.layoutPosition == selectedPosition + holder.itemView.setOnClickListener { + itemCheckedListener?.onItemChecked(rowsBean) + + holder.itemView.isSelected = true + temp = selectedPosition + //设置新的位置 + selectedPosition = holder.layoutPosition + //更新旧位置 + notifyItemChanged(temp) + } + } + + inner class ItemViewHolder(view: View) : RecyclerView.ViewHolder(view) { + var agreementLevelView: TextView = view.findViewById(R.id.agreementLevelView) + var customerNameView: TextView = view.findViewById(R.id.customerNameView) + var scaleView: TextView = view.findViewById(R.id.scaleView) + var overallView: TextView = view.findViewById(R.id.overallView) + var fullAddressView: TextView = view.findViewById(R.id.fullAddressView) + } + + private var itemCheckedListener: OnItemCheckedListener? = null + + interface OnItemCheckedListener { + fun onItemChecked(item: CustomerListModel.DataModel.RowsModel) + } + + fun setOnCheckedListener(listener: OnItemCheckedListener?) { + itemCheckedListener = listener + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt b/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt new file mode 100644 index 0000000..c29461e --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt @@ -0,0 +1,68 @@ +package com.casic.xz.meterage.adapter + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import com.casic.xz.meterage.R +import com.casic.xz.meterage.model.SampleListModel + +class SelectSampleAdapter( + context: Context, private val dataRows: MutableList +) : RecyclerView.Adapter() { + + private var layoutInflater = LayoutInflater.from(context) + private var multipleSelected = mutableSetOf() + private var sampleModes = ArrayList() + + override fun getItemCount(): Int = dataRows.size + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ItemViewHolder( + layoutInflater.inflate(R.layout.item_select_sample_lv, parent, false) + ) + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + //绑定数据 + val rowsBean = dataRows[position] + holder.sampleNameView.text = "${rowsBean.sampleName}【${rowsBean.sampleModel}】" + holder.manufacturingCodeView.text = "出厂编号:${rowsBean.manufacturingNo}" + holder.sampleCodeView.text = "样品编号:${rowsBean.sampleNo}" + holder.validDateView.text = "有效期至:${rowsBean.validDeadline}" + + holder.checkImageView.isSelected = multipleSelected.contains(position) + holder.itemView.setOnClickListener { + if (multipleSelected.contains(position)) { + multipleSelected.remove(position) + sampleModes.remove(dataRows[position]) + holder.checkImageView.isSelected = false + } else { + multipleSelected.add(position) + sampleModes.add(dataRows[position]) + holder.checkImageView.isSelected = true + } + + itemCheckedListener?.onItemChecked(sampleModes) + } + } + + inner class ItemViewHolder(view: View) : RecyclerView.ViewHolder(view) { + var sampleNameView: TextView = view.findViewById(R.id.sampleNameView) + var manufacturingCodeView: TextView = view.findViewById(R.id.manufacturingCodeView) + var sampleCodeView: TextView = view.findViewById(R.id.sampleCodeView) + var validDateView: TextView = view.findViewById(R.id.validDateView) + var checkImageView: ImageView = view.findViewById(R.id.checkImageView) + } + + private var itemCheckedListener: OnItemCheckedListener? = null + + interface OnItemCheckedListener { + fun onItemChecked(items: ArrayList) + } + + fun setOnCheckedListener(listener: OnItemCheckedListener?) { + itemCheckedListener = listener + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/callback/DateSelectedCallback.kt b/app/src/main/java/com/casic/xz/meterage/callback/DateSelectedCallback.kt new file mode 100644 index 0000000..8196110 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/callback/DateSelectedCallback.kt @@ -0,0 +1,5 @@ +package com.casic.xz.meterage.callback + +interface DateSelectedCallback { + fun onDateSelected(date: String) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/Activity.kt b/app/src/main/java/com/casic/xz/meterage/extensions/Activity.kt new file mode 100644 index 0000000..e112d1c --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/extensions/Activity.kt @@ -0,0 +1,33 @@ +package com.casic.xz.meterage.extensions + +import android.app.Activity +import com.casic.xz.meterage.R +import com.casic.xz.meterage.callback.DateSelectedCallback +import com.github.gzuliyujiang.wheelpicker.DatePicker +import com.github.gzuliyujiang.wheelpicker.annotation.DateMode +import com.github.gzuliyujiang.wheelpicker.entity.DateEntity +import com.pengxh.kt.lite.extensions.convertColor +import com.pengxh.kt.lite.extensions.sp2px + +fun Activity.showDatePicker(callback: DateSelectedCallback) { + val datePicker = DatePicker(this) + + val layout = datePicker.wheelLayout + layout.setDateMode(DateMode.YEAR_MONTH_DAY) + layout.setDateLabel("年", "月", "日"); + layout.setTextSize(14f.sp2px(this).toFloat()) + layout.setSelectedTextSize(16f.sp2px(this).toFloat()) + layout.setSelectedTextColor(R.color.themeColor.convertColor(this)) + layout.setSelectedTextBold(true) + layout.setResetWhenLinkage(false) + layout.setRange( + DateEntity.today(), + DateEntity.target(2050, 12, 31), + DateEntity.today() + ) + + datePicker.setOnDatePickedListener { year, month, day -> + callback.onDateSelected(String.format("%s-%s-%s", year, month, day)) + } + datePicker.show() +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt b/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt index 016ebcb..cf6bf49 100644 --- a/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt +++ b/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt @@ -4,7 +4,7 @@ * ArrayList扩展方法 */ -//将图片集合格式化成满足上传格式的数据 +//将集合格式化成满足上传格式的数据 fun ArrayList.reformat(): String { if (this.isEmpty()) return "" val builder = StringBuilder() diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt b/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt index 7c57643..aa9b92b 100644 --- a/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt +++ b/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt @@ -1,7 +1,6 @@ package com.casic.xz.meterage.extensions import android.content.Context -import android.util.Log import android.view.ViewGroup import com.casic.xz.meterage.base.BaseApplication import com.pengxh.kt.lite.extensions.dp2px @@ -9,9 +8,8 @@ fun Context.initLayoutImmersionBar(rootView: ViewGroup) { var statusBarHeight = QMUIDisplayHelper.getStatusBarHeight(this) - Log.d("Casic", "状态栏高度: $statusBarHeight") if (statusBarHeight == 0) { - statusBarHeight = 44f.dp2px(BaseApplication.get()) + statusBarHeight = 40f.dp2px(BaseApplication.get()) } rootView.setPadding(0, statusBarHeight, 0, 0) rootView.requestLayout() diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/String.kt b/app/src/main/java/com/casic/xz/meterage/extensions/String.kt index 28f70d8..6234d43 100644 --- a/app/src/main/java/com/casic/xz/meterage/extensions/String.kt +++ b/app/src/main/java/com/casic/xz/meterage/extensions/String.kt @@ -128,9 +128,10 @@ fun String.combineImagePath(): String { if (this.isEmpty()) return this val defaultValue = SaveKeyValues.getValue( - LocaleConstant.DEFAULT_SERVER_CONFIG, LocaleConstant.SERVER_BASE_URL + LocaleConstant.FILE_SERVER_CONFIG, LocaleConstant.File_SERVER_URL ) as String - return "$defaultValue/static/${this.replace("\\", "/")}" + //http://111.198.10.15:21408/test/1677479806059688_1677479806038.jpeg + return "$defaultValue/test/${this.replace("\\", "/")}" } fun String.isEarlier(time: String): Boolean { diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt index 25fa87b..a0e1358 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt @@ -1,18 +1,12 @@ package com.casic.xz.meterage.fragment.customer +import android.graphics.Color import android.graphics.Paint import com.casic.xz.meterage.R -import com.casic.xz.meterage.extensions.combineImagePath import com.casic.xz.meterage.extensions.toChineseGrade +import com.casic.xz.meterage.extensions.watchAttachFile import com.casic.xz.meterage.model.CustomerDetailModel -import com.casic.xz.meterage.view.BigImageActivity -import com.casic.xz.meterage.view.notice.PreviewDocumentActivity -import com.casic.xz.meterage.view.notice.PreviewPdfActivity -import com.casic.xz.meterage.view.notice.PreviewTextActivity import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.extensions.show import kotlinx.android.synthetic.main.fragment_customer_basic_information.* class BasicInformationFragment(private val data: CustomerDetailModel.DataModel) : @@ -48,30 +42,11 @@ val textPaint = minioFileView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - minioFileView.setTextColor(R.color.themeColor.convertColor(requireContext())) + minioFileView.setTextColor(Color.BLUE) minioFileView.setOnClickListener { //查看附件 - if (minioFileName.endsWith("pdf")) { - requireContext().navigatePageTo(minioFileName) - } else if ( - minioFileName.endsWith("doc") || - minioFileName.endsWith("docx") - ) { - requireContext().navigatePageTo(minioFileName) - } else if (minioFileName.endsWith("txt")) { - requireContext().navigatePageTo(minioFileName) - } else if ( - minioFileName.endsWith("png") || - minioFileName.endsWith("jpeg") || - minioFileName.endsWith("jpg") - ) { - val urls = ArrayList() - urls.add(minioFileName.combineImagePath()) - requireContext().navigatePageTo(0, urls) - } else { - "文件类型未知,无法打开附件".show(requireContext()) - } + minioFileName.watchAttachFile(requireContext()) } } } diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt index 77846b4..3a0fe2e 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt @@ -1,5 +1,6 @@ package com.casic.xz.meterage.fragment.device +import android.graphics.Color import android.graphics.Paint import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R @@ -7,7 +8,6 @@ import com.casic.xz.meterage.utils.LoadingDialogHub import com.casic.xz.meterage.vm.EquipmentViewModel import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor import com.pengxh.kt.lite.vm.LoadState import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import kotlinx.android.synthetic.main.fragment_device_basic_information.* @@ -56,7 +56,7 @@ val textPaint = documentsView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - documentsView.setTextColor(R.color.themeColor.convertColor(requireContext())) + documentsView.setTextColor(Color.BLUE) val files = ArrayList() data.fileList.forEach { file -> @@ -66,7 +66,7 @@ BottomActionSheet.Builder() .setContext(requireContext()) .setActionItemTitle(files) - .setItemTextColor(R.color.themeColor.convertColor(requireContext())) + .setItemTextColor(Color.BLUE) .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { override fun onActionItemClick(position: Int) { diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt index 15dc3d2..10eeff8 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt @@ -1,5 +1,6 @@ package com.casic.xz.meterage.fragment.entrust +import android.graphics.Color import android.graphics.Paint import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R @@ -9,7 +10,6 @@ import com.casic.xz.meterage.model.EntrustDetailModel import com.casic.xz.meterage.vm.DictionaryViewModel import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor import kotlinx.android.synthetic.main.fragment_entrust_basic_information.* class BasicInformationFragment(private val data: EntrustDetailModel.DataModel) : @@ -38,7 +38,7 @@ val textPaint = annexView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - annexView.setTextColor(R.color.themeColor.convertColor(requireContext())) + annexView.setTextColor(Color.BLUE) annexView.setOnClickListener { minioFileName.watchAttachFile(requireContext()) @@ -59,9 +59,9 @@ //加急 if (data.isUrgent == "0") { - RadioButton2.isChecked = true + radioButton2.isChecked = true } else { - RadioButton1.isChecked = true + radioButton1.isChecked = true } //样品 diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/equipment/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/equipment/BasicInformationFragment.kt index 72b523c..7bc3b01 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/equipment/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/equipment/BasicInformationFragment.kt @@ -1,5 +1,6 @@ package com.casic.xz.meterage.fragment.equipment +import android.graphics.Color import android.graphics.Paint import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R @@ -7,7 +8,6 @@ import com.casic.xz.meterage.utils.LoadingDialogHub import com.casic.xz.meterage.vm.EquipmentViewModel import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor import com.pengxh.kt.lite.vm.LoadState import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import kotlinx.android.synthetic.main.fragment_equipment_basic_information.* @@ -74,7 +74,7 @@ val textPaint = instructionsView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - instructionsView.setTextColor(R.color.themeColor.convertColor(requireContext())) + instructionsView.setTextColor(Color.BLUE) val files = ArrayList() data.fileList.forEach { file -> @@ -84,7 +84,7 @@ BottomActionSheet.Builder() .setContext(requireContext()) .setActionItemTitle(files) - .setItemTextColor(R.color.themeColor.convertColor(requireContext())) + .setItemTextColor(Color.BLUE) .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { override fun onActionItemClick(position: Int) { diff --git a/app/src/main/java/com/casic/xz/meterage/model/SampleListModel.java b/app/src/main/java/com/casic/xz/meterage/model/SampleListModel.java new file mode 100644 index 0000000..5784343 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/model/SampleListModel.java @@ -0,0 +1,193 @@ +package com.casic.xz.meterage.model; + +import java.util.List; + +public class SampleListModel { + + private int code; + private DataModel data; + private String message; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataModel getData() { + return data; + } + + public void setData(DataModel data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public static class DataModel { + private List rows; + private int total; + + public List getRows() { + return rows; + } + + public void setRows(List rows) { + this.rows = rows; + } + + public int getTotal() { + return total; + } + + public void setTotal(int total) { + this.total = total; + } + + public static class RowsModel { + private String certificationStatus; + private String customerName; + private String customerNo; + private String id; + private String manufacturingNo; + private String measureLastTime; + private String measurePeriod; + private String orderId; + private String remark; + private String sampleModel; + private String sampleName; + private String sampleNo; + private String sampleSatus; + private String sampleSatusName; + private String validDeadline; + + public String getCertificationStatus() { + return certificationStatus; + } + + public void setCertificationStatus(String certificationStatus) { + this.certificationStatus = certificationStatus; + } + + public String getCustomerName() { + return customerName; + } + + public void setCustomerName(String customerName) { + this.customerName = customerName; + } + + public String getCustomerNo() { + return customerNo; + } + + public void setCustomerNo(String customerNo) { + this.customerNo = customerNo; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getManufacturingNo() { + return manufacturingNo; + } + + public void setManufacturingNo(String manufacturingNo) { + this.manufacturingNo = manufacturingNo; + } + + public String getMeasureLastTime() { + return measureLastTime; + } + + public void setMeasureLastTime(String measureLastTime) { + this.measureLastTime = measureLastTime; + } + + public String getMeasurePeriod() { + return measurePeriod; + } + + public void setMeasurePeriod(String measurePeriod) { + this.measurePeriod = measurePeriod; + } + + public String getOrderId() { + return orderId; + } + + public void setOrderId(String orderId) { + this.orderId = orderId; + } + + public String getRemark() { + return remark; + } + + public void setRemark(String remark) { + this.remark = remark; + } + + public String getSampleModel() { + return sampleModel; + } + + public void setSampleModel(String sampleModel) { + this.sampleModel = sampleModel; + } + + public String getSampleName() { + return sampleName; + } + + public void setSampleName(String sampleName) { + this.sampleName = sampleName; + } + + public String getSampleNo() { + return sampleNo; + } + + public void setSampleNo(String sampleNo) { + this.sampleNo = sampleNo; + } + + public String getSampleSatus() { + return sampleSatus; + } + + public void setSampleSatus(String sampleSatus) { + this.sampleSatus = sampleSatus; + } + + public String getSampleSatusName() { + return sampleSatusName; + } + + public void setSampleSatusName(String sampleSatusName) { + this.sampleSatusName = sampleSatusName; + } + + public String getValidDeadline() { + return validDeadline; + } + + public void setValidDeadline(String validDeadline) { + this.validDeadline = validDeadline; + } + } + } +} diff --git a/app/src/main/java/com/casic/xz/meterage/model/UploadResultModel.java b/app/src/main/java/com/casic/xz/meterage/model/UploadResultModel.java new file mode 100644 index 0000000..f2a6a41 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/model/UploadResultModel.java @@ -0,0 +1,34 @@ +package com.casic.xz.meterage.model; + +import java.util.List; + +public class UploadResultModel { + + private int code; + private List data; + private String message; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public List getData() { + return data; + } + + public void setData(List data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } +} diff --git a/app/src/main/java/com/casic/xz/meterage/utils/FileType.kt b/app/src/main/java/com/casic/xz/meterage/utils/FileType.kt new file mode 100644 index 0000000..17e2bca --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/utils/FileType.kt @@ -0,0 +1,23 @@ +package com.casic.xz.meterage.utils + +sealed class FileType { + /** + * PDF文件 + */ + object PDF : FileType() + + /** + * WORD文件 + */ + object WORD : FileType() + + /** + * IMAGE图片 + */ + object IMAGE : FileType() + + /** + * 未知类型(Excel) + */ + object UNKNOWN : FileType() +} diff --git a/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitService.kt index bc3f8d6..8f4fe44 100644 --- a/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitService.kt @@ -1,5 +1,6 @@ package com.casic.xz.meterage.utils.retrofit +import okhttp3.MultipartBody import okhttp3.RequestBody import retrofit2.http.* @@ -35,6 +36,16 @@ ): String /** + * 上传文件 + */ + @Multipart + @POST("/minio/file/upload") + suspend fun uploadFile( + @Header("token") token: String, + @Part file: MultipartBody.Part + ): String + + /** * 获取通知公告列表 */ @POST("/system/notice/listPage") @@ -209,4 +220,24 @@ @Header("token") token: String, @Body requestBody: RequestBody ): String + + /** + * 获取样品列表 + */ + @POST("/customer/sample/listPage") + suspend fun getSampleList( + @Header("token") token: String, + @Body requestBody: RequestBody, + @QueryMap limit: Map, + @QueryMap offset: Map + ): String + + /** + * 新增委托书 + */ + @POST("/business/order/add") + suspend fun addEntrust( + @Header("token") token: String, + @Body requestBody: RequestBody + ): String } \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitServiceManager.kt index cb22e45..90abe5a 100644 --- a/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitServiceManager.kt @@ -1,13 +1,20 @@ package com.casic.xz.meterage.utils.retrofit +import com.alibaba.fastjson2.JSON +import com.alibaba.fastjson2.JSONArray +import com.alibaba.fastjson2.JSONObject +import com.casic.xz.meterage.model.SampleListModel import com.casic.xz.meterage.utils.AuthenticationHelper +import com.casic.xz.meterage.utils.FileType import com.casic.xz.meterage.utils.LocaleConstant import com.pengxh.kt.lite.utils.RetrofitFactory import com.pengxh.kt.lite.utils.SaveKeyValues import okhttp3.MediaType.Companion.toMediaType +import okhttp3.MediaType.Companion.toMediaTypeOrNull +import okhttp3.MultipartBody +import okhttp3.RequestBody.Companion.asRequestBody import okhttp3.RequestBody.Companion.toRequestBody -import org.json.JSONArray -import org.json.JSONObject +import java.io.File object RetrofitServiceManager { @@ -31,9 +38,9 @@ */ suspend fun login(sid: String, account: String, secretKey: String): String { val paramObject = JSONObject() - paramObject.put("sid", sid) - paramObject.put("username", account) - paramObject.put("password", secretKey) + paramObject["sid"] = sid + paramObject["username"] = account + paramObject["password"] = secretKey val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -55,6 +62,20 @@ } /** + * 上传文件 + */ + suspend fun uploadFile(file: File, type: FileType): String { + val requestBody = when (type) { + FileType.PDF -> file.asRequestBody("application/pdf".toMediaTypeOrNull()) + FileType.WORD -> file.asRequestBody("application/msword".toMediaTypeOrNull()) + FileType.IMAGE -> file.asRequestBody("image/png".toMediaTypeOrNull()) + else -> file.asRequestBody("application/vnd.ms-excel".toMediaTypeOrNull()) + } + val filePart = MultipartBody.Part.createFormData("multipartFile", file.name, requestBody) + return api.uploadFile(AuthenticationHelper.token!!, filePart) + } + + /** * 获取通知公告列表 */ suspend fun getNoticeList( @@ -66,11 +87,11 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("noticeNo", noticeNo) - paramObject.put("noticeTitle", noticeTitle) - paramObject.put("noticePublisher", noticePublisher) - paramObject.put("noticeStartTime", noticeStartTime) - paramObject.put("noticeEndTime", noticeEndTime) + paramObject["noticeNo"] = noticeNo + paramObject["noticeTitle"] = noticeTitle + paramObject["noticePublisher"] = noticePublisher + paramObject["noticeStartTime"] = noticeStartTime + paramObject["noticeEndTime"] = noticeEndTime val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -105,26 +126,21 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("equipmentNo", equipmentNo) - paramObject.put("equipmentName", equipmentName) - paramObject.put("mesureType", mesureType) - paramObject.put("managerState", managerState) - paramObject.put("useDept", useDept) - paramObject.put("assetType", assetType) - paramObject.put("equipmentCategory", equipmentCategory) - paramObject.put("isCalibrationTestEquipment", isCalibrationTestEquipment) - paramObject.put("isMeasureAccount", isMeasureAccount) - paramObject.put("isStandardSupportEquipment", isStandardSupportEquipment) - paramObject.put("isFixedAssets", isFixedAssets) - paramObject.put("validStartDate", validStartDate) - paramObject.put("validEndDate", validEndDate) - paramObject.put("abc", abc) - - val jsonArray = JSONArray() - ids.forEach { - jsonArray.put(it) - } - paramObject.put("ids", jsonArray) + paramObject["equipmentNo"] = equipmentNo + paramObject["equipmentName"] = equipmentName + paramObject["mesureType"] = mesureType + paramObject["managerState"] = managerState + paramObject["useDept"] = useDept + paramObject["assetType"] = assetType + paramObject["equipmentCategory"] = equipmentCategory + paramObject["isCalibrationTestEquipment"] = isCalibrationTestEquipment + paramObject["isMeasureAccount"] = isMeasureAccount + paramObject["isStandardSupportEquipment"] = isStandardSupportEquipment + paramObject["isFixedAssets"] = isFixedAssets + paramObject["validStartDate"] = validStartDate + paramObject["validEndDate"] = validEndDate + paramObject["abc"] = abc + paramObject["ids"] = JSONArray.parseArray(JSON.toJSONString(ids)) val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() @@ -143,7 +159,7 @@ */ suspend fun getEquipmentDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -164,13 +180,13 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("standardNo", standardNo) - paramObject.put("standardName", standardName) - paramObject.put("category", category) - paramObject.put("managerState", managerState) - paramObject.put("standardLaboratory", standardLaboratory) - paramObject.put("preparationDate", preparationDate) - paramObject.put("id", id) + paramObject["standardNo"] = standardNo + paramObject["standardName"] = standardName + paramObject["category"] = category + paramObject["managerState"] = managerState + paramObject["standardLaboratory"] = standardLaboratory + paramObject["preparationDate"] = preparationDate + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -193,7 +209,7 @@ */ suspend fun getStandardDeviceDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -212,11 +228,11 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("checkType", checkType) - paramObject.put("priceItem", priceItem) - paramObject.put("priceName", priceName) - paramObject.put("priceNo", priceNo) - paramObject.put("priceType", priceType) + paramObject["checkType"] = checkType + paramObject["priceItem"] = priceItem + paramObject["priceName"] = priceName + paramObject["priceNo"] = priceNo + paramObject["priceType"] = priceType val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -234,7 +250,7 @@ */ suspend fun getCapabilityDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -257,20 +273,15 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("createStartTime", createStartTime) - paramObject.put("createEndTime", createEndTime) - paramObject.put("deptId", deptId) - paramObject.put("director", director) - paramObject.put("effectiveCompany", effectiveCompany) - paramObject.put("trainStartTime", trainStartTime) - paramObject.put("trainEndTime", trainEndTime) - paramObject.put("formId", formId) - - val jsonArray = JSONArray() - ids.forEach { - jsonArray.put(it) - } - paramObject.put("ids", jsonArray) + paramObject["createStartTime"] = createStartTime + paramObject["createEndTime"] = createEndTime + paramObject["deptId"] = deptId + paramObject["director"] = director + paramObject["effectiveCompany"] = effectiveCompany + paramObject["trainStartTime"] = trainStartTime + paramObject["trainEndTime"] = trainEndTime + paramObject["formId"] = formId + paramObject["ids"] = JSONArray.parseArray(JSON.toJSONString(ids)) val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() @@ -294,7 +305,7 @@ */ suspend fun getMeterageTrainDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -308,10 +319,10 @@ bussinessSize: String, customerName: String, customerNo: String, grade: String, offset: Int ): String { val paramObject = JSONObject() - paramObject.put("bussinessSize", bussinessSize) - paramObject.put("customerName", customerName) - paramObject.put("customerNo", customerNo) - paramObject.put("grade", grade) + paramObject["bussinessSize"] = bussinessSize + paramObject["customerName"] = customerName + paramObject["customerNo"] = customerNo + paramObject["grade"] = grade val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() @@ -330,7 +341,7 @@ */ suspend fun getCustomerDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -342,7 +353,7 @@ */ suspend fun getStaffList(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -354,7 +365,7 @@ */ suspend fun getSupportEquipmentList(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -366,7 +377,7 @@ */ suspend fun getVerifyProcedureList(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -389,20 +400,15 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("customerName", customerName) - paramObject.put("customerNo", customerNo) - paramObject.put("deliverer", deliverer) - paramObject.put("orderCode", orderCode) - paramObject.put("startTime", startTime) - paramObject.put("endTime", endTime) - paramObject.put("isUrgent", isUrgent) - paramObject.put("status", status) - - val jsonArray = JSONArray() - ids.forEach { - jsonArray.put(it) - } - paramObject.put("ids", jsonArray) + paramObject["customerName"] = customerName + paramObject["customerNo"] = customerNo + paramObject["deliverer"] = deliverer + paramObject["orderCode"] = orderCode + paramObject["startTime"] = startTime + paramObject["endTime"] = endTime + paramObject["isUrgent"] = isUrgent + paramObject["status"] = status + paramObject["ids"] = JSONArray.parseArray(JSON.toJSONString(ids)) val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() @@ -421,7 +427,7 @@ */ suspend fun getEntrustDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -433,7 +439,7 @@ */ suspend fun acceptEntrust(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -446,10 +452,89 @@ */ suspend fun returnEntrust(id: String, selected: ArrayList): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) return api.returnEntrust(AuthenticationHelper.token!!, requestBody) } + + /** + * 获取样品列表 + */ + suspend fun getSampleList( + customerName: String, + customerNo: String, + startTime: String, + endTime: String, + sampleName: String, + sampleNo: String, + sampleModel: String, + sampleBelong: String, + overtimeStatus: String, + ids: Array, + offset: Int + ): String { + val paramObject = JSONObject() + paramObject["customerName"] = customerName + paramObject["customerNo"] = customerNo + paramObject["startTime"] = startTime + paramObject["endTime"] = endTime + paramObject["sampleName"] = sampleName + paramObject["sampleNo"] = sampleNo + paramObject["sampleModel"] = sampleModel + paramObject["sampleBelong"] = sampleBelong + paramObject["overtimeStatus"] = overtimeStatus + paramObject["ids"] = JSONArray.parseArray(JSON.toJSONString(ids)) + + val requestBody = paramObject.toString().toRequestBody( + "application/json;charset=UTF-8".toMediaType() + ) + + val limitMap = HashMap() + limitMap["limit"] = LocaleConstant.PAGE_LIMIT + + val offsetMap = HashMap() + offsetMap["offset"] = offset + return api.getSampleList(AuthenticationHelper.token!!, requestBody, limitMap, offsetMap) + } + + /** + * 新增委托书 + */ + suspend fun addEntrust( + deliverer: String, + delivererTel: String, + orderTime: String, + planDeliverTime: String, + requireOverTime: String, + customerName: String, + customerPhone: String, + customerAddress: String, + remark: String, + minioFileName: String, + certifications: String, + isUrgent: String, + samples: List + ): String { + val paramObject = JSONObject() + paramObject["deliverer"] = deliverer + paramObject["delivererTel"] = delivererTel + paramObject["orderTime"] = orderTime + paramObject["planDeliverTime"] = planDeliverTime + paramObject["requireOverTime"] = requireOverTime + paramObject["customerName"] = customerName + paramObject["customerPhone"] = customerPhone + paramObject["customerAddress"] = customerAddress + paramObject["remark"] = remark + paramObject["minioFileName"] = minioFileName + paramObject["certifications"] = certifications + paramObject["isUrgent"] = isUrgent + paramObject["customerSampleInfoList"] = JSONArray.parseArray(JSON.toJSONString(samples)) + + val requestBody = paramObject.toString().toRequestBody( + "application/json;charset=UTF-8".toMediaType() + ) + return api.addEntrust(AuthenticationHelper.token!!, requestBody) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/view/home/EntrustAddActivity.kt b/app/src/main/java/com/casic/xz/meterage/view/home/EntrustAddActivity.kt index 3e30095..9c8d27b 100644 --- a/app/src/main/java/com/casic/xz/meterage/view/home/EntrustAddActivity.kt +++ b/app/src/main/java/com/casic/xz/meterage/view/home/EntrustAddActivity.kt @@ -1,52 +1,211 @@ package com.casic.xz.meterage.view.home +import android.app.Activity +import android.content.Context +import android.content.Intent +import android.graphics.Color +import android.graphics.Paint import android.util.Log +import androidx.activity.result.ActivityResult +import androidx.activity.result.ActivityResultCallback +import androidx.activity.result.contract.ActivityResultContracts import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R import com.casic.xz.meterage.adapter.CertificateTypeAdapter2 -import com.casic.xz.meterage.extensions.initLayoutImmersionBar +import com.casic.xz.meterage.adapter.CustomerSampleAdapter +import com.casic.xz.meterage.callback.DateSelectedCallback +import com.casic.xz.meterage.callback.OnImageCompressListener +import com.casic.xz.meterage.extensions.* +import com.casic.xz.meterage.model.EntrustDetailModel +import com.casic.xz.meterage.model.SampleListModel +import com.casic.xz.meterage.utils.FileType +import com.casic.xz.meterage.utils.GlideLoadEngine +import com.casic.xz.meterage.utils.LoadingDialogHub import com.casic.xz.meterage.vm.DictionaryViewModel +import com.casic.xz.meterage.vm.EntrustViewModel +import com.casic.xz.meterage.vm.FileUploadViewModel +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken import com.gyf.immersionbar.ImmersionBar +import com.luck.picture.lib.basic.PictureSelector +import com.luck.picture.lib.config.SelectMimeType +import com.luck.picture.lib.entity.LocalMedia +import com.luck.picture.lib.interfaces.OnResultCallbackListener import com.pengxh.kt.lite.base.KotlinBaseActivity -import com.pengxh.kt.lite.extensions.toJson +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.vm.LoadState +import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import kotlinx.android.synthetic.main.activity_entrust_add.* +import java.io.File + class EntrustAddActivity : KotlinBaseActivity() { + private val context: Context = this@EntrustAddActivity + private val gson by lazy { Gson() } private lateinit var dictionaryViewModel: DictionaryViewModel - private var checkedItems = ArrayList() + private lateinit var fileUploadViewModel: FileUploadViewModel + private lateinit var entrustViewModel: EntrustViewModel + private lateinit var sampleAdapter: CustomerSampleAdapter + private var checkedItems = ArrayList() + private var isUrgent = "0" + private var sampleModels: ArrayList? = null + private var dataBeans = ArrayList() override fun initData() { //证书 dictionaryViewModel = ViewModelProvider(this)[DictionaryViewModel::class.java] dictionaryViewModel.getDictionaryByCode("certificationClass") - dictionaryViewModel.dictionary.observe(this) { dic -> - if (dic.code == 200) { - val typeAdapter2 = CertificateTypeAdapter2(this, dic.data) + dictionaryViewModel.dictionary.observe(this) { + if (it.code == 200) { + val typeAdapter2 = CertificateTypeAdapter2(this, it.data) typeRecyclerView.adapter = typeAdapter2 typeAdapter2.setOnItemCheckedListener(object : CertificateTypeAdapter2.OnItemCheckedListener { override fun onItemChecked(position: Int, isChecked: Boolean) { if (isChecked) { - checkedItems.add(position) + checkedItems.add(position.toString()) } else { - checkedItems.remove(position) + checkedItems.remove(position.toString()) } } }) } } + + fileUploadViewModel = ViewModelProvider(this)[FileUploadViewModel::class.java] + fileUploadViewModel.resultModel.observe(this) { + if (it.code == 200) { + val annexName = it.data[0] + annexView.text = annexName + val textPaint = annexView.paint + textPaint.flags = Paint.UNDERLINE_TEXT_FLAG + textPaint.isAntiAlias = true + annexView.setTextColor(Color.BLUE) + + annexView.setOnClickListener { + annexName.watchAttachFile(this) + } + } + } + + entrustViewModel = ViewModelProvider(this)[EntrustViewModel::class.java] + entrustViewModel.addResult.observe(this) { + if (it.code == 200) { + finish() + } + } + + //样品列表 + sampleAdapter = CustomerSampleAdapter(this, dataBeans) + sampleRecyclerView.adapter = sampleAdapter } + private val selectCustomerLauncher = + registerForActivityResult(ActivityResultContracts.StartActivityForResult(), + object : ActivityResultCallback { + override fun onActivityResult(result: ActivityResult?) { + if (result?.resultCode == Activity.RESULT_OK) { + val data = result.data ?: return + + entrustNameView.text = data.getStringExtra("entrustName") + entrustContactView.text = data.getStringExtra("entrustContact") + entrustAddressView.text = data.getStringExtra("entrustAddress") + } + } + }) + + private val selectSampleLauncher = + registerForActivityResult(ActivityResultContracts.StartActivityForResult(), + object : ActivityResultCallback { + override fun onActivityResult(result: ActivityResult?) { + if (result?.resultCode == Activity.RESULT_OK) { + val data = result.data ?: return + + val modelsJson = data.getStringExtra("sampleModels") + if (!modelsJson.isNullOrBlank()) { + sampleModels = gson.fromJson( + modelsJson, + object : + TypeToken>() {}.type + ) + } + + //刷新列表 + dataBeans.clear() + sampleModels?.forEach { + val model = + EntrustDetailModel.DataModel.CustomerSampleInfoListModel() + + model.customerName = it.customerName + model.customerNo = it.customerNo + model.id = it.id + model.manufacturingNo = it.manufacturingNo + model.measureLastTime = it.measureLastTime + model.measurePeriod = it.measurePeriod + model.orderId = it.orderId + model.remark = it.remark + model.sampleModel = it.sampleModel + model.sampleName = it.sampleName + model.sampleNo = it.sampleNo + model.validDeadline = it.validDeadline + + dataBeans.add(model) + } + sampleAdapter.notifyDataSetChanged() + } + } + }) + override fun initEvent() { + leftBackView.setOnClickListener { finish() } + + estimateTimeView.setOnClickListener { + showDatePicker(object : DateSelectedCallback { + override fun onDateSelected(date: String) { + estimateTimeView.text = date + } + }) + } + + completedView.setOnClickListener { + showDatePicker(object : DateSelectedCallback { + override fun onDateSelected(date: String) { + completedView.text = date + } + }) + } + + entrustNameView.setOnClickListener { + selectCustomerLauncher.launch(Intent(this, SelectCustomerActivity::class.java)) + } + //上传附件 uploadFileButton.setOnClickListener { + BottomActionSheet.Builder() + .setContext(this) + .setItemTextColor(Color.BLUE) + .setActionItemTitle(listOf("文件", "图片")) + .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { + override fun onActionItemClick(position: Int) { + when (position) { + 0 -> uploadFile() + 1 -> uploadImage() + } + } + }).build().show() + } + radioGroup.setOnCheckedChangeListener { _, checkedId -> + when (checkedId) { + R.id.radioButton1 -> isUrgent = "1" + R.id.radioButton2 -> isUrgent = "0" + } } //选择样品 selectSampleButton.setOnClickListener { - + selectSampleLauncher.launch(Intent(this, SelectSampleActivity::class.java)) } //写入样品信息 @@ -55,14 +214,68 @@ } pushEntrustView.setOnClickListener { - Log.d("Casic", "EntrustAddActivity => initEvent: ${checkedItems.toJson()}") + val sender = senderView.text.toString() + if (sender.isBlank()) { + "请填写送样人名字".show(this) + return@setOnClickListener + } + + val contact = contactView.text.toString() + if (contact.isBlank()) { + "请填写送样人联系方式".show(this) + return@setOnClickListener + } + + val estimateTime = estimateTimeView.text.toString() + if (estimateTime.isBlank()) { + "请选择预计送到的时间".show(this) + return@setOnClickListener + } + + val entrustName = entrustNameView.text.toString() + if (entrustName.isBlank()) { + "请选择委托方".show(this) + return@setOnClickListener + } + + if (sampleModels == null) { + "请选择样品".show(this) + return@setOnClickListener + } + entrustViewModel.addEntrust( + sender, + contact, + createEntrustDateView.text.toString(), + estimateTime, + completedView.text.toString(), + entrustName, + entrustContactView.text.toString(), + entrustAddressView.text.toString(), + remarkView.text.toString(), + annexView.text.toString(), + checkedItems.reformat(), + isUrgent, + sampleModels!! + ) } } override fun initLayoutView(): Int = R.layout.activity_entrust_add override fun observeRequestState() { + fileUploadViewModel.loadState.observe(this) { + when (it) { + LoadState.Loading -> LoadingDialogHub.show(this, "文件上传中,请稍后...") + else -> LoadingDialogHub.dismiss() + } + } + entrustViewModel.loadState.observe(this) { + when (it) { + LoadState.Loading -> LoadingDialogHub.show(this, "委托创建中,请稍后...") + else -> LoadingDialogHub.dismiss() + } + } } override fun setupTopBarLayout() { @@ -70,4 +283,62 @@ initLayoutImmersionBar(rootView) titleView.text = "委托需求" } + + private fun uploadFile() { +// val explorer = FileExplorer(this) +// explorer.setInitDir(ExplorerMode.FILE, Environment.getExternalStorageDirectory()) +// explorer.setShowHomeDir(true) +// explorer.setShowUpDir(true) +// explorer.setShowHideDir(true) +// explorer.setAllowExtensions(arrayOf(".doc", ".docx", ".xls", ".xlsx", ".pdf")) +// explorer.setOnFileClickedListener { +// val type = if (it.name.endsWith(".doc") || it.name.endsWith(".docx")) { +// FileType.WORD +// } else if (it.name.endsWith(".pdf")) { +// FileType.PDF +// } else { +// FileType.UNKNOWN +// } +// +// Log.d("Casic", "EntrustAddActivity => uploadFile: ${it.absolutePath}") +// fileUploadViewModel.uploadFile(it, type) +// } + } + + private fun uploadImage() { + PictureSelector.create(this) + .openGallery(SelectMimeType.ofImage()) + .isGif(false) + .isMaxSelectEnabledMask(true) + .setFilterMinFileSize(100) + .setMaxSelectNum(1) + .isDisplayCamera(false) + .setImageEngine(GlideLoadEngine.instance) + .forResult(object : OnResultCallbackListener { + override fun onResult(result: ArrayList?) { + if (result == null) { + "选择照片失败,请重试".show(context) + return + } + result[0].realPath.compressImage(context, object : OnImageCompressListener { + override fun onSuccess(file: File) { + Log.d( + "Casic", "EntrustAddActivity => onSuccess: ${file.absolutePath}" + ) + ///storage/emulated/0/Android/data/com.casic.xz.meterage/files/Pictures/CompressImage/1677478115391211.jpeg + //上传图片 + fileUploadViewModel.uploadFile(file, FileType.IMAGE) + } + + override fun onError(e: Throwable) { + e.printStackTrace() + } + }) + } + + override fun onCancel() { + + } + }) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/view/home/SelectCustomerActivity.kt b/app/src/main/java/com/casic/xz/meterage/view/home/SelectCustomerActivity.kt new file mode 100644 index 0000000..9bf6a1a --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/view/home/SelectCustomerActivity.kt @@ -0,0 +1,158 @@ +package com.casic.xz.meterage.view.home + +import android.content.Intent +import android.os.Handler +import androidx.lifecycle.ViewModelProvider +import androidx.recyclerview.widget.DefaultItemAnimator +import androidx.recyclerview.widget.DividerItemDecoration +import com.casic.xz.meterage.R +import com.casic.xz.meterage.adapter.SelectCustomerAdapter +import com.casic.xz.meterage.extensions.initLayoutImmersionBar +import com.casic.xz.meterage.extensions.showEmptyPage +import com.casic.xz.meterage.model.CustomerListModel +import com.casic.xz.meterage.utils.LoadingDialogHub +import com.casic.xz.meterage.vm.CustomerViewModel +import com.gyf.immersionbar.ImmersionBar +import com.pengxh.kt.lite.base.KotlinBaseActivity +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.utils.WeakReferenceHandler +import com.pengxh.kt.lite.vm.LoadState +import kotlinx.android.synthetic.main.activity_select_customer.* +import kotlinx.android.synthetic.main.include_base_title.* +import kotlinx.android.synthetic.main.include_empty_view.* + +class SelectCustomerActivity : KotlinBaseActivity() { + + private lateinit var weakReferenceHandler: WeakReferenceHandler + private lateinit var customerViewModel: CustomerViewModel + private lateinit var selectCustomerAdapter: SelectCustomerAdapter + private var dataBeans: MutableList = ArrayList() + private var pageIndex = 1 + private var isRefresh = false + private var isLoadMore = false + private var customerModel: CustomerListModel.DataModel.RowsModel? = null + + override fun initData() { + weakReferenceHandler = WeakReferenceHandler(callback) + customerViewModel = ViewModelProvider(this)[CustomerViewModel::class.java] + customerViewModel.customerList.observe(this) { + if (it.code == 200) { + val dataRows = it.data?.rows!! + when { + isRefresh -> { + dataBeans.clear() + dataBeans = dataRows + customerLayout.finishRefresh() + isRefresh = false + } + isLoadMore -> { + if (dataRows.size == 0) { + "到底了,别拉了".show(this) + } + dataBeans.addAll(dataRows) + customerLayout.finishLoadMore() + isLoadMore = false + } + else -> { + dataBeans = dataRows + } + } + weakReferenceHandler.sendEmptyMessage(2023022701) + } + } + } + + override fun initEvent() { + leftBackView.setOnClickListener { + if (customerModel == null) { + "请选择委托方".show(this) + return@setOnClickListener + } + val intent = Intent() + intent.putExtra("entrustName", customerModel!!.customerName) + intent.putExtra("entrustContact", customerModel!!.phone) + intent.putExtra("entrustAddress", customerModel!!.fullAddress) + setResult(RESULT_OK, intent) + finish() + } + + customerLayout.setOnRefreshListener { + isRefresh = true + //刷新之后页码重置 + pageIndex = 1 + getCustomerList() + } + + customerLayout.setOnLoadMoreListener { + isLoadMore = true + pageIndex++ + getCustomerList() + } + } + + override fun initLayoutView(): Int = R.layout.activity_select_customer + + override fun observeRequestState() { + customerViewModel.loadState.observe(this) { + when (it) { + LoadState.Loading -> LoadingDialogHub.show(this, "数据加载中...") + else -> LoadingDialogHub.dismiss() + } + } + } + + override fun setupTopBarLayout() { + ImmersionBar.with(this).statusBarDarkFont(true).init() + initLayoutImmersionBar(rootView) + titleView.text = "客户列表" + } + + override fun onResume() { + super.onResume() + pageIndex = 1 + getCustomerList() + } + + private fun getCustomerList() { + customerViewModel.getCustomerList( + "", + "", + "", + "", + pageIndex + ) + } + + private val callback = Handler.Callback { + when (it.what) { + 2023022701 -> { + if (isRefresh || isLoadMore) { + selectCustomerAdapter.notifyDataSetChanged() + } else { + if (dataBeans.size == 0) { + emptyView!!.showEmptyPage("无客户数据") { + pageIndex = 1 + getCustomerList() + } + } else { + emptyView!!.hide() + selectCustomerAdapter = SelectCustomerAdapter(this, dataBeans) + customerRecyclerView.addItemDecoration( + DividerItemDecoration(this, DividerItemDecoration.VERTICAL) + ) + (customerRecyclerView.itemAnimator as DefaultItemAnimator).supportsChangeAnimations = + false + customerRecyclerView.adapter = selectCustomerAdapter + selectCustomerAdapter.setOnCheckedListener(object : + SelectCustomerAdapter.OnItemCheckedListener { + override fun onItemChecked(item: CustomerListModel.DataModel.RowsModel) { + customerModel = item + } + }) + } + } + } + } + true + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/view/home/SelectSampleActivity.kt b/app/src/main/java/com/casic/xz/meterage/view/home/SelectSampleActivity.kt new file mode 100644 index 0000000..f85cb44 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/view/home/SelectSampleActivity.kt @@ -0,0 +1,152 @@ +package com.casic.xz.meterage.view.home + +import android.content.Intent +import android.os.Handler +import androidx.lifecycle.ViewModelProvider +import androidx.recyclerview.widget.DefaultItemAnimator +import androidx.recyclerview.widget.DividerItemDecoration +import com.casic.xz.meterage.R +import com.casic.xz.meterage.adapter.SelectSampleAdapter +import com.casic.xz.meterage.extensions.initLayoutImmersionBar +import com.casic.xz.meterage.extensions.showEmptyPage +import com.casic.xz.meterage.model.SampleListModel +import com.casic.xz.meterage.vm.SampleViewModel +import com.gyf.immersionbar.ImmersionBar +import com.pengxh.kt.lite.base.KotlinBaseActivity +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.extensions.toJson +import com.pengxh.kt.lite.utils.WeakReferenceHandler +import kotlinx.android.synthetic.main.activity_select_sample.* +import kotlinx.android.synthetic.main.include_base_title.* +import kotlinx.android.synthetic.main.include_empty_view.* + +class SelectSampleActivity : KotlinBaseActivity() { + + private lateinit var weakReferenceHandler: WeakReferenceHandler + private lateinit var sampleViewModel: SampleViewModel + private lateinit var selectSampleAdapter: SelectSampleAdapter + private var dataBeans: MutableList = ArrayList() + private var pageIndex = 1 + private var isRefresh = false + private var isLoadMore = false + private var sampleModels = ArrayList() + + override fun initData() { + weakReferenceHandler = WeakReferenceHandler(callback) + sampleViewModel = ViewModelProvider(this)[SampleViewModel::class.java] + sampleViewModel.sampleList.observe(this) { + if (it.code == 200) { + val dataRows = it.data?.rows!! + when { + isRefresh -> { + dataBeans.clear() + dataBeans = dataRows + sampleLayout.finishRefresh() + isRefresh = false + } + isLoadMore -> { + if (dataRows.size == 0) { + "到底了,别拉了".show(this) + } + dataBeans.addAll(dataRows) + sampleLayout.finishLoadMore() + isLoadMore = false + } + else -> { + dataBeans = dataRows + } + } + weakReferenceHandler.sendEmptyMessage(2023030101) + } + } + } + + override fun initEvent() { + leftBackView.setOnClickListener { + val intent = Intent() + intent.putExtra("sampleModels", sampleModels.toJson()) + setResult(RESULT_OK, intent) + finish() + } + + sampleLayout.setOnRefreshListener { + isRefresh = true + //刷新之后页码重置 + pageIndex = 1 + getSampleList() + } + + sampleLayout.setOnLoadMoreListener { + isLoadMore = true + pageIndex++ + getSampleList() + } + } + + override fun initLayoutView(): Int = R.layout.activity_select_sample + + override fun observeRequestState() { + + } + + override fun setupTopBarLayout() { + ImmersionBar.with(this).statusBarDarkFont(true).init() + initLayoutImmersionBar(rootView) + titleView.text = "样品列表" + } + + override fun onResume() { + super.onResume() + pageIndex = 1 + getSampleList() + } + + private fun getSampleList() { + sampleViewModel.getSampleList( + "", + "", + "", + "", + "", + "", + "", + "", + "", + arrayOf(), + pageIndex + ) + } + + private val callback = Handler.Callback { + when (it.what) { + 2023030101 -> { + if (isRefresh || isLoadMore) { + selectSampleAdapter.notifyDataSetChanged() + } else { + if (dataBeans.size == 0) { + emptyView!!.showEmptyPage("无样品数据") { + pageIndex = 1 + getSampleList() + } + } else { + emptyView!!.hide() + selectSampleAdapter = SelectSampleAdapter(this, dataBeans) + sampleRecyclerView.addItemDecoration( + DividerItemDecoration(this, DividerItemDecoration.VERTICAL) + ) + (sampleRecyclerView.itemAnimator as DefaultItemAnimator).supportsChangeAnimations = + false + sampleRecyclerView.adapter = selectSampleAdapter + selectSampleAdapter.setOnCheckedListener(object : + SelectSampleAdapter.OnItemCheckedListener { + override fun onItemChecked(items: ArrayList) { + sampleModels = items + } + }) + } + } + } + } + true + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/view/notice/NoticeDetailActivity.kt b/app/src/main/java/com/casic/xz/meterage/view/notice/NoticeDetailActivity.kt index a9d9422..9596985 100644 --- a/app/src/main/java/com/casic/xz/meterage/view/notice/NoticeDetailActivity.kt +++ b/app/src/main/java/com/casic/xz/meterage/view/notice/NoticeDetailActivity.kt @@ -1,6 +1,7 @@ package com.casic.xz.meterage.view.notice import android.annotation.SuppressLint +import android.graphics.Color import android.graphics.Paint import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R @@ -10,7 +11,6 @@ import com.casic.xz.meterage.vm.NoticeViewModel import com.gyf.immersionbar.ImmersionBar import com.pengxh.kt.lite.base.KotlinBaseActivity -import com.pengxh.kt.lite.extensions.convertColor import com.pengxh.kt.lite.extensions.obtainScreenWidth import com.pengxh.kt.lite.utils.Constant import kotlinx.android.synthetic.main.activity_notice_detail.* @@ -54,7 +54,7 @@ val textPaint = minioFileView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - minioFileView.setTextColor(R.color.themeColor.convertColor(this)) + minioFileView.setTextColor(Color.BLUE) minioFileView.setOnClickListener { minioFileName.watchAttachFile(this) diff --git a/app/src/main/java/com/casic/xz/meterage/vm/EntrustViewModel.kt b/app/src/main/java/com/casic/xz/meterage/vm/EntrustViewModel.kt index 2280f88..103c002 100644 --- a/app/src/main/java/com/casic/xz/meterage/vm/EntrustViewModel.kt +++ b/app/src/main/java/com/casic/xz/meterage/vm/EntrustViewModel.kt @@ -7,6 +7,7 @@ import com.casic.xz.meterage.model.ActionResultModel import com.casic.xz.meterage.model.EntrustDetailModel import com.casic.xz.meterage.model.EntrustListModel +import com.casic.xz.meterage.model.SampleListModel import com.casic.xz.meterage.utils.retrofit.RetrofitServiceManager import com.google.gson.Gson import com.google.gson.reflect.TypeToken @@ -25,6 +26,7 @@ val entrustDetail = MutableLiveData() val acceptResult = MutableLiveData() val returnResult = MutableLiveData() + val addResult = MutableLiveData() fun getEntrustList( customerName: String, @@ -119,4 +121,50 @@ loadState.value = LoadState.Fail it.cause.toString().show(BaseApplication.get()) }) + + fun addEntrust( + deliverer: String, + delivererTel: String, + orderTime: String, + planDeliverTime: String, + requireOverTime: String, + customerName: String, + customerPhone: String, + customerAddress: String, + remark: String, + minioFileName: String, + certifications: String, + isUrgent: String, + samples: List + ) = launch({ + loadState.value = LoadState.Loading + val response = RetrofitServiceManager.addEntrust( + deliverer, + delivererTel, + orderTime, + planDeliverTime, + requireOverTime, + customerName, + customerPhone, + customerAddress, + remark, + minioFileName, + certifications, + isUrgent, + samples + ) + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + loadState.value = LoadState.Success + addResult.value = gson.fromJson( + response, object : TypeToken() {}.type + ) + } else { + loadState.value = LoadState.Fail + response.toErrorMessage().show(BaseApplication.get()) + } + }, { + loadState.value = LoadState.Fail + it.cause.toString().show(BaseApplication.get()) + }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/vm/FileUploadViewModel.kt b/app/src/main/java/com/casic/xz/meterage/vm/FileUploadViewModel.kt new file mode 100644 index 0000000..b16c1c7 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/vm/FileUploadViewModel.kt @@ -0,0 +1,40 @@ +package com.casic.xz.meterage.vm + +import androidx.lifecycle.MutableLiveData +import com.casic.xz.meterage.base.BaseApplication +import com.casic.xz.meterage.extensions.separateResponseCode +import com.casic.xz.meterage.extensions.toErrorMessage +import com.casic.xz.meterage.model.UploadResultModel +import com.casic.xz.meterage.utils.FileType +import com.casic.xz.meterage.utils.retrofit.RetrofitServiceManager +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken +import com.pengxh.kt.lite.extensions.launch +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.vm.BaseViewModel +import com.pengxh.kt.lite.vm.LoadState +import java.io.File + +class FileUploadViewModel : BaseViewModel() { + + private val gson by lazy { Gson() } + val resultModel = MutableLiveData() + + fun uploadFile(file: File, type: FileType) = launch({ + loadState.value = LoadState.Loading + val response = RetrofitServiceManager.uploadFile(file, type) + 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(BaseApplication.get()) + } + }, { + loadState.value = LoadState.Fail + it.cause.toString().show(BaseApplication.get()) + }) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/vm/SampleViewModel.kt b/app/src/main/java/com/casic/xz/meterage/vm/SampleViewModel.kt new file mode 100644 index 0000000..182140d --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/vm/SampleViewModel.kt @@ -0,0 +1,65 @@ +package com.casic.xz.meterage.vm + +import androidx.lifecycle.MutableLiveData +import com.casic.xz.meterage.base.BaseApplication +import com.casic.xz.meterage.extensions.separateResponseCode +import com.casic.xz.meterage.extensions.toErrorMessage +import com.casic.xz.meterage.model.SampleListModel +import com.casic.xz.meterage.utils.retrofit.RetrofitServiceManager +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken +import com.pengxh.kt.lite.extensions.launch +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.vm.BaseViewModel +import com.pengxh.kt.lite.vm.LoadState + +/** + * 样品相关 VM + * */ +class SampleViewModel : BaseViewModel() { + + private val gson by lazy { Gson() } + val sampleList = MutableLiveData() + + fun getSampleList( + customerName: String, + customerNo: String, + startTime: String, + endTime: String, + sampleName: String, + sampleNo: String, + sampleModel: String, + sampleBelong: String, + overtimeStatus: String, + ids: Array, + offset: Int + ) = launch({ + loadState.value = LoadState.Loading + val response = RetrofitServiceManager.getSampleList( + customerName, + customerNo, + startTime, + endTime, + sampleName, + sampleNo, + sampleModel, + sampleBelong, + overtimeStatus, + ids, + offset + ) + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + loadState.value = LoadState.Success + sampleList.value = gson.fromJson( + response, object : TypeToken() {}.type + ) + } else { + loadState.value = LoadState.Fail + response.toErrorMessage().show(BaseApplication.get()) + } + }, { + loadState.value = LoadState.Fail + it.cause.toString().show(BaseApplication.get()) + }) +} \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 0ae369f..687b02b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -15,7 +15,6 @@ } compileSdkVersion 31 - buildToolsVersion "30.0.3" defaultConfig { applicationId "com.casic.xz.meterage" @@ -84,11 +83,13 @@ implementation 'top.zibin:Luban:1.1.8' //官方Json解析库 implementation 'com.google.code.gson:gson:2.9.0' + //阿里巴巴JSON库 + implementation 'com.alibaba.fastjson2:fastjson2:2.0.24' //Kotlin协程 implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.5.1' //MVVM+LiveData implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.5.1" - implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.0" + implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1" implementation "androidx.lifecycle:lifecycle-extensions:2.2.0" //返回值转换器 implementation 'com.jakewharton.retrofit:retrofit2-kotlin-coroutines-adapter:0.9.2' @@ -109,4 +110,8 @@ implementation 'com.github.barteksc:android-pdf-viewer:2.8.2' //绕过Android 11反射限制 implementation 'com.github.tiann:FreeReflection:3.1.0' + //单项/数字、二三级联动、日期/时间等滚轮选择器 + implementation 'com.github.gzu-liyujiang.AndroidPicker:WheelPicker:4.1.8' + //文件/目录选择器 + implementation 'com.github.gzu-liyujiang.AndroidPicker:FilePicker:4.1.1' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 1ccc12b..0fba91b 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -60,6 +60,8 @@ + + diff --git a/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt b/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt new file mode 100644 index 0000000..21a71d8 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt @@ -0,0 +1,70 @@ +package com.casic.xz.meterage.adapter + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import com.casic.xz.meterage.R +import com.casic.xz.meterage.extensions.toChineseGrade +import com.casic.xz.meterage.model.CustomerListModel + +class SelectCustomerAdapter( + context: Context, private val dataRows: MutableList +) : RecyclerView.Adapter() { + + private var layoutInflater = LayoutInflater.from(context) + + //选择的位置 + private var selectedPosition = 0 + + //临时记录上次选择的位置 + private var temp = -1 + + override fun getItemCount(): Int = dataRows.size + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ItemViewHolder( + layoutInflater.inflate(R.layout.item_select_customer_lv, parent, false) + ) + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + //绑定数据 + val rowsBean = dataRows[position] + holder.agreementLevelView.text = rowsBean.grade.toChineseGrade() + holder.customerNameView.text = rowsBean.customerName + holder.scaleView.text = rowsBean.companySizeName + holder.overallView.text = "公司规模:${rowsBean.evaluationName}" + holder.fullAddressView.text = "公司地址:${rowsBean.fullAddress}" + + holder.itemView.isSelected = holder.layoutPosition == selectedPosition + holder.itemView.setOnClickListener { + itemCheckedListener?.onItemChecked(rowsBean) + + holder.itemView.isSelected = true + temp = selectedPosition + //设置新的位置 + selectedPosition = holder.layoutPosition + //更新旧位置 + notifyItemChanged(temp) + } + } + + inner class ItemViewHolder(view: View) : RecyclerView.ViewHolder(view) { + var agreementLevelView: TextView = view.findViewById(R.id.agreementLevelView) + var customerNameView: TextView = view.findViewById(R.id.customerNameView) + var scaleView: TextView = view.findViewById(R.id.scaleView) + var overallView: TextView = view.findViewById(R.id.overallView) + var fullAddressView: TextView = view.findViewById(R.id.fullAddressView) + } + + private var itemCheckedListener: OnItemCheckedListener? = null + + interface OnItemCheckedListener { + fun onItemChecked(item: CustomerListModel.DataModel.RowsModel) + } + + fun setOnCheckedListener(listener: OnItemCheckedListener?) { + itemCheckedListener = listener + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt b/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt new file mode 100644 index 0000000..c29461e --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt @@ -0,0 +1,68 @@ +package com.casic.xz.meterage.adapter + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import com.casic.xz.meterage.R +import com.casic.xz.meterage.model.SampleListModel + +class SelectSampleAdapter( + context: Context, private val dataRows: MutableList +) : RecyclerView.Adapter() { + + private var layoutInflater = LayoutInflater.from(context) + private var multipleSelected = mutableSetOf() + private var sampleModes = ArrayList() + + override fun getItemCount(): Int = dataRows.size + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ItemViewHolder( + layoutInflater.inflate(R.layout.item_select_sample_lv, parent, false) + ) + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + //绑定数据 + val rowsBean = dataRows[position] + holder.sampleNameView.text = "${rowsBean.sampleName}【${rowsBean.sampleModel}】" + holder.manufacturingCodeView.text = "出厂编号:${rowsBean.manufacturingNo}" + holder.sampleCodeView.text = "样品编号:${rowsBean.sampleNo}" + holder.validDateView.text = "有效期至:${rowsBean.validDeadline}" + + holder.checkImageView.isSelected = multipleSelected.contains(position) + holder.itemView.setOnClickListener { + if (multipleSelected.contains(position)) { + multipleSelected.remove(position) + sampleModes.remove(dataRows[position]) + holder.checkImageView.isSelected = false + } else { + multipleSelected.add(position) + sampleModes.add(dataRows[position]) + holder.checkImageView.isSelected = true + } + + itemCheckedListener?.onItemChecked(sampleModes) + } + } + + inner class ItemViewHolder(view: View) : RecyclerView.ViewHolder(view) { + var sampleNameView: TextView = view.findViewById(R.id.sampleNameView) + var manufacturingCodeView: TextView = view.findViewById(R.id.manufacturingCodeView) + var sampleCodeView: TextView = view.findViewById(R.id.sampleCodeView) + var validDateView: TextView = view.findViewById(R.id.validDateView) + var checkImageView: ImageView = view.findViewById(R.id.checkImageView) + } + + private var itemCheckedListener: OnItemCheckedListener? = null + + interface OnItemCheckedListener { + fun onItemChecked(items: ArrayList) + } + + fun setOnCheckedListener(listener: OnItemCheckedListener?) { + itemCheckedListener = listener + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/callback/DateSelectedCallback.kt b/app/src/main/java/com/casic/xz/meterage/callback/DateSelectedCallback.kt new file mode 100644 index 0000000..8196110 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/callback/DateSelectedCallback.kt @@ -0,0 +1,5 @@ +package com.casic.xz.meterage.callback + +interface DateSelectedCallback { + fun onDateSelected(date: String) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/Activity.kt b/app/src/main/java/com/casic/xz/meterage/extensions/Activity.kt new file mode 100644 index 0000000..e112d1c --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/extensions/Activity.kt @@ -0,0 +1,33 @@ +package com.casic.xz.meterage.extensions + +import android.app.Activity +import com.casic.xz.meterage.R +import com.casic.xz.meterage.callback.DateSelectedCallback +import com.github.gzuliyujiang.wheelpicker.DatePicker +import com.github.gzuliyujiang.wheelpicker.annotation.DateMode +import com.github.gzuliyujiang.wheelpicker.entity.DateEntity +import com.pengxh.kt.lite.extensions.convertColor +import com.pengxh.kt.lite.extensions.sp2px + +fun Activity.showDatePicker(callback: DateSelectedCallback) { + val datePicker = DatePicker(this) + + val layout = datePicker.wheelLayout + layout.setDateMode(DateMode.YEAR_MONTH_DAY) + layout.setDateLabel("年", "月", "日"); + layout.setTextSize(14f.sp2px(this).toFloat()) + layout.setSelectedTextSize(16f.sp2px(this).toFloat()) + layout.setSelectedTextColor(R.color.themeColor.convertColor(this)) + layout.setSelectedTextBold(true) + layout.setResetWhenLinkage(false) + layout.setRange( + DateEntity.today(), + DateEntity.target(2050, 12, 31), + DateEntity.today() + ) + + datePicker.setOnDatePickedListener { year, month, day -> + callback.onDateSelected(String.format("%s-%s-%s", year, month, day)) + } + datePicker.show() +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt b/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt index 016ebcb..cf6bf49 100644 --- a/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt +++ b/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt @@ -4,7 +4,7 @@ * ArrayList扩展方法 */ -//将图片集合格式化成满足上传格式的数据 +//将集合格式化成满足上传格式的数据 fun ArrayList.reformat(): String { if (this.isEmpty()) return "" val builder = StringBuilder() diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt b/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt index 7c57643..aa9b92b 100644 --- a/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt +++ b/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt @@ -1,7 +1,6 @@ package com.casic.xz.meterage.extensions import android.content.Context -import android.util.Log import android.view.ViewGroup import com.casic.xz.meterage.base.BaseApplication import com.pengxh.kt.lite.extensions.dp2px @@ -9,9 +8,8 @@ fun Context.initLayoutImmersionBar(rootView: ViewGroup) { var statusBarHeight = QMUIDisplayHelper.getStatusBarHeight(this) - Log.d("Casic", "状态栏高度: $statusBarHeight") if (statusBarHeight == 0) { - statusBarHeight = 44f.dp2px(BaseApplication.get()) + statusBarHeight = 40f.dp2px(BaseApplication.get()) } rootView.setPadding(0, statusBarHeight, 0, 0) rootView.requestLayout() diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/String.kt b/app/src/main/java/com/casic/xz/meterage/extensions/String.kt index 28f70d8..6234d43 100644 --- a/app/src/main/java/com/casic/xz/meterage/extensions/String.kt +++ b/app/src/main/java/com/casic/xz/meterage/extensions/String.kt @@ -128,9 +128,10 @@ fun String.combineImagePath(): String { if (this.isEmpty()) return this val defaultValue = SaveKeyValues.getValue( - LocaleConstant.DEFAULT_SERVER_CONFIG, LocaleConstant.SERVER_BASE_URL + LocaleConstant.FILE_SERVER_CONFIG, LocaleConstant.File_SERVER_URL ) as String - return "$defaultValue/static/${this.replace("\\", "/")}" + //http://111.198.10.15:21408/test/1677479806059688_1677479806038.jpeg + return "$defaultValue/test/${this.replace("\\", "/")}" } fun String.isEarlier(time: String): Boolean { diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt index 25fa87b..a0e1358 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt @@ -1,18 +1,12 @@ package com.casic.xz.meterage.fragment.customer +import android.graphics.Color import android.graphics.Paint import com.casic.xz.meterage.R -import com.casic.xz.meterage.extensions.combineImagePath import com.casic.xz.meterage.extensions.toChineseGrade +import com.casic.xz.meterage.extensions.watchAttachFile import com.casic.xz.meterage.model.CustomerDetailModel -import com.casic.xz.meterage.view.BigImageActivity -import com.casic.xz.meterage.view.notice.PreviewDocumentActivity -import com.casic.xz.meterage.view.notice.PreviewPdfActivity -import com.casic.xz.meterage.view.notice.PreviewTextActivity import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.extensions.show import kotlinx.android.synthetic.main.fragment_customer_basic_information.* class BasicInformationFragment(private val data: CustomerDetailModel.DataModel) : @@ -48,30 +42,11 @@ val textPaint = minioFileView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - minioFileView.setTextColor(R.color.themeColor.convertColor(requireContext())) + minioFileView.setTextColor(Color.BLUE) minioFileView.setOnClickListener { //查看附件 - if (minioFileName.endsWith("pdf")) { - requireContext().navigatePageTo(minioFileName) - } else if ( - minioFileName.endsWith("doc") || - minioFileName.endsWith("docx") - ) { - requireContext().navigatePageTo(minioFileName) - } else if (minioFileName.endsWith("txt")) { - requireContext().navigatePageTo(minioFileName) - } else if ( - minioFileName.endsWith("png") || - minioFileName.endsWith("jpeg") || - minioFileName.endsWith("jpg") - ) { - val urls = ArrayList() - urls.add(minioFileName.combineImagePath()) - requireContext().navigatePageTo(0, urls) - } else { - "文件类型未知,无法打开附件".show(requireContext()) - } + minioFileName.watchAttachFile(requireContext()) } } } diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt index 77846b4..3a0fe2e 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt @@ -1,5 +1,6 @@ package com.casic.xz.meterage.fragment.device +import android.graphics.Color import android.graphics.Paint import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R @@ -7,7 +8,6 @@ import com.casic.xz.meterage.utils.LoadingDialogHub import com.casic.xz.meterage.vm.EquipmentViewModel import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor import com.pengxh.kt.lite.vm.LoadState import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import kotlinx.android.synthetic.main.fragment_device_basic_information.* @@ -56,7 +56,7 @@ val textPaint = documentsView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - documentsView.setTextColor(R.color.themeColor.convertColor(requireContext())) + documentsView.setTextColor(Color.BLUE) val files = ArrayList() data.fileList.forEach { file -> @@ -66,7 +66,7 @@ BottomActionSheet.Builder() .setContext(requireContext()) .setActionItemTitle(files) - .setItemTextColor(R.color.themeColor.convertColor(requireContext())) + .setItemTextColor(Color.BLUE) .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { override fun onActionItemClick(position: Int) { diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt index 15dc3d2..10eeff8 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt @@ -1,5 +1,6 @@ package com.casic.xz.meterage.fragment.entrust +import android.graphics.Color import android.graphics.Paint import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R @@ -9,7 +10,6 @@ import com.casic.xz.meterage.model.EntrustDetailModel import com.casic.xz.meterage.vm.DictionaryViewModel import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor import kotlinx.android.synthetic.main.fragment_entrust_basic_information.* class BasicInformationFragment(private val data: EntrustDetailModel.DataModel) : @@ -38,7 +38,7 @@ val textPaint = annexView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - annexView.setTextColor(R.color.themeColor.convertColor(requireContext())) + annexView.setTextColor(Color.BLUE) annexView.setOnClickListener { minioFileName.watchAttachFile(requireContext()) @@ -59,9 +59,9 @@ //加急 if (data.isUrgent == "0") { - RadioButton2.isChecked = true + radioButton2.isChecked = true } else { - RadioButton1.isChecked = true + radioButton1.isChecked = true } //样品 diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/equipment/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/equipment/BasicInformationFragment.kt index 72b523c..7bc3b01 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/equipment/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/equipment/BasicInformationFragment.kt @@ -1,5 +1,6 @@ package com.casic.xz.meterage.fragment.equipment +import android.graphics.Color import android.graphics.Paint import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R @@ -7,7 +8,6 @@ import com.casic.xz.meterage.utils.LoadingDialogHub import com.casic.xz.meterage.vm.EquipmentViewModel import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor import com.pengxh.kt.lite.vm.LoadState import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import kotlinx.android.synthetic.main.fragment_equipment_basic_information.* @@ -74,7 +74,7 @@ val textPaint = instructionsView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - instructionsView.setTextColor(R.color.themeColor.convertColor(requireContext())) + instructionsView.setTextColor(Color.BLUE) val files = ArrayList() data.fileList.forEach { file -> @@ -84,7 +84,7 @@ BottomActionSheet.Builder() .setContext(requireContext()) .setActionItemTitle(files) - .setItemTextColor(R.color.themeColor.convertColor(requireContext())) + .setItemTextColor(Color.BLUE) .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { override fun onActionItemClick(position: Int) { diff --git a/app/src/main/java/com/casic/xz/meterage/model/SampleListModel.java b/app/src/main/java/com/casic/xz/meterage/model/SampleListModel.java new file mode 100644 index 0000000..5784343 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/model/SampleListModel.java @@ -0,0 +1,193 @@ +package com.casic.xz.meterage.model; + +import java.util.List; + +public class SampleListModel { + + private int code; + private DataModel data; + private String message; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataModel getData() { + return data; + } + + public void setData(DataModel data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public static class DataModel { + private List rows; + private int total; + + public List getRows() { + return rows; + } + + public void setRows(List rows) { + this.rows = rows; + } + + public int getTotal() { + return total; + } + + public void setTotal(int total) { + this.total = total; + } + + public static class RowsModel { + private String certificationStatus; + private String customerName; + private String customerNo; + private String id; + private String manufacturingNo; + private String measureLastTime; + private String measurePeriod; + private String orderId; + private String remark; + private String sampleModel; + private String sampleName; + private String sampleNo; + private String sampleSatus; + private String sampleSatusName; + private String validDeadline; + + public String getCertificationStatus() { + return certificationStatus; + } + + public void setCertificationStatus(String certificationStatus) { + this.certificationStatus = certificationStatus; + } + + public String getCustomerName() { + return customerName; + } + + public void setCustomerName(String customerName) { + this.customerName = customerName; + } + + public String getCustomerNo() { + return customerNo; + } + + public void setCustomerNo(String customerNo) { + this.customerNo = customerNo; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getManufacturingNo() { + return manufacturingNo; + } + + public void setManufacturingNo(String manufacturingNo) { + this.manufacturingNo = manufacturingNo; + } + + public String getMeasureLastTime() { + return measureLastTime; + } + + public void setMeasureLastTime(String measureLastTime) { + this.measureLastTime = measureLastTime; + } + + public String getMeasurePeriod() { + return measurePeriod; + } + + public void setMeasurePeriod(String measurePeriod) { + this.measurePeriod = measurePeriod; + } + + public String getOrderId() { + return orderId; + } + + public void setOrderId(String orderId) { + this.orderId = orderId; + } + + public String getRemark() { + return remark; + } + + public void setRemark(String remark) { + this.remark = remark; + } + + public String getSampleModel() { + return sampleModel; + } + + public void setSampleModel(String sampleModel) { + this.sampleModel = sampleModel; + } + + public String getSampleName() { + return sampleName; + } + + public void setSampleName(String sampleName) { + this.sampleName = sampleName; + } + + public String getSampleNo() { + return sampleNo; + } + + public void setSampleNo(String sampleNo) { + this.sampleNo = sampleNo; + } + + public String getSampleSatus() { + return sampleSatus; + } + + public void setSampleSatus(String sampleSatus) { + this.sampleSatus = sampleSatus; + } + + public String getSampleSatusName() { + return sampleSatusName; + } + + public void setSampleSatusName(String sampleSatusName) { + this.sampleSatusName = sampleSatusName; + } + + public String getValidDeadline() { + return validDeadline; + } + + public void setValidDeadline(String validDeadline) { + this.validDeadline = validDeadline; + } + } + } +} diff --git a/app/src/main/java/com/casic/xz/meterage/model/UploadResultModel.java b/app/src/main/java/com/casic/xz/meterage/model/UploadResultModel.java new file mode 100644 index 0000000..f2a6a41 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/model/UploadResultModel.java @@ -0,0 +1,34 @@ +package com.casic.xz.meterage.model; + +import java.util.List; + +public class UploadResultModel { + + private int code; + private List data; + private String message; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public List getData() { + return data; + } + + public void setData(List data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } +} diff --git a/app/src/main/java/com/casic/xz/meterage/utils/FileType.kt b/app/src/main/java/com/casic/xz/meterage/utils/FileType.kt new file mode 100644 index 0000000..17e2bca --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/utils/FileType.kt @@ -0,0 +1,23 @@ +package com.casic.xz.meterage.utils + +sealed class FileType { + /** + * PDF文件 + */ + object PDF : FileType() + + /** + * WORD文件 + */ + object WORD : FileType() + + /** + * IMAGE图片 + */ + object IMAGE : FileType() + + /** + * 未知类型(Excel) + */ + object UNKNOWN : FileType() +} diff --git a/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitService.kt index bc3f8d6..8f4fe44 100644 --- a/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitService.kt @@ -1,5 +1,6 @@ package com.casic.xz.meterage.utils.retrofit +import okhttp3.MultipartBody import okhttp3.RequestBody import retrofit2.http.* @@ -35,6 +36,16 @@ ): String /** + * 上传文件 + */ + @Multipart + @POST("/minio/file/upload") + suspend fun uploadFile( + @Header("token") token: String, + @Part file: MultipartBody.Part + ): String + + /** * 获取通知公告列表 */ @POST("/system/notice/listPage") @@ -209,4 +220,24 @@ @Header("token") token: String, @Body requestBody: RequestBody ): String + + /** + * 获取样品列表 + */ + @POST("/customer/sample/listPage") + suspend fun getSampleList( + @Header("token") token: String, + @Body requestBody: RequestBody, + @QueryMap limit: Map, + @QueryMap offset: Map + ): String + + /** + * 新增委托书 + */ + @POST("/business/order/add") + suspend fun addEntrust( + @Header("token") token: String, + @Body requestBody: RequestBody + ): String } \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitServiceManager.kt index cb22e45..90abe5a 100644 --- a/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitServiceManager.kt @@ -1,13 +1,20 @@ package com.casic.xz.meterage.utils.retrofit +import com.alibaba.fastjson2.JSON +import com.alibaba.fastjson2.JSONArray +import com.alibaba.fastjson2.JSONObject +import com.casic.xz.meterage.model.SampleListModel import com.casic.xz.meterage.utils.AuthenticationHelper +import com.casic.xz.meterage.utils.FileType import com.casic.xz.meterage.utils.LocaleConstant import com.pengxh.kt.lite.utils.RetrofitFactory import com.pengxh.kt.lite.utils.SaveKeyValues import okhttp3.MediaType.Companion.toMediaType +import okhttp3.MediaType.Companion.toMediaTypeOrNull +import okhttp3.MultipartBody +import okhttp3.RequestBody.Companion.asRequestBody import okhttp3.RequestBody.Companion.toRequestBody -import org.json.JSONArray -import org.json.JSONObject +import java.io.File object RetrofitServiceManager { @@ -31,9 +38,9 @@ */ suspend fun login(sid: String, account: String, secretKey: String): String { val paramObject = JSONObject() - paramObject.put("sid", sid) - paramObject.put("username", account) - paramObject.put("password", secretKey) + paramObject["sid"] = sid + paramObject["username"] = account + paramObject["password"] = secretKey val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -55,6 +62,20 @@ } /** + * 上传文件 + */ + suspend fun uploadFile(file: File, type: FileType): String { + val requestBody = when (type) { + FileType.PDF -> file.asRequestBody("application/pdf".toMediaTypeOrNull()) + FileType.WORD -> file.asRequestBody("application/msword".toMediaTypeOrNull()) + FileType.IMAGE -> file.asRequestBody("image/png".toMediaTypeOrNull()) + else -> file.asRequestBody("application/vnd.ms-excel".toMediaTypeOrNull()) + } + val filePart = MultipartBody.Part.createFormData("multipartFile", file.name, requestBody) + return api.uploadFile(AuthenticationHelper.token!!, filePart) + } + + /** * 获取通知公告列表 */ suspend fun getNoticeList( @@ -66,11 +87,11 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("noticeNo", noticeNo) - paramObject.put("noticeTitle", noticeTitle) - paramObject.put("noticePublisher", noticePublisher) - paramObject.put("noticeStartTime", noticeStartTime) - paramObject.put("noticeEndTime", noticeEndTime) + paramObject["noticeNo"] = noticeNo + paramObject["noticeTitle"] = noticeTitle + paramObject["noticePublisher"] = noticePublisher + paramObject["noticeStartTime"] = noticeStartTime + paramObject["noticeEndTime"] = noticeEndTime val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -105,26 +126,21 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("equipmentNo", equipmentNo) - paramObject.put("equipmentName", equipmentName) - paramObject.put("mesureType", mesureType) - paramObject.put("managerState", managerState) - paramObject.put("useDept", useDept) - paramObject.put("assetType", assetType) - paramObject.put("equipmentCategory", equipmentCategory) - paramObject.put("isCalibrationTestEquipment", isCalibrationTestEquipment) - paramObject.put("isMeasureAccount", isMeasureAccount) - paramObject.put("isStandardSupportEquipment", isStandardSupportEquipment) - paramObject.put("isFixedAssets", isFixedAssets) - paramObject.put("validStartDate", validStartDate) - paramObject.put("validEndDate", validEndDate) - paramObject.put("abc", abc) - - val jsonArray = JSONArray() - ids.forEach { - jsonArray.put(it) - } - paramObject.put("ids", jsonArray) + paramObject["equipmentNo"] = equipmentNo + paramObject["equipmentName"] = equipmentName + paramObject["mesureType"] = mesureType + paramObject["managerState"] = managerState + paramObject["useDept"] = useDept + paramObject["assetType"] = assetType + paramObject["equipmentCategory"] = equipmentCategory + paramObject["isCalibrationTestEquipment"] = isCalibrationTestEquipment + paramObject["isMeasureAccount"] = isMeasureAccount + paramObject["isStandardSupportEquipment"] = isStandardSupportEquipment + paramObject["isFixedAssets"] = isFixedAssets + paramObject["validStartDate"] = validStartDate + paramObject["validEndDate"] = validEndDate + paramObject["abc"] = abc + paramObject["ids"] = JSONArray.parseArray(JSON.toJSONString(ids)) val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() @@ -143,7 +159,7 @@ */ suspend fun getEquipmentDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -164,13 +180,13 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("standardNo", standardNo) - paramObject.put("standardName", standardName) - paramObject.put("category", category) - paramObject.put("managerState", managerState) - paramObject.put("standardLaboratory", standardLaboratory) - paramObject.put("preparationDate", preparationDate) - paramObject.put("id", id) + paramObject["standardNo"] = standardNo + paramObject["standardName"] = standardName + paramObject["category"] = category + paramObject["managerState"] = managerState + paramObject["standardLaboratory"] = standardLaboratory + paramObject["preparationDate"] = preparationDate + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -193,7 +209,7 @@ */ suspend fun getStandardDeviceDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -212,11 +228,11 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("checkType", checkType) - paramObject.put("priceItem", priceItem) - paramObject.put("priceName", priceName) - paramObject.put("priceNo", priceNo) - paramObject.put("priceType", priceType) + paramObject["checkType"] = checkType + paramObject["priceItem"] = priceItem + paramObject["priceName"] = priceName + paramObject["priceNo"] = priceNo + paramObject["priceType"] = priceType val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -234,7 +250,7 @@ */ suspend fun getCapabilityDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -257,20 +273,15 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("createStartTime", createStartTime) - paramObject.put("createEndTime", createEndTime) - paramObject.put("deptId", deptId) - paramObject.put("director", director) - paramObject.put("effectiveCompany", effectiveCompany) - paramObject.put("trainStartTime", trainStartTime) - paramObject.put("trainEndTime", trainEndTime) - paramObject.put("formId", formId) - - val jsonArray = JSONArray() - ids.forEach { - jsonArray.put(it) - } - paramObject.put("ids", jsonArray) + paramObject["createStartTime"] = createStartTime + paramObject["createEndTime"] = createEndTime + paramObject["deptId"] = deptId + paramObject["director"] = director + paramObject["effectiveCompany"] = effectiveCompany + paramObject["trainStartTime"] = trainStartTime + paramObject["trainEndTime"] = trainEndTime + paramObject["formId"] = formId + paramObject["ids"] = JSONArray.parseArray(JSON.toJSONString(ids)) val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() @@ -294,7 +305,7 @@ */ suspend fun getMeterageTrainDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -308,10 +319,10 @@ bussinessSize: String, customerName: String, customerNo: String, grade: String, offset: Int ): String { val paramObject = JSONObject() - paramObject.put("bussinessSize", bussinessSize) - paramObject.put("customerName", customerName) - paramObject.put("customerNo", customerNo) - paramObject.put("grade", grade) + paramObject["bussinessSize"] = bussinessSize + paramObject["customerName"] = customerName + paramObject["customerNo"] = customerNo + paramObject["grade"] = grade val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() @@ -330,7 +341,7 @@ */ suspend fun getCustomerDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -342,7 +353,7 @@ */ suspend fun getStaffList(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -354,7 +365,7 @@ */ suspend fun getSupportEquipmentList(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -366,7 +377,7 @@ */ suspend fun getVerifyProcedureList(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -389,20 +400,15 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("customerName", customerName) - paramObject.put("customerNo", customerNo) - paramObject.put("deliverer", deliverer) - paramObject.put("orderCode", orderCode) - paramObject.put("startTime", startTime) - paramObject.put("endTime", endTime) - paramObject.put("isUrgent", isUrgent) - paramObject.put("status", status) - - val jsonArray = JSONArray() - ids.forEach { - jsonArray.put(it) - } - paramObject.put("ids", jsonArray) + paramObject["customerName"] = customerName + paramObject["customerNo"] = customerNo + paramObject["deliverer"] = deliverer + paramObject["orderCode"] = orderCode + paramObject["startTime"] = startTime + paramObject["endTime"] = endTime + paramObject["isUrgent"] = isUrgent + paramObject["status"] = status + paramObject["ids"] = JSONArray.parseArray(JSON.toJSONString(ids)) val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() @@ -421,7 +427,7 @@ */ suspend fun getEntrustDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -433,7 +439,7 @@ */ suspend fun acceptEntrust(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -446,10 +452,89 @@ */ suspend fun returnEntrust(id: String, selected: ArrayList): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) return api.returnEntrust(AuthenticationHelper.token!!, requestBody) } + + /** + * 获取样品列表 + */ + suspend fun getSampleList( + customerName: String, + customerNo: String, + startTime: String, + endTime: String, + sampleName: String, + sampleNo: String, + sampleModel: String, + sampleBelong: String, + overtimeStatus: String, + ids: Array, + offset: Int + ): String { + val paramObject = JSONObject() + paramObject["customerName"] = customerName + paramObject["customerNo"] = customerNo + paramObject["startTime"] = startTime + paramObject["endTime"] = endTime + paramObject["sampleName"] = sampleName + paramObject["sampleNo"] = sampleNo + paramObject["sampleModel"] = sampleModel + paramObject["sampleBelong"] = sampleBelong + paramObject["overtimeStatus"] = overtimeStatus + paramObject["ids"] = JSONArray.parseArray(JSON.toJSONString(ids)) + + val requestBody = paramObject.toString().toRequestBody( + "application/json;charset=UTF-8".toMediaType() + ) + + val limitMap = HashMap() + limitMap["limit"] = LocaleConstant.PAGE_LIMIT + + val offsetMap = HashMap() + offsetMap["offset"] = offset + return api.getSampleList(AuthenticationHelper.token!!, requestBody, limitMap, offsetMap) + } + + /** + * 新增委托书 + */ + suspend fun addEntrust( + deliverer: String, + delivererTel: String, + orderTime: String, + planDeliverTime: String, + requireOverTime: String, + customerName: String, + customerPhone: String, + customerAddress: String, + remark: String, + minioFileName: String, + certifications: String, + isUrgent: String, + samples: List + ): String { + val paramObject = JSONObject() + paramObject["deliverer"] = deliverer + paramObject["delivererTel"] = delivererTel + paramObject["orderTime"] = orderTime + paramObject["planDeliverTime"] = planDeliverTime + paramObject["requireOverTime"] = requireOverTime + paramObject["customerName"] = customerName + paramObject["customerPhone"] = customerPhone + paramObject["customerAddress"] = customerAddress + paramObject["remark"] = remark + paramObject["minioFileName"] = minioFileName + paramObject["certifications"] = certifications + paramObject["isUrgent"] = isUrgent + paramObject["customerSampleInfoList"] = JSONArray.parseArray(JSON.toJSONString(samples)) + + val requestBody = paramObject.toString().toRequestBody( + "application/json;charset=UTF-8".toMediaType() + ) + return api.addEntrust(AuthenticationHelper.token!!, requestBody) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/view/home/EntrustAddActivity.kt b/app/src/main/java/com/casic/xz/meterage/view/home/EntrustAddActivity.kt index 3e30095..9c8d27b 100644 --- a/app/src/main/java/com/casic/xz/meterage/view/home/EntrustAddActivity.kt +++ b/app/src/main/java/com/casic/xz/meterage/view/home/EntrustAddActivity.kt @@ -1,52 +1,211 @@ package com.casic.xz.meterage.view.home +import android.app.Activity +import android.content.Context +import android.content.Intent +import android.graphics.Color +import android.graphics.Paint import android.util.Log +import androidx.activity.result.ActivityResult +import androidx.activity.result.ActivityResultCallback +import androidx.activity.result.contract.ActivityResultContracts import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R import com.casic.xz.meterage.adapter.CertificateTypeAdapter2 -import com.casic.xz.meterage.extensions.initLayoutImmersionBar +import com.casic.xz.meterage.adapter.CustomerSampleAdapter +import com.casic.xz.meterage.callback.DateSelectedCallback +import com.casic.xz.meterage.callback.OnImageCompressListener +import com.casic.xz.meterage.extensions.* +import com.casic.xz.meterage.model.EntrustDetailModel +import com.casic.xz.meterage.model.SampleListModel +import com.casic.xz.meterage.utils.FileType +import com.casic.xz.meterage.utils.GlideLoadEngine +import com.casic.xz.meterage.utils.LoadingDialogHub import com.casic.xz.meterage.vm.DictionaryViewModel +import com.casic.xz.meterage.vm.EntrustViewModel +import com.casic.xz.meterage.vm.FileUploadViewModel +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken import com.gyf.immersionbar.ImmersionBar +import com.luck.picture.lib.basic.PictureSelector +import com.luck.picture.lib.config.SelectMimeType +import com.luck.picture.lib.entity.LocalMedia +import com.luck.picture.lib.interfaces.OnResultCallbackListener import com.pengxh.kt.lite.base.KotlinBaseActivity -import com.pengxh.kt.lite.extensions.toJson +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.vm.LoadState +import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import kotlinx.android.synthetic.main.activity_entrust_add.* +import java.io.File + class EntrustAddActivity : KotlinBaseActivity() { + private val context: Context = this@EntrustAddActivity + private val gson by lazy { Gson() } private lateinit var dictionaryViewModel: DictionaryViewModel - private var checkedItems = ArrayList() + private lateinit var fileUploadViewModel: FileUploadViewModel + private lateinit var entrustViewModel: EntrustViewModel + private lateinit var sampleAdapter: CustomerSampleAdapter + private var checkedItems = ArrayList() + private var isUrgent = "0" + private var sampleModels: ArrayList? = null + private var dataBeans = ArrayList() override fun initData() { //证书 dictionaryViewModel = ViewModelProvider(this)[DictionaryViewModel::class.java] dictionaryViewModel.getDictionaryByCode("certificationClass") - dictionaryViewModel.dictionary.observe(this) { dic -> - if (dic.code == 200) { - val typeAdapter2 = CertificateTypeAdapter2(this, dic.data) + dictionaryViewModel.dictionary.observe(this) { + if (it.code == 200) { + val typeAdapter2 = CertificateTypeAdapter2(this, it.data) typeRecyclerView.adapter = typeAdapter2 typeAdapter2.setOnItemCheckedListener(object : CertificateTypeAdapter2.OnItemCheckedListener { override fun onItemChecked(position: Int, isChecked: Boolean) { if (isChecked) { - checkedItems.add(position) + checkedItems.add(position.toString()) } else { - checkedItems.remove(position) + checkedItems.remove(position.toString()) } } }) } } + + fileUploadViewModel = ViewModelProvider(this)[FileUploadViewModel::class.java] + fileUploadViewModel.resultModel.observe(this) { + if (it.code == 200) { + val annexName = it.data[0] + annexView.text = annexName + val textPaint = annexView.paint + textPaint.flags = Paint.UNDERLINE_TEXT_FLAG + textPaint.isAntiAlias = true + annexView.setTextColor(Color.BLUE) + + annexView.setOnClickListener { + annexName.watchAttachFile(this) + } + } + } + + entrustViewModel = ViewModelProvider(this)[EntrustViewModel::class.java] + entrustViewModel.addResult.observe(this) { + if (it.code == 200) { + finish() + } + } + + //样品列表 + sampleAdapter = CustomerSampleAdapter(this, dataBeans) + sampleRecyclerView.adapter = sampleAdapter } + private val selectCustomerLauncher = + registerForActivityResult(ActivityResultContracts.StartActivityForResult(), + object : ActivityResultCallback { + override fun onActivityResult(result: ActivityResult?) { + if (result?.resultCode == Activity.RESULT_OK) { + val data = result.data ?: return + + entrustNameView.text = data.getStringExtra("entrustName") + entrustContactView.text = data.getStringExtra("entrustContact") + entrustAddressView.text = data.getStringExtra("entrustAddress") + } + } + }) + + private val selectSampleLauncher = + registerForActivityResult(ActivityResultContracts.StartActivityForResult(), + object : ActivityResultCallback { + override fun onActivityResult(result: ActivityResult?) { + if (result?.resultCode == Activity.RESULT_OK) { + val data = result.data ?: return + + val modelsJson = data.getStringExtra("sampleModels") + if (!modelsJson.isNullOrBlank()) { + sampleModels = gson.fromJson( + modelsJson, + object : + TypeToken>() {}.type + ) + } + + //刷新列表 + dataBeans.clear() + sampleModels?.forEach { + val model = + EntrustDetailModel.DataModel.CustomerSampleInfoListModel() + + model.customerName = it.customerName + model.customerNo = it.customerNo + model.id = it.id + model.manufacturingNo = it.manufacturingNo + model.measureLastTime = it.measureLastTime + model.measurePeriod = it.measurePeriod + model.orderId = it.orderId + model.remark = it.remark + model.sampleModel = it.sampleModel + model.sampleName = it.sampleName + model.sampleNo = it.sampleNo + model.validDeadline = it.validDeadline + + dataBeans.add(model) + } + sampleAdapter.notifyDataSetChanged() + } + } + }) + override fun initEvent() { + leftBackView.setOnClickListener { finish() } + + estimateTimeView.setOnClickListener { + showDatePicker(object : DateSelectedCallback { + override fun onDateSelected(date: String) { + estimateTimeView.text = date + } + }) + } + + completedView.setOnClickListener { + showDatePicker(object : DateSelectedCallback { + override fun onDateSelected(date: String) { + completedView.text = date + } + }) + } + + entrustNameView.setOnClickListener { + selectCustomerLauncher.launch(Intent(this, SelectCustomerActivity::class.java)) + } + //上传附件 uploadFileButton.setOnClickListener { + BottomActionSheet.Builder() + .setContext(this) + .setItemTextColor(Color.BLUE) + .setActionItemTitle(listOf("文件", "图片")) + .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { + override fun onActionItemClick(position: Int) { + when (position) { + 0 -> uploadFile() + 1 -> uploadImage() + } + } + }).build().show() + } + radioGroup.setOnCheckedChangeListener { _, checkedId -> + when (checkedId) { + R.id.radioButton1 -> isUrgent = "1" + R.id.radioButton2 -> isUrgent = "0" + } } //选择样品 selectSampleButton.setOnClickListener { - + selectSampleLauncher.launch(Intent(this, SelectSampleActivity::class.java)) } //写入样品信息 @@ -55,14 +214,68 @@ } pushEntrustView.setOnClickListener { - Log.d("Casic", "EntrustAddActivity => initEvent: ${checkedItems.toJson()}") + val sender = senderView.text.toString() + if (sender.isBlank()) { + "请填写送样人名字".show(this) + return@setOnClickListener + } + + val contact = contactView.text.toString() + if (contact.isBlank()) { + "请填写送样人联系方式".show(this) + return@setOnClickListener + } + + val estimateTime = estimateTimeView.text.toString() + if (estimateTime.isBlank()) { + "请选择预计送到的时间".show(this) + return@setOnClickListener + } + + val entrustName = entrustNameView.text.toString() + if (entrustName.isBlank()) { + "请选择委托方".show(this) + return@setOnClickListener + } + + if (sampleModels == null) { + "请选择样品".show(this) + return@setOnClickListener + } + entrustViewModel.addEntrust( + sender, + contact, + createEntrustDateView.text.toString(), + estimateTime, + completedView.text.toString(), + entrustName, + entrustContactView.text.toString(), + entrustAddressView.text.toString(), + remarkView.text.toString(), + annexView.text.toString(), + checkedItems.reformat(), + isUrgent, + sampleModels!! + ) } } override fun initLayoutView(): Int = R.layout.activity_entrust_add override fun observeRequestState() { + fileUploadViewModel.loadState.observe(this) { + when (it) { + LoadState.Loading -> LoadingDialogHub.show(this, "文件上传中,请稍后...") + else -> LoadingDialogHub.dismiss() + } + } + entrustViewModel.loadState.observe(this) { + when (it) { + LoadState.Loading -> LoadingDialogHub.show(this, "委托创建中,请稍后...") + else -> LoadingDialogHub.dismiss() + } + } } override fun setupTopBarLayout() { @@ -70,4 +283,62 @@ initLayoutImmersionBar(rootView) titleView.text = "委托需求" } + + private fun uploadFile() { +// val explorer = FileExplorer(this) +// explorer.setInitDir(ExplorerMode.FILE, Environment.getExternalStorageDirectory()) +// explorer.setShowHomeDir(true) +// explorer.setShowUpDir(true) +// explorer.setShowHideDir(true) +// explorer.setAllowExtensions(arrayOf(".doc", ".docx", ".xls", ".xlsx", ".pdf")) +// explorer.setOnFileClickedListener { +// val type = if (it.name.endsWith(".doc") || it.name.endsWith(".docx")) { +// FileType.WORD +// } else if (it.name.endsWith(".pdf")) { +// FileType.PDF +// } else { +// FileType.UNKNOWN +// } +// +// Log.d("Casic", "EntrustAddActivity => uploadFile: ${it.absolutePath}") +// fileUploadViewModel.uploadFile(it, type) +// } + } + + private fun uploadImage() { + PictureSelector.create(this) + .openGallery(SelectMimeType.ofImage()) + .isGif(false) + .isMaxSelectEnabledMask(true) + .setFilterMinFileSize(100) + .setMaxSelectNum(1) + .isDisplayCamera(false) + .setImageEngine(GlideLoadEngine.instance) + .forResult(object : OnResultCallbackListener { + override fun onResult(result: ArrayList?) { + if (result == null) { + "选择照片失败,请重试".show(context) + return + } + result[0].realPath.compressImage(context, object : OnImageCompressListener { + override fun onSuccess(file: File) { + Log.d( + "Casic", "EntrustAddActivity => onSuccess: ${file.absolutePath}" + ) + ///storage/emulated/0/Android/data/com.casic.xz.meterage/files/Pictures/CompressImage/1677478115391211.jpeg + //上传图片 + fileUploadViewModel.uploadFile(file, FileType.IMAGE) + } + + override fun onError(e: Throwable) { + e.printStackTrace() + } + }) + } + + override fun onCancel() { + + } + }) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/view/home/SelectCustomerActivity.kt b/app/src/main/java/com/casic/xz/meterage/view/home/SelectCustomerActivity.kt new file mode 100644 index 0000000..9bf6a1a --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/view/home/SelectCustomerActivity.kt @@ -0,0 +1,158 @@ +package com.casic.xz.meterage.view.home + +import android.content.Intent +import android.os.Handler +import androidx.lifecycle.ViewModelProvider +import androidx.recyclerview.widget.DefaultItemAnimator +import androidx.recyclerview.widget.DividerItemDecoration +import com.casic.xz.meterage.R +import com.casic.xz.meterage.adapter.SelectCustomerAdapter +import com.casic.xz.meterage.extensions.initLayoutImmersionBar +import com.casic.xz.meterage.extensions.showEmptyPage +import com.casic.xz.meterage.model.CustomerListModel +import com.casic.xz.meterage.utils.LoadingDialogHub +import com.casic.xz.meterage.vm.CustomerViewModel +import com.gyf.immersionbar.ImmersionBar +import com.pengxh.kt.lite.base.KotlinBaseActivity +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.utils.WeakReferenceHandler +import com.pengxh.kt.lite.vm.LoadState +import kotlinx.android.synthetic.main.activity_select_customer.* +import kotlinx.android.synthetic.main.include_base_title.* +import kotlinx.android.synthetic.main.include_empty_view.* + +class SelectCustomerActivity : KotlinBaseActivity() { + + private lateinit var weakReferenceHandler: WeakReferenceHandler + private lateinit var customerViewModel: CustomerViewModel + private lateinit var selectCustomerAdapter: SelectCustomerAdapter + private var dataBeans: MutableList = ArrayList() + private var pageIndex = 1 + private var isRefresh = false + private var isLoadMore = false + private var customerModel: CustomerListModel.DataModel.RowsModel? = null + + override fun initData() { + weakReferenceHandler = WeakReferenceHandler(callback) + customerViewModel = ViewModelProvider(this)[CustomerViewModel::class.java] + customerViewModel.customerList.observe(this) { + if (it.code == 200) { + val dataRows = it.data?.rows!! + when { + isRefresh -> { + dataBeans.clear() + dataBeans = dataRows + customerLayout.finishRefresh() + isRefresh = false + } + isLoadMore -> { + if (dataRows.size == 0) { + "到底了,别拉了".show(this) + } + dataBeans.addAll(dataRows) + customerLayout.finishLoadMore() + isLoadMore = false + } + else -> { + dataBeans = dataRows + } + } + weakReferenceHandler.sendEmptyMessage(2023022701) + } + } + } + + override fun initEvent() { + leftBackView.setOnClickListener { + if (customerModel == null) { + "请选择委托方".show(this) + return@setOnClickListener + } + val intent = Intent() + intent.putExtra("entrustName", customerModel!!.customerName) + intent.putExtra("entrustContact", customerModel!!.phone) + intent.putExtra("entrustAddress", customerModel!!.fullAddress) + setResult(RESULT_OK, intent) + finish() + } + + customerLayout.setOnRefreshListener { + isRefresh = true + //刷新之后页码重置 + pageIndex = 1 + getCustomerList() + } + + customerLayout.setOnLoadMoreListener { + isLoadMore = true + pageIndex++ + getCustomerList() + } + } + + override fun initLayoutView(): Int = R.layout.activity_select_customer + + override fun observeRequestState() { + customerViewModel.loadState.observe(this) { + when (it) { + LoadState.Loading -> LoadingDialogHub.show(this, "数据加载中...") + else -> LoadingDialogHub.dismiss() + } + } + } + + override fun setupTopBarLayout() { + ImmersionBar.with(this).statusBarDarkFont(true).init() + initLayoutImmersionBar(rootView) + titleView.text = "客户列表" + } + + override fun onResume() { + super.onResume() + pageIndex = 1 + getCustomerList() + } + + private fun getCustomerList() { + customerViewModel.getCustomerList( + "", + "", + "", + "", + pageIndex + ) + } + + private val callback = Handler.Callback { + when (it.what) { + 2023022701 -> { + if (isRefresh || isLoadMore) { + selectCustomerAdapter.notifyDataSetChanged() + } else { + if (dataBeans.size == 0) { + emptyView!!.showEmptyPage("无客户数据") { + pageIndex = 1 + getCustomerList() + } + } else { + emptyView!!.hide() + selectCustomerAdapter = SelectCustomerAdapter(this, dataBeans) + customerRecyclerView.addItemDecoration( + DividerItemDecoration(this, DividerItemDecoration.VERTICAL) + ) + (customerRecyclerView.itemAnimator as DefaultItemAnimator).supportsChangeAnimations = + false + customerRecyclerView.adapter = selectCustomerAdapter + selectCustomerAdapter.setOnCheckedListener(object : + SelectCustomerAdapter.OnItemCheckedListener { + override fun onItemChecked(item: CustomerListModel.DataModel.RowsModel) { + customerModel = item + } + }) + } + } + } + } + true + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/view/home/SelectSampleActivity.kt b/app/src/main/java/com/casic/xz/meterage/view/home/SelectSampleActivity.kt new file mode 100644 index 0000000..f85cb44 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/view/home/SelectSampleActivity.kt @@ -0,0 +1,152 @@ +package com.casic.xz.meterage.view.home + +import android.content.Intent +import android.os.Handler +import androidx.lifecycle.ViewModelProvider +import androidx.recyclerview.widget.DefaultItemAnimator +import androidx.recyclerview.widget.DividerItemDecoration +import com.casic.xz.meterage.R +import com.casic.xz.meterage.adapter.SelectSampleAdapter +import com.casic.xz.meterage.extensions.initLayoutImmersionBar +import com.casic.xz.meterage.extensions.showEmptyPage +import com.casic.xz.meterage.model.SampleListModel +import com.casic.xz.meterage.vm.SampleViewModel +import com.gyf.immersionbar.ImmersionBar +import com.pengxh.kt.lite.base.KotlinBaseActivity +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.extensions.toJson +import com.pengxh.kt.lite.utils.WeakReferenceHandler +import kotlinx.android.synthetic.main.activity_select_sample.* +import kotlinx.android.synthetic.main.include_base_title.* +import kotlinx.android.synthetic.main.include_empty_view.* + +class SelectSampleActivity : KotlinBaseActivity() { + + private lateinit var weakReferenceHandler: WeakReferenceHandler + private lateinit var sampleViewModel: SampleViewModel + private lateinit var selectSampleAdapter: SelectSampleAdapter + private var dataBeans: MutableList = ArrayList() + private var pageIndex = 1 + private var isRefresh = false + private var isLoadMore = false + private var sampleModels = ArrayList() + + override fun initData() { + weakReferenceHandler = WeakReferenceHandler(callback) + sampleViewModel = ViewModelProvider(this)[SampleViewModel::class.java] + sampleViewModel.sampleList.observe(this) { + if (it.code == 200) { + val dataRows = it.data?.rows!! + when { + isRefresh -> { + dataBeans.clear() + dataBeans = dataRows + sampleLayout.finishRefresh() + isRefresh = false + } + isLoadMore -> { + if (dataRows.size == 0) { + "到底了,别拉了".show(this) + } + dataBeans.addAll(dataRows) + sampleLayout.finishLoadMore() + isLoadMore = false + } + else -> { + dataBeans = dataRows + } + } + weakReferenceHandler.sendEmptyMessage(2023030101) + } + } + } + + override fun initEvent() { + leftBackView.setOnClickListener { + val intent = Intent() + intent.putExtra("sampleModels", sampleModels.toJson()) + setResult(RESULT_OK, intent) + finish() + } + + sampleLayout.setOnRefreshListener { + isRefresh = true + //刷新之后页码重置 + pageIndex = 1 + getSampleList() + } + + sampleLayout.setOnLoadMoreListener { + isLoadMore = true + pageIndex++ + getSampleList() + } + } + + override fun initLayoutView(): Int = R.layout.activity_select_sample + + override fun observeRequestState() { + + } + + override fun setupTopBarLayout() { + ImmersionBar.with(this).statusBarDarkFont(true).init() + initLayoutImmersionBar(rootView) + titleView.text = "样品列表" + } + + override fun onResume() { + super.onResume() + pageIndex = 1 + getSampleList() + } + + private fun getSampleList() { + sampleViewModel.getSampleList( + "", + "", + "", + "", + "", + "", + "", + "", + "", + arrayOf(), + pageIndex + ) + } + + private val callback = Handler.Callback { + when (it.what) { + 2023030101 -> { + if (isRefresh || isLoadMore) { + selectSampleAdapter.notifyDataSetChanged() + } else { + if (dataBeans.size == 0) { + emptyView!!.showEmptyPage("无样品数据") { + pageIndex = 1 + getSampleList() + } + } else { + emptyView!!.hide() + selectSampleAdapter = SelectSampleAdapter(this, dataBeans) + sampleRecyclerView.addItemDecoration( + DividerItemDecoration(this, DividerItemDecoration.VERTICAL) + ) + (sampleRecyclerView.itemAnimator as DefaultItemAnimator).supportsChangeAnimations = + false + sampleRecyclerView.adapter = selectSampleAdapter + selectSampleAdapter.setOnCheckedListener(object : + SelectSampleAdapter.OnItemCheckedListener { + override fun onItemChecked(items: ArrayList) { + sampleModels = items + } + }) + } + } + } + } + true + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/view/notice/NoticeDetailActivity.kt b/app/src/main/java/com/casic/xz/meterage/view/notice/NoticeDetailActivity.kt index a9d9422..9596985 100644 --- a/app/src/main/java/com/casic/xz/meterage/view/notice/NoticeDetailActivity.kt +++ b/app/src/main/java/com/casic/xz/meterage/view/notice/NoticeDetailActivity.kt @@ -1,6 +1,7 @@ package com.casic.xz.meterage.view.notice import android.annotation.SuppressLint +import android.graphics.Color import android.graphics.Paint import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R @@ -10,7 +11,6 @@ import com.casic.xz.meterage.vm.NoticeViewModel import com.gyf.immersionbar.ImmersionBar import com.pengxh.kt.lite.base.KotlinBaseActivity -import com.pengxh.kt.lite.extensions.convertColor import com.pengxh.kt.lite.extensions.obtainScreenWidth import com.pengxh.kt.lite.utils.Constant import kotlinx.android.synthetic.main.activity_notice_detail.* @@ -54,7 +54,7 @@ val textPaint = minioFileView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - minioFileView.setTextColor(R.color.themeColor.convertColor(this)) + minioFileView.setTextColor(Color.BLUE) minioFileView.setOnClickListener { minioFileName.watchAttachFile(this) diff --git a/app/src/main/java/com/casic/xz/meterage/vm/EntrustViewModel.kt b/app/src/main/java/com/casic/xz/meterage/vm/EntrustViewModel.kt index 2280f88..103c002 100644 --- a/app/src/main/java/com/casic/xz/meterage/vm/EntrustViewModel.kt +++ b/app/src/main/java/com/casic/xz/meterage/vm/EntrustViewModel.kt @@ -7,6 +7,7 @@ import com.casic.xz.meterage.model.ActionResultModel import com.casic.xz.meterage.model.EntrustDetailModel import com.casic.xz.meterage.model.EntrustListModel +import com.casic.xz.meterage.model.SampleListModel import com.casic.xz.meterage.utils.retrofit.RetrofitServiceManager import com.google.gson.Gson import com.google.gson.reflect.TypeToken @@ -25,6 +26,7 @@ val entrustDetail = MutableLiveData() val acceptResult = MutableLiveData() val returnResult = MutableLiveData() + val addResult = MutableLiveData() fun getEntrustList( customerName: String, @@ -119,4 +121,50 @@ loadState.value = LoadState.Fail it.cause.toString().show(BaseApplication.get()) }) + + fun addEntrust( + deliverer: String, + delivererTel: String, + orderTime: String, + planDeliverTime: String, + requireOverTime: String, + customerName: String, + customerPhone: String, + customerAddress: String, + remark: String, + minioFileName: String, + certifications: String, + isUrgent: String, + samples: List + ) = launch({ + loadState.value = LoadState.Loading + val response = RetrofitServiceManager.addEntrust( + deliverer, + delivererTel, + orderTime, + planDeliverTime, + requireOverTime, + customerName, + customerPhone, + customerAddress, + remark, + minioFileName, + certifications, + isUrgent, + samples + ) + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + loadState.value = LoadState.Success + addResult.value = gson.fromJson( + response, object : TypeToken() {}.type + ) + } else { + loadState.value = LoadState.Fail + response.toErrorMessage().show(BaseApplication.get()) + } + }, { + loadState.value = LoadState.Fail + it.cause.toString().show(BaseApplication.get()) + }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/vm/FileUploadViewModel.kt b/app/src/main/java/com/casic/xz/meterage/vm/FileUploadViewModel.kt new file mode 100644 index 0000000..b16c1c7 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/vm/FileUploadViewModel.kt @@ -0,0 +1,40 @@ +package com.casic.xz.meterage.vm + +import androidx.lifecycle.MutableLiveData +import com.casic.xz.meterage.base.BaseApplication +import com.casic.xz.meterage.extensions.separateResponseCode +import com.casic.xz.meterage.extensions.toErrorMessage +import com.casic.xz.meterage.model.UploadResultModel +import com.casic.xz.meterage.utils.FileType +import com.casic.xz.meterage.utils.retrofit.RetrofitServiceManager +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken +import com.pengxh.kt.lite.extensions.launch +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.vm.BaseViewModel +import com.pengxh.kt.lite.vm.LoadState +import java.io.File + +class FileUploadViewModel : BaseViewModel() { + + private val gson by lazy { Gson() } + val resultModel = MutableLiveData() + + fun uploadFile(file: File, type: FileType) = launch({ + loadState.value = LoadState.Loading + val response = RetrofitServiceManager.uploadFile(file, type) + 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(BaseApplication.get()) + } + }, { + loadState.value = LoadState.Fail + it.cause.toString().show(BaseApplication.get()) + }) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/vm/SampleViewModel.kt b/app/src/main/java/com/casic/xz/meterage/vm/SampleViewModel.kt new file mode 100644 index 0000000..182140d --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/vm/SampleViewModel.kt @@ -0,0 +1,65 @@ +package com.casic.xz.meterage.vm + +import androidx.lifecycle.MutableLiveData +import com.casic.xz.meterage.base.BaseApplication +import com.casic.xz.meterage.extensions.separateResponseCode +import com.casic.xz.meterage.extensions.toErrorMessage +import com.casic.xz.meterage.model.SampleListModel +import com.casic.xz.meterage.utils.retrofit.RetrofitServiceManager +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken +import com.pengxh.kt.lite.extensions.launch +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.vm.BaseViewModel +import com.pengxh.kt.lite.vm.LoadState + +/** + * 样品相关 VM + * */ +class SampleViewModel : BaseViewModel() { + + private val gson by lazy { Gson() } + val sampleList = MutableLiveData() + + fun getSampleList( + customerName: String, + customerNo: String, + startTime: String, + endTime: String, + sampleName: String, + sampleNo: String, + sampleModel: String, + sampleBelong: String, + overtimeStatus: String, + ids: Array, + offset: Int + ) = launch({ + loadState.value = LoadState.Loading + val response = RetrofitServiceManager.getSampleList( + customerName, + customerNo, + startTime, + endTime, + sampleName, + sampleNo, + sampleModel, + sampleBelong, + overtimeStatus, + ids, + offset + ) + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + loadState.value = LoadState.Success + sampleList.value = gson.fromJson( + response, object : TypeToken() {}.type + ) + } else { + loadState.value = LoadState.Fail + response.toErrorMessage().show(BaseApplication.get()) + } + }, { + loadState.value = LoadState.Fail + it.cause.toString().show(BaseApplication.get()) + }) +} \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_customer_selector.xml b/app/src/main/res/drawable/bg_customer_selector.xml new file mode 100644 index 0000000..e7292d5 --- /dev/null +++ b/app/src/main/res/drawable/bg_customer_selector.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 0ae369f..687b02b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -15,7 +15,6 @@ } compileSdkVersion 31 - buildToolsVersion "30.0.3" defaultConfig { applicationId "com.casic.xz.meterage" @@ -84,11 +83,13 @@ implementation 'top.zibin:Luban:1.1.8' //官方Json解析库 implementation 'com.google.code.gson:gson:2.9.0' + //阿里巴巴JSON库 + implementation 'com.alibaba.fastjson2:fastjson2:2.0.24' //Kotlin协程 implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.5.1' //MVVM+LiveData implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.5.1" - implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.0" + implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1" implementation "androidx.lifecycle:lifecycle-extensions:2.2.0" //返回值转换器 implementation 'com.jakewharton.retrofit:retrofit2-kotlin-coroutines-adapter:0.9.2' @@ -109,4 +110,8 @@ implementation 'com.github.barteksc:android-pdf-viewer:2.8.2' //绕过Android 11反射限制 implementation 'com.github.tiann:FreeReflection:3.1.0' + //单项/数字、二三级联动、日期/时间等滚轮选择器 + implementation 'com.github.gzu-liyujiang.AndroidPicker:WheelPicker:4.1.8' + //文件/目录选择器 + implementation 'com.github.gzu-liyujiang.AndroidPicker:FilePicker:4.1.1' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 1ccc12b..0fba91b 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -60,6 +60,8 @@ + + diff --git a/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt b/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt new file mode 100644 index 0000000..21a71d8 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt @@ -0,0 +1,70 @@ +package com.casic.xz.meterage.adapter + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import com.casic.xz.meterage.R +import com.casic.xz.meterage.extensions.toChineseGrade +import com.casic.xz.meterage.model.CustomerListModel + +class SelectCustomerAdapter( + context: Context, private val dataRows: MutableList +) : RecyclerView.Adapter() { + + private var layoutInflater = LayoutInflater.from(context) + + //选择的位置 + private var selectedPosition = 0 + + //临时记录上次选择的位置 + private var temp = -1 + + override fun getItemCount(): Int = dataRows.size + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ItemViewHolder( + layoutInflater.inflate(R.layout.item_select_customer_lv, parent, false) + ) + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + //绑定数据 + val rowsBean = dataRows[position] + holder.agreementLevelView.text = rowsBean.grade.toChineseGrade() + holder.customerNameView.text = rowsBean.customerName + holder.scaleView.text = rowsBean.companySizeName + holder.overallView.text = "公司规模:${rowsBean.evaluationName}" + holder.fullAddressView.text = "公司地址:${rowsBean.fullAddress}" + + holder.itemView.isSelected = holder.layoutPosition == selectedPosition + holder.itemView.setOnClickListener { + itemCheckedListener?.onItemChecked(rowsBean) + + holder.itemView.isSelected = true + temp = selectedPosition + //设置新的位置 + selectedPosition = holder.layoutPosition + //更新旧位置 + notifyItemChanged(temp) + } + } + + inner class ItemViewHolder(view: View) : RecyclerView.ViewHolder(view) { + var agreementLevelView: TextView = view.findViewById(R.id.agreementLevelView) + var customerNameView: TextView = view.findViewById(R.id.customerNameView) + var scaleView: TextView = view.findViewById(R.id.scaleView) + var overallView: TextView = view.findViewById(R.id.overallView) + var fullAddressView: TextView = view.findViewById(R.id.fullAddressView) + } + + private var itemCheckedListener: OnItemCheckedListener? = null + + interface OnItemCheckedListener { + fun onItemChecked(item: CustomerListModel.DataModel.RowsModel) + } + + fun setOnCheckedListener(listener: OnItemCheckedListener?) { + itemCheckedListener = listener + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt b/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt new file mode 100644 index 0000000..c29461e --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt @@ -0,0 +1,68 @@ +package com.casic.xz.meterage.adapter + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import com.casic.xz.meterage.R +import com.casic.xz.meterage.model.SampleListModel + +class SelectSampleAdapter( + context: Context, private val dataRows: MutableList +) : RecyclerView.Adapter() { + + private var layoutInflater = LayoutInflater.from(context) + private var multipleSelected = mutableSetOf() + private var sampleModes = ArrayList() + + override fun getItemCount(): Int = dataRows.size + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ItemViewHolder( + layoutInflater.inflate(R.layout.item_select_sample_lv, parent, false) + ) + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + //绑定数据 + val rowsBean = dataRows[position] + holder.sampleNameView.text = "${rowsBean.sampleName}【${rowsBean.sampleModel}】" + holder.manufacturingCodeView.text = "出厂编号:${rowsBean.manufacturingNo}" + holder.sampleCodeView.text = "样品编号:${rowsBean.sampleNo}" + holder.validDateView.text = "有效期至:${rowsBean.validDeadline}" + + holder.checkImageView.isSelected = multipleSelected.contains(position) + holder.itemView.setOnClickListener { + if (multipleSelected.contains(position)) { + multipleSelected.remove(position) + sampleModes.remove(dataRows[position]) + holder.checkImageView.isSelected = false + } else { + multipleSelected.add(position) + sampleModes.add(dataRows[position]) + holder.checkImageView.isSelected = true + } + + itemCheckedListener?.onItemChecked(sampleModes) + } + } + + inner class ItemViewHolder(view: View) : RecyclerView.ViewHolder(view) { + var sampleNameView: TextView = view.findViewById(R.id.sampleNameView) + var manufacturingCodeView: TextView = view.findViewById(R.id.manufacturingCodeView) + var sampleCodeView: TextView = view.findViewById(R.id.sampleCodeView) + var validDateView: TextView = view.findViewById(R.id.validDateView) + var checkImageView: ImageView = view.findViewById(R.id.checkImageView) + } + + private var itemCheckedListener: OnItemCheckedListener? = null + + interface OnItemCheckedListener { + fun onItemChecked(items: ArrayList) + } + + fun setOnCheckedListener(listener: OnItemCheckedListener?) { + itemCheckedListener = listener + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/callback/DateSelectedCallback.kt b/app/src/main/java/com/casic/xz/meterage/callback/DateSelectedCallback.kt new file mode 100644 index 0000000..8196110 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/callback/DateSelectedCallback.kt @@ -0,0 +1,5 @@ +package com.casic.xz.meterage.callback + +interface DateSelectedCallback { + fun onDateSelected(date: String) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/Activity.kt b/app/src/main/java/com/casic/xz/meterage/extensions/Activity.kt new file mode 100644 index 0000000..e112d1c --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/extensions/Activity.kt @@ -0,0 +1,33 @@ +package com.casic.xz.meterage.extensions + +import android.app.Activity +import com.casic.xz.meterage.R +import com.casic.xz.meterage.callback.DateSelectedCallback +import com.github.gzuliyujiang.wheelpicker.DatePicker +import com.github.gzuliyujiang.wheelpicker.annotation.DateMode +import com.github.gzuliyujiang.wheelpicker.entity.DateEntity +import com.pengxh.kt.lite.extensions.convertColor +import com.pengxh.kt.lite.extensions.sp2px + +fun Activity.showDatePicker(callback: DateSelectedCallback) { + val datePicker = DatePicker(this) + + val layout = datePicker.wheelLayout + layout.setDateMode(DateMode.YEAR_MONTH_DAY) + layout.setDateLabel("年", "月", "日"); + layout.setTextSize(14f.sp2px(this).toFloat()) + layout.setSelectedTextSize(16f.sp2px(this).toFloat()) + layout.setSelectedTextColor(R.color.themeColor.convertColor(this)) + layout.setSelectedTextBold(true) + layout.setResetWhenLinkage(false) + layout.setRange( + DateEntity.today(), + DateEntity.target(2050, 12, 31), + DateEntity.today() + ) + + datePicker.setOnDatePickedListener { year, month, day -> + callback.onDateSelected(String.format("%s-%s-%s", year, month, day)) + } + datePicker.show() +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt b/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt index 016ebcb..cf6bf49 100644 --- a/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt +++ b/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt @@ -4,7 +4,7 @@ * ArrayList扩展方法 */ -//将图片集合格式化成满足上传格式的数据 +//将集合格式化成满足上传格式的数据 fun ArrayList.reformat(): String { if (this.isEmpty()) return "" val builder = StringBuilder() diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt b/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt index 7c57643..aa9b92b 100644 --- a/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt +++ b/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt @@ -1,7 +1,6 @@ package com.casic.xz.meterage.extensions import android.content.Context -import android.util.Log import android.view.ViewGroup import com.casic.xz.meterage.base.BaseApplication import com.pengxh.kt.lite.extensions.dp2px @@ -9,9 +8,8 @@ fun Context.initLayoutImmersionBar(rootView: ViewGroup) { var statusBarHeight = QMUIDisplayHelper.getStatusBarHeight(this) - Log.d("Casic", "状态栏高度: $statusBarHeight") if (statusBarHeight == 0) { - statusBarHeight = 44f.dp2px(BaseApplication.get()) + statusBarHeight = 40f.dp2px(BaseApplication.get()) } rootView.setPadding(0, statusBarHeight, 0, 0) rootView.requestLayout() diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/String.kt b/app/src/main/java/com/casic/xz/meterage/extensions/String.kt index 28f70d8..6234d43 100644 --- a/app/src/main/java/com/casic/xz/meterage/extensions/String.kt +++ b/app/src/main/java/com/casic/xz/meterage/extensions/String.kt @@ -128,9 +128,10 @@ fun String.combineImagePath(): String { if (this.isEmpty()) return this val defaultValue = SaveKeyValues.getValue( - LocaleConstant.DEFAULT_SERVER_CONFIG, LocaleConstant.SERVER_BASE_URL + LocaleConstant.FILE_SERVER_CONFIG, LocaleConstant.File_SERVER_URL ) as String - return "$defaultValue/static/${this.replace("\\", "/")}" + //http://111.198.10.15:21408/test/1677479806059688_1677479806038.jpeg + return "$defaultValue/test/${this.replace("\\", "/")}" } fun String.isEarlier(time: String): Boolean { diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt index 25fa87b..a0e1358 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt @@ -1,18 +1,12 @@ package com.casic.xz.meterage.fragment.customer +import android.graphics.Color import android.graphics.Paint import com.casic.xz.meterage.R -import com.casic.xz.meterage.extensions.combineImagePath import com.casic.xz.meterage.extensions.toChineseGrade +import com.casic.xz.meterage.extensions.watchAttachFile import com.casic.xz.meterage.model.CustomerDetailModel -import com.casic.xz.meterage.view.BigImageActivity -import com.casic.xz.meterage.view.notice.PreviewDocumentActivity -import com.casic.xz.meterage.view.notice.PreviewPdfActivity -import com.casic.xz.meterage.view.notice.PreviewTextActivity import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.extensions.show import kotlinx.android.synthetic.main.fragment_customer_basic_information.* class BasicInformationFragment(private val data: CustomerDetailModel.DataModel) : @@ -48,30 +42,11 @@ val textPaint = minioFileView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - minioFileView.setTextColor(R.color.themeColor.convertColor(requireContext())) + minioFileView.setTextColor(Color.BLUE) minioFileView.setOnClickListener { //查看附件 - if (minioFileName.endsWith("pdf")) { - requireContext().navigatePageTo(minioFileName) - } else if ( - minioFileName.endsWith("doc") || - minioFileName.endsWith("docx") - ) { - requireContext().navigatePageTo(minioFileName) - } else if (minioFileName.endsWith("txt")) { - requireContext().navigatePageTo(minioFileName) - } else if ( - minioFileName.endsWith("png") || - minioFileName.endsWith("jpeg") || - minioFileName.endsWith("jpg") - ) { - val urls = ArrayList() - urls.add(minioFileName.combineImagePath()) - requireContext().navigatePageTo(0, urls) - } else { - "文件类型未知,无法打开附件".show(requireContext()) - } + minioFileName.watchAttachFile(requireContext()) } } } diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt index 77846b4..3a0fe2e 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt @@ -1,5 +1,6 @@ package com.casic.xz.meterage.fragment.device +import android.graphics.Color import android.graphics.Paint import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R @@ -7,7 +8,6 @@ import com.casic.xz.meterage.utils.LoadingDialogHub import com.casic.xz.meterage.vm.EquipmentViewModel import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor import com.pengxh.kt.lite.vm.LoadState import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import kotlinx.android.synthetic.main.fragment_device_basic_information.* @@ -56,7 +56,7 @@ val textPaint = documentsView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - documentsView.setTextColor(R.color.themeColor.convertColor(requireContext())) + documentsView.setTextColor(Color.BLUE) val files = ArrayList() data.fileList.forEach { file -> @@ -66,7 +66,7 @@ BottomActionSheet.Builder() .setContext(requireContext()) .setActionItemTitle(files) - .setItemTextColor(R.color.themeColor.convertColor(requireContext())) + .setItemTextColor(Color.BLUE) .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { override fun onActionItemClick(position: Int) { diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt index 15dc3d2..10eeff8 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt @@ -1,5 +1,6 @@ package com.casic.xz.meterage.fragment.entrust +import android.graphics.Color import android.graphics.Paint import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R @@ -9,7 +10,6 @@ import com.casic.xz.meterage.model.EntrustDetailModel import com.casic.xz.meterage.vm.DictionaryViewModel import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor import kotlinx.android.synthetic.main.fragment_entrust_basic_information.* class BasicInformationFragment(private val data: EntrustDetailModel.DataModel) : @@ -38,7 +38,7 @@ val textPaint = annexView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - annexView.setTextColor(R.color.themeColor.convertColor(requireContext())) + annexView.setTextColor(Color.BLUE) annexView.setOnClickListener { minioFileName.watchAttachFile(requireContext()) @@ -59,9 +59,9 @@ //加急 if (data.isUrgent == "0") { - RadioButton2.isChecked = true + radioButton2.isChecked = true } else { - RadioButton1.isChecked = true + radioButton1.isChecked = true } //样品 diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/equipment/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/equipment/BasicInformationFragment.kt index 72b523c..7bc3b01 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/equipment/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/equipment/BasicInformationFragment.kt @@ -1,5 +1,6 @@ package com.casic.xz.meterage.fragment.equipment +import android.graphics.Color import android.graphics.Paint import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R @@ -7,7 +8,6 @@ import com.casic.xz.meterage.utils.LoadingDialogHub import com.casic.xz.meterage.vm.EquipmentViewModel import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor import com.pengxh.kt.lite.vm.LoadState import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import kotlinx.android.synthetic.main.fragment_equipment_basic_information.* @@ -74,7 +74,7 @@ val textPaint = instructionsView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - instructionsView.setTextColor(R.color.themeColor.convertColor(requireContext())) + instructionsView.setTextColor(Color.BLUE) val files = ArrayList() data.fileList.forEach { file -> @@ -84,7 +84,7 @@ BottomActionSheet.Builder() .setContext(requireContext()) .setActionItemTitle(files) - .setItemTextColor(R.color.themeColor.convertColor(requireContext())) + .setItemTextColor(Color.BLUE) .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { override fun onActionItemClick(position: Int) { diff --git a/app/src/main/java/com/casic/xz/meterage/model/SampleListModel.java b/app/src/main/java/com/casic/xz/meterage/model/SampleListModel.java new file mode 100644 index 0000000..5784343 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/model/SampleListModel.java @@ -0,0 +1,193 @@ +package com.casic.xz.meterage.model; + +import java.util.List; + +public class SampleListModel { + + private int code; + private DataModel data; + private String message; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataModel getData() { + return data; + } + + public void setData(DataModel data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public static class DataModel { + private List rows; + private int total; + + public List getRows() { + return rows; + } + + public void setRows(List rows) { + this.rows = rows; + } + + public int getTotal() { + return total; + } + + public void setTotal(int total) { + this.total = total; + } + + public static class RowsModel { + private String certificationStatus; + private String customerName; + private String customerNo; + private String id; + private String manufacturingNo; + private String measureLastTime; + private String measurePeriod; + private String orderId; + private String remark; + private String sampleModel; + private String sampleName; + private String sampleNo; + private String sampleSatus; + private String sampleSatusName; + private String validDeadline; + + public String getCertificationStatus() { + return certificationStatus; + } + + public void setCertificationStatus(String certificationStatus) { + this.certificationStatus = certificationStatus; + } + + public String getCustomerName() { + return customerName; + } + + public void setCustomerName(String customerName) { + this.customerName = customerName; + } + + public String getCustomerNo() { + return customerNo; + } + + public void setCustomerNo(String customerNo) { + this.customerNo = customerNo; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getManufacturingNo() { + return manufacturingNo; + } + + public void setManufacturingNo(String manufacturingNo) { + this.manufacturingNo = manufacturingNo; + } + + public String getMeasureLastTime() { + return measureLastTime; + } + + public void setMeasureLastTime(String measureLastTime) { + this.measureLastTime = measureLastTime; + } + + public String getMeasurePeriod() { + return measurePeriod; + } + + public void setMeasurePeriod(String measurePeriod) { + this.measurePeriod = measurePeriod; + } + + public String getOrderId() { + return orderId; + } + + public void setOrderId(String orderId) { + this.orderId = orderId; + } + + public String getRemark() { + return remark; + } + + public void setRemark(String remark) { + this.remark = remark; + } + + public String getSampleModel() { + return sampleModel; + } + + public void setSampleModel(String sampleModel) { + this.sampleModel = sampleModel; + } + + public String getSampleName() { + return sampleName; + } + + public void setSampleName(String sampleName) { + this.sampleName = sampleName; + } + + public String getSampleNo() { + return sampleNo; + } + + public void setSampleNo(String sampleNo) { + this.sampleNo = sampleNo; + } + + public String getSampleSatus() { + return sampleSatus; + } + + public void setSampleSatus(String sampleSatus) { + this.sampleSatus = sampleSatus; + } + + public String getSampleSatusName() { + return sampleSatusName; + } + + public void setSampleSatusName(String sampleSatusName) { + this.sampleSatusName = sampleSatusName; + } + + public String getValidDeadline() { + return validDeadline; + } + + public void setValidDeadline(String validDeadline) { + this.validDeadline = validDeadline; + } + } + } +} diff --git a/app/src/main/java/com/casic/xz/meterage/model/UploadResultModel.java b/app/src/main/java/com/casic/xz/meterage/model/UploadResultModel.java new file mode 100644 index 0000000..f2a6a41 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/model/UploadResultModel.java @@ -0,0 +1,34 @@ +package com.casic.xz.meterage.model; + +import java.util.List; + +public class UploadResultModel { + + private int code; + private List data; + private String message; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public List getData() { + return data; + } + + public void setData(List data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } +} diff --git a/app/src/main/java/com/casic/xz/meterage/utils/FileType.kt b/app/src/main/java/com/casic/xz/meterage/utils/FileType.kt new file mode 100644 index 0000000..17e2bca --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/utils/FileType.kt @@ -0,0 +1,23 @@ +package com.casic.xz.meterage.utils + +sealed class FileType { + /** + * PDF文件 + */ + object PDF : FileType() + + /** + * WORD文件 + */ + object WORD : FileType() + + /** + * IMAGE图片 + */ + object IMAGE : FileType() + + /** + * 未知类型(Excel) + */ + object UNKNOWN : FileType() +} diff --git a/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitService.kt index bc3f8d6..8f4fe44 100644 --- a/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitService.kt @@ -1,5 +1,6 @@ package com.casic.xz.meterage.utils.retrofit +import okhttp3.MultipartBody import okhttp3.RequestBody import retrofit2.http.* @@ -35,6 +36,16 @@ ): String /** + * 上传文件 + */ + @Multipart + @POST("/minio/file/upload") + suspend fun uploadFile( + @Header("token") token: String, + @Part file: MultipartBody.Part + ): String + + /** * 获取通知公告列表 */ @POST("/system/notice/listPage") @@ -209,4 +220,24 @@ @Header("token") token: String, @Body requestBody: RequestBody ): String + + /** + * 获取样品列表 + */ + @POST("/customer/sample/listPage") + suspend fun getSampleList( + @Header("token") token: String, + @Body requestBody: RequestBody, + @QueryMap limit: Map, + @QueryMap offset: Map + ): String + + /** + * 新增委托书 + */ + @POST("/business/order/add") + suspend fun addEntrust( + @Header("token") token: String, + @Body requestBody: RequestBody + ): String } \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitServiceManager.kt index cb22e45..90abe5a 100644 --- a/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitServiceManager.kt @@ -1,13 +1,20 @@ package com.casic.xz.meterage.utils.retrofit +import com.alibaba.fastjson2.JSON +import com.alibaba.fastjson2.JSONArray +import com.alibaba.fastjson2.JSONObject +import com.casic.xz.meterage.model.SampleListModel import com.casic.xz.meterage.utils.AuthenticationHelper +import com.casic.xz.meterage.utils.FileType import com.casic.xz.meterage.utils.LocaleConstant import com.pengxh.kt.lite.utils.RetrofitFactory import com.pengxh.kt.lite.utils.SaveKeyValues import okhttp3.MediaType.Companion.toMediaType +import okhttp3.MediaType.Companion.toMediaTypeOrNull +import okhttp3.MultipartBody +import okhttp3.RequestBody.Companion.asRequestBody import okhttp3.RequestBody.Companion.toRequestBody -import org.json.JSONArray -import org.json.JSONObject +import java.io.File object RetrofitServiceManager { @@ -31,9 +38,9 @@ */ suspend fun login(sid: String, account: String, secretKey: String): String { val paramObject = JSONObject() - paramObject.put("sid", sid) - paramObject.put("username", account) - paramObject.put("password", secretKey) + paramObject["sid"] = sid + paramObject["username"] = account + paramObject["password"] = secretKey val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -55,6 +62,20 @@ } /** + * 上传文件 + */ + suspend fun uploadFile(file: File, type: FileType): String { + val requestBody = when (type) { + FileType.PDF -> file.asRequestBody("application/pdf".toMediaTypeOrNull()) + FileType.WORD -> file.asRequestBody("application/msword".toMediaTypeOrNull()) + FileType.IMAGE -> file.asRequestBody("image/png".toMediaTypeOrNull()) + else -> file.asRequestBody("application/vnd.ms-excel".toMediaTypeOrNull()) + } + val filePart = MultipartBody.Part.createFormData("multipartFile", file.name, requestBody) + return api.uploadFile(AuthenticationHelper.token!!, filePart) + } + + /** * 获取通知公告列表 */ suspend fun getNoticeList( @@ -66,11 +87,11 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("noticeNo", noticeNo) - paramObject.put("noticeTitle", noticeTitle) - paramObject.put("noticePublisher", noticePublisher) - paramObject.put("noticeStartTime", noticeStartTime) - paramObject.put("noticeEndTime", noticeEndTime) + paramObject["noticeNo"] = noticeNo + paramObject["noticeTitle"] = noticeTitle + paramObject["noticePublisher"] = noticePublisher + paramObject["noticeStartTime"] = noticeStartTime + paramObject["noticeEndTime"] = noticeEndTime val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -105,26 +126,21 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("equipmentNo", equipmentNo) - paramObject.put("equipmentName", equipmentName) - paramObject.put("mesureType", mesureType) - paramObject.put("managerState", managerState) - paramObject.put("useDept", useDept) - paramObject.put("assetType", assetType) - paramObject.put("equipmentCategory", equipmentCategory) - paramObject.put("isCalibrationTestEquipment", isCalibrationTestEquipment) - paramObject.put("isMeasureAccount", isMeasureAccount) - paramObject.put("isStandardSupportEquipment", isStandardSupportEquipment) - paramObject.put("isFixedAssets", isFixedAssets) - paramObject.put("validStartDate", validStartDate) - paramObject.put("validEndDate", validEndDate) - paramObject.put("abc", abc) - - val jsonArray = JSONArray() - ids.forEach { - jsonArray.put(it) - } - paramObject.put("ids", jsonArray) + paramObject["equipmentNo"] = equipmentNo + paramObject["equipmentName"] = equipmentName + paramObject["mesureType"] = mesureType + paramObject["managerState"] = managerState + paramObject["useDept"] = useDept + paramObject["assetType"] = assetType + paramObject["equipmentCategory"] = equipmentCategory + paramObject["isCalibrationTestEquipment"] = isCalibrationTestEquipment + paramObject["isMeasureAccount"] = isMeasureAccount + paramObject["isStandardSupportEquipment"] = isStandardSupportEquipment + paramObject["isFixedAssets"] = isFixedAssets + paramObject["validStartDate"] = validStartDate + paramObject["validEndDate"] = validEndDate + paramObject["abc"] = abc + paramObject["ids"] = JSONArray.parseArray(JSON.toJSONString(ids)) val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() @@ -143,7 +159,7 @@ */ suspend fun getEquipmentDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -164,13 +180,13 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("standardNo", standardNo) - paramObject.put("standardName", standardName) - paramObject.put("category", category) - paramObject.put("managerState", managerState) - paramObject.put("standardLaboratory", standardLaboratory) - paramObject.put("preparationDate", preparationDate) - paramObject.put("id", id) + paramObject["standardNo"] = standardNo + paramObject["standardName"] = standardName + paramObject["category"] = category + paramObject["managerState"] = managerState + paramObject["standardLaboratory"] = standardLaboratory + paramObject["preparationDate"] = preparationDate + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -193,7 +209,7 @@ */ suspend fun getStandardDeviceDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -212,11 +228,11 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("checkType", checkType) - paramObject.put("priceItem", priceItem) - paramObject.put("priceName", priceName) - paramObject.put("priceNo", priceNo) - paramObject.put("priceType", priceType) + paramObject["checkType"] = checkType + paramObject["priceItem"] = priceItem + paramObject["priceName"] = priceName + paramObject["priceNo"] = priceNo + paramObject["priceType"] = priceType val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -234,7 +250,7 @@ */ suspend fun getCapabilityDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -257,20 +273,15 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("createStartTime", createStartTime) - paramObject.put("createEndTime", createEndTime) - paramObject.put("deptId", deptId) - paramObject.put("director", director) - paramObject.put("effectiveCompany", effectiveCompany) - paramObject.put("trainStartTime", trainStartTime) - paramObject.put("trainEndTime", trainEndTime) - paramObject.put("formId", formId) - - val jsonArray = JSONArray() - ids.forEach { - jsonArray.put(it) - } - paramObject.put("ids", jsonArray) + paramObject["createStartTime"] = createStartTime + paramObject["createEndTime"] = createEndTime + paramObject["deptId"] = deptId + paramObject["director"] = director + paramObject["effectiveCompany"] = effectiveCompany + paramObject["trainStartTime"] = trainStartTime + paramObject["trainEndTime"] = trainEndTime + paramObject["formId"] = formId + paramObject["ids"] = JSONArray.parseArray(JSON.toJSONString(ids)) val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() @@ -294,7 +305,7 @@ */ suspend fun getMeterageTrainDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -308,10 +319,10 @@ bussinessSize: String, customerName: String, customerNo: String, grade: String, offset: Int ): String { val paramObject = JSONObject() - paramObject.put("bussinessSize", bussinessSize) - paramObject.put("customerName", customerName) - paramObject.put("customerNo", customerNo) - paramObject.put("grade", grade) + paramObject["bussinessSize"] = bussinessSize + paramObject["customerName"] = customerName + paramObject["customerNo"] = customerNo + paramObject["grade"] = grade val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() @@ -330,7 +341,7 @@ */ suspend fun getCustomerDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -342,7 +353,7 @@ */ suspend fun getStaffList(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -354,7 +365,7 @@ */ suspend fun getSupportEquipmentList(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -366,7 +377,7 @@ */ suspend fun getVerifyProcedureList(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -389,20 +400,15 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("customerName", customerName) - paramObject.put("customerNo", customerNo) - paramObject.put("deliverer", deliverer) - paramObject.put("orderCode", orderCode) - paramObject.put("startTime", startTime) - paramObject.put("endTime", endTime) - paramObject.put("isUrgent", isUrgent) - paramObject.put("status", status) - - val jsonArray = JSONArray() - ids.forEach { - jsonArray.put(it) - } - paramObject.put("ids", jsonArray) + paramObject["customerName"] = customerName + paramObject["customerNo"] = customerNo + paramObject["deliverer"] = deliverer + paramObject["orderCode"] = orderCode + paramObject["startTime"] = startTime + paramObject["endTime"] = endTime + paramObject["isUrgent"] = isUrgent + paramObject["status"] = status + paramObject["ids"] = JSONArray.parseArray(JSON.toJSONString(ids)) val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() @@ -421,7 +427,7 @@ */ suspend fun getEntrustDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -433,7 +439,7 @@ */ suspend fun acceptEntrust(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -446,10 +452,89 @@ */ suspend fun returnEntrust(id: String, selected: ArrayList): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) return api.returnEntrust(AuthenticationHelper.token!!, requestBody) } + + /** + * 获取样品列表 + */ + suspend fun getSampleList( + customerName: String, + customerNo: String, + startTime: String, + endTime: String, + sampleName: String, + sampleNo: String, + sampleModel: String, + sampleBelong: String, + overtimeStatus: String, + ids: Array, + offset: Int + ): String { + val paramObject = JSONObject() + paramObject["customerName"] = customerName + paramObject["customerNo"] = customerNo + paramObject["startTime"] = startTime + paramObject["endTime"] = endTime + paramObject["sampleName"] = sampleName + paramObject["sampleNo"] = sampleNo + paramObject["sampleModel"] = sampleModel + paramObject["sampleBelong"] = sampleBelong + paramObject["overtimeStatus"] = overtimeStatus + paramObject["ids"] = JSONArray.parseArray(JSON.toJSONString(ids)) + + val requestBody = paramObject.toString().toRequestBody( + "application/json;charset=UTF-8".toMediaType() + ) + + val limitMap = HashMap() + limitMap["limit"] = LocaleConstant.PAGE_LIMIT + + val offsetMap = HashMap() + offsetMap["offset"] = offset + return api.getSampleList(AuthenticationHelper.token!!, requestBody, limitMap, offsetMap) + } + + /** + * 新增委托书 + */ + suspend fun addEntrust( + deliverer: String, + delivererTel: String, + orderTime: String, + planDeliverTime: String, + requireOverTime: String, + customerName: String, + customerPhone: String, + customerAddress: String, + remark: String, + minioFileName: String, + certifications: String, + isUrgent: String, + samples: List + ): String { + val paramObject = JSONObject() + paramObject["deliverer"] = deliverer + paramObject["delivererTel"] = delivererTel + paramObject["orderTime"] = orderTime + paramObject["planDeliverTime"] = planDeliverTime + paramObject["requireOverTime"] = requireOverTime + paramObject["customerName"] = customerName + paramObject["customerPhone"] = customerPhone + paramObject["customerAddress"] = customerAddress + paramObject["remark"] = remark + paramObject["minioFileName"] = minioFileName + paramObject["certifications"] = certifications + paramObject["isUrgent"] = isUrgent + paramObject["customerSampleInfoList"] = JSONArray.parseArray(JSON.toJSONString(samples)) + + val requestBody = paramObject.toString().toRequestBody( + "application/json;charset=UTF-8".toMediaType() + ) + return api.addEntrust(AuthenticationHelper.token!!, requestBody) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/view/home/EntrustAddActivity.kt b/app/src/main/java/com/casic/xz/meterage/view/home/EntrustAddActivity.kt index 3e30095..9c8d27b 100644 --- a/app/src/main/java/com/casic/xz/meterage/view/home/EntrustAddActivity.kt +++ b/app/src/main/java/com/casic/xz/meterage/view/home/EntrustAddActivity.kt @@ -1,52 +1,211 @@ package com.casic.xz.meterage.view.home +import android.app.Activity +import android.content.Context +import android.content.Intent +import android.graphics.Color +import android.graphics.Paint import android.util.Log +import androidx.activity.result.ActivityResult +import androidx.activity.result.ActivityResultCallback +import androidx.activity.result.contract.ActivityResultContracts import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R import com.casic.xz.meterage.adapter.CertificateTypeAdapter2 -import com.casic.xz.meterage.extensions.initLayoutImmersionBar +import com.casic.xz.meterage.adapter.CustomerSampleAdapter +import com.casic.xz.meterage.callback.DateSelectedCallback +import com.casic.xz.meterage.callback.OnImageCompressListener +import com.casic.xz.meterage.extensions.* +import com.casic.xz.meterage.model.EntrustDetailModel +import com.casic.xz.meterage.model.SampleListModel +import com.casic.xz.meterage.utils.FileType +import com.casic.xz.meterage.utils.GlideLoadEngine +import com.casic.xz.meterage.utils.LoadingDialogHub import com.casic.xz.meterage.vm.DictionaryViewModel +import com.casic.xz.meterage.vm.EntrustViewModel +import com.casic.xz.meterage.vm.FileUploadViewModel +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken import com.gyf.immersionbar.ImmersionBar +import com.luck.picture.lib.basic.PictureSelector +import com.luck.picture.lib.config.SelectMimeType +import com.luck.picture.lib.entity.LocalMedia +import com.luck.picture.lib.interfaces.OnResultCallbackListener import com.pengxh.kt.lite.base.KotlinBaseActivity -import com.pengxh.kt.lite.extensions.toJson +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.vm.LoadState +import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import kotlinx.android.synthetic.main.activity_entrust_add.* +import java.io.File + class EntrustAddActivity : KotlinBaseActivity() { + private val context: Context = this@EntrustAddActivity + private val gson by lazy { Gson() } private lateinit var dictionaryViewModel: DictionaryViewModel - private var checkedItems = ArrayList() + private lateinit var fileUploadViewModel: FileUploadViewModel + private lateinit var entrustViewModel: EntrustViewModel + private lateinit var sampleAdapter: CustomerSampleAdapter + private var checkedItems = ArrayList() + private var isUrgent = "0" + private var sampleModels: ArrayList? = null + private var dataBeans = ArrayList() override fun initData() { //证书 dictionaryViewModel = ViewModelProvider(this)[DictionaryViewModel::class.java] dictionaryViewModel.getDictionaryByCode("certificationClass") - dictionaryViewModel.dictionary.observe(this) { dic -> - if (dic.code == 200) { - val typeAdapter2 = CertificateTypeAdapter2(this, dic.data) + dictionaryViewModel.dictionary.observe(this) { + if (it.code == 200) { + val typeAdapter2 = CertificateTypeAdapter2(this, it.data) typeRecyclerView.adapter = typeAdapter2 typeAdapter2.setOnItemCheckedListener(object : CertificateTypeAdapter2.OnItemCheckedListener { override fun onItemChecked(position: Int, isChecked: Boolean) { if (isChecked) { - checkedItems.add(position) + checkedItems.add(position.toString()) } else { - checkedItems.remove(position) + checkedItems.remove(position.toString()) } } }) } } + + fileUploadViewModel = ViewModelProvider(this)[FileUploadViewModel::class.java] + fileUploadViewModel.resultModel.observe(this) { + if (it.code == 200) { + val annexName = it.data[0] + annexView.text = annexName + val textPaint = annexView.paint + textPaint.flags = Paint.UNDERLINE_TEXT_FLAG + textPaint.isAntiAlias = true + annexView.setTextColor(Color.BLUE) + + annexView.setOnClickListener { + annexName.watchAttachFile(this) + } + } + } + + entrustViewModel = ViewModelProvider(this)[EntrustViewModel::class.java] + entrustViewModel.addResult.observe(this) { + if (it.code == 200) { + finish() + } + } + + //样品列表 + sampleAdapter = CustomerSampleAdapter(this, dataBeans) + sampleRecyclerView.adapter = sampleAdapter } + private val selectCustomerLauncher = + registerForActivityResult(ActivityResultContracts.StartActivityForResult(), + object : ActivityResultCallback { + override fun onActivityResult(result: ActivityResult?) { + if (result?.resultCode == Activity.RESULT_OK) { + val data = result.data ?: return + + entrustNameView.text = data.getStringExtra("entrustName") + entrustContactView.text = data.getStringExtra("entrustContact") + entrustAddressView.text = data.getStringExtra("entrustAddress") + } + } + }) + + private val selectSampleLauncher = + registerForActivityResult(ActivityResultContracts.StartActivityForResult(), + object : ActivityResultCallback { + override fun onActivityResult(result: ActivityResult?) { + if (result?.resultCode == Activity.RESULT_OK) { + val data = result.data ?: return + + val modelsJson = data.getStringExtra("sampleModels") + if (!modelsJson.isNullOrBlank()) { + sampleModels = gson.fromJson( + modelsJson, + object : + TypeToken>() {}.type + ) + } + + //刷新列表 + dataBeans.clear() + sampleModels?.forEach { + val model = + EntrustDetailModel.DataModel.CustomerSampleInfoListModel() + + model.customerName = it.customerName + model.customerNo = it.customerNo + model.id = it.id + model.manufacturingNo = it.manufacturingNo + model.measureLastTime = it.measureLastTime + model.measurePeriod = it.measurePeriod + model.orderId = it.orderId + model.remark = it.remark + model.sampleModel = it.sampleModel + model.sampleName = it.sampleName + model.sampleNo = it.sampleNo + model.validDeadline = it.validDeadline + + dataBeans.add(model) + } + sampleAdapter.notifyDataSetChanged() + } + } + }) + override fun initEvent() { + leftBackView.setOnClickListener { finish() } + + estimateTimeView.setOnClickListener { + showDatePicker(object : DateSelectedCallback { + override fun onDateSelected(date: String) { + estimateTimeView.text = date + } + }) + } + + completedView.setOnClickListener { + showDatePicker(object : DateSelectedCallback { + override fun onDateSelected(date: String) { + completedView.text = date + } + }) + } + + entrustNameView.setOnClickListener { + selectCustomerLauncher.launch(Intent(this, SelectCustomerActivity::class.java)) + } + //上传附件 uploadFileButton.setOnClickListener { + BottomActionSheet.Builder() + .setContext(this) + .setItemTextColor(Color.BLUE) + .setActionItemTitle(listOf("文件", "图片")) + .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { + override fun onActionItemClick(position: Int) { + when (position) { + 0 -> uploadFile() + 1 -> uploadImage() + } + } + }).build().show() + } + radioGroup.setOnCheckedChangeListener { _, checkedId -> + when (checkedId) { + R.id.radioButton1 -> isUrgent = "1" + R.id.radioButton2 -> isUrgent = "0" + } } //选择样品 selectSampleButton.setOnClickListener { - + selectSampleLauncher.launch(Intent(this, SelectSampleActivity::class.java)) } //写入样品信息 @@ -55,14 +214,68 @@ } pushEntrustView.setOnClickListener { - Log.d("Casic", "EntrustAddActivity => initEvent: ${checkedItems.toJson()}") + val sender = senderView.text.toString() + if (sender.isBlank()) { + "请填写送样人名字".show(this) + return@setOnClickListener + } + + val contact = contactView.text.toString() + if (contact.isBlank()) { + "请填写送样人联系方式".show(this) + return@setOnClickListener + } + + val estimateTime = estimateTimeView.text.toString() + if (estimateTime.isBlank()) { + "请选择预计送到的时间".show(this) + return@setOnClickListener + } + + val entrustName = entrustNameView.text.toString() + if (entrustName.isBlank()) { + "请选择委托方".show(this) + return@setOnClickListener + } + + if (sampleModels == null) { + "请选择样品".show(this) + return@setOnClickListener + } + entrustViewModel.addEntrust( + sender, + contact, + createEntrustDateView.text.toString(), + estimateTime, + completedView.text.toString(), + entrustName, + entrustContactView.text.toString(), + entrustAddressView.text.toString(), + remarkView.text.toString(), + annexView.text.toString(), + checkedItems.reformat(), + isUrgent, + sampleModels!! + ) } } override fun initLayoutView(): Int = R.layout.activity_entrust_add override fun observeRequestState() { + fileUploadViewModel.loadState.observe(this) { + when (it) { + LoadState.Loading -> LoadingDialogHub.show(this, "文件上传中,请稍后...") + else -> LoadingDialogHub.dismiss() + } + } + entrustViewModel.loadState.observe(this) { + when (it) { + LoadState.Loading -> LoadingDialogHub.show(this, "委托创建中,请稍后...") + else -> LoadingDialogHub.dismiss() + } + } } override fun setupTopBarLayout() { @@ -70,4 +283,62 @@ initLayoutImmersionBar(rootView) titleView.text = "委托需求" } + + private fun uploadFile() { +// val explorer = FileExplorer(this) +// explorer.setInitDir(ExplorerMode.FILE, Environment.getExternalStorageDirectory()) +// explorer.setShowHomeDir(true) +// explorer.setShowUpDir(true) +// explorer.setShowHideDir(true) +// explorer.setAllowExtensions(arrayOf(".doc", ".docx", ".xls", ".xlsx", ".pdf")) +// explorer.setOnFileClickedListener { +// val type = if (it.name.endsWith(".doc") || it.name.endsWith(".docx")) { +// FileType.WORD +// } else if (it.name.endsWith(".pdf")) { +// FileType.PDF +// } else { +// FileType.UNKNOWN +// } +// +// Log.d("Casic", "EntrustAddActivity => uploadFile: ${it.absolutePath}") +// fileUploadViewModel.uploadFile(it, type) +// } + } + + private fun uploadImage() { + PictureSelector.create(this) + .openGallery(SelectMimeType.ofImage()) + .isGif(false) + .isMaxSelectEnabledMask(true) + .setFilterMinFileSize(100) + .setMaxSelectNum(1) + .isDisplayCamera(false) + .setImageEngine(GlideLoadEngine.instance) + .forResult(object : OnResultCallbackListener { + override fun onResult(result: ArrayList?) { + if (result == null) { + "选择照片失败,请重试".show(context) + return + } + result[0].realPath.compressImage(context, object : OnImageCompressListener { + override fun onSuccess(file: File) { + Log.d( + "Casic", "EntrustAddActivity => onSuccess: ${file.absolutePath}" + ) + ///storage/emulated/0/Android/data/com.casic.xz.meterage/files/Pictures/CompressImage/1677478115391211.jpeg + //上传图片 + fileUploadViewModel.uploadFile(file, FileType.IMAGE) + } + + override fun onError(e: Throwable) { + e.printStackTrace() + } + }) + } + + override fun onCancel() { + + } + }) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/view/home/SelectCustomerActivity.kt b/app/src/main/java/com/casic/xz/meterage/view/home/SelectCustomerActivity.kt new file mode 100644 index 0000000..9bf6a1a --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/view/home/SelectCustomerActivity.kt @@ -0,0 +1,158 @@ +package com.casic.xz.meterage.view.home + +import android.content.Intent +import android.os.Handler +import androidx.lifecycle.ViewModelProvider +import androidx.recyclerview.widget.DefaultItemAnimator +import androidx.recyclerview.widget.DividerItemDecoration +import com.casic.xz.meterage.R +import com.casic.xz.meterage.adapter.SelectCustomerAdapter +import com.casic.xz.meterage.extensions.initLayoutImmersionBar +import com.casic.xz.meterage.extensions.showEmptyPage +import com.casic.xz.meterage.model.CustomerListModel +import com.casic.xz.meterage.utils.LoadingDialogHub +import com.casic.xz.meterage.vm.CustomerViewModel +import com.gyf.immersionbar.ImmersionBar +import com.pengxh.kt.lite.base.KotlinBaseActivity +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.utils.WeakReferenceHandler +import com.pengxh.kt.lite.vm.LoadState +import kotlinx.android.synthetic.main.activity_select_customer.* +import kotlinx.android.synthetic.main.include_base_title.* +import kotlinx.android.synthetic.main.include_empty_view.* + +class SelectCustomerActivity : KotlinBaseActivity() { + + private lateinit var weakReferenceHandler: WeakReferenceHandler + private lateinit var customerViewModel: CustomerViewModel + private lateinit var selectCustomerAdapter: SelectCustomerAdapter + private var dataBeans: MutableList = ArrayList() + private var pageIndex = 1 + private var isRefresh = false + private var isLoadMore = false + private var customerModel: CustomerListModel.DataModel.RowsModel? = null + + override fun initData() { + weakReferenceHandler = WeakReferenceHandler(callback) + customerViewModel = ViewModelProvider(this)[CustomerViewModel::class.java] + customerViewModel.customerList.observe(this) { + if (it.code == 200) { + val dataRows = it.data?.rows!! + when { + isRefresh -> { + dataBeans.clear() + dataBeans = dataRows + customerLayout.finishRefresh() + isRefresh = false + } + isLoadMore -> { + if (dataRows.size == 0) { + "到底了,别拉了".show(this) + } + dataBeans.addAll(dataRows) + customerLayout.finishLoadMore() + isLoadMore = false + } + else -> { + dataBeans = dataRows + } + } + weakReferenceHandler.sendEmptyMessage(2023022701) + } + } + } + + override fun initEvent() { + leftBackView.setOnClickListener { + if (customerModel == null) { + "请选择委托方".show(this) + return@setOnClickListener + } + val intent = Intent() + intent.putExtra("entrustName", customerModel!!.customerName) + intent.putExtra("entrustContact", customerModel!!.phone) + intent.putExtra("entrustAddress", customerModel!!.fullAddress) + setResult(RESULT_OK, intent) + finish() + } + + customerLayout.setOnRefreshListener { + isRefresh = true + //刷新之后页码重置 + pageIndex = 1 + getCustomerList() + } + + customerLayout.setOnLoadMoreListener { + isLoadMore = true + pageIndex++ + getCustomerList() + } + } + + override fun initLayoutView(): Int = R.layout.activity_select_customer + + override fun observeRequestState() { + customerViewModel.loadState.observe(this) { + when (it) { + LoadState.Loading -> LoadingDialogHub.show(this, "数据加载中...") + else -> LoadingDialogHub.dismiss() + } + } + } + + override fun setupTopBarLayout() { + ImmersionBar.with(this).statusBarDarkFont(true).init() + initLayoutImmersionBar(rootView) + titleView.text = "客户列表" + } + + override fun onResume() { + super.onResume() + pageIndex = 1 + getCustomerList() + } + + private fun getCustomerList() { + customerViewModel.getCustomerList( + "", + "", + "", + "", + pageIndex + ) + } + + private val callback = Handler.Callback { + when (it.what) { + 2023022701 -> { + if (isRefresh || isLoadMore) { + selectCustomerAdapter.notifyDataSetChanged() + } else { + if (dataBeans.size == 0) { + emptyView!!.showEmptyPage("无客户数据") { + pageIndex = 1 + getCustomerList() + } + } else { + emptyView!!.hide() + selectCustomerAdapter = SelectCustomerAdapter(this, dataBeans) + customerRecyclerView.addItemDecoration( + DividerItemDecoration(this, DividerItemDecoration.VERTICAL) + ) + (customerRecyclerView.itemAnimator as DefaultItemAnimator).supportsChangeAnimations = + false + customerRecyclerView.adapter = selectCustomerAdapter + selectCustomerAdapter.setOnCheckedListener(object : + SelectCustomerAdapter.OnItemCheckedListener { + override fun onItemChecked(item: CustomerListModel.DataModel.RowsModel) { + customerModel = item + } + }) + } + } + } + } + true + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/view/home/SelectSampleActivity.kt b/app/src/main/java/com/casic/xz/meterage/view/home/SelectSampleActivity.kt new file mode 100644 index 0000000..f85cb44 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/view/home/SelectSampleActivity.kt @@ -0,0 +1,152 @@ +package com.casic.xz.meterage.view.home + +import android.content.Intent +import android.os.Handler +import androidx.lifecycle.ViewModelProvider +import androidx.recyclerview.widget.DefaultItemAnimator +import androidx.recyclerview.widget.DividerItemDecoration +import com.casic.xz.meterage.R +import com.casic.xz.meterage.adapter.SelectSampleAdapter +import com.casic.xz.meterage.extensions.initLayoutImmersionBar +import com.casic.xz.meterage.extensions.showEmptyPage +import com.casic.xz.meterage.model.SampleListModel +import com.casic.xz.meterage.vm.SampleViewModel +import com.gyf.immersionbar.ImmersionBar +import com.pengxh.kt.lite.base.KotlinBaseActivity +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.extensions.toJson +import com.pengxh.kt.lite.utils.WeakReferenceHandler +import kotlinx.android.synthetic.main.activity_select_sample.* +import kotlinx.android.synthetic.main.include_base_title.* +import kotlinx.android.synthetic.main.include_empty_view.* + +class SelectSampleActivity : KotlinBaseActivity() { + + private lateinit var weakReferenceHandler: WeakReferenceHandler + private lateinit var sampleViewModel: SampleViewModel + private lateinit var selectSampleAdapter: SelectSampleAdapter + private var dataBeans: MutableList = ArrayList() + private var pageIndex = 1 + private var isRefresh = false + private var isLoadMore = false + private var sampleModels = ArrayList() + + override fun initData() { + weakReferenceHandler = WeakReferenceHandler(callback) + sampleViewModel = ViewModelProvider(this)[SampleViewModel::class.java] + sampleViewModel.sampleList.observe(this) { + if (it.code == 200) { + val dataRows = it.data?.rows!! + when { + isRefresh -> { + dataBeans.clear() + dataBeans = dataRows + sampleLayout.finishRefresh() + isRefresh = false + } + isLoadMore -> { + if (dataRows.size == 0) { + "到底了,别拉了".show(this) + } + dataBeans.addAll(dataRows) + sampleLayout.finishLoadMore() + isLoadMore = false + } + else -> { + dataBeans = dataRows + } + } + weakReferenceHandler.sendEmptyMessage(2023030101) + } + } + } + + override fun initEvent() { + leftBackView.setOnClickListener { + val intent = Intent() + intent.putExtra("sampleModels", sampleModels.toJson()) + setResult(RESULT_OK, intent) + finish() + } + + sampleLayout.setOnRefreshListener { + isRefresh = true + //刷新之后页码重置 + pageIndex = 1 + getSampleList() + } + + sampleLayout.setOnLoadMoreListener { + isLoadMore = true + pageIndex++ + getSampleList() + } + } + + override fun initLayoutView(): Int = R.layout.activity_select_sample + + override fun observeRequestState() { + + } + + override fun setupTopBarLayout() { + ImmersionBar.with(this).statusBarDarkFont(true).init() + initLayoutImmersionBar(rootView) + titleView.text = "样品列表" + } + + override fun onResume() { + super.onResume() + pageIndex = 1 + getSampleList() + } + + private fun getSampleList() { + sampleViewModel.getSampleList( + "", + "", + "", + "", + "", + "", + "", + "", + "", + arrayOf(), + pageIndex + ) + } + + private val callback = Handler.Callback { + when (it.what) { + 2023030101 -> { + if (isRefresh || isLoadMore) { + selectSampleAdapter.notifyDataSetChanged() + } else { + if (dataBeans.size == 0) { + emptyView!!.showEmptyPage("无样品数据") { + pageIndex = 1 + getSampleList() + } + } else { + emptyView!!.hide() + selectSampleAdapter = SelectSampleAdapter(this, dataBeans) + sampleRecyclerView.addItemDecoration( + DividerItemDecoration(this, DividerItemDecoration.VERTICAL) + ) + (sampleRecyclerView.itemAnimator as DefaultItemAnimator).supportsChangeAnimations = + false + sampleRecyclerView.adapter = selectSampleAdapter + selectSampleAdapter.setOnCheckedListener(object : + SelectSampleAdapter.OnItemCheckedListener { + override fun onItemChecked(items: ArrayList) { + sampleModels = items + } + }) + } + } + } + } + true + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/view/notice/NoticeDetailActivity.kt b/app/src/main/java/com/casic/xz/meterage/view/notice/NoticeDetailActivity.kt index a9d9422..9596985 100644 --- a/app/src/main/java/com/casic/xz/meterage/view/notice/NoticeDetailActivity.kt +++ b/app/src/main/java/com/casic/xz/meterage/view/notice/NoticeDetailActivity.kt @@ -1,6 +1,7 @@ package com.casic.xz.meterage.view.notice import android.annotation.SuppressLint +import android.graphics.Color import android.graphics.Paint import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R @@ -10,7 +11,6 @@ import com.casic.xz.meterage.vm.NoticeViewModel import com.gyf.immersionbar.ImmersionBar import com.pengxh.kt.lite.base.KotlinBaseActivity -import com.pengxh.kt.lite.extensions.convertColor import com.pengxh.kt.lite.extensions.obtainScreenWidth import com.pengxh.kt.lite.utils.Constant import kotlinx.android.synthetic.main.activity_notice_detail.* @@ -54,7 +54,7 @@ val textPaint = minioFileView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - minioFileView.setTextColor(R.color.themeColor.convertColor(this)) + minioFileView.setTextColor(Color.BLUE) minioFileView.setOnClickListener { minioFileName.watchAttachFile(this) diff --git a/app/src/main/java/com/casic/xz/meterage/vm/EntrustViewModel.kt b/app/src/main/java/com/casic/xz/meterage/vm/EntrustViewModel.kt index 2280f88..103c002 100644 --- a/app/src/main/java/com/casic/xz/meterage/vm/EntrustViewModel.kt +++ b/app/src/main/java/com/casic/xz/meterage/vm/EntrustViewModel.kt @@ -7,6 +7,7 @@ import com.casic.xz.meterage.model.ActionResultModel import com.casic.xz.meterage.model.EntrustDetailModel import com.casic.xz.meterage.model.EntrustListModel +import com.casic.xz.meterage.model.SampleListModel import com.casic.xz.meterage.utils.retrofit.RetrofitServiceManager import com.google.gson.Gson import com.google.gson.reflect.TypeToken @@ -25,6 +26,7 @@ val entrustDetail = MutableLiveData() val acceptResult = MutableLiveData() val returnResult = MutableLiveData() + val addResult = MutableLiveData() fun getEntrustList( customerName: String, @@ -119,4 +121,50 @@ loadState.value = LoadState.Fail it.cause.toString().show(BaseApplication.get()) }) + + fun addEntrust( + deliverer: String, + delivererTel: String, + orderTime: String, + planDeliverTime: String, + requireOverTime: String, + customerName: String, + customerPhone: String, + customerAddress: String, + remark: String, + minioFileName: String, + certifications: String, + isUrgent: String, + samples: List + ) = launch({ + loadState.value = LoadState.Loading + val response = RetrofitServiceManager.addEntrust( + deliverer, + delivererTel, + orderTime, + planDeliverTime, + requireOverTime, + customerName, + customerPhone, + customerAddress, + remark, + minioFileName, + certifications, + isUrgent, + samples + ) + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + loadState.value = LoadState.Success + addResult.value = gson.fromJson( + response, object : TypeToken() {}.type + ) + } else { + loadState.value = LoadState.Fail + response.toErrorMessage().show(BaseApplication.get()) + } + }, { + loadState.value = LoadState.Fail + it.cause.toString().show(BaseApplication.get()) + }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/vm/FileUploadViewModel.kt b/app/src/main/java/com/casic/xz/meterage/vm/FileUploadViewModel.kt new file mode 100644 index 0000000..b16c1c7 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/vm/FileUploadViewModel.kt @@ -0,0 +1,40 @@ +package com.casic.xz.meterage.vm + +import androidx.lifecycle.MutableLiveData +import com.casic.xz.meterage.base.BaseApplication +import com.casic.xz.meterage.extensions.separateResponseCode +import com.casic.xz.meterage.extensions.toErrorMessage +import com.casic.xz.meterage.model.UploadResultModel +import com.casic.xz.meterage.utils.FileType +import com.casic.xz.meterage.utils.retrofit.RetrofitServiceManager +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken +import com.pengxh.kt.lite.extensions.launch +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.vm.BaseViewModel +import com.pengxh.kt.lite.vm.LoadState +import java.io.File + +class FileUploadViewModel : BaseViewModel() { + + private val gson by lazy { Gson() } + val resultModel = MutableLiveData() + + fun uploadFile(file: File, type: FileType) = launch({ + loadState.value = LoadState.Loading + val response = RetrofitServiceManager.uploadFile(file, type) + 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(BaseApplication.get()) + } + }, { + loadState.value = LoadState.Fail + it.cause.toString().show(BaseApplication.get()) + }) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/vm/SampleViewModel.kt b/app/src/main/java/com/casic/xz/meterage/vm/SampleViewModel.kt new file mode 100644 index 0000000..182140d --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/vm/SampleViewModel.kt @@ -0,0 +1,65 @@ +package com.casic.xz.meterage.vm + +import androidx.lifecycle.MutableLiveData +import com.casic.xz.meterage.base.BaseApplication +import com.casic.xz.meterage.extensions.separateResponseCode +import com.casic.xz.meterage.extensions.toErrorMessage +import com.casic.xz.meterage.model.SampleListModel +import com.casic.xz.meterage.utils.retrofit.RetrofitServiceManager +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken +import com.pengxh.kt.lite.extensions.launch +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.vm.BaseViewModel +import com.pengxh.kt.lite.vm.LoadState + +/** + * 样品相关 VM + * */ +class SampleViewModel : BaseViewModel() { + + private val gson by lazy { Gson() } + val sampleList = MutableLiveData() + + fun getSampleList( + customerName: String, + customerNo: String, + startTime: String, + endTime: String, + sampleName: String, + sampleNo: String, + sampleModel: String, + sampleBelong: String, + overtimeStatus: String, + ids: Array, + offset: Int + ) = launch({ + loadState.value = LoadState.Loading + val response = RetrofitServiceManager.getSampleList( + customerName, + customerNo, + startTime, + endTime, + sampleName, + sampleNo, + sampleModel, + sampleBelong, + overtimeStatus, + ids, + offset + ) + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + loadState.value = LoadState.Success + sampleList.value = gson.fromJson( + response, object : TypeToken() {}.type + ) + } else { + loadState.value = LoadState.Fail + response.toErrorMessage().show(BaseApplication.get()) + } + }, { + loadState.value = LoadState.Fail + it.cause.toString().show(BaseApplication.get()) + }) +} \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_customer_selector.xml b/app/src/main/res/drawable/bg_customer_selector.xml new file mode 100644 index 0000000..e7292d5 --- /dev/null +++ b/app/src/main/res/drawable/bg_customer_selector.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_sample_selector.xml b/app/src/main/res/drawable/bg_sample_selector.xml new file mode 100644 index 0000000..6b5d5e7 --- /dev/null +++ b/app/src/main/res/drawable/bg_sample_selector.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 0ae369f..687b02b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -15,7 +15,6 @@ } compileSdkVersion 31 - buildToolsVersion "30.0.3" defaultConfig { applicationId "com.casic.xz.meterage" @@ -84,11 +83,13 @@ implementation 'top.zibin:Luban:1.1.8' //官方Json解析库 implementation 'com.google.code.gson:gson:2.9.0' + //阿里巴巴JSON库 + implementation 'com.alibaba.fastjson2:fastjson2:2.0.24' //Kotlin协程 implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.5.1' //MVVM+LiveData implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.5.1" - implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.0" + implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1" implementation "androidx.lifecycle:lifecycle-extensions:2.2.0" //返回值转换器 implementation 'com.jakewharton.retrofit:retrofit2-kotlin-coroutines-adapter:0.9.2' @@ -109,4 +110,8 @@ implementation 'com.github.barteksc:android-pdf-viewer:2.8.2' //绕过Android 11反射限制 implementation 'com.github.tiann:FreeReflection:3.1.0' + //单项/数字、二三级联动、日期/时间等滚轮选择器 + implementation 'com.github.gzu-liyujiang.AndroidPicker:WheelPicker:4.1.8' + //文件/目录选择器 + implementation 'com.github.gzu-liyujiang.AndroidPicker:FilePicker:4.1.1' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 1ccc12b..0fba91b 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -60,6 +60,8 @@ + + diff --git a/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt b/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt new file mode 100644 index 0000000..21a71d8 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt @@ -0,0 +1,70 @@ +package com.casic.xz.meterage.adapter + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import com.casic.xz.meterage.R +import com.casic.xz.meterage.extensions.toChineseGrade +import com.casic.xz.meterage.model.CustomerListModel + +class SelectCustomerAdapter( + context: Context, private val dataRows: MutableList +) : RecyclerView.Adapter() { + + private var layoutInflater = LayoutInflater.from(context) + + //选择的位置 + private var selectedPosition = 0 + + //临时记录上次选择的位置 + private var temp = -1 + + override fun getItemCount(): Int = dataRows.size + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ItemViewHolder( + layoutInflater.inflate(R.layout.item_select_customer_lv, parent, false) + ) + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + //绑定数据 + val rowsBean = dataRows[position] + holder.agreementLevelView.text = rowsBean.grade.toChineseGrade() + holder.customerNameView.text = rowsBean.customerName + holder.scaleView.text = rowsBean.companySizeName + holder.overallView.text = "公司规模:${rowsBean.evaluationName}" + holder.fullAddressView.text = "公司地址:${rowsBean.fullAddress}" + + holder.itemView.isSelected = holder.layoutPosition == selectedPosition + holder.itemView.setOnClickListener { + itemCheckedListener?.onItemChecked(rowsBean) + + holder.itemView.isSelected = true + temp = selectedPosition + //设置新的位置 + selectedPosition = holder.layoutPosition + //更新旧位置 + notifyItemChanged(temp) + } + } + + inner class ItemViewHolder(view: View) : RecyclerView.ViewHolder(view) { + var agreementLevelView: TextView = view.findViewById(R.id.agreementLevelView) + var customerNameView: TextView = view.findViewById(R.id.customerNameView) + var scaleView: TextView = view.findViewById(R.id.scaleView) + var overallView: TextView = view.findViewById(R.id.overallView) + var fullAddressView: TextView = view.findViewById(R.id.fullAddressView) + } + + private var itemCheckedListener: OnItemCheckedListener? = null + + interface OnItemCheckedListener { + fun onItemChecked(item: CustomerListModel.DataModel.RowsModel) + } + + fun setOnCheckedListener(listener: OnItemCheckedListener?) { + itemCheckedListener = listener + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt b/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt new file mode 100644 index 0000000..c29461e --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt @@ -0,0 +1,68 @@ +package com.casic.xz.meterage.adapter + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import com.casic.xz.meterage.R +import com.casic.xz.meterage.model.SampleListModel + +class SelectSampleAdapter( + context: Context, private val dataRows: MutableList +) : RecyclerView.Adapter() { + + private var layoutInflater = LayoutInflater.from(context) + private var multipleSelected = mutableSetOf() + private var sampleModes = ArrayList() + + override fun getItemCount(): Int = dataRows.size + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ItemViewHolder( + layoutInflater.inflate(R.layout.item_select_sample_lv, parent, false) + ) + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + //绑定数据 + val rowsBean = dataRows[position] + holder.sampleNameView.text = "${rowsBean.sampleName}【${rowsBean.sampleModel}】" + holder.manufacturingCodeView.text = "出厂编号:${rowsBean.manufacturingNo}" + holder.sampleCodeView.text = "样品编号:${rowsBean.sampleNo}" + holder.validDateView.text = "有效期至:${rowsBean.validDeadline}" + + holder.checkImageView.isSelected = multipleSelected.contains(position) + holder.itemView.setOnClickListener { + if (multipleSelected.contains(position)) { + multipleSelected.remove(position) + sampleModes.remove(dataRows[position]) + holder.checkImageView.isSelected = false + } else { + multipleSelected.add(position) + sampleModes.add(dataRows[position]) + holder.checkImageView.isSelected = true + } + + itemCheckedListener?.onItemChecked(sampleModes) + } + } + + inner class ItemViewHolder(view: View) : RecyclerView.ViewHolder(view) { + var sampleNameView: TextView = view.findViewById(R.id.sampleNameView) + var manufacturingCodeView: TextView = view.findViewById(R.id.manufacturingCodeView) + var sampleCodeView: TextView = view.findViewById(R.id.sampleCodeView) + var validDateView: TextView = view.findViewById(R.id.validDateView) + var checkImageView: ImageView = view.findViewById(R.id.checkImageView) + } + + private var itemCheckedListener: OnItemCheckedListener? = null + + interface OnItemCheckedListener { + fun onItemChecked(items: ArrayList) + } + + fun setOnCheckedListener(listener: OnItemCheckedListener?) { + itemCheckedListener = listener + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/callback/DateSelectedCallback.kt b/app/src/main/java/com/casic/xz/meterage/callback/DateSelectedCallback.kt new file mode 100644 index 0000000..8196110 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/callback/DateSelectedCallback.kt @@ -0,0 +1,5 @@ +package com.casic.xz.meterage.callback + +interface DateSelectedCallback { + fun onDateSelected(date: String) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/Activity.kt b/app/src/main/java/com/casic/xz/meterage/extensions/Activity.kt new file mode 100644 index 0000000..e112d1c --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/extensions/Activity.kt @@ -0,0 +1,33 @@ +package com.casic.xz.meterage.extensions + +import android.app.Activity +import com.casic.xz.meterage.R +import com.casic.xz.meterage.callback.DateSelectedCallback +import com.github.gzuliyujiang.wheelpicker.DatePicker +import com.github.gzuliyujiang.wheelpicker.annotation.DateMode +import com.github.gzuliyujiang.wheelpicker.entity.DateEntity +import com.pengxh.kt.lite.extensions.convertColor +import com.pengxh.kt.lite.extensions.sp2px + +fun Activity.showDatePicker(callback: DateSelectedCallback) { + val datePicker = DatePicker(this) + + val layout = datePicker.wheelLayout + layout.setDateMode(DateMode.YEAR_MONTH_DAY) + layout.setDateLabel("年", "月", "日"); + layout.setTextSize(14f.sp2px(this).toFloat()) + layout.setSelectedTextSize(16f.sp2px(this).toFloat()) + layout.setSelectedTextColor(R.color.themeColor.convertColor(this)) + layout.setSelectedTextBold(true) + layout.setResetWhenLinkage(false) + layout.setRange( + DateEntity.today(), + DateEntity.target(2050, 12, 31), + DateEntity.today() + ) + + datePicker.setOnDatePickedListener { year, month, day -> + callback.onDateSelected(String.format("%s-%s-%s", year, month, day)) + } + datePicker.show() +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt b/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt index 016ebcb..cf6bf49 100644 --- a/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt +++ b/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt @@ -4,7 +4,7 @@ * ArrayList扩展方法 */ -//将图片集合格式化成满足上传格式的数据 +//将集合格式化成满足上传格式的数据 fun ArrayList.reformat(): String { if (this.isEmpty()) return "" val builder = StringBuilder() diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt b/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt index 7c57643..aa9b92b 100644 --- a/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt +++ b/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt @@ -1,7 +1,6 @@ package com.casic.xz.meterage.extensions import android.content.Context -import android.util.Log import android.view.ViewGroup import com.casic.xz.meterage.base.BaseApplication import com.pengxh.kt.lite.extensions.dp2px @@ -9,9 +8,8 @@ fun Context.initLayoutImmersionBar(rootView: ViewGroup) { var statusBarHeight = QMUIDisplayHelper.getStatusBarHeight(this) - Log.d("Casic", "状态栏高度: $statusBarHeight") if (statusBarHeight == 0) { - statusBarHeight = 44f.dp2px(BaseApplication.get()) + statusBarHeight = 40f.dp2px(BaseApplication.get()) } rootView.setPadding(0, statusBarHeight, 0, 0) rootView.requestLayout() diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/String.kt b/app/src/main/java/com/casic/xz/meterage/extensions/String.kt index 28f70d8..6234d43 100644 --- a/app/src/main/java/com/casic/xz/meterage/extensions/String.kt +++ b/app/src/main/java/com/casic/xz/meterage/extensions/String.kt @@ -128,9 +128,10 @@ fun String.combineImagePath(): String { if (this.isEmpty()) return this val defaultValue = SaveKeyValues.getValue( - LocaleConstant.DEFAULT_SERVER_CONFIG, LocaleConstant.SERVER_BASE_URL + LocaleConstant.FILE_SERVER_CONFIG, LocaleConstant.File_SERVER_URL ) as String - return "$defaultValue/static/${this.replace("\\", "/")}" + //http://111.198.10.15:21408/test/1677479806059688_1677479806038.jpeg + return "$defaultValue/test/${this.replace("\\", "/")}" } fun String.isEarlier(time: String): Boolean { diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt index 25fa87b..a0e1358 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt @@ -1,18 +1,12 @@ package com.casic.xz.meterage.fragment.customer +import android.graphics.Color import android.graphics.Paint import com.casic.xz.meterage.R -import com.casic.xz.meterage.extensions.combineImagePath import com.casic.xz.meterage.extensions.toChineseGrade +import com.casic.xz.meterage.extensions.watchAttachFile import com.casic.xz.meterage.model.CustomerDetailModel -import com.casic.xz.meterage.view.BigImageActivity -import com.casic.xz.meterage.view.notice.PreviewDocumentActivity -import com.casic.xz.meterage.view.notice.PreviewPdfActivity -import com.casic.xz.meterage.view.notice.PreviewTextActivity import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.extensions.show import kotlinx.android.synthetic.main.fragment_customer_basic_information.* class BasicInformationFragment(private val data: CustomerDetailModel.DataModel) : @@ -48,30 +42,11 @@ val textPaint = minioFileView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - minioFileView.setTextColor(R.color.themeColor.convertColor(requireContext())) + minioFileView.setTextColor(Color.BLUE) minioFileView.setOnClickListener { //查看附件 - if (minioFileName.endsWith("pdf")) { - requireContext().navigatePageTo(minioFileName) - } else if ( - minioFileName.endsWith("doc") || - minioFileName.endsWith("docx") - ) { - requireContext().navigatePageTo(minioFileName) - } else if (minioFileName.endsWith("txt")) { - requireContext().navigatePageTo(minioFileName) - } else if ( - minioFileName.endsWith("png") || - minioFileName.endsWith("jpeg") || - minioFileName.endsWith("jpg") - ) { - val urls = ArrayList() - urls.add(minioFileName.combineImagePath()) - requireContext().navigatePageTo(0, urls) - } else { - "文件类型未知,无法打开附件".show(requireContext()) - } + minioFileName.watchAttachFile(requireContext()) } } } diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt index 77846b4..3a0fe2e 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt @@ -1,5 +1,6 @@ package com.casic.xz.meterage.fragment.device +import android.graphics.Color import android.graphics.Paint import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R @@ -7,7 +8,6 @@ import com.casic.xz.meterage.utils.LoadingDialogHub import com.casic.xz.meterage.vm.EquipmentViewModel import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor import com.pengxh.kt.lite.vm.LoadState import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import kotlinx.android.synthetic.main.fragment_device_basic_information.* @@ -56,7 +56,7 @@ val textPaint = documentsView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - documentsView.setTextColor(R.color.themeColor.convertColor(requireContext())) + documentsView.setTextColor(Color.BLUE) val files = ArrayList() data.fileList.forEach { file -> @@ -66,7 +66,7 @@ BottomActionSheet.Builder() .setContext(requireContext()) .setActionItemTitle(files) - .setItemTextColor(R.color.themeColor.convertColor(requireContext())) + .setItemTextColor(Color.BLUE) .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { override fun onActionItemClick(position: Int) { diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt index 15dc3d2..10eeff8 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt @@ -1,5 +1,6 @@ package com.casic.xz.meterage.fragment.entrust +import android.graphics.Color import android.graphics.Paint import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R @@ -9,7 +10,6 @@ import com.casic.xz.meterage.model.EntrustDetailModel import com.casic.xz.meterage.vm.DictionaryViewModel import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor import kotlinx.android.synthetic.main.fragment_entrust_basic_information.* class BasicInformationFragment(private val data: EntrustDetailModel.DataModel) : @@ -38,7 +38,7 @@ val textPaint = annexView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - annexView.setTextColor(R.color.themeColor.convertColor(requireContext())) + annexView.setTextColor(Color.BLUE) annexView.setOnClickListener { minioFileName.watchAttachFile(requireContext()) @@ -59,9 +59,9 @@ //加急 if (data.isUrgent == "0") { - RadioButton2.isChecked = true + radioButton2.isChecked = true } else { - RadioButton1.isChecked = true + radioButton1.isChecked = true } //样品 diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/equipment/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/equipment/BasicInformationFragment.kt index 72b523c..7bc3b01 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/equipment/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/equipment/BasicInformationFragment.kt @@ -1,5 +1,6 @@ package com.casic.xz.meterage.fragment.equipment +import android.graphics.Color import android.graphics.Paint import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R @@ -7,7 +8,6 @@ import com.casic.xz.meterage.utils.LoadingDialogHub import com.casic.xz.meterage.vm.EquipmentViewModel import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor import com.pengxh.kt.lite.vm.LoadState import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import kotlinx.android.synthetic.main.fragment_equipment_basic_information.* @@ -74,7 +74,7 @@ val textPaint = instructionsView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - instructionsView.setTextColor(R.color.themeColor.convertColor(requireContext())) + instructionsView.setTextColor(Color.BLUE) val files = ArrayList() data.fileList.forEach { file -> @@ -84,7 +84,7 @@ BottomActionSheet.Builder() .setContext(requireContext()) .setActionItemTitle(files) - .setItemTextColor(R.color.themeColor.convertColor(requireContext())) + .setItemTextColor(Color.BLUE) .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { override fun onActionItemClick(position: Int) { diff --git a/app/src/main/java/com/casic/xz/meterage/model/SampleListModel.java b/app/src/main/java/com/casic/xz/meterage/model/SampleListModel.java new file mode 100644 index 0000000..5784343 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/model/SampleListModel.java @@ -0,0 +1,193 @@ +package com.casic.xz.meterage.model; + +import java.util.List; + +public class SampleListModel { + + private int code; + private DataModel data; + private String message; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataModel getData() { + return data; + } + + public void setData(DataModel data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public static class DataModel { + private List rows; + private int total; + + public List getRows() { + return rows; + } + + public void setRows(List rows) { + this.rows = rows; + } + + public int getTotal() { + return total; + } + + public void setTotal(int total) { + this.total = total; + } + + public static class RowsModel { + private String certificationStatus; + private String customerName; + private String customerNo; + private String id; + private String manufacturingNo; + private String measureLastTime; + private String measurePeriod; + private String orderId; + private String remark; + private String sampleModel; + private String sampleName; + private String sampleNo; + private String sampleSatus; + private String sampleSatusName; + private String validDeadline; + + public String getCertificationStatus() { + return certificationStatus; + } + + public void setCertificationStatus(String certificationStatus) { + this.certificationStatus = certificationStatus; + } + + public String getCustomerName() { + return customerName; + } + + public void setCustomerName(String customerName) { + this.customerName = customerName; + } + + public String getCustomerNo() { + return customerNo; + } + + public void setCustomerNo(String customerNo) { + this.customerNo = customerNo; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getManufacturingNo() { + return manufacturingNo; + } + + public void setManufacturingNo(String manufacturingNo) { + this.manufacturingNo = manufacturingNo; + } + + public String getMeasureLastTime() { + return measureLastTime; + } + + public void setMeasureLastTime(String measureLastTime) { + this.measureLastTime = measureLastTime; + } + + public String getMeasurePeriod() { + return measurePeriod; + } + + public void setMeasurePeriod(String measurePeriod) { + this.measurePeriod = measurePeriod; + } + + public String getOrderId() { + return orderId; + } + + public void setOrderId(String orderId) { + this.orderId = orderId; + } + + public String getRemark() { + return remark; + } + + public void setRemark(String remark) { + this.remark = remark; + } + + public String getSampleModel() { + return sampleModel; + } + + public void setSampleModel(String sampleModel) { + this.sampleModel = sampleModel; + } + + public String getSampleName() { + return sampleName; + } + + public void setSampleName(String sampleName) { + this.sampleName = sampleName; + } + + public String getSampleNo() { + return sampleNo; + } + + public void setSampleNo(String sampleNo) { + this.sampleNo = sampleNo; + } + + public String getSampleSatus() { + return sampleSatus; + } + + public void setSampleSatus(String sampleSatus) { + this.sampleSatus = sampleSatus; + } + + public String getSampleSatusName() { + return sampleSatusName; + } + + public void setSampleSatusName(String sampleSatusName) { + this.sampleSatusName = sampleSatusName; + } + + public String getValidDeadline() { + return validDeadline; + } + + public void setValidDeadline(String validDeadline) { + this.validDeadline = validDeadline; + } + } + } +} diff --git a/app/src/main/java/com/casic/xz/meterage/model/UploadResultModel.java b/app/src/main/java/com/casic/xz/meterage/model/UploadResultModel.java new file mode 100644 index 0000000..f2a6a41 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/model/UploadResultModel.java @@ -0,0 +1,34 @@ +package com.casic.xz.meterage.model; + +import java.util.List; + +public class UploadResultModel { + + private int code; + private List data; + private String message; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public List getData() { + return data; + } + + public void setData(List data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } +} diff --git a/app/src/main/java/com/casic/xz/meterage/utils/FileType.kt b/app/src/main/java/com/casic/xz/meterage/utils/FileType.kt new file mode 100644 index 0000000..17e2bca --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/utils/FileType.kt @@ -0,0 +1,23 @@ +package com.casic.xz.meterage.utils + +sealed class FileType { + /** + * PDF文件 + */ + object PDF : FileType() + + /** + * WORD文件 + */ + object WORD : FileType() + + /** + * IMAGE图片 + */ + object IMAGE : FileType() + + /** + * 未知类型(Excel) + */ + object UNKNOWN : FileType() +} diff --git a/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitService.kt index bc3f8d6..8f4fe44 100644 --- a/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitService.kt @@ -1,5 +1,6 @@ package com.casic.xz.meterage.utils.retrofit +import okhttp3.MultipartBody import okhttp3.RequestBody import retrofit2.http.* @@ -35,6 +36,16 @@ ): String /** + * 上传文件 + */ + @Multipart + @POST("/minio/file/upload") + suspend fun uploadFile( + @Header("token") token: String, + @Part file: MultipartBody.Part + ): String + + /** * 获取通知公告列表 */ @POST("/system/notice/listPage") @@ -209,4 +220,24 @@ @Header("token") token: String, @Body requestBody: RequestBody ): String + + /** + * 获取样品列表 + */ + @POST("/customer/sample/listPage") + suspend fun getSampleList( + @Header("token") token: String, + @Body requestBody: RequestBody, + @QueryMap limit: Map, + @QueryMap offset: Map + ): String + + /** + * 新增委托书 + */ + @POST("/business/order/add") + suspend fun addEntrust( + @Header("token") token: String, + @Body requestBody: RequestBody + ): String } \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitServiceManager.kt index cb22e45..90abe5a 100644 --- a/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitServiceManager.kt @@ -1,13 +1,20 @@ package com.casic.xz.meterage.utils.retrofit +import com.alibaba.fastjson2.JSON +import com.alibaba.fastjson2.JSONArray +import com.alibaba.fastjson2.JSONObject +import com.casic.xz.meterage.model.SampleListModel import com.casic.xz.meterage.utils.AuthenticationHelper +import com.casic.xz.meterage.utils.FileType import com.casic.xz.meterage.utils.LocaleConstant import com.pengxh.kt.lite.utils.RetrofitFactory import com.pengxh.kt.lite.utils.SaveKeyValues import okhttp3.MediaType.Companion.toMediaType +import okhttp3.MediaType.Companion.toMediaTypeOrNull +import okhttp3.MultipartBody +import okhttp3.RequestBody.Companion.asRequestBody import okhttp3.RequestBody.Companion.toRequestBody -import org.json.JSONArray -import org.json.JSONObject +import java.io.File object RetrofitServiceManager { @@ -31,9 +38,9 @@ */ suspend fun login(sid: String, account: String, secretKey: String): String { val paramObject = JSONObject() - paramObject.put("sid", sid) - paramObject.put("username", account) - paramObject.put("password", secretKey) + paramObject["sid"] = sid + paramObject["username"] = account + paramObject["password"] = secretKey val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -55,6 +62,20 @@ } /** + * 上传文件 + */ + suspend fun uploadFile(file: File, type: FileType): String { + val requestBody = when (type) { + FileType.PDF -> file.asRequestBody("application/pdf".toMediaTypeOrNull()) + FileType.WORD -> file.asRequestBody("application/msword".toMediaTypeOrNull()) + FileType.IMAGE -> file.asRequestBody("image/png".toMediaTypeOrNull()) + else -> file.asRequestBody("application/vnd.ms-excel".toMediaTypeOrNull()) + } + val filePart = MultipartBody.Part.createFormData("multipartFile", file.name, requestBody) + return api.uploadFile(AuthenticationHelper.token!!, filePart) + } + + /** * 获取通知公告列表 */ suspend fun getNoticeList( @@ -66,11 +87,11 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("noticeNo", noticeNo) - paramObject.put("noticeTitle", noticeTitle) - paramObject.put("noticePublisher", noticePublisher) - paramObject.put("noticeStartTime", noticeStartTime) - paramObject.put("noticeEndTime", noticeEndTime) + paramObject["noticeNo"] = noticeNo + paramObject["noticeTitle"] = noticeTitle + paramObject["noticePublisher"] = noticePublisher + paramObject["noticeStartTime"] = noticeStartTime + paramObject["noticeEndTime"] = noticeEndTime val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -105,26 +126,21 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("equipmentNo", equipmentNo) - paramObject.put("equipmentName", equipmentName) - paramObject.put("mesureType", mesureType) - paramObject.put("managerState", managerState) - paramObject.put("useDept", useDept) - paramObject.put("assetType", assetType) - paramObject.put("equipmentCategory", equipmentCategory) - paramObject.put("isCalibrationTestEquipment", isCalibrationTestEquipment) - paramObject.put("isMeasureAccount", isMeasureAccount) - paramObject.put("isStandardSupportEquipment", isStandardSupportEquipment) - paramObject.put("isFixedAssets", isFixedAssets) - paramObject.put("validStartDate", validStartDate) - paramObject.put("validEndDate", validEndDate) - paramObject.put("abc", abc) - - val jsonArray = JSONArray() - ids.forEach { - jsonArray.put(it) - } - paramObject.put("ids", jsonArray) + paramObject["equipmentNo"] = equipmentNo + paramObject["equipmentName"] = equipmentName + paramObject["mesureType"] = mesureType + paramObject["managerState"] = managerState + paramObject["useDept"] = useDept + paramObject["assetType"] = assetType + paramObject["equipmentCategory"] = equipmentCategory + paramObject["isCalibrationTestEquipment"] = isCalibrationTestEquipment + paramObject["isMeasureAccount"] = isMeasureAccount + paramObject["isStandardSupportEquipment"] = isStandardSupportEquipment + paramObject["isFixedAssets"] = isFixedAssets + paramObject["validStartDate"] = validStartDate + paramObject["validEndDate"] = validEndDate + paramObject["abc"] = abc + paramObject["ids"] = JSONArray.parseArray(JSON.toJSONString(ids)) val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() @@ -143,7 +159,7 @@ */ suspend fun getEquipmentDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -164,13 +180,13 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("standardNo", standardNo) - paramObject.put("standardName", standardName) - paramObject.put("category", category) - paramObject.put("managerState", managerState) - paramObject.put("standardLaboratory", standardLaboratory) - paramObject.put("preparationDate", preparationDate) - paramObject.put("id", id) + paramObject["standardNo"] = standardNo + paramObject["standardName"] = standardName + paramObject["category"] = category + paramObject["managerState"] = managerState + paramObject["standardLaboratory"] = standardLaboratory + paramObject["preparationDate"] = preparationDate + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -193,7 +209,7 @@ */ suspend fun getStandardDeviceDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -212,11 +228,11 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("checkType", checkType) - paramObject.put("priceItem", priceItem) - paramObject.put("priceName", priceName) - paramObject.put("priceNo", priceNo) - paramObject.put("priceType", priceType) + paramObject["checkType"] = checkType + paramObject["priceItem"] = priceItem + paramObject["priceName"] = priceName + paramObject["priceNo"] = priceNo + paramObject["priceType"] = priceType val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -234,7 +250,7 @@ */ suspend fun getCapabilityDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -257,20 +273,15 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("createStartTime", createStartTime) - paramObject.put("createEndTime", createEndTime) - paramObject.put("deptId", deptId) - paramObject.put("director", director) - paramObject.put("effectiveCompany", effectiveCompany) - paramObject.put("trainStartTime", trainStartTime) - paramObject.put("trainEndTime", trainEndTime) - paramObject.put("formId", formId) - - val jsonArray = JSONArray() - ids.forEach { - jsonArray.put(it) - } - paramObject.put("ids", jsonArray) + paramObject["createStartTime"] = createStartTime + paramObject["createEndTime"] = createEndTime + paramObject["deptId"] = deptId + paramObject["director"] = director + paramObject["effectiveCompany"] = effectiveCompany + paramObject["trainStartTime"] = trainStartTime + paramObject["trainEndTime"] = trainEndTime + paramObject["formId"] = formId + paramObject["ids"] = JSONArray.parseArray(JSON.toJSONString(ids)) val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() @@ -294,7 +305,7 @@ */ suspend fun getMeterageTrainDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -308,10 +319,10 @@ bussinessSize: String, customerName: String, customerNo: String, grade: String, offset: Int ): String { val paramObject = JSONObject() - paramObject.put("bussinessSize", bussinessSize) - paramObject.put("customerName", customerName) - paramObject.put("customerNo", customerNo) - paramObject.put("grade", grade) + paramObject["bussinessSize"] = bussinessSize + paramObject["customerName"] = customerName + paramObject["customerNo"] = customerNo + paramObject["grade"] = grade val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() @@ -330,7 +341,7 @@ */ suspend fun getCustomerDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -342,7 +353,7 @@ */ suspend fun getStaffList(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -354,7 +365,7 @@ */ suspend fun getSupportEquipmentList(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -366,7 +377,7 @@ */ suspend fun getVerifyProcedureList(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -389,20 +400,15 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("customerName", customerName) - paramObject.put("customerNo", customerNo) - paramObject.put("deliverer", deliverer) - paramObject.put("orderCode", orderCode) - paramObject.put("startTime", startTime) - paramObject.put("endTime", endTime) - paramObject.put("isUrgent", isUrgent) - paramObject.put("status", status) - - val jsonArray = JSONArray() - ids.forEach { - jsonArray.put(it) - } - paramObject.put("ids", jsonArray) + paramObject["customerName"] = customerName + paramObject["customerNo"] = customerNo + paramObject["deliverer"] = deliverer + paramObject["orderCode"] = orderCode + paramObject["startTime"] = startTime + paramObject["endTime"] = endTime + paramObject["isUrgent"] = isUrgent + paramObject["status"] = status + paramObject["ids"] = JSONArray.parseArray(JSON.toJSONString(ids)) val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() @@ -421,7 +427,7 @@ */ suspend fun getEntrustDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -433,7 +439,7 @@ */ suspend fun acceptEntrust(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -446,10 +452,89 @@ */ suspend fun returnEntrust(id: String, selected: ArrayList): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) return api.returnEntrust(AuthenticationHelper.token!!, requestBody) } + + /** + * 获取样品列表 + */ + suspend fun getSampleList( + customerName: String, + customerNo: String, + startTime: String, + endTime: String, + sampleName: String, + sampleNo: String, + sampleModel: String, + sampleBelong: String, + overtimeStatus: String, + ids: Array, + offset: Int + ): String { + val paramObject = JSONObject() + paramObject["customerName"] = customerName + paramObject["customerNo"] = customerNo + paramObject["startTime"] = startTime + paramObject["endTime"] = endTime + paramObject["sampleName"] = sampleName + paramObject["sampleNo"] = sampleNo + paramObject["sampleModel"] = sampleModel + paramObject["sampleBelong"] = sampleBelong + paramObject["overtimeStatus"] = overtimeStatus + paramObject["ids"] = JSONArray.parseArray(JSON.toJSONString(ids)) + + val requestBody = paramObject.toString().toRequestBody( + "application/json;charset=UTF-8".toMediaType() + ) + + val limitMap = HashMap() + limitMap["limit"] = LocaleConstant.PAGE_LIMIT + + val offsetMap = HashMap() + offsetMap["offset"] = offset + return api.getSampleList(AuthenticationHelper.token!!, requestBody, limitMap, offsetMap) + } + + /** + * 新增委托书 + */ + suspend fun addEntrust( + deliverer: String, + delivererTel: String, + orderTime: String, + planDeliverTime: String, + requireOverTime: String, + customerName: String, + customerPhone: String, + customerAddress: String, + remark: String, + minioFileName: String, + certifications: String, + isUrgent: String, + samples: List + ): String { + val paramObject = JSONObject() + paramObject["deliverer"] = deliverer + paramObject["delivererTel"] = delivererTel + paramObject["orderTime"] = orderTime + paramObject["planDeliverTime"] = planDeliverTime + paramObject["requireOverTime"] = requireOverTime + paramObject["customerName"] = customerName + paramObject["customerPhone"] = customerPhone + paramObject["customerAddress"] = customerAddress + paramObject["remark"] = remark + paramObject["minioFileName"] = minioFileName + paramObject["certifications"] = certifications + paramObject["isUrgent"] = isUrgent + paramObject["customerSampleInfoList"] = JSONArray.parseArray(JSON.toJSONString(samples)) + + val requestBody = paramObject.toString().toRequestBody( + "application/json;charset=UTF-8".toMediaType() + ) + return api.addEntrust(AuthenticationHelper.token!!, requestBody) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/view/home/EntrustAddActivity.kt b/app/src/main/java/com/casic/xz/meterage/view/home/EntrustAddActivity.kt index 3e30095..9c8d27b 100644 --- a/app/src/main/java/com/casic/xz/meterage/view/home/EntrustAddActivity.kt +++ b/app/src/main/java/com/casic/xz/meterage/view/home/EntrustAddActivity.kt @@ -1,52 +1,211 @@ package com.casic.xz.meterage.view.home +import android.app.Activity +import android.content.Context +import android.content.Intent +import android.graphics.Color +import android.graphics.Paint import android.util.Log +import androidx.activity.result.ActivityResult +import androidx.activity.result.ActivityResultCallback +import androidx.activity.result.contract.ActivityResultContracts import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R import com.casic.xz.meterage.adapter.CertificateTypeAdapter2 -import com.casic.xz.meterage.extensions.initLayoutImmersionBar +import com.casic.xz.meterage.adapter.CustomerSampleAdapter +import com.casic.xz.meterage.callback.DateSelectedCallback +import com.casic.xz.meterage.callback.OnImageCompressListener +import com.casic.xz.meterage.extensions.* +import com.casic.xz.meterage.model.EntrustDetailModel +import com.casic.xz.meterage.model.SampleListModel +import com.casic.xz.meterage.utils.FileType +import com.casic.xz.meterage.utils.GlideLoadEngine +import com.casic.xz.meterage.utils.LoadingDialogHub import com.casic.xz.meterage.vm.DictionaryViewModel +import com.casic.xz.meterage.vm.EntrustViewModel +import com.casic.xz.meterage.vm.FileUploadViewModel +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken import com.gyf.immersionbar.ImmersionBar +import com.luck.picture.lib.basic.PictureSelector +import com.luck.picture.lib.config.SelectMimeType +import com.luck.picture.lib.entity.LocalMedia +import com.luck.picture.lib.interfaces.OnResultCallbackListener import com.pengxh.kt.lite.base.KotlinBaseActivity -import com.pengxh.kt.lite.extensions.toJson +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.vm.LoadState +import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import kotlinx.android.synthetic.main.activity_entrust_add.* +import java.io.File + class EntrustAddActivity : KotlinBaseActivity() { + private val context: Context = this@EntrustAddActivity + private val gson by lazy { Gson() } private lateinit var dictionaryViewModel: DictionaryViewModel - private var checkedItems = ArrayList() + private lateinit var fileUploadViewModel: FileUploadViewModel + private lateinit var entrustViewModel: EntrustViewModel + private lateinit var sampleAdapter: CustomerSampleAdapter + private var checkedItems = ArrayList() + private var isUrgent = "0" + private var sampleModels: ArrayList? = null + private var dataBeans = ArrayList() override fun initData() { //证书 dictionaryViewModel = ViewModelProvider(this)[DictionaryViewModel::class.java] dictionaryViewModel.getDictionaryByCode("certificationClass") - dictionaryViewModel.dictionary.observe(this) { dic -> - if (dic.code == 200) { - val typeAdapter2 = CertificateTypeAdapter2(this, dic.data) + dictionaryViewModel.dictionary.observe(this) { + if (it.code == 200) { + val typeAdapter2 = CertificateTypeAdapter2(this, it.data) typeRecyclerView.adapter = typeAdapter2 typeAdapter2.setOnItemCheckedListener(object : CertificateTypeAdapter2.OnItemCheckedListener { override fun onItemChecked(position: Int, isChecked: Boolean) { if (isChecked) { - checkedItems.add(position) + checkedItems.add(position.toString()) } else { - checkedItems.remove(position) + checkedItems.remove(position.toString()) } } }) } } + + fileUploadViewModel = ViewModelProvider(this)[FileUploadViewModel::class.java] + fileUploadViewModel.resultModel.observe(this) { + if (it.code == 200) { + val annexName = it.data[0] + annexView.text = annexName + val textPaint = annexView.paint + textPaint.flags = Paint.UNDERLINE_TEXT_FLAG + textPaint.isAntiAlias = true + annexView.setTextColor(Color.BLUE) + + annexView.setOnClickListener { + annexName.watchAttachFile(this) + } + } + } + + entrustViewModel = ViewModelProvider(this)[EntrustViewModel::class.java] + entrustViewModel.addResult.observe(this) { + if (it.code == 200) { + finish() + } + } + + //样品列表 + sampleAdapter = CustomerSampleAdapter(this, dataBeans) + sampleRecyclerView.adapter = sampleAdapter } + private val selectCustomerLauncher = + registerForActivityResult(ActivityResultContracts.StartActivityForResult(), + object : ActivityResultCallback { + override fun onActivityResult(result: ActivityResult?) { + if (result?.resultCode == Activity.RESULT_OK) { + val data = result.data ?: return + + entrustNameView.text = data.getStringExtra("entrustName") + entrustContactView.text = data.getStringExtra("entrustContact") + entrustAddressView.text = data.getStringExtra("entrustAddress") + } + } + }) + + private val selectSampleLauncher = + registerForActivityResult(ActivityResultContracts.StartActivityForResult(), + object : ActivityResultCallback { + override fun onActivityResult(result: ActivityResult?) { + if (result?.resultCode == Activity.RESULT_OK) { + val data = result.data ?: return + + val modelsJson = data.getStringExtra("sampleModels") + if (!modelsJson.isNullOrBlank()) { + sampleModels = gson.fromJson( + modelsJson, + object : + TypeToken>() {}.type + ) + } + + //刷新列表 + dataBeans.clear() + sampleModels?.forEach { + val model = + EntrustDetailModel.DataModel.CustomerSampleInfoListModel() + + model.customerName = it.customerName + model.customerNo = it.customerNo + model.id = it.id + model.manufacturingNo = it.manufacturingNo + model.measureLastTime = it.measureLastTime + model.measurePeriod = it.measurePeriod + model.orderId = it.orderId + model.remark = it.remark + model.sampleModel = it.sampleModel + model.sampleName = it.sampleName + model.sampleNo = it.sampleNo + model.validDeadline = it.validDeadline + + dataBeans.add(model) + } + sampleAdapter.notifyDataSetChanged() + } + } + }) + override fun initEvent() { + leftBackView.setOnClickListener { finish() } + + estimateTimeView.setOnClickListener { + showDatePicker(object : DateSelectedCallback { + override fun onDateSelected(date: String) { + estimateTimeView.text = date + } + }) + } + + completedView.setOnClickListener { + showDatePicker(object : DateSelectedCallback { + override fun onDateSelected(date: String) { + completedView.text = date + } + }) + } + + entrustNameView.setOnClickListener { + selectCustomerLauncher.launch(Intent(this, SelectCustomerActivity::class.java)) + } + //上传附件 uploadFileButton.setOnClickListener { + BottomActionSheet.Builder() + .setContext(this) + .setItemTextColor(Color.BLUE) + .setActionItemTitle(listOf("文件", "图片")) + .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { + override fun onActionItemClick(position: Int) { + when (position) { + 0 -> uploadFile() + 1 -> uploadImage() + } + } + }).build().show() + } + radioGroup.setOnCheckedChangeListener { _, checkedId -> + when (checkedId) { + R.id.radioButton1 -> isUrgent = "1" + R.id.radioButton2 -> isUrgent = "0" + } } //选择样品 selectSampleButton.setOnClickListener { - + selectSampleLauncher.launch(Intent(this, SelectSampleActivity::class.java)) } //写入样品信息 @@ -55,14 +214,68 @@ } pushEntrustView.setOnClickListener { - Log.d("Casic", "EntrustAddActivity => initEvent: ${checkedItems.toJson()}") + val sender = senderView.text.toString() + if (sender.isBlank()) { + "请填写送样人名字".show(this) + return@setOnClickListener + } + + val contact = contactView.text.toString() + if (contact.isBlank()) { + "请填写送样人联系方式".show(this) + return@setOnClickListener + } + + val estimateTime = estimateTimeView.text.toString() + if (estimateTime.isBlank()) { + "请选择预计送到的时间".show(this) + return@setOnClickListener + } + + val entrustName = entrustNameView.text.toString() + if (entrustName.isBlank()) { + "请选择委托方".show(this) + return@setOnClickListener + } + + if (sampleModels == null) { + "请选择样品".show(this) + return@setOnClickListener + } + entrustViewModel.addEntrust( + sender, + contact, + createEntrustDateView.text.toString(), + estimateTime, + completedView.text.toString(), + entrustName, + entrustContactView.text.toString(), + entrustAddressView.text.toString(), + remarkView.text.toString(), + annexView.text.toString(), + checkedItems.reformat(), + isUrgent, + sampleModels!! + ) } } override fun initLayoutView(): Int = R.layout.activity_entrust_add override fun observeRequestState() { + fileUploadViewModel.loadState.observe(this) { + when (it) { + LoadState.Loading -> LoadingDialogHub.show(this, "文件上传中,请稍后...") + else -> LoadingDialogHub.dismiss() + } + } + entrustViewModel.loadState.observe(this) { + when (it) { + LoadState.Loading -> LoadingDialogHub.show(this, "委托创建中,请稍后...") + else -> LoadingDialogHub.dismiss() + } + } } override fun setupTopBarLayout() { @@ -70,4 +283,62 @@ initLayoutImmersionBar(rootView) titleView.text = "委托需求" } + + private fun uploadFile() { +// val explorer = FileExplorer(this) +// explorer.setInitDir(ExplorerMode.FILE, Environment.getExternalStorageDirectory()) +// explorer.setShowHomeDir(true) +// explorer.setShowUpDir(true) +// explorer.setShowHideDir(true) +// explorer.setAllowExtensions(arrayOf(".doc", ".docx", ".xls", ".xlsx", ".pdf")) +// explorer.setOnFileClickedListener { +// val type = if (it.name.endsWith(".doc") || it.name.endsWith(".docx")) { +// FileType.WORD +// } else if (it.name.endsWith(".pdf")) { +// FileType.PDF +// } else { +// FileType.UNKNOWN +// } +// +// Log.d("Casic", "EntrustAddActivity => uploadFile: ${it.absolutePath}") +// fileUploadViewModel.uploadFile(it, type) +// } + } + + private fun uploadImage() { + PictureSelector.create(this) + .openGallery(SelectMimeType.ofImage()) + .isGif(false) + .isMaxSelectEnabledMask(true) + .setFilterMinFileSize(100) + .setMaxSelectNum(1) + .isDisplayCamera(false) + .setImageEngine(GlideLoadEngine.instance) + .forResult(object : OnResultCallbackListener { + override fun onResult(result: ArrayList?) { + if (result == null) { + "选择照片失败,请重试".show(context) + return + } + result[0].realPath.compressImage(context, object : OnImageCompressListener { + override fun onSuccess(file: File) { + Log.d( + "Casic", "EntrustAddActivity => onSuccess: ${file.absolutePath}" + ) + ///storage/emulated/0/Android/data/com.casic.xz.meterage/files/Pictures/CompressImage/1677478115391211.jpeg + //上传图片 + fileUploadViewModel.uploadFile(file, FileType.IMAGE) + } + + override fun onError(e: Throwable) { + e.printStackTrace() + } + }) + } + + override fun onCancel() { + + } + }) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/view/home/SelectCustomerActivity.kt b/app/src/main/java/com/casic/xz/meterage/view/home/SelectCustomerActivity.kt new file mode 100644 index 0000000..9bf6a1a --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/view/home/SelectCustomerActivity.kt @@ -0,0 +1,158 @@ +package com.casic.xz.meterage.view.home + +import android.content.Intent +import android.os.Handler +import androidx.lifecycle.ViewModelProvider +import androidx.recyclerview.widget.DefaultItemAnimator +import androidx.recyclerview.widget.DividerItemDecoration +import com.casic.xz.meterage.R +import com.casic.xz.meterage.adapter.SelectCustomerAdapter +import com.casic.xz.meterage.extensions.initLayoutImmersionBar +import com.casic.xz.meterage.extensions.showEmptyPage +import com.casic.xz.meterage.model.CustomerListModel +import com.casic.xz.meterage.utils.LoadingDialogHub +import com.casic.xz.meterage.vm.CustomerViewModel +import com.gyf.immersionbar.ImmersionBar +import com.pengxh.kt.lite.base.KotlinBaseActivity +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.utils.WeakReferenceHandler +import com.pengxh.kt.lite.vm.LoadState +import kotlinx.android.synthetic.main.activity_select_customer.* +import kotlinx.android.synthetic.main.include_base_title.* +import kotlinx.android.synthetic.main.include_empty_view.* + +class SelectCustomerActivity : KotlinBaseActivity() { + + private lateinit var weakReferenceHandler: WeakReferenceHandler + private lateinit var customerViewModel: CustomerViewModel + private lateinit var selectCustomerAdapter: SelectCustomerAdapter + private var dataBeans: MutableList = ArrayList() + private var pageIndex = 1 + private var isRefresh = false + private var isLoadMore = false + private var customerModel: CustomerListModel.DataModel.RowsModel? = null + + override fun initData() { + weakReferenceHandler = WeakReferenceHandler(callback) + customerViewModel = ViewModelProvider(this)[CustomerViewModel::class.java] + customerViewModel.customerList.observe(this) { + if (it.code == 200) { + val dataRows = it.data?.rows!! + when { + isRefresh -> { + dataBeans.clear() + dataBeans = dataRows + customerLayout.finishRefresh() + isRefresh = false + } + isLoadMore -> { + if (dataRows.size == 0) { + "到底了,别拉了".show(this) + } + dataBeans.addAll(dataRows) + customerLayout.finishLoadMore() + isLoadMore = false + } + else -> { + dataBeans = dataRows + } + } + weakReferenceHandler.sendEmptyMessage(2023022701) + } + } + } + + override fun initEvent() { + leftBackView.setOnClickListener { + if (customerModel == null) { + "请选择委托方".show(this) + return@setOnClickListener + } + val intent = Intent() + intent.putExtra("entrustName", customerModel!!.customerName) + intent.putExtra("entrustContact", customerModel!!.phone) + intent.putExtra("entrustAddress", customerModel!!.fullAddress) + setResult(RESULT_OK, intent) + finish() + } + + customerLayout.setOnRefreshListener { + isRefresh = true + //刷新之后页码重置 + pageIndex = 1 + getCustomerList() + } + + customerLayout.setOnLoadMoreListener { + isLoadMore = true + pageIndex++ + getCustomerList() + } + } + + override fun initLayoutView(): Int = R.layout.activity_select_customer + + override fun observeRequestState() { + customerViewModel.loadState.observe(this) { + when (it) { + LoadState.Loading -> LoadingDialogHub.show(this, "数据加载中...") + else -> LoadingDialogHub.dismiss() + } + } + } + + override fun setupTopBarLayout() { + ImmersionBar.with(this).statusBarDarkFont(true).init() + initLayoutImmersionBar(rootView) + titleView.text = "客户列表" + } + + override fun onResume() { + super.onResume() + pageIndex = 1 + getCustomerList() + } + + private fun getCustomerList() { + customerViewModel.getCustomerList( + "", + "", + "", + "", + pageIndex + ) + } + + private val callback = Handler.Callback { + when (it.what) { + 2023022701 -> { + if (isRefresh || isLoadMore) { + selectCustomerAdapter.notifyDataSetChanged() + } else { + if (dataBeans.size == 0) { + emptyView!!.showEmptyPage("无客户数据") { + pageIndex = 1 + getCustomerList() + } + } else { + emptyView!!.hide() + selectCustomerAdapter = SelectCustomerAdapter(this, dataBeans) + customerRecyclerView.addItemDecoration( + DividerItemDecoration(this, DividerItemDecoration.VERTICAL) + ) + (customerRecyclerView.itemAnimator as DefaultItemAnimator).supportsChangeAnimations = + false + customerRecyclerView.adapter = selectCustomerAdapter + selectCustomerAdapter.setOnCheckedListener(object : + SelectCustomerAdapter.OnItemCheckedListener { + override fun onItemChecked(item: CustomerListModel.DataModel.RowsModel) { + customerModel = item + } + }) + } + } + } + } + true + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/view/home/SelectSampleActivity.kt b/app/src/main/java/com/casic/xz/meterage/view/home/SelectSampleActivity.kt new file mode 100644 index 0000000..f85cb44 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/view/home/SelectSampleActivity.kt @@ -0,0 +1,152 @@ +package com.casic.xz.meterage.view.home + +import android.content.Intent +import android.os.Handler +import androidx.lifecycle.ViewModelProvider +import androidx.recyclerview.widget.DefaultItemAnimator +import androidx.recyclerview.widget.DividerItemDecoration +import com.casic.xz.meterage.R +import com.casic.xz.meterage.adapter.SelectSampleAdapter +import com.casic.xz.meterage.extensions.initLayoutImmersionBar +import com.casic.xz.meterage.extensions.showEmptyPage +import com.casic.xz.meterage.model.SampleListModel +import com.casic.xz.meterage.vm.SampleViewModel +import com.gyf.immersionbar.ImmersionBar +import com.pengxh.kt.lite.base.KotlinBaseActivity +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.extensions.toJson +import com.pengxh.kt.lite.utils.WeakReferenceHandler +import kotlinx.android.synthetic.main.activity_select_sample.* +import kotlinx.android.synthetic.main.include_base_title.* +import kotlinx.android.synthetic.main.include_empty_view.* + +class SelectSampleActivity : KotlinBaseActivity() { + + private lateinit var weakReferenceHandler: WeakReferenceHandler + private lateinit var sampleViewModel: SampleViewModel + private lateinit var selectSampleAdapter: SelectSampleAdapter + private var dataBeans: MutableList = ArrayList() + private var pageIndex = 1 + private var isRefresh = false + private var isLoadMore = false + private var sampleModels = ArrayList() + + override fun initData() { + weakReferenceHandler = WeakReferenceHandler(callback) + sampleViewModel = ViewModelProvider(this)[SampleViewModel::class.java] + sampleViewModel.sampleList.observe(this) { + if (it.code == 200) { + val dataRows = it.data?.rows!! + when { + isRefresh -> { + dataBeans.clear() + dataBeans = dataRows + sampleLayout.finishRefresh() + isRefresh = false + } + isLoadMore -> { + if (dataRows.size == 0) { + "到底了,别拉了".show(this) + } + dataBeans.addAll(dataRows) + sampleLayout.finishLoadMore() + isLoadMore = false + } + else -> { + dataBeans = dataRows + } + } + weakReferenceHandler.sendEmptyMessage(2023030101) + } + } + } + + override fun initEvent() { + leftBackView.setOnClickListener { + val intent = Intent() + intent.putExtra("sampleModels", sampleModels.toJson()) + setResult(RESULT_OK, intent) + finish() + } + + sampleLayout.setOnRefreshListener { + isRefresh = true + //刷新之后页码重置 + pageIndex = 1 + getSampleList() + } + + sampleLayout.setOnLoadMoreListener { + isLoadMore = true + pageIndex++ + getSampleList() + } + } + + override fun initLayoutView(): Int = R.layout.activity_select_sample + + override fun observeRequestState() { + + } + + override fun setupTopBarLayout() { + ImmersionBar.with(this).statusBarDarkFont(true).init() + initLayoutImmersionBar(rootView) + titleView.text = "样品列表" + } + + override fun onResume() { + super.onResume() + pageIndex = 1 + getSampleList() + } + + private fun getSampleList() { + sampleViewModel.getSampleList( + "", + "", + "", + "", + "", + "", + "", + "", + "", + arrayOf(), + pageIndex + ) + } + + private val callback = Handler.Callback { + when (it.what) { + 2023030101 -> { + if (isRefresh || isLoadMore) { + selectSampleAdapter.notifyDataSetChanged() + } else { + if (dataBeans.size == 0) { + emptyView!!.showEmptyPage("无样品数据") { + pageIndex = 1 + getSampleList() + } + } else { + emptyView!!.hide() + selectSampleAdapter = SelectSampleAdapter(this, dataBeans) + sampleRecyclerView.addItemDecoration( + DividerItemDecoration(this, DividerItemDecoration.VERTICAL) + ) + (sampleRecyclerView.itemAnimator as DefaultItemAnimator).supportsChangeAnimations = + false + sampleRecyclerView.adapter = selectSampleAdapter + selectSampleAdapter.setOnCheckedListener(object : + SelectSampleAdapter.OnItemCheckedListener { + override fun onItemChecked(items: ArrayList) { + sampleModels = items + } + }) + } + } + } + } + true + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/view/notice/NoticeDetailActivity.kt b/app/src/main/java/com/casic/xz/meterage/view/notice/NoticeDetailActivity.kt index a9d9422..9596985 100644 --- a/app/src/main/java/com/casic/xz/meterage/view/notice/NoticeDetailActivity.kt +++ b/app/src/main/java/com/casic/xz/meterage/view/notice/NoticeDetailActivity.kt @@ -1,6 +1,7 @@ package com.casic.xz.meterage.view.notice import android.annotation.SuppressLint +import android.graphics.Color import android.graphics.Paint import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R @@ -10,7 +11,6 @@ import com.casic.xz.meterage.vm.NoticeViewModel import com.gyf.immersionbar.ImmersionBar import com.pengxh.kt.lite.base.KotlinBaseActivity -import com.pengxh.kt.lite.extensions.convertColor import com.pengxh.kt.lite.extensions.obtainScreenWidth import com.pengxh.kt.lite.utils.Constant import kotlinx.android.synthetic.main.activity_notice_detail.* @@ -54,7 +54,7 @@ val textPaint = minioFileView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - minioFileView.setTextColor(R.color.themeColor.convertColor(this)) + minioFileView.setTextColor(Color.BLUE) minioFileView.setOnClickListener { minioFileName.watchAttachFile(this) diff --git a/app/src/main/java/com/casic/xz/meterage/vm/EntrustViewModel.kt b/app/src/main/java/com/casic/xz/meterage/vm/EntrustViewModel.kt index 2280f88..103c002 100644 --- a/app/src/main/java/com/casic/xz/meterage/vm/EntrustViewModel.kt +++ b/app/src/main/java/com/casic/xz/meterage/vm/EntrustViewModel.kt @@ -7,6 +7,7 @@ import com.casic.xz.meterage.model.ActionResultModel import com.casic.xz.meterage.model.EntrustDetailModel import com.casic.xz.meterage.model.EntrustListModel +import com.casic.xz.meterage.model.SampleListModel import com.casic.xz.meterage.utils.retrofit.RetrofitServiceManager import com.google.gson.Gson import com.google.gson.reflect.TypeToken @@ -25,6 +26,7 @@ val entrustDetail = MutableLiveData() val acceptResult = MutableLiveData() val returnResult = MutableLiveData() + val addResult = MutableLiveData() fun getEntrustList( customerName: String, @@ -119,4 +121,50 @@ loadState.value = LoadState.Fail it.cause.toString().show(BaseApplication.get()) }) + + fun addEntrust( + deliverer: String, + delivererTel: String, + orderTime: String, + planDeliverTime: String, + requireOverTime: String, + customerName: String, + customerPhone: String, + customerAddress: String, + remark: String, + minioFileName: String, + certifications: String, + isUrgent: String, + samples: List + ) = launch({ + loadState.value = LoadState.Loading + val response = RetrofitServiceManager.addEntrust( + deliverer, + delivererTel, + orderTime, + planDeliverTime, + requireOverTime, + customerName, + customerPhone, + customerAddress, + remark, + minioFileName, + certifications, + isUrgent, + samples + ) + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + loadState.value = LoadState.Success + addResult.value = gson.fromJson( + response, object : TypeToken() {}.type + ) + } else { + loadState.value = LoadState.Fail + response.toErrorMessage().show(BaseApplication.get()) + } + }, { + loadState.value = LoadState.Fail + it.cause.toString().show(BaseApplication.get()) + }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/vm/FileUploadViewModel.kt b/app/src/main/java/com/casic/xz/meterage/vm/FileUploadViewModel.kt new file mode 100644 index 0000000..b16c1c7 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/vm/FileUploadViewModel.kt @@ -0,0 +1,40 @@ +package com.casic.xz.meterage.vm + +import androidx.lifecycle.MutableLiveData +import com.casic.xz.meterage.base.BaseApplication +import com.casic.xz.meterage.extensions.separateResponseCode +import com.casic.xz.meterage.extensions.toErrorMessage +import com.casic.xz.meterage.model.UploadResultModel +import com.casic.xz.meterage.utils.FileType +import com.casic.xz.meterage.utils.retrofit.RetrofitServiceManager +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken +import com.pengxh.kt.lite.extensions.launch +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.vm.BaseViewModel +import com.pengxh.kt.lite.vm.LoadState +import java.io.File + +class FileUploadViewModel : BaseViewModel() { + + private val gson by lazy { Gson() } + val resultModel = MutableLiveData() + + fun uploadFile(file: File, type: FileType) = launch({ + loadState.value = LoadState.Loading + val response = RetrofitServiceManager.uploadFile(file, type) + 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(BaseApplication.get()) + } + }, { + loadState.value = LoadState.Fail + it.cause.toString().show(BaseApplication.get()) + }) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/vm/SampleViewModel.kt b/app/src/main/java/com/casic/xz/meterage/vm/SampleViewModel.kt new file mode 100644 index 0000000..182140d --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/vm/SampleViewModel.kt @@ -0,0 +1,65 @@ +package com.casic.xz.meterage.vm + +import androidx.lifecycle.MutableLiveData +import com.casic.xz.meterage.base.BaseApplication +import com.casic.xz.meterage.extensions.separateResponseCode +import com.casic.xz.meterage.extensions.toErrorMessage +import com.casic.xz.meterage.model.SampleListModel +import com.casic.xz.meterage.utils.retrofit.RetrofitServiceManager +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken +import com.pengxh.kt.lite.extensions.launch +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.vm.BaseViewModel +import com.pengxh.kt.lite.vm.LoadState + +/** + * 样品相关 VM + * */ +class SampleViewModel : BaseViewModel() { + + private val gson by lazy { Gson() } + val sampleList = MutableLiveData() + + fun getSampleList( + customerName: String, + customerNo: String, + startTime: String, + endTime: String, + sampleName: String, + sampleNo: String, + sampleModel: String, + sampleBelong: String, + overtimeStatus: String, + ids: Array, + offset: Int + ) = launch({ + loadState.value = LoadState.Loading + val response = RetrofitServiceManager.getSampleList( + customerName, + customerNo, + startTime, + endTime, + sampleName, + sampleNo, + sampleModel, + sampleBelong, + overtimeStatus, + ids, + offset + ) + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + loadState.value = LoadState.Success + sampleList.value = gson.fromJson( + response, object : TypeToken() {}.type + ) + } else { + loadState.value = LoadState.Fail + response.toErrorMessage().show(BaseApplication.get()) + } + }, { + loadState.value = LoadState.Fail + it.cause.toString().show(BaseApplication.get()) + }) +} \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_customer_selector.xml b/app/src/main/res/drawable/bg_customer_selector.xml new file mode 100644 index 0000000..e7292d5 --- /dev/null +++ b/app/src/main/res/drawable/bg_customer_selector.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_sample_selector.xml b/app/src/main/res/drawable/bg_sample_selector.xml new file mode 100644 index 0000000..6b5d5e7 --- /dev/null +++ b/app/src/main/res/drawable/bg_sample_selector.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_check_selected.xml b/app/src/main/res/drawable/ic_check_selected.xml new file mode 100644 index 0000000..4d93f9f --- /dev/null +++ b/app/src/main/res/drawable/ic_check_selected.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/build.gradle b/app/build.gradle index 0ae369f..687b02b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -15,7 +15,6 @@ } compileSdkVersion 31 - buildToolsVersion "30.0.3" defaultConfig { applicationId "com.casic.xz.meterage" @@ -84,11 +83,13 @@ implementation 'top.zibin:Luban:1.1.8' //官方Json解析库 implementation 'com.google.code.gson:gson:2.9.0' + //阿里巴巴JSON库 + implementation 'com.alibaba.fastjson2:fastjson2:2.0.24' //Kotlin协程 implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.5.1' //MVVM+LiveData implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.5.1" - implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.0" + implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1" implementation "androidx.lifecycle:lifecycle-extensions:2.2.0" //返回值转换器 implementation 'com.jakewharton.retrofit:retrofit2-kotlin-coroutines-adapter:0.9.2' @@ -109,4 +110,8 @@ implementation 'com.github.barteksc:android-pdf-viewer:2.8.2' //绕过Android 11反射限制 implementation 'com.github.tiann:FreeReflection:3.1.0' + //单项/数字、二三级联动、日期/时间等滚轮选择器 + implementation 'com.github.gzu-liyujiang.AndroidPicker:WheelPicker:4.1.8' + //文件/目录选择器 + implementation 'com.github.gzu-liyujiang.AndroidPicker:FilePicker:4.1.1' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 1ccc12b..0fba91b 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -60,6 +60,8 @@ + + diff --git a/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt b/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt new file mode 100644 index 0000000..21a71d8 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt @@ -0,0 +1,70 @@ +package com.casic.xz.meterage.adapter + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import com.casic.xz.meterage.R +import com.casic.xz.meterage.extensions.toChineseGrade +import com.casic.xz.meterage.model.CustomerListModel + +class SelectCustomerAdapter( + context: Context, private val dataRows: MutableList +) : RecyclerView.Adapter() { + + private var layoutInflater = LayoutInflater.from(context) + + //选择的位置 + private var selectedPosition = 0 + + //临时记录上次选择的位置 + private var temp = -1 + + override fun getItemCount(): Int = dataRows.size + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ItemViewHolder( + layoutInflater.inflate(R.layout.item_select_customer_lv, parent, false) + ) + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + //绑定数据 + val rowsBean = dataRows[position] + holder.agreementLevelView.text = rowsBean.grade.toChineseGrade() + holder.customerNameView.text = rowsBean.customerName + holder.scaleView.text = rowsBean.companySizeName + holder.overallView.text = "公司规模:${rowsBean.evaluationName}" + holder.fullAddressView.text = "公司地址:${rowsBean.fullAddress}" + + holder.itemView.isSelected = holder.layoutPosition == selectedPosition + holder.itemView.setOnClickListener { + itemCheckedListener?.onItemChecked(rowsBean) + + holder.itemView.isSelected = true + temp = selectedPosition + //设置新的位置 + selectedPosition = holder.layoutPosition + //更新旧位置 + notifyItemChanged(temp) + } + } + + inner class ItemViewHolder(view: View) : RecyclerView.ViewHolder(view) { + var agreementLevelView: TextView = view.findViewById(R.id.agreementLevelView) + var customerNameView: TextView = view.findViewById(R.id.customerNameView) + var scaleView: TextView = view.findViewById(R.id.scaleView) + var overallView: TextView = view.findViewById(R.id.overallView) + var fullAddressView: TextView = view.findViewById(R.id.fullAddressView) + } + + private var itemCheckedListener: OnItemCheckedListener? = null + + interface OnItemCheckedListener { + fun onItemChecked(item: CustomerListModel.DataModel.RowsModel) + } + + fun setOnCheckedListener(listener: OnItemCheckedListener?) { + itemCheckedListener = listener + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt b/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt new file mode 100644 index 0000000..c29461e --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt @@ -0,0 +1,68 @@ +package com.casic.xz.meterage.adapter + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import com.casic.xz.meterage.R +import com.casic.xz.meterage.model.SampleListModel + +class SelectSampleAdapter( + context: Context, private val dataRows: MutableList +) : RecyclerView.Adapter() { + + private var layoutInflater = LayoutInflater.from(context) + private var multipleSelected = mutableSetOf() + private var sampleModes = ArrayList() + + override fun getItemCount(): Int = dataRows.size + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ItemViewHolder( + layoutInflater.inflate(R.layout.item_select_sample_lv, parent, false) + ) + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + //绑定数据 + val rowsBean = dataRows[position] + holder.sampleNameView.text = "${rowsBean.sampleName}【${rowsBean.sampleModel}】" + holder.manufacturingCodeView.text = "出厂编号:${rowsBean.manufacturingNo}" + holder.sampleCodeView.text = "样品编号:${rowsBean.sampleNo}" + holder.validDateView.text = "有效期至:${rowsBean.validDeadline}" + + holder.checkImageView.isSelected = multipleSelected.contains(position) + holder.itemView.setOnClickListener { + if (multipleSelected.contains(position)) { + multipleSelected.remove(position) + sampleModes.remove(dataRows[position]) + holder.checkImageView.isSelected = false + } else { + multipleSelected.add(position) + sampleModes.add(dataRows[position]) + holder.checkImageView.isSelected = true + } + + itemCheckedListener?.onItemChecked(sampleModes) + } + } + + inner class ItemViewHolder(view: View) : RecyclerView.ViewHolder(view) { + var sampleNameView: TextView = view.findViewById(R.id.sampleNameView) + var manufacturingCodeView: TextView = view.findViewById(R.id.manufacturingCodeView) + var sampleCodeView: TextView = view.findViewById(R.id.sampleCodeView) + var validDateView: TextView = view.findViewById(R.id.validDateView) + var checkImageView: ImageView = view.findViewById(R.id.checkImageView) + } + + private var itemCheckedListener: OnItemCheckedListener? = null + + interface OnItemCheckedListener { + fun onItemChecked(items: ArrayList) + } + + fun setOnCheckedListener(listener: OnItemCheckedListener?) { + itemCheckedListener = listener + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/callback/DateSelectedCallback.kt b/app/src/main/java/com/casic/xz/meterage/callback/DateSelectedCallback.kt new file mode 100644 index 0000000..8196110 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/callback/DateSelectedCallback.kt @@ -0,0 +1,5 @@ +package com.casic.xz.meterage.callback + +interface DateSelectedCallback { + fun onDateSelected(date: String) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/Activity.kt b/app/src/main/java/com/casic/xz/meterage/extensions/Activity.kt new file mode 100644 index 0000000..e112d1c --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/extensions/Activity.kt @@ -0,0 +1,33 @@ +package com.casic.xz.meterage.extensions + +import android.app.Activity +import com.casic.xz.meterage.R +import com.casic.xz.meterage.callback.DateSelectedCallback +import com.github.gzuliyujiang.wheelpicker.DatePicker +import com.github.gzuliyujiang.wheelpicker.annotation.DateMode +import com.github.gzuliyujiang.wheelpicker.entity.DateEntity +import com.pengxh.kt.lite.extensions.convertColor +import com.pengxh.kt.lite.extensions.sp2px + +fun Activity.showDatePicker(callback: DateSelectedCallback) { + val datePicker = DatePicker(this) + + val layout = datePicker.wheelLayout + layout.setDateMode(DateMode.YEAR_MONTH_DAY) + layout.setDateLabel("年", "月", "日"); + layout.setTextSize(14f.sp2px(this).toFloat()) + layout.setSelectedTextSize(16f.sp2px(this).toFloat()) + layout.setSelectedTextColor(R.color.themeColor.convertColor(this)) + layout.setSelectedTextBold(true) + layout.setResetWhenLinkage(false) + layout.setRange( + DateEntity.today(), + DateEntity.target(2050, 12, 31), + DateEntity.today() + ) + + datePicker.setOnDatePickedListener { year, month, day -> + callback.onDateSelected(String.format("%s-%s-%s", year, month, day)) + } + datePicker.show() +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt b/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt index 016ebcb..cf6bf49 100644 --- a/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt +++ b/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt @@ -4,7 +4,7 @@ * ArrayList扩展方法 */ -//将图片集合格式化成满足上传格式的数据 +//将集合格式化成满足上传格式的数据 fun ArrayList.reformat(): String { if (this.isEmpty()) return "" val builder = StringBuilder() diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt b/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt index 7c57643..aa9b92b 100644 --- a/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt +++ b/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt @@ -1,7 +1,6 @@ package com.casic.xz.meterage.extensions import android.content.Context -import android.util.Log import android.view.ViewGroup import com.casic.xz.meterage.base.BaseApplication import com.pengxh.kt.lite.extensions.dp2px @@ -9,9 +8,8 @@ fun Context.initLayoutImmersionBar(rootView: ViewGroup) { var statusBarHeight = QMUIDisplayHelper.getStatusBarHeight(this) - Log.d("Casic", "状态栏高度: $statusBarHeight") if (statusBarHeight == 0) { - statusBarHeight = 44f.dp2px(BaseApplication.get()) + statusBarHeight = 40f.dp2px(BaseApplication.get()) } rootView.setPadding(0, statusBarHeight, 0, 0) rootView.requestLayout() diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/String.kt b/app/src/main/java/com/casic/xz/meterage/extensions/String.kt index 28f70d8..6234d43 100644 --- a/app/src/main/java/com/casic/xz/meterage/extensions/String.kt +++ b/app/src/main/java/com/casic/xz/meterage/extensions/String.kt @@ -128,9 +128,10 @@ fun String.combineImagePath(): String { if (this.isEmpty()) return this val defaultValue = SaveKeyValues.getValue( - LocaleConstant.DEFAULT_SERVER_CONFIG, LocaleConstant.SERVER_BASE_URL + LocaleConstant.FILE_SERVER_CONFIG, LocaleConstant.File_SERVER_URL ) as String - return "$defaultValue/static/${this.replace("\\", "/")}" + //http://111.198.10.15:21408/test/1677479806059688_1677479806038.jpeg + return "$defaultValue/test/${this.replace("\\", "/")}" } fun String.isEarlier(time: String): Boolean { diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt index 25fa87b..a0e1358 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt @@ -1,18 +1,12 @@ package com.casic.xz.meterage.fragment.customer +import android.graphics.Color import android.graphics.Paint import com.casic.xz.meterage.R -import com.casic.xz.meterage.extensions.combineImagePath import com.casic.xz.meterage.extensions.toChineseGrade +import com.casic.xz.meterage.extensions.watchAttachFile import com.casic.xz.meterage.model.CustomerDetailModel -import com.casic.xz.meterage.view.BigImageActivity -import com.casic.xz.meterage.view.notice.PreviewDocumentActivity -import com.casic.xz.meterage.view.notice.PreviewPdfActivity -import com.casic.xz.meterage.view.notice.PreviewTextActivity import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.extensions.show import kotlinx.android.synthetic.main.fragment_customer_basic_information.* class BasicInformationFragment(private val data: CustomerDetailModel.DataModel) : @@ -48,30 +42,11 @@ val textPaint = minioFileView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - minioFileView.setTextColor(R.color.themeColor.convertColor(requireContext())) + minioFileView.setTextColor(Color.BLUE) minioFileView.setOnClickListener { //查看附件 - if (minioFileName.endsWith("pdf")) { - requireContext().navigatePageTo(minioFileName) - } else if ( - minioFileName.endsWith("doc") || - minioFileName.endsWith("docx") - ) { - requireContext().navigatePageTo(minioFileName) - } else if (minioFileName.endsWith("txt")) { - requireContext().navigatePageTo(minioFileName) - } else if ( - minioFileName.endsWith("png") || - minioFileName.endsWith("jpeg") || - minioFileName.endsWith("jpg") - ) { - val urls = ArrayList() - urls.add(minioFileName.combineImagePath()) - requireContext().navigatePageTo(0, urls) - } else { - "文件类型未知,无法打开附件".show(requireContext()) - } + minioFileName.watchAttachFile(requireContext()) } } } diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt index 77846b4..3a0fe2e 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt @@ -1,5 +1,6 @@ package com.casic.xz.meterage.fragment.device +import android.graphics.Color import android.graphics.Paint import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R @@ -7,7 +8,6 @@ import com.casic.xz.meterage.utils.LoadingDialogHub import com.casic.xz.meterage.vm.EquipmentViewModel import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor import com.pengxh.kt.lite.vm.LoadState import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import kotlinx.android.synthetic.main.fragment_device_basic_information.* @@ -56,7 +56,7 @@ val textPaint = documentsView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - documentsView.setTextColor(R.color.themeColor.convertColor(requireContext())) + documentsView.setTextColor(Color.BLUE) val files = ArrayList() data.fileList.forEach { file -> @@ -66,7 +66,7 @@ BottomActionSheet.Builder() .setContext(requireContext()) .setActionItemTitle(files) - .setItemTextColor(R.color.themeColor.convertColor(requireContext())) + .setItemTextColor(Color.BLUE) .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { override fun onActionItemClick(position: Int) { diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt index 15dc3d2..10eeff8 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt @@ -1,5 +1,6 @@ package com.casic.xz.meterage.fragment.entrust +import android.graphics.Color import android.graphics.Paint import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R @@ -9,7 +10,6 @@ import com.casic.xz.meterage.model.EntrustDetailModel import com.casic.xz.meterage.vm.DictionaryViewModel import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor import kotlinx.android.synthetic.main.fragment_entrust_basic_information.* class BasicInformationFragment(private val data: EntrustDetailModel.DataModel) : @@ -38,7 +38,7 @@ val textPaint = annexView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - annexView.setTextColor(R.color.themeColor.convertColor(requireContext())) + annexView.setTextColor(Color.BLUE) annexView.setOnClickListener { minioFileName.watchAttachFile(requireContext()) @@ -59,9 +59,9 @@ //加急 if (data.isUrgent == "0") { - RadioButton2.isChecked = true + radioButton2.isChecked = true } else { - RadioButton1.isChecked = true + radioButton1.isChecked = true } //样品 diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/equipment/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/equipment/BasicInformationFragment.kt index 72b523c..7bc3b01 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/equipment/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/equipment/BasicInformationFragment.kt @@ -1,5 +1,6 @@ package com.casic.xz.meterage.fragment.equipment +import android.graphics.Color import android.graphics.Paint import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R @@ -7,7 +8,6 @@ import com.casic.xz.meterage.utils.LoadingDialogHub import com.casic.xz.meterage.vm.EquipmentViewModel import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor import com.pengxh.kt.lite.vm.LoadState import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import kotlinx.android.synthetic.main.fragment_equipment_basic_information.* @@ -74,7 +74,7 @@ val textPaint = instructionsView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - instructionsView.setTextColor(R.color.themeColor.convertColor(requireContext())) + instructionsView.setTextColor(Color.BLUE) val files = ArrayList() data.fileList.forEach { file -> @@ -84,7 +84,7 @@ BottomActionSheet.Builder() .setContext(requireContext()) .setActionItemTitle(files) - .setItemTextColor(R.color.themeColor.convertColor(requireContext())) + .setItemTextColor(Color.BLUE) .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { override fun onActionItemClick(position: Int) { diff --git a/app/src/main/java/com/casic/xz/meterage/model/SampleListModel.java b/app/src/main/java/com/casic/xz/meterage/model/SampleListModel.java new file mode 100644 index 0000000..5784343 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/model/SampleListModel.java @@ -0,0 +1,193 @@ +package com.casic.xz.meterage.model; + +import java.util.List; + +public class SampleListModel { + + private int code; + private DataModel data; + private String message; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataModel getData() { + return data; + } + + public void setData(DataModel data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public static class DataModel { + private List rows; + private int total; + + public List getRows() { + return rows; + } + + public void setRows(List rows) { + this.rows = rows; + } + + public int getTotal() { + return total; + } + + public void setTotal(int total) { + this.total = total; + } + + public static class RowsModel { + private String certificationStatus; + private String customerName; + private String customerNo; + private String id; + private String manufacturingNo; + private String measureLastTime; + private String measurePeriod; + private String orderId; + private String remark; + private String sampleModel; + private String sampleName; + private String sampleNo; + private String sampleSatus; + private String sampleSatusName; + private String validDeadline; + + public String getCertificationStatus() { + return certificationStatus; + } + + public void setCertificationStatus(String certificationStatus) { + this.certificationStatus = certificationStatus; + } + + public String getCustomerName() { + return customerName; + } + + public void setCustomerName(String customerName) { + this.customerName = customerName; + } + + public String getCustomerNo() { + return customerNo; + } + + public void setCustomerNo(String customerNo) { + this.customerNo = customerNo; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getManufacturingNo() { + return manufacturingNo; + } + + public void setManufacturingNo(String manufacturingNo) { + this.manufacturingNo = manufacturingNo; + } + + public String getMeasureLastTime() { + return measureLastTime; + } + + public void setMeasureLastTime(String measureLastTime) { + this.measureLastTime = measureLastTime; + } + + public String getMeasurePeriod() { + return measurePeriod; + } + + public void setMeasurePeriod(String measurePeriod) { + this.measurePeriod = measurePeriod; + } + + public String getOrderId() { + return orderId; + } + + public void setOrderId(String orderId) { + this.orderId = orderId; + } + + public String getRemark() { + return remark; + } + + public void setRemark(String remark) { + this.remark = remark; + } + + public String getSampleModel() { + return sampleModel; + } + + public void setSampleModel(String sampleModel) { + this.sampleModel = sampleModel; + } + + public String getSampleName() { + return sampleName; + } + + public void setSampleName(String sampleName) { + this.sampleName = sampleName; + } + + public String getSampleNo() { + return sampleNo; + } + + public void setSampleNo(String sampleNo) { + this.sampleNo = sampleNo; + } + + public String getSampleSatus() { + return sampleSatus; + } + + public void setSampleSatus(String sampleSatus) { + this.sampleSatus = sampleSatus; + } + + public String getSampleSatusName() { + return sampleSatusName; + } + + public void setSampleSatusName(String sampleSatusName) { + this.sampleSatusName = sampleSatusName; + } + + public String getValidDeadline() { + return validDeadline; + } + + public void setValidDeadline(String validDeadline) { + this.validDeadline = validDeadline; + } + } + } +} diff --git a/app/src/main/java/com/casic/xz/meterage/model/UploadResultModel.java b/app/src/main/java/com/casic/xz/meterage/model/UploadResultModel.java new file mode 100644 index 0000000..f2a6a41 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/model/UploadResultModel.java @@ -0,0 +1,34 @@ +package com.casic.xz.meterage.model; + +import java.util.List; + +public class UploadResultModel { + + private int code; + private List data; + private String message; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public List getData() { + return data; + } + + public void setData(List data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } +} diff --git a/app/src/main/java/com/casic/xz/meterage/utils/FileType.kt b/app/src/main/java/com/casic/xz/meterage/utils/FileType.kt new file mode 100644 index 0000000..17e2bca --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/utils/FileType.kt @@ -0,0 +1,23 @@ +package com.casic.xz.meterage.utils + +sealed class FileType { + /** + * PDF文件 + */ + object PDF : FileType() + + /** + * WORD文件 + */ + object WORD : FileType() + + /** + * IMAGE图片 + */ + object IMAGE : FileType() + + /** + * 未知类型(Excel) + */ + object UNKNOWN : FileType() +} diff --git a/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitService.kt index bc3f8d6..8f4fe44 100644 --- a/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitService.kt @@ -1,5 +1,6 @@ package com.casic.xz.meterage.utils.retrofit +import okhttp3.MultipartBody import okhttp3.RequestBody import retrofit2.http.* @@ -35,6 +36,16 @@ ): String /** + * 上传文件 + */ + @Multipart + @POST("/minio/file/upload") + suspend fun uploadFile( + @Header("token") token: String, + @Part file: MultipartBody.Part + ): String + + /** * 获取通知公告列表 */ @POST("/system/notice/listPage") @@ -209,4 +220,24 @@ @Header("token") token: String, @Body requestBody: RequestBody ): String + + /** + * 获取样品列表 + */ + @POST("/customer/sample/listPage") + suspend fun getSampleList( + @Header("token") token: String, + @Body requestBody: RequestBody, + @QueryMap limit: Map, + @QueryMap offset: Map + ): String + + /** + * 新增委托书 + */ + @POST("/business/order/add") + suspend fun addEntrust( + @Header("token") token: String, + @Body requestBody: RequestBody + ): String } \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitServiceManager.kt index cb22e45..90abe5a 100644 --- a/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitServiceManager.kt @@ -1,13 +1,20 @@ package com.casic.xz.meterage.utils.retrofit +import com.alibaba.fastjson2.JSON +import com.alibaba.fastjson2.JSONArray +import com.alibaba.fastjson2.JSONObject +import com.casic.xz.meterage.model.SampleListModel import com.casic.xz.meterage.utils.AuthenticationHelper +import com.casic.xz.meterage.utils.FileType import com.casic.xz.meterage.utils.LocaleConstant import com.pengxh.kt.lite.utils.RetrofitFactory import com.pengxh.kt.lite.utils.SaveKeyValues import okhttp3.MediaType.Companion.toMediaType +import okhttp3.MediaType.Companion.toMediaTypeOrNull +import okhttp3.MultipartBody +import okhttp3.RequestBody.Companion.asRequestBody import okhttp3.RequestBody.Companion.toRequestBody -import org.json.JSONArray -import org.json.JSONObject +import java.io.File object RetrofitServiceManager { @@ -31,9 +38,9 @@ */ suspend fun login(sid: String, account: String, secretKey: String): String { val paramObject = JSONObject() - paramObject.put("sid", sid) - paramObject.put("username", account) - paramObject.put("password", secretKey) + paramObject["sid"] = sid + paramObject["username"] = account + paramObject["password"] = secretKey val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -55,6 +62,20 @@ } /** + * 上传文件 + */ + suspend fun uploadFile(file: File, type: FileType): String { + val requestBody = when (type) { + FileType.PDF -> file.asRequestBody("application/pdf".toMediaTypeOrNull()) + FileType.WORD -> file.asRequestBody("application/msword".toMediaTypeOrNull()) + FileType.IMAGE -> file.asRequestBody("image/png".toMediaTypeOrNull()) + else -> file.asRequestBody("application/vnd.ms-excel".toMediaTypeOrNull()) + } + val filePart = MultipartBody.Part.createFormData("multipartFile", file.name, requestBody) + return api.uploadFile(AuthenticationHelper.token!!, filePart) + } + + /** * 获取通知公告列表 */ suspend fun getNoticeList( @@ -66,11 +87,11 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("noticeNo", noticeNo) - paramObject.put("noticeTitle", noticeTitle) - paramObject.put("noticePublisher", noticePublisher) - paramObject.put("noticeStartTime", noticeStartTime) - paramObject.put("noticeEndTime", noticeEndTime) + paramObject["noticeNo"] = noticeNo + paramObject["noticeTitle"] = noticeTitle + paramObject["noticePublisher"] = noticePublisher + paramObject["noticeStartTime"] = noticeStartTime + paramObject["noticeEndTime"] = noticeEndTime val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -105,26 +126,21 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("equipmentNo", equipmentNo) - paramObject.put("equipmentName", equipmentName) - paramObject.put("mesureType", mesureType) - paramObject.put("managerState", managerState) - paramObject.put("useDept", useDept) - paramObject.put("assetType", assetType) - paramObject.put("equipmentCategory", equipmentCategory) - paramObject.put("isCalibrationTestEquipment", isCalibrationTestEquipment) - paramObject.put("isMeasureAccount", isMeasureAccount) - paramObject.put("isStandardSupportEquipment", isStandardSupportEquipment) - paramObject.put("isFixedAssets", isFixedAssets) - paramObject.put("validStartDate", validStartDate) - paramObject.put("validEndDate", validEndDate) - paramObject.put("abc", abc) - - val jsonArray = JSONArray() - ids.forEach { - jsonArray.put(it) - } - paramObject.put("ids", jsonArray) + paramObject["equipmentNo"] = equipmentNo + paramObject["equipmentName"] = equipmentName + paramObject["mesureType"] = mesureType + paramObject["managerState"] = managerState + paramObject["useDept"] = useDept + paramObject["assetType"] = assetType + paramObject["equipmentCategory"] = equipmentCategory + paramObject["isCalibrationTestEquipment"] = isCalibrationTestEquipment + paramObject["isMeasureAccount"] = isMeasureAccount + paramObject["isStandardSupportEquipment"] = isStandardSupportEquipment + paramObject["isFixedAssets"] = isFixedAssets + paramObject["validStartDate"] = validStartDate + paramObject["validEndDate"] = validEndDate + paramObject["abc"] = abc + paramObject["ids"] = JSONArray.parseArray(JSON.toJSONString(ids)) val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() @@ -143,7 +159,7 @@ */ suspend fun getEquipmentDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -164,13 +180,13 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("standardNo", standardNo) - paramObject.put("standardName", standardName) - paramObject.put("category", category) - paramObject.put("managerState", managerState) - paramObject.put("standardLaboratory", standardLaboratory) - paramObject.put("preparationDate", preparationDate) - paramObject.put("id", id) + paramObject["standardNo"] = standardNo + paramObject["standardName"] = standardName + paramObject["category"] = category + paramObject["managerState"] = managerState + paramObject["standardLaboratory"] = standardLaboratory + paramObject["preparationDate"] = preparationDate + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -193,7 +209,7 @@ */ suspend fun getStandardDeviceDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -212,11 +228,11 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("checkType", checkType) - paramObject.put("priceItem", priceItem) - paramObject.put("priceName", priceName) - paramObject.put("priceNo", priceNo) - paramObject.put("priceType", priceType) + paramObject["checkType"] = checkType + paramObject["priceItem"] = priceItem + paramObject["priceName"] = priceName + paramObject["priceNo"] = priceNo + paramObject["priceType"] = priceType val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -234,7 +250,7 @@ */ suspend fun getCapabilityDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -257,20 +273,15 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("createStartTime", createStartTime) - paramObject.put("createEndTime", createEndTime) - paramObject.put("deptId", deptId) - paramObject.put("director", director) - paramObject.put("effectiveCompany", effectiveCompany) - paramObject.put("trainStartTime", trainStartTime) - paramObject.put("trainEndTime", trainEndTime) - paramObject.put("formId", formId) - - val jsonArray = JSONArray() - ids.forEach { - jsonArray.put(it) - } - paramObject.put("ids", jsonArray) + paramObject["createStartTime"] = createStartTime + paramObject["createEndTime"] = createEndTime + paramObject["deptId"] = deptId + paramObject["director"] = director + paramObject["effectiveCompany"] = effectiveCompany + paramObject["trainStartTime"] = trainStartTime + paramObject["trainEndTime"] = trainEndTime + paramObject["formId"] = formId + paramObject["ids"] = JSONArray.parseArray(JSON.toJSONString(ids)) val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() @@ -294,7 +305,7 @@ */ suspend fun getMeterageTrainDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -308,10 +319,10 @@ bussinessSize: String, customerName: String, customerNo: String, grade: String, offset: Int ): String { val paramObject = JSONObject() - paramObject.put("bussinessSize", bussinessSize) - paramObject.put("customerName", customerName) - paramObject.put("customerNo", customerNo) - paramObject.put("grade", grade) + paramObject["bussinessSize"] = bussinessSize + paramObject["customerName"] = customerName + paramObject["customerNo"] = customerNo + paramObject["grade"] = grade val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() @@ -330,7 +341,7 @@ */ suspend fun getCustomerDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -342,7 +353,7 @@ */ suspend fun getStaffList(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -354,7 +365,7 @@ */ suspend fun getSupportEquipmentList(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -366,7 +377,7 @@ */ suspend fun getVerifyProcedureList(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -389,20 +400,15 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("customerName", customerName) - paramObject.put("customerNo", customerNo) - paramObject.put("deliverer", deliverer) - paramObject.put("orderCode", orderCode) - paramObject.put("startTime", startTime) - paramObject.put("endTime", endTime) - paramObject.put("isUrgent", isUrgent) - paramObject.put("status", status) - - val jsonArray = JSONArray() - ids.forEach { - jsonArray.put(it) - } - paramObject.put("ids", jsonArray) + paramObject["customerName"] = customerName + paramObject["customerNo"] = customerNo + paramObject["deliverer"] = deliverer + paramObject["orderCode"] = orderCode + paramObject["startTime"] = startTime + paramObject["endTime"] = endTime + paramObject["isUrgent"] = isUrgent + paramObject["status"] = status + paramObject["ids"] = JSONArray.parseArray(JSON.toJSONString(ids)) val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() @@ -421,7 +427,7 @@ */ suspend fun getEntrustDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -433,7 +439,7 @@ */ suspend fun acceptEntrust(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -446,10 +452,89 @@ */ suspend fun returnEntrust(id: String, selected: ArrayList): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) return api.returnEntrust(AuthenticationHelper.token!!, requestBody) } + + /** + * 获取样品列表 + */ + suspend fun getSampleList( + customerName: String, + customerNo: String, + startTime: String, + endTime: String, + sampleName: String, + sampleNo: String, + sampleModel: String, + sampleBelong: String, + overtimeStatus: String, + ids: Array, + offset: Int + ): String { + val paramObject = JSONObject() + paramObject["customerName"] = customerName + paramObject["customerNo"] = customerNo + paramObject["startTime"] = startTime + paramObject["endTime"] = endTime + paramObject["sampleName"] = sampleName + paramObject["sampleNo"] = sampleNo + paramObject["sampleModel"] = sampleModel + paramObject["sampleBelong"] = sampleBelong + paramObject["overtimeStatus"] = overtimeStatus + paramObject["ids"] = JSONArray.parseArray(JSON.toJSONString(ids)) + + val requestBody = paramObject.toString().toRequestBody( + "application/json;charset=UTF-8".toMediaType() + ) + + val limitMap = HashMap() + limitMap["limit"] = LocaleConstant.PAGE_LIMIT + + val offsetMap = HashMap() + offsetMap["offset"] = offset + return api.getSampleList(AuthenticationHelper.token!!, requestBody, limitMap, offsetMap) + } + + /** + * 新增委托书 + */ + suspend fun addEntrust( + deliverer: String, + delivererTel: String, + orderTime: String, + planDeliverTime: String, + requireOverTime: String, + customerName: String, + customerPhone: String, + customerAddress: String, + remark: String, + minioFileName: String, + certifications: String, + isUrgent: String, + samples: List + ): String { + val paramObject = JSONObject() + paramObject["deliverer"] = deliverer + paramObject["delivererTel"] = delivererTel + paramObject["orderTime"] = orderTime + paramObject["planDeliverTime"] = planDeliverTime + paramObject["requireOverTime"] = requireOverTime + paramObject["customerName"] = customerName + paramObject["customerPhone"] = customerPhone + paramObject["customerAddress"] = customerAddress + paramObject["remark"] = remark + paramObject["minioFileName"] = minioFileName + paramObject["certifications"] = certifications + paramObject["isUrgent"] = isUrgent + paramObject["customerSampleInfoList"] = JSONArray.parseArray(JSON.toJSONString(samples)) + + val requestBody = paramObject.toString().toRequestBody( + "application/json;charset=UTF-8".toMediaType() + ) + return api.addEntrust(AuthenticationHelper.token!!, requestBody) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/view/home/EntrustAddActivity.kt b/app/src/main/java/com/casic/xz/meterage/view/home/EntrustAddActivity.kt index 3e30095..9c8d27b 100644 --- a/app/src/main/java/com/casic/xz/meterage/view/home/EntrustAddActivity.kt +++ b/app/src/main/java/com/casic/xz/meterage/view/home/EntrustAddActivity.kt @@ -1,52 +1,211 @@ package com.casic.xz.meterage.view.home +import android.app.Activity +import android.content.Context +import android.content.Intent +import android.graphics.Color +import android.graphics.Paint import android.util.Log +import androidx.activity.result.ActivityResult +import androidx.activity.result.ActivityResultCallback +import androidx.activity.result.contract.ActivityResultContracts import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R import com.casic.xz.meterage.adapter.CertificateTypeAdapter2 -import com.casic.xz.meterage.extensions.initLayoutImmersionBar +import com.casic.xz.meterage.adapter.CustomerSampleAdapter +import com.casic.xz.meterage.callback.DateSelectedCallback +import com.casic.xz.meterage.callback.OnImageCompressListener +import com.casic.xz.meterage.extensions.* +import com.casic.xz.meterage.model.EntrustDetailModel +import com.casic.xz.meterage.model.SampleListModel +import com.casic.xz.meterage.utils.FileType +import com.casic.xz.meterage.utils.GlideLoadEngine +import com.casic.xz.meterage.utils.LoadingDialogHub import com.casic.xz.meterage.vm.DictionaryViewModel +import com.casic.xz.meterage.vm.EntrustViewModel +import com.casic.xz.meterage.vm.FileUploadViewModel +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken import com.gyf.immersionbar.ImmersionBar +import com.luck.picture.lib.basic.PictureSelector +import com.luck.picture.lib.config.SelectMimeType +import com.luck.picture.lib.entity.LocalMedia +import com.luck.picture.lib.interfaces.OnResultCallbackListener import com.pengxh.kt.lite.base.KotlinBaseActivity -import com.pengxh.kt.lite.extensions.toJson +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.vm.LoadState +import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import kotlinx.android.synthetic.main.activity_entrust_add.* +import java.io.File + class EntrustAddActivity : KotlinBaseActivity() { + private val context: Context = this@EntrustAddActivity + private val gson by lazy { Gson() } private lateinit var dictionaryViewModel: DictionaryViewModel - private var checkedItems = ArrayList() + private lateinit var fileUploadViewModel: FileUploadViewModel + private lateinit var entrustViewModel: EntrustViewModel + private lateinit var sampleAdapter: CustomerSampleAdapter + private var checkedItems = ArrayList() + private var isUrgent = "0" + private var sampleModels: ArrayList? = null + private var dataBeans = ArrayList() override fun initData() { //证书 dictionaryViewModel = ViewModelProvider(this)[DictionaryViewModel::class.java] dictionaryViewModel.getDictionaryByCode("certificationClass") - dictionaryViewModel.dictionary.observe(this) { dic -> - if (dic.code == 200) { - val typeAdapter2 = CertificateTypeAdapter2(this, dic.data) + dictionaryViewModel.dictionary.observe(this) { + if (it.code == 200) { + val typeAdapter2 = CertificateTypeAdapter2(this, it.data) typeRecyclerView.adapter = typeAdapter2 typeAdapter2.setOnItemCheckedListener(object : CertificateTypeAdapter2.OnItemCheckedListener { override fun onItemChecked(position: Int, isChecked: Boolean) { if (isChecked) { - checkedItems.add(position) + checkedItems.add(position.toString()) } else { - checkedItems.remove(position) + checkedItems.remove(position.toString()) } } }) } } + + fileUploadViewModel = ViewModelProvider(this)[FileUploadViewModel::class.java] + fileUploadViewModel.resultModel.observe(this) { + if (it.code == 200) { + val annexName = it.data[0] + annexView.text = annexName + val textPaint = annexView.paint + textPaint.flags = Paint.UNDERLINE_TEXT_FLAG + textPaint.isAntiAlias = true + annexView.setTextColor(Color.BLUE) + + annexView.setOnClickListener { + annexName.watchAttachFile(this) + } + } + } + + entrustViewModel = ViewModelProvider(this)[EntrustViewModel::class.java] + entrustViewModel.addResult.observe(this) { + if (it.code == 200) { + finish() + } + } + + //样品列表 + sampleAdapter = CustomerSampleAdapter(this, dataBeans) + sampleRecyclerView.adapter = sampleAdapter } + private val selectCustomerLauncher = + registerForActivityResult(ActivityResultContracts.StartActivityForResult(), + object : ActivityResultCallback { + override fun onActivityResult(result: ActivityResult?) { + if (result?.resultCode == Activity.RESULT_OK) { + val data = result.data ?: return + + entrustNameView.text = data.getStringExtra("entrustName") + entrustContactView.text = data.getStringExtra("entrustContact") + entrustAddressView.text = data.getStringExtra("entrustAddress") + } + } + }) + + private val selectSampleLauncher = + registerForActivityResult(ActivityResultContracts.StartActivityForResult(), + object : ActivityResultCallback { + override fun onActivityResult(result: ActivityResult?) { + if (result?.resultCode == Activity.RESULT_OK) { + val data = result.data ?: return + + val modelsJson = data.getStringExtra("sampleModels") + if (!modelsJson.isNullOrBlank()) { + sampleModels = gson.fromJson( + modelsJson, + object : + TypeToken>() {}.type + ) + } + + //刷新列表 + dataBeans.clear() + sampleModels?.forEach { + val model = + EntrustDetailModel.DataModel.CustomerSampleInfoListModel() + + model.customerName = it.customerName + model.customerNo = it.customerNo + model.id = it.id + model.manufacturingNo = it.manufacturingNo + model.measureLastTime = it.measureLastTime + model.measurePeriod = it.measurePeriod + model.orderId = it.orderId + model.remark = it.remark + model.sampleModel = it.sampleModel + model.sampleName = it.sampleName + model.sampleNo = it.sampleNo + model.validDeadline = it.validDeadline + + dataBeans.add(model) + } + sampleAdapter.notifyDataSetChanged() + } + } + }) + override fun initEvent() { + leftBackView.setOnClickListener { finish() } + + estimateTimeView.setOnClickListener { + showDatePicker(object : DateSelectedCallback { + override fun onDateSelected(date: String) { + estimateTimeView.text = date + } + }) + } + + completedView.setOnClickListener { + showDatePicker(object : DateSelectedCallback { + override fun onDateSelected(date: String) { + completedView.text = date + } + }) + } + + entrustNameView.setOnClickListener { + selectCustomerLauncher.launch(Intent(this, SelectCustomerActivity::class.java)) + } + //上传附件 uploadFileButton.setOnClickListener { + BottomActionSheet.Builder() + .setContext(this) + .setItemTextColor(Color.BLUE) + .setActionItemTitle(listOf("文件", "图片")) + .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { + override fun onActionItemClick(position: Int) { + when (position) { + 0 -> uploadFile() + 1 -> uploadImage() + } + } + }).build().show() + } + radioGroup.setOnCheckedChangeListener { _, checkedId -> + when (checkedId) { + R.id.radioButton1 -> isUrgent = "1" + R.id.radioButton2 -> isUrgent = "0" + } } //选择样品 selectSampleButton.setOnClickListener { - + selectSampleLauncher.launch(Intent(this, SelectSampleActivity::class.java)) } //写入样品信息 @@ -55,14 +214,68 @@ } pushEntrustView.setOnClickListener { - Log.d("Casic", "EntrustAddActivity => initEvent: ${checkedItems.toJson()}") + val sender = senderView.text.toString() + if (sender.isBlank()) { + "请填写送样人名字".show(this) + return@setOnClickListener + } + + val contact = contactView.text.toString() + if (contact.isBlank()) { + "请填写送样人联系方式".show(this) + return@setOnClickListener + } + + val estimateTime = estimateTimeView.text.toString() + if (estimateTime.isBlank()) { + "请选择预计送到的时间".show(this) + return@setOnClickListener + } + + val entrustName = entrustNameView.text.toString() + if (entrustName.isBlank()) { + "请选择委托方".show(this) + return@setOnClickListener + } + + if (sampleModels == null) { + "请选择样品".show(this) + return@setOnClickListener + } + entrustViewModel.addEntrust( + sender, + contact, + createEntrustDateView.text.toString(), + estimateTime, + completedView.text.toString(), + entrustName, + entrustContactView.text.toString(), + entrustAddressView.text.toString(), + remarkView.text.toString(), + annexView.text.toString(), + checkedItems.reformat(), + isUrgent, + sampleModels!! + ) } } override fun initLayoutView(): Int = R.layout.activity_entrust_add override fun observeRequestState() { + fileUploadViewModel.loadState.observe(this) { + when (it) { + LoadState.Loading -> LoadingDialogHub.show(this, "文件上传中,请稍后...") + else -> LoadingDialogHub.dismiss() + } + } + entrustViewModel.loadState.observe(this) { + when (it) { + LoadState.Loading -> LoadingDialogHub.show(this, "委托创建中,请稍后...") + else -> LoadingDialogHub.dismiss() + } + } } override fun setupTopBarLayout() { @@ -70,4 +283,62 @@ initLayoutImmersionBar(rootView) titleView.text = "委托需求" } + + private fun uploadFile() { +// val explorer = FileExplorer(this) +// explorer.setInitDir(ExplorerMode.FILE, Environment.getExternalStorageDirectory()) +// explorer.setShowHomeDir(true) +// explorer.setShowUpDir(true) +// explorer.setShowHideDir(true) +// explorer.setAllowExtensions(arrayOf(".doc", ".docx", ".xls", ".xlsx", ".pdf")) +// explorer.setOnFileClickedListener { +// val type = if (it.name.endsWith(".doc") || it.name.endsWith(".docx")) { +// FileType.WORD +// } else if (it.name.endsWith(".pdf")) { +// FileType.PDF +// } else { +// FileType.UNKNOWN +// } +// +// Log.d("Casic", "EntrustAddActivity => uploadFile: ${it.absolutePath}") +// fileUploadViewModel.uploadFile(it, type) +// } + } + + private fun uploadImage() { + PictureSelector.create(this) + .openGallery(SelectMimeType.ofImage()) + .isGif(false) + .isMaxSelectEnabledMask(true) + .setFilterMinFileSize(100) + .setMaxSelectNum(1) + .isDisplayCamera(false) + .setImageEngine(GlideLoadEngine.instance) + .forResult(object : OnResultCallbackListener { + override fun onResult(result: ArrayList?) { + if (result == null) { + "选择照片失败,请重试".show(context) + return + } + result[0].realPath.compressImage(context, object : OnImageCompressListener { + override fun onSuccess(file: File) { + Log.d( + "Casic", "EntrustAddActivity => onSuccess: ${file.absolutePath}" + ) + ///storage/emulated/0/Android/data/com.casic.xz.meterage/files/Pictures/CompressImage/1677478115391211.jpeg + //上传图片 + fileUploadViewModel.uploadFile(file, FileType.IMAGE) + } + + override fun onError(e: Throwable) { + e.printStackTrace() + } + }) + } + + override fun onCancel() { + + } + }) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/view/home/SelectCustomerActivity.kt b/app/src/main/java/com/casic/xz/meterage/view/home/SelectCustomerActivity.kt new file mode 100644 index 0000000..9bf6a1a --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/view/home/SelectCustomerActivity.kt @@ -0,0 +1,158 @@ +package com.casic.xz.meterage.view.home + +import android.content.Intent +import android.os.Handler +import androidx.lifecycle.ViewModelProvider +import androidx.recyclerview.widget.DefaultItemAnimator +import androidx.recyclerview.widget.DividerItemDecoration +import com.casic.xz.meterage.R +import com.casic.xz.meterage.adapter.SelectCustomerAdapter +import com.casic.xz.meterage.extensions.initLayoutImmersionBar +import com.casic.xz.meterage.extensions.showEmptyPage +import com.casic.xz.meterage.model.CustomerListModel +import com.casic.xz.meterage.utils.LoadingDialogHub +import com.casic.xz.meterage.vm.CustomerViewModel +import com.gyf.immersionbar.ImmersionBar +import com.pengxh.kt.lite.base.KotlinBaseActivity +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.utils.WeakReferenceHandler +import com.pengxh.kt.lite.vm.LoadState +import kotlinx.android.synthetic.main.activity_select_customer.* +import kotlinx.android.synthetic.main.include_base_title.* +import kotlinx.android.synthetic.main.include_empty_view.* + +class SelectCustomerActivity : KotlinBaseActivity() { + + private lateinit var weakReferenceHandler: WeakReferenceHandler + private lateinit var customerViewModel: CustomerViewModel + private lateinit var selectCustomerAdapter: SelectCustomerAdapter + private var dataBeans: MutableList = ArrayList() + private var pageIndex = 1 + private var isRefresh = false + private var isLoadMore = false + private var customerModel: CustomerListModel.DataModel.RowsModel? = null + + override fun initData() { + weakReferenceHandler = WeakReferenceHandler(callback) + customerViewModel = ViewModelProvider(this)[CustomerViewModel::class.java] + customerViewModel.customerList.observe(this) { + if (it.code == 200) { + val dataRows = it.data?.rows!! + when { + isRefresh -> { + dataBeans.clear() + dataBeans = dataRows + customerLayout.finishRefresh() + isRefresh = false + } + isLoadMore -> { + if (dataRows.size == 0) { + "到底了,别拉了".show(this) + } + dataBeans.addAll(dataRows) + customerLayout.finishLoadMore() + isLoadMore = false + } + else -> { + dataBeans = dataRows + } + } + weakReferenceHandler.sendEmptyMessage(2023022701) + } + } + } + + override fun initEvent() { + leftBackView.setOnClickListener { + if (customerModel == null) { + "请选择委托方".show(this) + return@setOnClickListener + } + val intent = Intent() + intent.putExtra("entrustName", customerModel!!.customerName) + intent.putExtra("entrustContact", customerModel!!.phone) + intent.putExtra("entrustAddress", customerModel!!.fullAddress) + setResult(RESULT_OK, intent) + finish() + } + + customerLayout.setOnRefreshListener { + isRefresh = true + //刷新之后页码重置 + pageIndex = 1 + getCustomerList() + } + + customerLayout.setOnLoadMoreListener { + isLoadMore = true + pageIndex++ + getCustomerList() + } + } + + override fun initLayoutView(): Int = R.layout.activity_select_customer + + override fun observeRequestState() { + customerViewModel.loadState.observe(this) { + when (it) { + LoadState.Loading -> LoadingDialogHub.show(this, "数据加载中...") + else -> LoadingDialogHub.dismiss() + } + } + } + + override fun setupTopBarLayout() { + ImmersionBar.with(this).statusBarDarkFont(true).init() + initLayoutImmersionBar(rootView) + titleView.text = "客户列表" + } + + override fun onResume() { + super.onResume() + pageIndex = 1 + getCustomerList() + } + + private fun getCustomerList() { + customerViewModel.getCustomerList( + "", + "", + "", + "", + pageIndex + ) + } + + private val callback = Handler.Callback { + when (it.what) { + 2023022701 -> { + if (isRefresh || isLoadMore) { + selectCustomerAdapter.notifyDataSetChanged() + } else { + if (dataBeans.size == 0) { + emptyView!!.showEmptyPage("无客户数据") { + pageIndex = 1 + getCustomerList() + } + } else { + emptyView!!.hide() + selectCustomerAdapter = SelectCustomerAdapter(this, dataBeans) + customerRecyclerView.addItemDecoration( + DividerItemDecoration(this, DividerItemDecoration.VERTICAL) + ) + (customerRecyclerView.itemAnimator as DefaultItemAnimator).supportsChangeAnimations = + false + customerRecyclerView.adapter = selectCustomerAdapter + selectCustomerAdapter.setOnCheckedListener(object : + SelectCustomerAdapter.OnItemCheckedListener { + override fun onItemChecked(item: CustomerListModel.DataModel.RowsModel) { + customerModel = item + } + }) + } + } + } + } + true + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/view/home/SelectSampleActivity.kt b/app/src/main/java/com/casic/xz/meterage/view/home/SelectSampleActivity.kt new file mode 100644 index 0000000..f85cb44 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/view/home/SelectSampleActivity.kt @@ -0,0 +1,152 @@ +package com.casic.xz.meterage.view.home + +import android.content.Intent +import android.os.Handler +import androidx.lifecycle.ViewModelProvider +import androidx.recyclerview.widget.DefaultItemAnimator +import androidx.recyclerview.widget.DividerItemDecoration +import com.casic.xz.meterage.R +import com.casic.xz.meterage.adapter.SelectSampleAdapter +import com.casic.xz.meterage.extensions.initLayoutImmersionBar +import com.casic.xz.meterage.extensions.showEmptyPage +import com.casic.xz.meterage.model.SampleListModel +import com.casic.xz.meterage.vm.SampleViewModel +import com.gyf.immersionbar.ImmersionBar +import com.pengxh.kt.lite.base.KotlinBaseActivity +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.extensions.toJson +import com.pengxh.kt.lite.utils.WeakReferenceHandler +import kotlinx.android.synthetic.main.activity_select_sample.* +import kotlinx.android.synthetic.main.include_base_title.* +import kotlinx.android.synthetic.main.include_empty_view.* + +class SelectSampleActivity : KotlinBaseActivity() { + + private lateinit var weakReferenceHandler: WeakReferenceHandler + private lateinit var sampleViewModel: SampleViewModel + private lateinit var selectSampleAdapter: SelectSampleAdapter + private var dataBeans: MutableList = ArrayList() + private var pageIndex = 1 + private var isRefresh = false + private var isLoadMore = false + private var sampleModels = ArrayList() + + override fun initData() { + weakReferenceHandler = WeakReferenceHandler(callback) + sampleViewModel = ViewModelProvider(this)[SampleViewModel::class.java] + sampleViewModel.sampleList.observe(this) { + if (it.code == 200) { + val dataRows = it.data?.rows!! + when { + isRefresh -> { + dataBeans.clear() + dataBeans = dataRows + sampleLayout.finishRefresh() + isRefresh = false + } + isLoadMore -> { + if (dataRows.size == 0) { + "到底了,别拉了".show(this) + } + dataBeans.addAll(dataRows) + sampleLayout.finishLoadMore() + isLoadMore = false + } + else -> { + dataBeans = dataRows + } + } + weakReferenceHandler.sendEmptyMessage(2023030101) + } + } + } + + override fun initEvent() { + leftBackView.setOnClickListener { + val intent = Intent() + intent.putExtra("sampleModels", sampleModels.toJson()) + setResult(RESULT_OK, intent) + finish() + } + + sampleLayout.setOnRefreshListener { + isRefresh = true + //刷新之后页码重置 + pageIndex = 1 + getSampleList() + } + + sampleLayout.setOnLoadMoreListener { + isLoadMore = true + pageIndex++ + getSampleList() + } + } + + override fun initLayoutView(): Int = R.layout.activity_select_sample + + override fun observeRequestState() { + + } + + override fun setupTopBarLayout() { + ImmersionBar.with(this).statusBarDarkFont(true).init() + initLayoutImmersionBar(rootView) + titleView.text = "样品列表" + } + + override fun onResume() { + super.onResume() + pageIndex = 1 + getSampleList() + } + + private fun getSampleList() { + sampleViewModel.getSampleList( + "", + "", + "", + "", + "", + "", + "", + "", + "", + arrayOf(), + pageIndex + ) + } + + private val callback = Handler.Callback { + when (it.what) { + 2023030101 -> { + if (isRefresh || isLoadMore) { + selectSampleAdapter.notifyDataSetChanged() + } else { + if (dataBeans.size == 0) { + emptyView!!.showEmptyPage("无样品数据") { + pageIndex = 1 + getSampleList() + } + } else { + emptyView!!.hide() + selectSampleAdapter = SelectSampleAdapter(this, dataBeans) + sampleRecyclerView.addItemDecoration( + DividerItemDecoration(this, DividerItemDecoration.VERTICAL) + ) + (sampleRecyclerView.itemAnimator as DefaultItemAnimator).supportsChangeAnimations = + false + sampleRecyclerView.adapter = selectSampleAdapter + selectSampleAdapter.setOnCheckedListener(object : + SelectSampleAdapter.OnItemCheckedListener { + override fun onItemChecked(items: ArrayList) { + sampleModels = items + } + }) + } + } + } + } + true + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/view/notice/NoticeDetailActivity.kt b/app/src/main/java/com/casic/xz/meterage/view/notice/NoticeDetailActivity.kt index a9d9422..9596985 100644 --- a/app/src/main/java/com/casic/xz/meterage/view/notice/NoticeDetailActivity.kt +++ b/app/src/main/java/com/casic/xz/meterage/view/notice/NoticeDetailActivity.kt @@ -1,6 +1,7 @@ package com.casic.xz.meterage.view.notice import android.annotation.SuppressLint +import android.graphics.Color import android.graphics.Paint import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R @@ -10,7 +11,6 @@ import com.casic.xz.meterage.vm.NoticeViewModel import com.gyf.immersionbar.ImmersionBar import com.pengxh.kt.lite.base.KotlinBaseActivity -import com.pengxh.kt.lite.extensions.convertColor import com.pengxh.kt.lite.extensions.obtainScreenWidth import com.pengxh.kt.lite.utils.Constant import kotlinx.android.synthetic.main.activity_notice_detail.* @@ -54,7 +54,7 @@ val textPaint = minioFileView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - minioFileView.setTextColor(R.color.themeColor.convertColor(this)) + minioFileView.setTextColor(Color.BLUE) minioFileView.setOnClickListener { minioFileName.watchAttachFile(this) diff --git a/app/src/main/java/com/casic/xz/meterage/vm/EntrustViewModel.kt b/app/src/main/java/com/casic/xz/meterage/vm/EntrustViewModel.kt index 2280f88..103c002 100644 --- a/app/src/main/java/com/casic/xz/meterage/vm/EntrustViewModel.kt +++ b/app/src/main/java/com/casic/xz/meterage/vm/EntrustViewModel.kt @@ -7,6 +7,7 @@ import com.casic.xz.meterage.model.ActionResultModel import com.casic.xz.meterage.model.EntrustDetailModel import com.casic.xz.meterage.model.EntrustListModel +import com.casic.xz.meterage.model.SampleListModel import com.casic.xz.meterage.utils.retrofit.RetrofitServiceManager import com.google.gson.Gson import com.google.gson.reflect.TypeToken @@ -25,6 +26,7 @@ val entrustDetail = MutableLiveData() val acceptResult = MutableLiveData() val returnResult = MutableLiveData() + val addResult = MutableLiveData() fun getEntrustList( customerName: String, @@ -119,4 +121,50 @@ loadState.value = LoadState.Fail it.cause.toString().show(BaseApplication.get()) }) + + fun addEntrust( + deliverer: String, + delivererTel: String, + orderTime: String, + planDeliverTime: String, + requireOverTime: String, + customerName: String, + customerPhone: String, + customerAddress: String, + remark: String, + minioFileName: String, + certifications: String, + isUrgent: String, + samples: List + ) = launch({ + loadState.value = LoadState.Loading + val response = RetrofitServiceManager.addEntrust( + deliverer, + delivererTel, + orderTime, + planDeliverTime, + requireOverTime, + customerName, + customerPhone, + customerAddress, + remark, + minioFileName, + certifications, + isUrgent, + samples + ) + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + loadState.value = LoadState.Success + addResult.value = gson.fromJson( + response, object : TypeToken() {}.type + ) + } else { + loadState.value = LoadState.Fail + response.toErrorMessage().show(BaseApplication.get()) + } + }, { + loadState.value = LoadState.Fail + it.cause.toString().show(BaseApplication.get()) + }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/vm/FileUploadViewModel.kt b/app/src/main/java/com/casic/xz/meterage/vm/FileUploadViewModel.kt new file mode 100644 index 0000000..b16c1c7 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/vm/FileUploadViewModel.kt @@ -0,0 +1,40 @@ +package com.casic.xz.meterage.vm + +import androidx.lifecycle.MutableLiveData +import com.casic.xz.meterage.base.BaseApplication +import com.casic.xz.meterage.extensions.separateResponseCode +import com.casic.xz.meterage.extensions.toErrorMessage +import com.casic.xz.meterage.model.UploadResultModel +import com.casic.xz.meterage.utils.FileType +import com.casic.xz.meterage.utils.retrofit.RetrofitServiceManager +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken +import com.pengxh.kt.lite.extensions.launch +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.vm.BaseViewModel +import com.pengxh.kt.lite.vm.LoadState +import java.io.File + +class FileUploadViewModel : BaseViewModel() { + + private val gson by lazy { Gson() } + val resultModel = MutableLiveData() + + fun uploadFile(file: File, type: FileType) = launch({ + loadState.value = LoadState.Loading + val response = RetrofitServiceManager.uploadFile(file, type) + 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(BaseApplication.get()) + } + }, { + loadState.value = LoadState.Fail + it.cause.toString().show(BaseApplication.get()) + }) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/vm/SampleViewModel.kt b/app/src/main/java/com/casic/xz/meterage/vm/SampleViewModel.kt new file mode 100644 index 0000000..182140d --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/vm/SampleViewModel.kt @@ -0,0 +1,65 @@ +package com.casic.xz.meterage.vm + +import androidx.lifecycle.MutableLiveData +import com.casic.xz.meterage.base.BaseApplication +import com.casic.xz.meterage.extensions.separateResponseCode +import com.casic.xz.meterage.extensions.toErrorMessage +import com.casic.xz.meterage.model.SampleListModel +import com.casic.xz.meterage.utils.retrofit.RetrofitServiceManager +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken +import com.pengxh.kt.lite.extensions.launch +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.vm.BaseViewModel +import com.pengxh.kt.lite.vm.LoadState + +/** + * 样品相关 VM + * */ +class SampleViewModel : BaseViewModel() { + + private val gson by lazy { Gson() } + val sampleList = MutableLiveData() + + fun getSampleList( + customerName: String, + customerNo: String, + startTime: String, + endTime: String, + sampleName: String, + sampleNo: String, + sampleModel: String, + sampleBelong: String, + overtimeStatus: String, + ids: Array, + offset: Int + ) = launch({ + loadState.value = LoadState.Loading + val response = RetrofitServiceManager.getSampleList( + customerName, + customerNo, + startTime, + endTime, + sampleName, + sampleNo, + sampleModel, + sampleBelong, + overtimeStatus, + ids, + offset + ) + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + loadState.value = LoadState.Success + sampleList.value = gson.fromJson( + response, object : TypeToken() {}.type + ) + } else { + loadState.value = LoadState.Fail + response.toErrorMessage().show(BaseApplication.get()) + } + }, { + loadState.value = LoadState.Fail + it.cause.toString().show(BaseApplication.get()) + }) +} \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_customer_selector.xml b/app/src/main/res/drawable/bg_customer_selector.xml new file mode 100644 index 0000000..e7292d5 --- /dev/null +++ b/app/src/main/res/drawable/bg_customer_selector.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_sample_selector.xml b/app/src/main/res/drawable/bg_sample_selector.xml new file mode 100644 index 0000000..6b5d5e7 --- /dev/null +++ b/app/src/main/res/drawable/bg_sample_selector.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_check_selected.xml b/app/src/main/res/drawable/ic_check_selected.xml new file mode 100644 index 0000000..4d93f9f --- /dev/null +++ b/app/src/main/res/drawable/ic_check_selected.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_entrust_add.xml b/app/src/main/res/layout/activity_entrust_add.xml index 3d00784..8450d1d 100644 --- a/app/src/main/res/layout/activity_entrust_add.xml +++ b/app/src/main/res/layout/activity_entrust_add.xml @@ -68,6 +68,7 @@ android:text="送样人" /> @@ -81,6 +82,7 @@ android:text="联系方式" /> @@ -115,10 +117,10 @@ style="@style/textViewStyle" android:text="预计送到时间" /> - + android:hint="请选择预计送到时间" /> @@ -129,10 +131,10 @@ style="@style/textViewStyle" android:text="要求检完时间" /> - + android:hint="请选择要求检完时间" /> @@ -143,10 +145,10 @@ style="@style/textViewStyle" android:text="委托方名称" /> - + android:hint="请选择委托方" /> @@ -157,10 +159,9 @@ style="@style/textViewStyle" android:text="委托方电话" /> - + @@ -171,10 +172,9 @@ style="@style/textViewStyle" android:text="委托方地址" /> - + @@ -186,9 +186,9 @@ android:text="备注" /> + android:hint="请输入" /> @@ -200,6 +200,7 @@ android:text="附件" /> diff --git a/app/build.gradle b/app/build.gradle index 0ae369f..687b02b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -15,7 +15,6 @@ } compileSdkVersion 31 - buildToolsVersion "30.0.3" defaultConfig { applicationId "com.casic.xz.meterage" @@ -84,11 +83,13 @@ implementation 'top.zibin:Luban:1.1.8' //官方Json解析库 implementation 'com.google.code.gson:gson:2.9.0' + //阿里巴巴JSON库 + implementation 'com.alibaba.fastjson2:fastjson2:2.0.24' //Kotlin协程 implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.5.1' //MVVM+LiveData implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.5.1" - implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.0" + implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1" implementation "androidx.lifecycle:lifecycle-extensions:2.2.0" //返回值转换器 implementation 'com.jakewharton.retrofit:retrofit2-kotlin-coroutines-adapter:0.9.2' @@ -109,4 +110,8 @@ implementation 'com.github.barteksc:android-pdf-viewer:2.8.2' //绕过Android 11反射限制 implementation 'com.github.tiann:FreeReflection:3.1.0' + //单项/数字、二三级联动、日期/时间等滚轮选择器 + implementation 'com.github.gzu-liyujiang.AndroidPicker:WheelPicker:4.1.8' + //文件/目录选择器 + implementation 'com.github.gzu-liyujiang.AndroidPicker:FilePicker:4.1.1' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 1ccc12b..0fba91b 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -60,6 +60,8 @@ + + diff --git a/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt b/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt new file mode 100644 index 0000000..21a71d8 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt @@ -0,0 +1,70 @@ +package com.casic.xz.meterage.adapter + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import com.casic.xz.meterage.R +import com.casic.xz.meterage.extensions.toChineseGrade +import com.casic.xz.meterage.model.CustomerListModel + +class SelectCustomerAdapter( + context: Context, private val dataRows: MutableList +) : RecyclerView.Adapter() { + + private var layoutInflater = LayoutInflater.from(context) + + //选择的位置 + private var selectedPosition = 0 + + //临时记录上次选择的位置 + private var temp = -1 + + override fun getItemCount(): Int = dataRows.size + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ItemViewHolder( + layoutInflater.inflate(R.layout.item_select_customer_lv, parent, false) + ) + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + //绑定数据 + val rowsBean = dataRows[position] + holder.agreementLevelView.text = rowsBean.grade.toChineseGrade() + holder.customerNameView.text = rowsBean.customerName + holder.scaleView.text = rowsBean.companySizeName + holder.overallView.text = "公司规模:${rowsBean.evaluationName}" + holder.fullAddressView.text = "公司地址:${rowsBean.fullAddress}" + + holder.itemView.isSelected = holder.layoutPosition == selectedPosition + holder.itemView.setOnClickListener { + itemCheckedListener?.onItemChecked(rowsBean) + + holder.itemView.isSelected = true + temp = selectedPosition + //设置新的位置 + selectedPosition = holder.layoutPosition + //更新旧位置 + notifyItemChanged(temp) + } + } + + inner class ItemViewHolder(view: View) : RecyclerView.ViewHolder(view) { + var agreementLevelView: TextView = view.findViewById(R.id.agreementLevelView) + var customerNameView: TextView = view.findViewById(R.id.customerNameView) + var scaleView: TextView = view.findViewById(R.id.scaleView) + var overallView: TextView = view.findViewById(R.id.overallView) + var fullAddressView: TextView = view.findViewById(R.id.fullAddressView) + } + + private var itemCheckedListener: OnItemCheckedListener? = null + + interface OnItemCheckedListener { + fun onItemChecked(item: CustomerListModel.DataModel.RowsModel) + } + + fun setOnCheckedListener(listener: OnItemCheckedListener?) { + itemCheckedListener = listener + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt b/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt new file mode 100644 index 0000000..c29461e --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt @@ -0,0 +1,68 @@ +package com.casic.xz.meterage.adapter + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import com.casic.xz.meterage.R +import com.casic.xz.meterage.model.SampleListModel + +class SelectSampleAdapter( + context: Context, private val dataRows: MutableList +) : RecyclerView.Adapter() { + + private var layoutInflater = LayoutInflater.from(context) + private var multipleSelected = mutableSetOf() + private var sampleModes = ArrayList() + + override fun getItemCount(): Int = dataRows.size + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ItemViewHolder( + layoutInflater.inflate(R.layout.item_select_sample_lv, parent, false) + ) + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + //绑定数据 + val rowsBean = dataRows[position] + holder.sampleNameView.text = "${rowsBean.sampleName}【${rowsBean.sampleModel}】" + holder.manufacturingCodeView.text = "出厂编号:${rowsBean.manufacturingNo}" + holder.sampleCodeView.text = "样品编号:${rowsBean.sampleNo}" + holder.validDateView.text = "有效期至:${rowsBean.validDeadline}" + + holder.checkImageView.isSelected = multipleSelected.contains(position) + holder.itemView.setOnClickListener { + if (multipleSelected.contains(position)) { + multipleSelected.remove(position) + sampleModes.remove(dataRows[position]) + holder.checkImageView.isSelected = false + } else { + multipleSelected.add(position) + sampleModes.add(dataRows[position]) + holder.checkImageView.isSelected = true + } + + itemCheckedListener?.onItemChecked(sampleModes) + } + } + + inner class ItemViewHolder(view: View) : RecyclerView.ViewHolder(view) { + var sampleNameView: TextView = view.findViewById(R.id.sampleNameView) + var manufacturingCodeView: TextView = view.findViewById(R.id.manufacturingCodeView) + var sampleCodeView: TextView = view.findViewById(R.id.sampleCodeView) + var validDateView: TextView = view.findViewById(R.id.validDateView) + var checkImageView: ImageView = view.findViewById(R.id.checkImageView) + } + + private var itemCheckedListener: OnItemCheckedListener? = null + + interface OnItemCheckedListener { + fun onItemChecked(items: ArrayList) + } + + fun setOnCheckedListener(listener: OnItemCheckedListener?) { + itemCheckedListener = listener + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/callback/DateSelectedCallback.kt b/app/src/main/java/com/casic/xz/meterage/callback/DateSelectedCallback.kt new file mode 100644 index 0000000..8196110 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/callback/DateSelectedCallback.kt @@ -0,0 +1,5 @@ +package com.casic.xz.meterage.callback + +interface DateSelectedCallback { + fun onDateSelected(date: String) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/Activity.kt b/app/src/main/java/com/casic/xz/meterage/extensions/Activity.kt new file mode 100644 index 0000000..e112d1c --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/extensions/Activity.kt @@ -0,0 +1,33 @@ +package com.casic.xz.meterage.extensions + +import android.app.Activity +import com.casic.xz.meterage.R +import com.casic.xz.meterage.callback.DateSelectedCallback +import com.github.gzuliyujiang.wheelpicker.DatePicker +import com.github.gzuliyujiang.wheelpicker.annotation.DateMode +import com.github.gzuliyujiang.wheelpicker.entity.DateEntity +import com.pengxh.kt.lite.extensions.convertColor +import com.pengxh.kt.lite.extensions.sp2px + +fun Activity.showDatePicker(callback: DateSelectedCallback) { + val datePicker = DatePicker(this) + + val layout = datePicker.wheelLayout + layout.setDateMode(DateMode.YEAR_MONTH_DAY) + layout.setDateLabel("年", "月", "日"); + layout.setTextSize(14f.sp2px(this).toFloat()) + layout.setSelectedTextSize(16f.sp2px(this).toFloat()) + layout.setSelectedTextColor(R.color.themeColor.convertColor(this)) + layout.setSelectedTextBold(true) + layout.setResetWhenLinkage(false) + layout.setRange( + DateEntity.today(), + DateEntity.target(2050, 12, 31), + DateEntity.today() + ) + + datePicker.setOnDatePickedListener { year, month, day -> + callback.onDateSelected(String.format("%s-%s-%s", year, month, day)) + } + datePicker.show() +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt b/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt index 016ebcb..cf6bf49 100644 --- a/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt +++ b/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt @@ -4,7 +4,7 @@ * ArrayList扩展方法 */ -//将图片集合格式化成满足上传格式的数据 +//将集合格式化成满足上传格式的数据 fun ArrayList.reformat(): String { if (this.isEmpty()) return "" val builder = StringBuilder() diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt b/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt index 7c57643..aa9b92b 100644 --- a/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt +++ b/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt @@ -1,7 +1,6 @@ package com.casic.xz.meterage.extensions import android.content.Context -import android.util.Log import android.view.ViewGroup import com.casic.xz.meterage.base.BaseApplication import com.pengxh.kt.lite.extensions.dp2px @@ -9,9 +8,8 @@ fun Context.initLayoutImmersionBar(rootView: ViewGroup) { var statusBarHeight = QMUIDisplayHelper.getStatusBarHeight(this) - Log.d("Casic", "状态栏高度: $statusBarHeight") if (statusBarHeight == 0) { - statusBarHeight = 44f.dp2px(BaseApplication.get()) + statusBarHeight = 40f.dp2px(BaseApplication.get()) } rootView.setPadding(0, statusBarHeight, 0, 0) rootView.requestLayout() diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/String.kt b/app/src/main/java/com/casic/xz/meterage/extensions/String.kt index 28f70d8..6234d43 100644 --- a/app/src/main/java/com/casic/xz/meterage/extensions/String.kt +++ b/app/src/main/java/com/casic/xz/meterage/extensions/String.kt @@ -128,9 +128,10 @@ fun String.combineImagePath(): String { if (this.isEmpty()) return this val defaultValue = SaveKeyValues.getValue( - LocaleConstant.DEFAULT_SERVER_CONFIG, LocaleConstant.SERVER_BASE_URL + LocaleConstant.FILE_SERVER_CONFIG, LocaleConstant.File_SERVER_URL ) as String - return "$defaultValue/static/${this.replace("\\", "/")}" + //http://111.198.10.15:21408/test/1677479806059688_1677479806038.jpeg + return "$defaultValue/test/${this.replace("\\", "/")}" } fun String.isEarlier(time: String): Boolean { diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt index 25fa87b..a0e1358 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt @@ -1,18 +1,12 @@ package com.casic.xz.meterage.fragment.customer +import android.graphics.Color import android.graphics.Paint import com.casic.xz.meterage.R -import com.casic.xz.meterage.extensions.combineImagePath import com.casic.xz.meterage.extensions.toChineseGrade +import com.casic.xz.meterage.extensions.watchAttachFile import com.casic.xz.meterage.model.CustomerDetailModel -import com.casic.xz.meterage.view.BigImageActivity -import com.casic.xz.meterage.view.notice.PreviewDocumentActivity -import com.casic.xz.meterage.view.notice.PreviewPdfActivity -import com.casic.xz.meterage.view.notice.PreviewTextActivity import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.extensions.show import kotlinx.android.synthetic.main.fragment_customer_basic_information.* class BasicInformationFragment(private val data: CustomerDetailModel.DataModel) : @@ -48,30 +42,11 @@ val textPaint = minioFileView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - minioFileView.setTextColor(R.color.themeColor.convertColor(requireContext())) + minioFileView.setTextColor(Color.BLUE) minioFileView.setOnClickListener { //查看附件 - if (minioFileName.endsWith("pdf")) { - requireContext().navigatePageTo(minioFileName) - } else if ( - minioFileName.endsWith("doc") || - minioFileName.endsWith("docx") - ) { - requireContext().navigatePageTo(minioFileName) - } else if (minioFileName.endsWith("txt")) { - requireContext().navigatePageTo(minioFileName) - } else if ( - minioFileName.endsWith("png") || - minioFileName.endsWith("jpeg") || - minioFileName.endsWith("jpg") - ) { - val urls = ArrayList() - urls.add(minioFileName.combineImagePath()) - requireContext().navigatePageTo(0, urls) - } else { - "文件类型未知,无法打开附件".show(requireContext()) - } + minioFileName.watchAttachFile(requireContext()) } } } diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt index 77846b4..3a0fe2e 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt @@ -1,5 +1,6 @@ package com.casic.xz.meterage.fragment.device +import android.graphics.Color import android.graphics.Paint import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R @@ -7,7 +8,6 @@ import com.casic.xz.meterage.utils.LoadingDialogHub import com.casic.xz.meterage.vm.EquipmentViewModel import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor import com.pengxh.kt.lite.vm.LoadState import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import kotlinx.android.synthetic.main.fragment_device_basic_information.* @@ -56,7 +56,7 @@ val textPaint = documentsView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - documentsView.setTextColor(R.color.themeColor.convertColor(requireContext())) + documentsView.setTextColor(Color.BLUE) val files = ArrayList() data.fileList.forEach { file -> @@ -66,7 +66,7 @@ BottomActionSheet.Builder() .setContext(requireContext()) .setActionItemTitle(files) - .setItemTextColor(R.color.themeColor.convertColor(requireContext())) + .setItemTextColor(Color.BLUE) .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { override fun onActionItemClick(position: Int) { diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt index 15dc3d2..10eeff8 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt @@ -1,5 +1,6 @@ package com.casic.xz.meterage.fragment.entrust +import android.graphics.Color import android.graphics.Paint import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R @@ -9,7 +10,6 @@ import com.casic.xz.meterage.model.EntrustDetailModel import com.casic.xz.meterage.vm.DictionaryViewModel import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor import kotlinx.android.synthetic.main.fragment_entrust_basic_information.* class BasicInformationFragment(private val data: EntrustDetailModel.DataModel) : @@ -38,7 +38,7 @@ val textPaint = annexView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - annexView.setTextColor(R.color.themeColor.convertColor(requireContext())) + annexView.setTextColor(Color.BLUE) annexView.setOnClickListener { minioFileName.watchAttachFile(requireContext()) @@ -59,9 +59,9 @@ //加急 if (data.isUrgent == "0") { - RadioButton2.isChecked = true + radioButton2.isChecked = true } else { - RadioButton1.isChecked = true + radioButton1.isChecked = true } //样品 diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/equipment/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/equipment/BasicInformationFragment.kt index 72b523c..7bc3b01 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/equipment/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/equipment/BasicInformationFragment.kt @@ -1,5 +1,6 @@ package com.casic.xz.meterage.fragment.equipment +import android.graphics.Color import android.graphics.Paint import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R @@ -7,7 +8,6 @@ import com.casic.xz.meterage.utils.LoadingDialogHub import com.casic.xz.meterage.vm.EquipmentViewModel import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor import com.pengxh.kt.lite.vm.LoadState import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import kotlinx.android.synthetic.main.fragment_equipment_basic_information.* @@ -74,7 +74,7 @@ val textPaint = instructionsView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - instructionsView.setTextColor(R.color.themeColor.convertColor(requireContext())) + instructionsView.setTextColor(Color.BLUE) val files = ArrayList() data.fileList.forEach { file -> @@ -84,7 +84,7 @@ BottomActionSheet.Builder() .setContext(requireContext()) .setActionItemTitle(files) - .setItemTextColor(R.color.themeColor.convertColor(requireContext())) + .setItemTextColor(Color.BLUE) .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { override fun onActionItemClick(position: Int) { diff --git a/app/src/main/java/com/casic/xz/meterage/model/SampleListModel.java b/app/src/main/java/com/casic/xz/meterage/model/SampleListModel.java new file mode 100644 index 0000000..5784343 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/model/SampleListModel.java @@ -0,0 +1,193 @@ +package com.casic.xz.meterage.model; + +import java.util.List; + +public class SampleListModel { + + private int code; + private DataModel data; + private String message; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataModel getData() { + return data; + } + + public void setData(DataModel data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public static class DataModel { + private List rows; + private int total; + + public List getRows() { + return rows; + } + + public void setRows(List rows) { + this.rows = rows; + } + + public int getTotal() { + return total; + } + + public void setTotal(int total) { + this.total = total; + } + + public static class RowsModel { + private String certificationStatus; + private String customerName; + private String customerNo; + private String id; + private String manufacturingNo; + private String measureLastTime; + private String measurePeriod; + private String orderId; + private String remark; + private String sampleModel; + private String sampleName; + private String sampleNo; + private String sampleSatus; + private String sampleSatusName; + private String validDeadline; + + public String getCertificationStatus() { + return certificationStatus; + } + + public void setCertificationStatus(String certificationStatus) { + this.certificationStatus = certificationStatus; + } + + public String getCustomerName() { + return customerName; + } + + public void setCustomerName(String customerName) { + this.customerName = customerName; + } + + public String getCustomerNo() { + return customerNo; + } + + public void setCustomerNo(String customerNo) { + this.customerNo = customerNo; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getManufacturingNo() { + return manufacturingNo; + } + + public void setManufacturingNo(String manufacturingNo) { + this.manufacturingNo = manufacturingNo; + } + + public String getMeasureLastTime() { + return measureLastTime; + } + + public void setMeasureLastTime(String measureLastTime) { + this.measureLastTime = measureLastTime; + } + + public String getMeasurePeriod() { + return measurePeriod; + } + + public void setMeasurePeriod(String measurePeriod) { + this.measurePeriod = measurePeriod; + } + + public String getOrderId() { + return orderId; + } + + public void setOrderId(String orderId) { + this.orderId = orderId; + } + + public String getRemark() { + return remark; + } + + public void setRemark(String remark) { + this.remark = remark; + } + + public String getSampleModel() { + return sampleModel; + } + + public void setSampleModel(String sampleModel) { + this.sampleModel = sampleModel; + } + + public String getSampleName() { + return sampleName; + } + + public void setSampleName(String sampleName) { + this.sampleName = sampleName; + } + + public String getSampleNo() { + return sampleNo; + } + + public void setSampleNo(String sampleNo) { + this.sampleNo = sampleNo; + } + + public String getSampleSatus() { + return sampleSatus; + } + + public void setSampleSatus(String sampleSatus) { + this.sampleSatus = sampleSatus; + } + + public String getSampleSatusName() { + return sampleSatusName; + } + + public void setSampleSatusName(String sampleSatusName) { + this.sampleSatusName = sampleSatusName; + } + + public String getValidDeadline() { + return validDeadline; + } + + public void setValidDeadline(String validDeadline) { + this.validDeadline = validDeadline; + } + } + } +} diff --git a/app/src/main/java/com/casic/xz/meterage/model/UploadResultModel.java b/app/src/main/java/com/casic/xz/meterage/model/UploadResultModel.java new file mode 100644 index 0000000..f2a6a41 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/model/UploadResultModel.java @@ -0,0 +1,34 @@ +package com.casic.xz.meterage.model; + +import java.util.List; + +public class UploadResultModel { + + private int code; + private List data; + private String message; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public List getData() { + return data; + } + + public void setData(List data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } +} diff --git a/app/src/main/java/com/casic/xz/meterage/utils/FileType.kt b/app/src/main/java/com/casic/xz/meterage/utils/FileType.kt new file mode 100644 index 0000000..17e2bca --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/utils/FileType.kt @@ -0,0 +1,23 @@ +package com.casic.xz.meterage.utils + +sealed class FileType { + /** + * PDF文件 + */ + object PDF : FileType() + + /** + * WORD文件 + */ + object WORD : FileType() + + /** + * IMAGE图片 + */ + object IMAGE : FileType() + + /** + * 未知类型(Excel) + */ + object UNKNOWN : FileType() +} diff --git a/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitService.kt index bc3f8d6..8f4fe44 100644 --- a/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitService.kt @@ -1,5 +1,6 @@ package com.casic.xz.meterage.utils.retrofit +import okhttp3.MultipartBody import okhttp3.RequestBody import retrofit2.http.* @@ -35,6 +36,16 @@ ): String /** + * 上传文件 + */ + @Multipart + @POST("/minio/file/upload") + suspend fun uploadFile( + @Header("token") token: String, + @Part file: MultipartBody.Part + ): String + + /** * 获取通知公告列表 */ @POST("/system/notice/listPage") @@ -209,4 +220,24 @@ @Header("token") token: String, @Body requestBody: RequestBody ): String + + /** + * 获取样品列表 + */ + @POST("/customer/sample/listPage") + suspend fun getSampleList( + @Header("token") token: String, + @Body requestBody: RequestBody, + @QueryMap limit: Map, + @QueryMap offset: Map + ): String + + /** + * 新增委托书 + */ + @POST("/business/order/add") + suspend fun addEntrust( + @Header("token") token: String, + @Body requestBody: RequestBody + ): String } \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitServiceManager.kt index cb22e45..90abe5a 100644 --- a/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitServiceManager.kt @@ -1,13 +1,20 @@ package com.casic.xz.meterage.utils.retrofit +import com.alibaba.fastjson2.JSON +import com.alibaba.fastjson2.JSONArray +import com.alibaba.fastjson2.JSONObject +import com.casic.xz.meterage.model.SampleListModel import com.casic.xz.meterage.utils.AuthenticationHelper +import com.casic.xz.meterage.utils.FileType import com.casic.xz.meterage.utils.LocaleConstant import com.pengxh.kt.lite.utils.RetrofitFactory import com.pengxh.kt.lite.utils.SaveKeyValues import okhttp3.MediaType.Companion.toMediaType +import okhttp3.MediaType.Companion.toMediaTypeOrNull +import okhttp3.MultipartBody +import okhttp3.RequestBody.Companion.asRequestBody import okhttp3.RequestBody.Companion.toRequestBody -import org.json.JSONArray -import org.json.JSONObject +import java.io.File object RetrofitServiceManager { @@ -31,9 +38,9 @@ */ suspend fun login(sid: String, account: String, secretKey: String): String { val paramObject = JSONObject() - paramObject.put("sid", sid) - paramObject.put("username", account) - paramObject.put("password", secretKey) + paramObject["sid"] = sid + paramObject["username"] = account + paramObject["password"] = secretKey val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -55,6 +62,20 @@ } /** + * 上传文件 + */ + suspend fun uploadFile(file: File, type: FileType): String { + val requestBody = when (type) { + FileType.PDF -> file.asRequestBody("application/pdf".toMediaTypeOrNull()) + FileType.WORD -> file.asRequestBody("application/msword".toMediaTypeOrNull()) + FileType.IMAGE -> file.asRequestBody("image/png".toMediaTypeOrNull()) + else -> file.asRequestBody("application/vnd.ms-excel".toMediaTypeOrNull()) + } + val filePart = MultipartBody.Part.createFormData("multipartFile", file.name, requestBody) + return api.uploadFile(AuthenticationHelper.token!!, filePart) + } + + /** * 获取通知公告列表 */ suspend fun getNoticeList( @@ -66,11 +87,11 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("noticeNo", noticeNo) - paramObject.put("noticeTitle", noticeTitle) - paramObject.put("noticePublisher", noticePublisher) - paramObject.put("noticeStartTime", noticeStartTime) - paramObject.put("noticeEndTime", noticeEndTime) + paramObject["noticeNo"] = noticeNo + paramObject["noticeTitle"] = noticeTitle + paramObject["noticePublisher"] = noticePublisher + paramObject["noticeStartTime"] = noticeStartTime + paramObject["noticeEndTime"] = noticeEndTime val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -105,26 +126,21 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("equipmentNo", equipmentNo) - paramObject.put("equipmentName", equipmentName) - paramObject.put("mesureType", mesureType) - paramObject.put("managerState", managerState) - paramObject.put("useDept", useDept) - paramObject.put("assetType", assetType) - paramObject.put("equipmentCategory", equipmentCategory) - paramObject.put("isCalibrationTestEquipment", isCalibrationTestEquipment) - paramObject.put("isMeasureAccount", isMeasureAccount) - paramObject.put("isStandardSupportEquipment", isStandardSupportEquipment) - paramObject.put("isFixedAssets", isFixedAssets) - paramObject.put("validStartDate", validStartDate) - paramObject.put("validEndDate", validEndDate) - paramObject.put("abc", abc) - - val jsonArray = JSONArray() - ids.forEach { - jsonArray.put(it) - } - paramObject.put("ids", jsonArray) + paramObject["equipmentNo"] = equipmentNo + paramObject["equipmentName"] = equipmentName + paramObject["mesureType"] = mesureType + paramObject["managerState"] = managerState + paramObject["useDept"] = useDept + paramObject["assetType"] = assetType + paramObject["equipmentCategory"] = equipmentCategory + paramObject["isCalibrationTestEquipment"] = isCalibrationTestEquipment + paramObject["isMeasureAccount"] = isMeasureAccount + paramObject["isStandardSupportEquipment"] = isStandardSupportEquipment + paramObject["isFixedAssets"] = isFixedAssets + paramObject["validStartDate"] = validStartDate + paramObject["validEndDate"] = validEndDate + paramObject["abc"] = abc + paramObject["ids"] = JSONArray.parseArray(JSON.toJSONString(ids)) val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() @@ -143,7 +159,7 @@ */ suspend fun getEquipmentDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -164,13 +180,13 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("standardNo", standardNo) - paramObject.put("standardName", standardName) - paramObject.put("category", category) - paramObject.put("managerState", managerState) - paramObject.put("standardLaboratory", standardLaboratory) - paramObject.put("preparationDate", preparationDate) - paramObject.put("id", id) + paramObject["standardNo"] = standardNo + paramObject["standardName"] = standardName + paramObject["category"] = category + paramObject["managerState"] = managerState + paramObject["standardLaboratory"] = standardLaboratory + paramObject["preparationDate"] = preparationDate + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -193,7 +209,7 @@ */ suspend fun getStandardDeviceDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -212,11 +228,11 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("checkType", checkType) - paramObject.put("priceItem", priceItem) - paramObject.put("priceName", priceName) - paramObject.put("priceNo", priceNo) - paramObject.put("priceType", priceType) + paramObject["checkType"] = checkType + paramObject["priceItem"] = priceItem + paramObject["priceName"] = priceName + paramObject["priceNo"] = priceNo + paramObject["priceType"] = priceType val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -234,7 +250,7 @@ */ suspend fun getCapabilityDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -257,20 +273,15 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("createStartTime", createStartTime) - paramObject.put("createEndTime", createEndTime) - paramObject.put("deptId", deptId) - paramObject.put("director", director) - paramObject.put("effectiveCompany", effectiveCompany) - paramObject.put("trainStartTime", trainStartTime) - paramObject.put("trainEndTime", trainEndTime) - paramObject.put("formId", formId) - - val jsonArray = JSONArray() - ids.forEach { - jsonArray.put(it) - } - paramObject.put("ids", jsonArray) + paramObject["createStartTime"] = createStartTime + paramObject["createEndTime"] = createEndTime + paramObject["deptId"] = deptId + paramObject["director"] = director + paramObject["effectiveCompany"] = effectiveCompany + paramObject["trainStartTime"] = trainStartTime + paramObject["trainEndTime"] = trainEndTime + paramObject["formId"] = formId + paramObject["ids"] = JSONArray.parseArray(JSON.toJSONString(ids)) val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() @@ -294,7 +305,7 @@ */ suspend fun getMeterageTrainDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -308,10 +319,10 @@ bussinessSize: String, customerName: String, customerNo: String, grade: String, offset: Int ): String { val paramObject = JSONObject() - paramObject.put("bussinessSize", bussinessSize) - paramObject.put("customerName", customerName) - paramObject.put("customerNo", customerNo) - paramObject.put("grade", grade) + paramObject["bussinessSize"] = bussinessSize + paramObject["customerName"] = customerName + paramObject["customerNo"] = customerNo + paramObject["grade"] = grade val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() @@ -330,7 +341,7 @@ */ suspend fun getCustomerDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -342,7 +353,7 @@ */ suspend fun getStaffList(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -354,7 +365,7 @@ */ suspend fun getSupportEquipmentList(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -366,7 +377,7 @@ */ suspend fun getVerifyProcedureList(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -389,20 +400,15 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("customerName", customerName) - paramObject.put("customerNo", customerNo) - paramObject.put("deliverer", deliverer) - paramObject.put("orderCode", orderCode) - paramObject.put("startTime", startTime) - paramObject.put("endTime", endTime) - paramObject.put("isUrgent", isUrgent) - paramObject.put("status", status) - - val jsonArray = JSONArray() - ids.forEach { - jsonArray.put(it) - } - paramObject.put("ids", jsonArray) + paramObject["customerName"] = customerName + paramObject["customerNo"] = customerNo + paramObject["deliverer"] = deliverer + paramObject["orderCode"] = orderCode + paramObject["startTime"] = startTime + paramObject["endTime"] = endTime + paramObject["isUrgent"] = isUrgent + paramObject["status"] = status + paramObject["ids"] = JSONArray.parseArray(JSON.toJSONString(ids)) val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() @@ -421,7 +427,7 @@ */ suspend fun getEntrustDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -433,7 +439,7 @@ */ suspend fun acceptEntrust(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -446,10 +452,89 @@ */ suspend fun returnEntrust(id: String, selected: ArrayList): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) return api.returnEntrust(AuthenticationHelper.token!!, requestBody) } + + /** + * 获取样品列表 + */ + suspend fun getSampleList( + customerName: String, + customerNo: String, + startTime: String, + endTime: String, + sampleName: String, + sampleNo: String, + sampleModel: String, + sampleBelong: String, + overtimeStatus: String, + ids: Array, + offset: Int + ): String { + val paramObject = JSONObject() + paramObject["customerName"] = customerName + paramObject["customerNo"] = customerNo + paramObject["startTime"] = startTime + paramObject["endTime"] = endTime + paramObject["sampleName"] = sampleName + paramObject["sampleNo"] = sampleNo + paramObject["sampleModel"] = sampleModel + paramObject["sampleBelong"] = sampleBelong + paramObject["overtimeStatus"] = overtimeStatus + paramObject["ids"] = JSONArray.parseArray(JSON.toJSONString(ids)) + + val requestBody = paramObject.toString().toRequestBody( + "application/json;charset=UTF-8".toMediaType() + ) + + val limitMap = HashMap() + limitMap["limit"] = LocaleConstant.PAGE_LIMIT + + val offsetMap = HashMap() + offsetMap["offset"] = offset + return api.getSampleList(AuthenticationHelper.token!!, requestBody, limitMap, offsetMap) + } + + /** + * 新增委托书 + */ + suspend fun addEntrust( + deliverer: String, + delivererTel: String, + orderTime: String, + planDeliverTime: String, + requireOverTime: String, + customerName: String, + customerPhone: String, + customerAddress: String, + remark: String, + minioFileName: String, + certifications: String, + isUrgent: String, + samples: List + ): String { + val paramObject = JSONObject() + paramObject["deliverer"] = deliverer + paramObject["delivererTel"] = delivererTel + paramObject["orderTime"] = orderTime + paramObject["planDeliverTime"] = planDeliverTime + paramObject["requireOverTime"] = requireOverTime + paramObject["customerName"] = customerName + paramObject["customerPhone"] = customerPhone + paramObject["customerAddress"] = customerAddress + paramObject["remark"] = remark + paramObject["minioFileName"] = minioFileName + paramObject["certifications"] = certifications + paramObject["isUrgent"] = isUrgent + paramObject["customerSampleInfoList"] = JSONArray.parseArray(JSON.toJSONString(samples)) + + val requestBody = paramObject.toString().toRequestBody( + "application/json;charset=UTF-8".toMediaType() + ) + return api.addEntrust(AuthenticationHelper.token!!, requestBody) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/view/home/EntrustAddActivity.kt b/app/src/main/java/com/casic/xz/meterage/view/home/EntrustAddActivity.kt index 3e30095..9c8d27b 100644 --- a/app/src/main/java/com/casic/xz/meterage/view/home/EntrustAddActivity.kt +++ b/app/src/main/java/com/casic/xz/meterage/view/home/EntrustAddActivity.kt @@ -1,52 +1,211 @@ package com.casic.xz.meterage.view.home +import android.app.Activity +import android.content.Context +import android.content.Intent +import android.graphics.Color +import android.graphics.Paint import android.util.Log +import androidx.activity.result.ActivityResult +import androidx.activity.result.ActivityResultCallback +import androidx.activity.result.contract.ActivityResultContracts import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R import com.casic.xz.meterage.adapter.CertificateTypeAdapter2 -import com.casic.xz.meterage.extensions.initLayoutImmersionBar +import com.casic.xz.meterage.adapter.CustomerSampleAdapter +import com.casic.xz.meterage.callback.DateSelectedCallback +import com.casic.xz.meterage.callback.OnImageCompressListener +import com.casic.xz.meterage.extensions.* +import com.casic.xz.meterage.model.EntrustDetailModel +import com.casic.xz.meterage.model.SampleListModel +import com.casic.xz.meterage.utils.FileType +import com.casic.xz.meterage.utils.GlideLoadEngine +import com.casic.xz.meterage.utils.LoadingDialogHub import com.casic.xz.meterage.vm.DictionaryViewModel +import com.casic.xz.meterage.vm.EntrustViewModel +import com.casic.xz.meterage.vm.FileUploadViewModel +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken import com.gyf.immersionbar.ImmersionBar +import com.luck.picture.lib.basic.PictureSelector +import com.luck.picture.lib.config.SelectMimeType +import com.luck.picture.lib.entity.LocalMedia +import com.luck.picture.lib.interfaces.OnResultCallbackListener import com.pengxh.kt.lite.base.KotlinBaseActivity -import com.pengxh.kt.lite.extensions.toJson +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.vm.LoadState +import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import kotlinx.android.synthetic.main.activity_entrust_add.* +import java.io.File + class EntrustAddActivity : KotlinBaseActivity() { + private val context: Context = this@EntrustAddActivity + private val gson by lazy { Gson() } private lateinit var dictionaryViewModel: DictionaryViewModel - private var checkedItems = ArrayList() + private lateinit var fileUploadViewModel: FileUploadViewModel + private lateinit var entrustViewModel: EntrustViewModel + private lateinit var sampleAdapter: CustomerSampleAdapter + private var checkedItems = ArrayList() + private var isUrgent = "0" + private var sampleModels: ArrayList? = null + private var dataBeans = ArrayList() override fun initData() { //证书 dictionaryViewModel = ViewModelProvider(this)[DictionaryViewModel::class.java] dictionaryViewModel.getDictionaryByCode("certificationClass") - dictionaryViewModel.dictionary.observe(this) { dic -> - if (dic.code == 200) { - val typeAdapter2 = CertificateTypeAdapter2(this, dic.data) + dictionaryViewModel.dictionary.observe(this) { + if (it.code == 200) { + val typeAdapter2 = CertificateTypeAdapter2(this, it.data) typeRecyclerView.adapter = typeAdapter2 typeAdapter2.setOnItemCheckedListener(object : CertificateTypeAdapter2.OnItemCheckedListener { override fun onItemChecked(position: Int, isChecked: Boolean) { if (isChecked) { - checkedItems.add(position) + checkedItems.add(position.toString()) } else { - checkedItems.remove(position) + checkedItems.remove(position.toString()) } } }) } } + + fileUploadViewModel = ViewModelProvider(this)[FileUploadViewModel::class.java] + fileUploadViewModel.resultModel.observe(this) { + if (it.code == 200) { + val annexName = it.data[0] + annexView.text = annexName + val textPaint = annexView.paint + textPaint.flags = Paint.UNDERLINE_TEXT_FLAG + textPaint.isAntiAlias = true + annexView.setTextColor(Color.BLUE) + + annexView.setOnClickListener { + annexName.watchAttachFile(this) + } + } + } + + entrustViewModel = ViewModelProvider(this)[EntrustViewModel::class.java] + entrustViewModel.addResult.observe(this) { + if (it.code == 200) { + finish() + } + } + + //样品列表 + sampleAdapter = CustomerSampleAdapter(this, dataBeans) + sampleRecyclerView.adapter = sampleAdapter } + private val selectCustomerLauncher = + registerForActivityResult(ActivityResultContracts.StartActivityForResult(), + object : ActivityResultCallback { + override fun onActivityResult(result: ActivityResult?) { + if (result?.resultCode == Activity.RESULT_OK) { + val data = result.data ?: return + + entrustNameView.text = data.getStringExtra("entrustName") + entrustContactView.text = data.getStringExtra("entrustContact") + entrustAddressView.text = data.getStringExtra("entrustAddress") + } + } + }) + + private val selectSampleLauncher = + registerForActivityResult(ActivityResultContracts.StartActivityForResult(), + object : ActivityResultCallback { + override fun onActivityResult(result: ActivityResult?) { + if (result?.resultCode == Activity.RESULT_OK) { + val data = result.data ?: return + + val modelsJson = data.getStringExtra("sampleModels") + if (!modelsJson.isNullOrBlank()) { + sampleModels = gson.fromJson( + modelsJson, + object : + TypeToken>() {}.type + ) + } + + //刷新列表 + dataBeans.clear() + sampleModels?.forEach { + val model = + EntrustDetailModel.DataModel.CustomerSampleInfoListModel() + + model.customerName = it.customerName + model.customerNo = it.customerNo + model.id = it.id + model.manufacturingNo = it.manufacturingNo + model.measureLastTime = it.measureLastTime + model.measurePeriod = it.measurePeriod + model.orderId = it.orderId + model.remark = it.remark + model.sampleModel = it.sampleModel + model.sampleName = it.sampleName + model.sampleNo = it.sampleNo + model.validDeadline = it.validDeadline + + dataBeans.add(model) + } + sampleAdapter.notifyDataSetChanged() + } + } + }) + override fun initEvent() { + leftBackView.setOnClickListener { finish() } + + estimateTimeView.setOnClickListener { + showDatePicker(object : DateSelectedCallback { + override fun onDateSelected(date: String) { + estimateTimeView.text = date + } + }) + } + + completedView.setOnClickListener { + showDatePicker(object : DateSelectedCallback { + override fun onDateSelected(date: String) { + completedView.text = date + } + }) + } + + entrustNameView.setOnClickListener { + selectCustomerLauncher.launch(Intent(this, SelectCustomerActivity::class.java)) + } + //上传附件 uploadFileButton.setOnClickListener { + BottomActionSheet.Builder() + .setContext(this) + .setItemTextColor(Color.BLUE) + .setActionItemTitle(listOf("文件", "图片")) + .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { + override fun onActionItemClick(position: Int) { + when (position) { + 0 -> uploadFile() + 1 -> uploadImage() + } + } + }).build().show() + } + radioGroup.setOnCheckedChangeListener { _, checkedId -> + when (checkedId) { + R.id.radioButton1 -> isUrgent = "1" + R.id.radioButton2 -> isUrgent = "0" + } } //选择样品 selectSampleButton.setOnClickListener { - + selectSampleLauncher.launch(Intent(this, SelectSampleActivity::class.java)) } //写入样品信息 @@ -55,14 +214,68 @@ } pushEntrustView.setOnClickListener { - Log.d("Casic", "EntrustAddActivity => initEvent: ${checkedItems.toJson()}") + val sender = senderView.text.toString() + if (sender.isBlank()) { + "请填写送样人名字".show(this) + return@setOnClickListener + } + + val contact = contactView.text.toString() + if (contact.isBlank()) { + "请填写送样人联系方式".show(this) + return@setOnClickListener + } + + val estimateTime = estimateTimeView.text.toString() + if (estimateTime.isBlank()) { + "请选择预计送到的时间".show(this) + return@setOnClickListener + } + + val entrustName = entrustNameView.text.toString() + if (entrustName.isBlank()) { + "请选择委托方".show(this) + return@setOnClickListener + } + + if (sampleModels == null) { + "请选择样品".show(this) + return@setOnClickListener + } + entrustViewModel.addEntrust( + sender, + contact, + createEntrustDateView.text.toString(), + estimateTime, + completedView.text.toString(), + entrustName, + entrustContactView.text.toString(), + entrustAddressView.text.toString(), + remarkView.text.toString(), + annexView.text.toString(), + checkedItems.reformat(), + isUrgent, + sampleModels!! + ) } } override fun initLayoutView(): Int = R.layout.activity_entrust_add override fun observeRequestState() { + fileUploadViewModel.loadState.observe(this) { + when (it) { + LoadState.Loading -> LoadingDialogHub.show(this, "文件上传中,请稍后...") + else -> LoadingDialogHub.dismiss() + } + } + entrustViewModel.loadState.observe(this) { + when (it) { + LoadState.Loading -> LoadingDialogHub.show(this, "委托创建中,请稍后...") + else -> LoadingDialogHub.dismiss() + } + } } override fun setupTopBarLayout() { @@ -70,4 +283,62 @@ initLayoutImmersionBar(rootView) titleView.text = "委托需求" } + + private fun uploadFile() { +// val explorer = FileExplorer(this) +// explorer.setInitDir(ExplorerMode.FILE, Environment.getExternalStorageDirectory()) +// explorer.setShowHomeDir(true) +// explorer.setShowUpDir(true) +// explorer.setShowHideDir(true) +// explorer.setAllowExtensions(arrayOf(".doc", ".docx", ".xls", ".xlsx", ".pdf")) +// explorer.setOnFileClickedListener { +// val type = if (it.name.endsWith(".doc") || it.name.endsWith(".docx")) { +// FileType.WORD +// } else if (it.name.endsWith(".pdf")) { +// FileType.PDF +// } else { +// FileType.UNKNOWN +// } +// +// Log.d("Casic", "EntrustAddActivity => uploadFile: ${it.absolutePath}") +// fileUploadViewModel.uploadFile(it, type) +// } + } + + private fun uploadImage() { + PictureSelector.create(this) + .openGallery(SelectMimeType.ofImage()) + .isGif(false) + .isMaxSelectEnabledMask(true) + .setFilterMinFileSize(100) + .setMaxSelectNum(1) + .isDisplayCamera(false) + .setImageEngine(GlideLoadEngine.instance) + .forResult(object : OnResultCallbackListener { + override fun onResult(result: ArrayList?) { + if (result == null) { + "选择照片失败,请重试".show(context) + return + } + result[0].realPath.compressImage(context, object : OnImageCompressListener { + override fun onSuccess(file: File) { + Log.d( + "Casic", "EntrustAddActivity => onSuccess: ${file.absolutePath}" + ) + ///storage/emulated/0/Android/data/com.casic.xz.meterage/files/Pictures/CompressImage/1677478115391211.jpeg + //上传图片 + fileUploadViewModel.uploadFile(file, FileType.IMAGE) + } + + override fun onError(e: Throwable) { + e.printStackTrace() + } + }) + } + + override fun onCancel() { + + } + }) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/view/home/SelectCustomerActivity.kt b/app/src/main/java/com/casic/xz/meterage/view/home/SelectCustomerActivity.kt new file mode 100644 index 0000000..9bf6a1a --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/view/home/SelectCustomerActivity.kt @@ -0,0 +1,158 @@ +package com.casic.xz.meterage.view.home + +import android.content.Intent +import android.os.Handler +import androidx.lifecycle.ViewModelProvider +import androidx.recyclerview.widget.DefaultItemAnimator +import androidx.recyclerview.widget.DividerItemDecoration +import com.casic.xz.meterage.R +import com.casic.xz.meterage.adapter.SelectCustomerAdapter +import com.casic.xz.meterage.extensions.initLayoutImmersionBar +import com.casic.xz.meterage.extensions.showEmptyPage +import com.casic.xz.meterage.model.CustomerListModel +import com.casic.xz.meterage.utils.LoadingDialogHub +import com.casic.xz.meterage.vm.CustomerViewModel +import com.gyf.immersionbar.ImmersionBar +import com.pengxh.kt.lite.base.KotlinBaseActivity +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.utils.WeakReferenceHandler +import com.pengxh.kt.lite.vm.LoadState +import kotlinx.android.synthetic.main.activity_select_customer.* +import kotlinx.android.synthetic.main.include_base_title.* +import kotlinx.android.synthetic.main.include_empty_view.* + +class SelectCustomerActivity : KotlinBaseActivity() { + + private lateinit var weakReferenceHandler: WeakReferenceHandler + private lateinit var customerViewModel: CustomerViewModel + private lateinit var selectCustomerAdapter: SelectCustomerAdapter + private var dataBeans: MutableList = ArrayList() + private var pageIndex = 1 + private var isRefresh = false + private var isLoadMore = false + private var customerModel: CustomerListModel.DataModel.RowsModel? = null + + override fun initData() { + weakReferenceHandler = WeakReferenceHandler(callback) + customerViewModel = ViewModelProvider(this)[CustomerViewModel::class.java] + customerViewModel.customerList.observe(this) { + if (it.code == 200) { + val dataRows = it.data?.rows!! + when { + isRefresh -> { + dataBeans.clear() + dataBeans = dataRows + customerLayout.finishRefresh() + isRefresh = false + } + isLoadMore -> { + if (dataRows.size == 0) { + "到底了,别拉了".show(this) + } + dataBeans.addAll(dataRows) + customerLayout.finishLoadMore() + isLoadMore = false + } + else -> { + dataBeans = dataRows + } + } + weakReferenceHandler.sendEmptyMessage(2023022701) + } + } + } + + override fun initEvent() { + leftBackView.setOnClickListener { + if (customerModel == null) { + "请选择委托方".show(this) + return@setOnClickListener + } + val intent = Intent() + intent.putExtra("entrustName", customerModel!!.customerName) + intent.putExtra("entrustContact", customerModel!!.phone) + intent.putExtra("entrustAddress", customerModel!!.fullAddress) + setResult(RESULT_OK, intent) + finish() + } + + customerLayout.setOnRefreshListener { + isRefresh = true + //刷新之后页码重置 + pageIndex = 1 + getCustomerList() + } + + customerLayout.setOnLoadMoreListener { + isLoadMore = true + pageIndex++ + getCustomerList() + } + } + + override fun initLayoutView(): Int = R.layout.activity_select_customer + + override fun observeRequestState() { + customerViewModel.loadState.observe(this) { + when (it) { + LoadState.Loading -> LoadingDialogHub.show(this, "数据加载中...") + else -> LoadingDialogHub.dismiss() + } + } + } + + override fun setupTopBarLayout() { + ImmersionBar.with(this).statusBarDarkFont(true).init() + initLayoutImmersionBar(rootView) + titleView.text = "客户列表" + } + + override fun onResume() { + super.onResume() + pageIndex = 1 + getCustomerList() + } + + private fun getCustomerList() { + customerViewModel.getCustomerList( + "", + "", + "", + "", + pageIndex + ) + } + + private val callback = Handler.Callback { + when (it.what) { + 2023022701 -> { + if (isRefresh || isLoadMore) { + selectCustomerAdapter.notifyDataSetChanged() + } else { + if (dataBeans.size == 0) { + emptyView!!.showEmptyPage("无客户数据") { + pageIndex = 1 + getCustomerList() + } + } else { + emptyView!!.hide() + selectCustomerAdapter = SelectCustomerAdapter(this, dataBeans) + customerRecyclerView.addItemDecoration( + DividerItemDecoration(this, DividerItemDecoration.VERTICAL) + ) + (customerRecyclerView.itemAnimator as DefaultItemAnimator).supportsChangeAnimations = + false + customerRecyclerView.adapter = selectCustomerAdapter + selectCustomerAdapter.setOnCheckedListener(object : + SelectCustomerAdapter.OnItemCheckedListener { + override fun onItemChecked(item: CustomerListModel.DataModel.RowsModel) { + customerModel = item + } + }) + } + } + } + } + true + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/view/home/SelectSampleActivity.kt b/app/src/main/java/com/casic/xz/meterage/view/home/SelectSampleActivity.kt new file mode 100644 index 0000000..f85cb44 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/view/home/SelectSampleActivity.kt @@ -0,0 +1,152 @@ +package com.casic.xz.meterage.view.home + +import android.content.Intent +import android.os.Handler +import androidx.lifecycle.ViewModelProvider +import androidx.recyclerview.widget.DefaultItemAnimator +import androidx.recyclerview.widget.DividerItemDecoration +import com.casic.xz.meterage.R +import com.casic.xz.meterage.adapter.SelectSampleAdapter +import com.casic.xz.meterage.extensions.initLayoutImmersionBar +import com.casic.xz.meterage.extensions.showEmptyPage +import com.casic.xz.meterage.model.SampleListModel +import com.casic.xz.meterage.vm.SampleViewModel +import com.gyf.immersionbar.ImmersionBar +import com.pengxh.kt.lite.base.KotlinBaseActivity +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.extensions.toJson +import com.pengxh.kt.lite.utils.WeakReferenceHandler +import kotlinx.android.synthetic.main.activity_select_sample.* +import kotlinx.android.synthetic.main.include_base_title.* +import kotlinx.android.synthetic.main.include_empty_view.* + +class SelectSampleActivity : KotlinBaseActivity() { + + private lateinit var weakReferenceHandler: WeakReferenceHandler + private lateinit var sampleViewModel: SampleViewModel + private lateinit var selectSampleAdapter: SelectSampleAdapter + private var dataBeans: MutableList = ArrayList() + private var pageIndex = 1 + private var isRefresh = false + private var isLoadMore = false + private var sampleModels = ArrayList() + + override fun initData() { + weakReferenceHandler = WeakReferenceHandler(callback) + sampleViewModel = ViewModelProvider(this)[SampleViewModel::class.java] + sampleViewModel.sampleList.observe(this) { + if (it.code == 200) { + val dataRows = it.data?.rows!! + when { + isRefresh -> { + dataBeans.clear() + dataBeans = dataRows + sampleLayout.finishRefresh() + isRefresh = false + } + isLoadMore -> { + if (dataRows.size == 0) { + "到底了,别拉了".show(this) + } + dataBeans.addAll(dataRows) + sampleLayout.finishLoadMore() + isLoadMore = false + } + else -> { + dataBeans = dataRows + } + } + weakReferenceHandler.sendEmptyMessage(2023030101) + } + } + } + + override fun initEvent() { + leftBackView.setOnClickListener { + val intent = Intent() + intent.putExtra("sampleModels", sampleModels.toJson()) + setResult(RESULT_OK, intent) + finish() + } + + sampleLayout.setOnRefreshListener { + isRefresh = true + //刷新之后页码重置 + pageIndex = 1 + getSampleList() + } + + sampleLayout.setOnLoadMoreListener { + isLoadMore = true + pageIndex++ + getSampleList() + } + } + + override fun initLayoutView(): Int = R.layout.activity_select_sample + + override fun observeRequestState() { + + } + + override fun setupTopBarLayout() { + ImmersionBar.with(this).statusBarDarkFont(true).init() + initLayoutImmersionBar(rootView) + titleView.text = "样品列表" + } + + override fun onResume() { + super.onResume() + pageIndex = 1 + getSampleList() + } + + private fun getSampleList() { + sampleViewModel.getSampleList( + "", + "", + "", + "", + "", + "", + "", + "", + "", + arrayOf(), + pageIndex + ) + } + + private val callback = Handler.Callback { + when (it.what) { + 2023030101 -> { + if (isRefresh || isLoadMore) { + selectSampleAdapter.notifyDataSetChanged() + } else { + if (dataBeans.size == 0) { + emptyView!!.showEmptyPage("无样品数据") { + pageIndex = 1 + getSampleList() + } + } else { + emptyView!!.hide() + selectSampleAdapter = SelectSampleAdapter(this, dataBeans) + sampleRecyclerView.addItemDecoration( + DividerItemDecoration(this, DividerItemDecoration.VERTICAL) + ) + (sampleRecyclerView.itemAnimator as DefaultItemAnimator).supportsChangeAnimations = + false + sampleRecyclerView.adapter = selectSampleAdapter + selectSampleAdapter.setOnCheckedListener(object : + SelectSampleAdapter.OnItemCheckedListener { + override fun onItemChecked(items: ArrayList) { + sampleModels = items + } + }) + } + } + } + } + true + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/view/notice/NoticeDetailActivity.kt b/app/src/main/java/com/casic/xz/meterage/view/notice/NoticeDetailActivity.kt index a9d9422..9596985 100644 --- a/app/src/main/java/com/casic/xz/meterage/view/notice/NoticeDetailActivity.kt +++ b/app/src/main/java/com/casic/xz/meterage/view/notice/NoticeDetailActivity.kt @@ -1,6 +1,7 @@ package com.casic.xz.meterage.view.notice import android.annotation.SuppressLint +import android.graphics.Color import android.graphics.Paint import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R @@ -10,7 +11,6 @@ import com.casic.xz.meterage.vm.NoticeViewModel import com.gyf.immersionbar.ImmersionBar import com.pengxh.kt.lite.base.KotlinBaseActivity -import com.pengxh.kt.lite.extensions.convertColor import com.pengxh.kt.lite.extensions.obtainScreenWidth import com.pengxh.kt.lite.utils.Constant import kotlinx.android.synthetic.main.activity_notice_detail.* @@ -54,7 +54,7 @@ val textPaint = minioFileView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - minioFileView.setTextColor(R.color.themeColor.convertColor(this)) + minioFileView.setTextColor(Color.BLUE) minioFileView.setOnClickListener { minioFileName.watchAttachFile(this) diff --git a/app/src/main/java/com/casic/xz/meterage/vm/EntrustViewModel.kt b/app/src/main/java/com/casic/xz/meterage/vm/EntrustViewModel.kt index 2280f88..103c002 100644 --- a/app/src/main/java/com/casic/xz/meterage/vm/EntrustViewModel.kt +++ b/app/src/main/java/com/casic/xz/meterage/vm/EntrustViewModel.kt @@ -7,6 +7,7 @@ import com.casic.xz.meterage.model.ActionResultModel import com.casic.xz.meterage.model.EntrustDetailModel import com.casic.xz.meterage.model.EntrustListModel +import com.casic.xz.meterage.model.SampleListModel import com.casic.xz.meterage.utils.retrofit.RetrofitServiceManager import com.google.gson.Gson import com.google.gson.reflect.TypeToken @@ -25,6 +26,7 @@ val entrustDetail = MutableLiveData() val acceptResult = MutableLiveData() val returnResult = MutableLiveData() + val addResult = MutableLiveData() fun getEntrustList( customerName: String, @@ -119,4 +121,50 @@ loadState.value = LoadState.Fail it.cause.toString().show(BaseApplication.get()) }) + + fun addEntrust( + deliverer: String, + delivererTel: String, + orderTime: String, + planDeliverTime: String, + requireOverTime: String, + customerName: String, + customerPhone: String, + customerAddress: String, + remark: String, + minioFileName: String, + certifications: String, + isUrgent: String, + samples: List + ) = launch({ + loadState.value = LoadState.Loading + val response = RetrofitServiceManager.addEntrust( + deliverer, + delivererTel, + orderTime, + planDeliverTime, + requireOverTime, + customerName, + customerPhone, + customerAddress, + remark, + minioFileName, + certifications, + isUrgent, + samples + ) + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + loadState.value = LoadState.Success + addResult.value = gson.fromJson( + response, object : TypeToken() {}.type + ) + } else { + loadState.value = LoadState.Fail + response.toErrorMessage().show(BaseApplication.get()) + } + }, { + loadState.value = LoadState.Fail + it.cause.toString().show(BaseApplication.get()) + }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/vm/FileUploadViewModel.kt b/app/src/main/java/com/casic/xz/meterage/vm/FileUploadViewModel.kt new file mode 100644 index 0000000..b16c1c7 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/vm/FileUploadViewModel.kt @@ -0,0 +1,40 @@ +package com.casic.xz.meterage.vm + +import androidx.lifecycle.MutableLiveData +import com.casic.xz.meterage.base.BaseApplication +import com.casic.xz.meterage.extensions.separateResponseCode +import com.casic.xz.meterage.extensions.toErrorMessage +import com.casic.xz.meterage.model.UploadResultModel +import com.casic.xz.meterage.utils.FileType +import com.casic.xz.meterage.utils.retrofit.RetrofitServiceManager +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken +import com.pengxh.kt.lite.extensions.launch +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.vm.BaseViewModel +import com.pengxh.kt.lite.vm.LoadState +import java.io.File + +class FileUploadViewModel : BaseViewModel() { + + private val gson by lazy { Gson() } + val resultModel = MutableLiveData() + + fun uploadFile(file: File, type: FileType) = launch({ + loadState.value = LoadState.Loading + val response = RetrofitServiceManager.uploadFile(file, type) + 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(BaseApplication.get()) + } + }, { + loadState.value = LoadState.Fail + it.cause.toString().show(BaseApplication.get()) + }) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/vm/SampleViewModel.kt b/app/src/main/java/com/casic/xz/meterage/vm/SampleViewModel.kt new file mode 100644 index 0000000..182140d --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/vm/SampleViewModel.kt @@ -0,0 +1,65 @@ +package com.casic.xz.meterage.vm + +import androidx.lifecycle.MutableLiveData +import com.casic.xz.meterage.base.BaseApplication +import com.casic.xz.meterage.extensions.separateResponseCode +import com.casic.xz.meterage.extensions.toErrorMessage +import com.casic.xz.meterage.model.SampleListModel +import com.casic.xz.meterage.utils.retrofit.RetrofitServiceManager +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken +import com.pengxh.kt.lite.extensions.launch +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.vm.BaseViewModel +import com.pengxh.kt.lite.vm.LoadState + +/** + * 样品相关 VM + * */ +class SampleViewModel : BaseViewModel() { + + private val gson by lazy { Gson() } + val sampleList = MutableLiveData() + + fun getSampleList( + customerName: String, + customerNo: String, + startTime: String, + endTime: String, + sampleName: String, + sampleNo: String, + sampleModel: String, + sampleBelong: String, + overtimeStatus: String, + ids: Array, + offset: Int + ) = launch({ + loadState.value = LoadState.Loading + val response = RetrofitServiceManager.getSampleList( + customerName, + customerNo, + startTime, + endTime, + sampleName, + sampleNo, + sampleModel, + sampleBelong, + overtimeStatus, + ids, + offset + ) + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + loadState.value = LoadState.Success + sampleList.value = gson.fromJson( + response, object : TypeToken() {}.type + ) + } else { + loadState.value = LoadState.Fail + response.toErrorMessage().show(BaseApplication.get()) + } + }, { + loadState.value = LoadState.Fail + it.cause.toString().show(BaseApplication.get()) + }) +} \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_customer_selector.xml b/app/src/main/res/drawable/bg_customer_selector.xml new file mode 100644 index 0000000..e7292d5 --- /dev/null +++ b/app/src/main/res/drawable/bg_customer_selector.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_sample_selector.xml b/app/src/main/res/drawable/bg_sample_selector.xml new file mode 100644 index 0000000..6b5d5e7 --- /dev/null +++ b/app/src/main/res/drawable/bg_sample_selector.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_check_selected.xml b/app/src/main/res/drawable/ic_check_selected.xml new file mode 100644 index 0000000..4d93f9f --- /dev/null +++ b/app/src/main/res/drawable/ic_check_selected.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_entrust_add.xml b/app/src/main/res/layout/activity_entrust_add.xml index 3d00784..8450d1d 100644 --- a/app/src/main/res/layout/activity_entrust_add.xml +++ b/app/src/main/res/layout/activity_entrust_add.xml @@ -68,6 +68,7 @@ android:text="送样人" /> @@ -81,6 +82,7 @@ android:text="联系方式" /> @@ -115,10 +117,10 @@ style="@style/textViewStyle" android:text="预计送到时间" /> - + android:hint="请选择预计送到时间" /> @@ -129,10 +131,10 @@ style="@style/textViewStyle" android:text="要求检完时间" /> - + android:hint="请选择要求检完时间" /> @@ -143,10 +145,10 @@ style="@style/textViewStyle" android:text="委托方名称" /> - + android:hint="请选择委托方" /> @@ -157,10 +159,9 @@ style="@style/textViewStyle" android:text="委托方电话" /> - + @@ -171,10 +172,9 @@ style="@style/textViewStyle" android:text="委托方地址" /> - + @@ -186,9 +186,9 @@ android:text="备注" /> + android:hint="请输入" /> @@ -200,6 +200,7 @@ android:text="附件" /> diff --git a/app/src/main/res/layout/activity_select_customer.xml b/app/src/main/res/layout/activity_select_customer.xml new file mode 100644 index 0000000..01f5ca1 --- /dev/null +++ b/app/src/main/res/layout/activity_select_customer.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 0ae369f..687b02b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -15,7 +15,6 @@ } compileSdkVersion 31 - buildToolsVersion "30.0.3" defaultConfig { applicationId "com.casic.xz.meterage" @@ -84,11 +83,13 @@ implementation 'top.zibin:Luban:1.1.8' //官方Json解析库 implementation 'com.google.code.gson:gson:2.9.0' + //阿里巴巴JSON库 + implementation 'com.alibaba.fastjson2:fastjson2:2.0.24' //Kotlin协程 implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.5.1' //MVVM+LiveData implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.5.1" - implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.0" + implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1" implementation "androidx.lifecycle:lifecycle-extensions:2.2.0" //返回值转换器 implementation 'com.jakewharton.retrofit:retrofit2-kotlin-coroutines-adapter:0.9.2' @@ -109,4 +110,8 @@ implementation 'com.github.barteksc:android-pdf-viewer:2.8.2' //绕过Android 11反射限制 implementation 'com.github.tiann:FreeReflection:3.1.0' + //单项/数字、二三级联动、日期/时间等滚轮选择器 + implementation 'com.github.gzu-liyujiang.AndroidPicker:WheelPicker:4.1.8' + //文件/目录选择器 + implementation 'com.github.gzu-liyujiang.AndroidPicker:FilePicker:4.1.1' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 1ccc12b..0fba91b 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -60,6 +60,8 @@ + + diff --git a/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt b/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt new file mode 100644 index 0000000..21a71d8 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt @@ -0,0 +1,70 @@ +package com.casic.xz.meterage.adapter + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import com.casic.xz.meterage.R +import com.casic.xz.meterage.extensions.toChineseGrade +import com.casic.xz.meterage.model.CustomerListModel + +class SelectCustomerAdapter( + context: Context, private val dataRows: MutableList +) : RecyclerView.Adapter() { + + private var layoutInflater = LayoutInflater.from(context) + + //选择的位置 + private var selectedPosition = 0 + + //临时记录上次选择的位置 + private var temp = -1 + + override fun getItemCount(): Int = dataRows.size + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ItemViewHolder( + layoutInflater.inflate(R.layout.item_select_customer_lv, parent, false) + ) + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + //绑定数据 + val rowsBean = dataRows[position] + holder.agreementLevelView.text = rowsBean.grade.toChineseGrade() + holder.customerNameView.text = rowsBean.customerName + holder.scaleView.text = rowsBean.companySizeName + holder.overallView.text = "公司规模:${rowsBean.evaluationName}" + holder.fullAddressView.text = "公司地址:${rowsBean.fullAddress}" + + holder.itemView.isSelected = holder.layoutPosition == selectedPosition + holder.itemView.setOnClickListener { + itemCheckedListener?.onItemChecked(rowsBean) + + holder.itemView.isSelected = true + temp = selectedPosition + //设置新的位置 + selectedPosition = holder.layoutPosition + //更新旧位置 + notifyItemChanged(temp) + } + } + + inner class ItemViewHolder(view: View) : RecyclerView.ViewHolder(view) { + var agreementLevelView: TextView = view.findViewById(R.id.agreementLevelView) + var customerNameView: TextView = view.findViewById(R.id.customerNameView) + var scaleView: TextView = view.findViewById(R.id.scaleView) + var overallView: TextView = view.findViewById(R.id.overallView) + var fullAddressView: TextView = view.findViewById(R.id.fullAddressView) + } + + private var itemCheckedListener: OnItemCheckedListener? = null + + interface OnItemCheckedListener { + fun onItemChecked(item: CustomerListModel.DataModel.RowsModel) + } + + fun setOnCheckedListener(listener: OnItemCheckedListener?) { + itemCheckedListener = listener + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt b/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt new file mode 100644 index 0000000..c29461e --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt @@ -0,0 +1,68 @@ +package com.casic.xz.meterage.adapter + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import com.casic.xz.meterage.R +import com.casic.xz.meterage.model.SampleListModel + +class SelectSampleAdapter( + context: Context, private val dataRows: MutableList +) : RecyclerView.Adapter() { + + private var layoutInflater = LayoutInflater.from(context) + private var multipleSelected = mutableSetOf() + private var sampleModes = ArrayList() + + override fun getItemCount(): Int = dataRows.size + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ItemViewHolder( + layoutInflater.inflate(R.layout.item_select_sample_lv, parent, false) + ) + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + //绑定数据 + val rowsBean = dataRows[position] + holder.sampleNameView.text = "${rowsBean.sampleName}【${rowsBean.sampleModel}】" + holder.manufacturingCodeView.text = "出厂编号:${rowsBean.manufacturingNo}" + holder.sampleCodeView.text = "样品编号:${rowsBean.sampleNo}" + holder.validDateView.text = "有效期至:${rowsBean.validDeadline}" + + holder.checkImageView.isSelected = multipleSelected.contains(position) + holder.itemView.setOnClickListener { + if (multipleSelected.contains(position)) { + multipleSelected.remove(position) + sampleModes.remove(dataRows[position]) + holder.checkImageView.isSelected = false + } else { + multipleSelected.add(position) + sampleModes.add(dataRows[position]) + holder.checkImageView.isSelected = true + } + + itemCheckedListener?.onItemChecked(sampleModes) + } + } + + inner class ItemViewHolder(view: View) : RecyclerView.ViewHolder(view) { + var sampleNameView: TextView = view.findViewById(R.id.sampleNameView) + var manufacturingCodeView: TextView = view.findViewById(R.id.manufacturingCodeView) + var sampleCodeView: TextView = view.findViewById(R.id.sampleCodeView) + var validDateView: TextView = view.findViewById(R.id.validDateView) + var checkImageView: ImageView = view.findViewById(R.id.checkImageView) + } + + private var itemCheckedListener: OnItemCheckedListener? = null + + interface OnItemCheckedListener { + fun onItemChecked(items: ArrayList) + } + + fun setOnCheckedListener(listener: OnItemCheckedListener?) { + itemCheckedListener = listener + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/callback/DateSelectedCallback.kt b/app/src/main/java/com/casic/xz/meterage/callback/DateSelectedCallback.kt new file mode 100644 index 0000000..8196110 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/callback/DateSelectedCallback.kt @@ -0,0 +1,5 @@ +package com.casic.xz.meterage.callback + +interface DateSelectedCallback { + fun onDateSelected(date: String) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/Activity.kt b/app/src/main/java/com/casic/xz/meterage/extensions/Activity.kt new file mode 100644 index 0000000..e112d1c --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/extensions/Activity.kt @@ -0,0 +1,33 @@ +package com.casic.xz.meterage.extensions + +import android.app.Activity +import com.casic.xz.meterage.R +import com.casic.xz.meterage.callback.DateSelectedCallback +import com.github.gzuliyujiang.wheelpicker.DatePicker +import com.github.gzuliyujiang.wheelpicker.annotation.DateMode +import com.github.gzuliyujiang.wheelpicker.entity.DateEntity +import com.pengxh.kt.lite.extensions.convertColor +import com.pengxh.kt.lite.extensions.sp2px + +fun Activity.showDatePicker(callback: DateSelectedCallback) { + val datePicker = DatePicker(this) + + val layout = datePicker.wheelLayout + layout.setDateMode(DateMode.YEAR_MONTH_DAY) + layout.setDateLabel("年", "月", "日"); + layout.setTextSize(14f.sp2px(this).toFloat()) + layout.setSelectedTextSize(16f.sp2px(this).toFloat()) + layout.setSelectedTextColor(R.color.themeColor.convertColor(this)) + layout.setSelectedTextBold(true) + layout.setResetWhenLinkage(false) + layout.setRange( + DateEntity.today(), + DateEntity.target(2050, 12, 31), + DateEntity.today() + ) + + datePicker.setOnDatePickedListener { year, month, day -> + callback.onDateSelected(String.format("%s-%s-%s", year, month, day)) + } + datePicker.show() +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt b/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt index 016ebcb..cf6bf49 100644 --- a/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt +++ b/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt @@ -4,7 +4,7 @@ * ArrayList扩展方法 */ -//将图片集合格式化成满足上传格式的数据 +//将集合格式化成满足上传格式的数据 fun ArrayList.reformat(): String { if (this.isEmpty()) return "" val builder = StringBuilder() diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt b/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt index 7c57643..aa9b92b 100644 --- a/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt +++ b/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt @@ -1,7 +1,6 @@ package com.casic.xz.meterage.extensions import android.content.Context -import android.util.Log import android.view.ViewGroup import com.casic.xz.meterage.base.BaseApplication import com.pengxh.kt.lite.extensions.dp2px @@ -9,9 +8,8 @@ fun Context.initLayoutImmersionBar(rootView: ViewGroup) { var statusBarHeight = QMUIDisplayHelper.getStatusBarHeight(this) - Log.d("Casic", "状态栏高度: $statusBarHeight") if (statusBarHeight == 0) { - statusBarHeight = 44f.dp2px(BaseApplication.get()) + statusBarHeight = 40f.dp2px(BaseApplication.get()) } rootView.setPadding(0, statusBarHeight, 0, 0) rootView.requestLayout() diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/String.kt b/app/src/main/java/com/casic/xz/meterage/extensions/String.kt index 28f70d8..6234d43 100644 --- a/app/src/main/java/com/casic/xz/meterage/extensions/String.kt +++ b/app/src/main/java/com/casic/xz/meterage/extensions/String.kt @@ -128,9 +128,10 @@ fun String.combineImagePath(): String { if (this.isEmpty()) return this val defaultValue = SaveKeyValues.getValue( - LocaleConstant.DEFAULT_SERVER_CONFIG, LocaleConstant.SERVER_BASE_URL + LocaleConstant.FILE_SERVER_CONFIG, LocaleConstant.File_SERVER_URL ) as String - return "$defaultValue/static/${this.replace("\\", "/")}" + //http://111.198.10.15:21408/test/1677479806059688_1677479806038.jpeg + return "$defaultValue/test/${this.replace("\\", "/")}" } fun String.isEarlier(time: String): Boolean { diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt index 25fa87b..a0e1358 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt @@ -1,18 +1,12 @@ package com.casic.xz.meterage.fragment.customer +import android.graphics.Color import android.graphics.Paint import com.casic.xz.meterage.R -import com.casic.xz.meterage.extensions.combineImagePath import com.casic.xz.meterage.extensions.toChineseGrade +import com.casic.xz.meterage.extensions.watchAttachFile import com.casic.xz.meterage.model.CustomerDetailModel -import com.casic.xz.meterage.view.BigImageActivity -import com.casic.xz.meterage.view.notice.PreviewDocumentActivity -import com.casic.xz.meterage.view.notice.PreviewPdfActivity -import com.casic.xz.meterage.view.notice.PreviewTextActivity import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.extensions.show import kotlinx.android.synthetic.main.fragment_customer_basic_information.* class BasicInformationFragment(private val data: CustomerDetailModel.DataModel) : @@ -48,30 +42,11 @@ val textPaint = minioFileView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - minioFileView.setTextColor(R.color.themeColor.convertColor(requireContext())) + minioFileView.setTextColor(Color.BLUE) minioFileView.setOnClickListener { //查看附件 - if (minioFileName.endsWith("pdf")) { - requireContext().navigatePageTo(minioFileName) - } else if ( - minioFileName.endsWith("doc") || - minioFileName.endsWith("docx") - ) { - requireContext().navigatePageTo(minioFileName) - } else if (minioFileName.endsWith("txt")) { - requireContext().navigatePageTo(minioFileName) - } else if ( - minioFileName.endsWith("png") || - minioFileName.endsWith("jpeg") || - minioFileName.endsWith("jpg") - ) { - val urls = ArrayList() - urls.add(minioFileName.combineImagePath()) - requireContext().navigatePageTo(0, urls) - } else { - "文件类型未知,无法打开附件".show(requireContext()) - } + minioFileName.watchAttachFile(requireContext()) } } } diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt index 77846b4..3a0fe2e 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt @@ -1,5 +1,6 @@ package com.casic.xz.meterage.fragment.device +import android.graphics.Color import android.graphics.Paint import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R @@ -7,7 +8,6 @@ import com.casic.xz.meterage.utils.LoadingDialogHub import com.casic.xz.meterage.vm.EquipmentViewModel import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor import com.pengxh.kt.lite.vm.LoadState import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import kotlinx.android.synthetic.main.fragment_device_basic_information.* @@ -56,7 +56,7 @@ val textPaint = documentsView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - documentsView.setTextColor(R.color.themeColor.convertColor(requireContext())) + documentsView.setTextColor(Color.BLUE) val files = ArrayList() data.fileList.forEach { file -> @@ -66,7 +66,7 @@ BottomActionSheet.Builder() .setContext(requireContext()) .setActionItemTitle(files) - .setItemTextColor(R.color.themeColor.convertColor(requireContext())) + .setItemTextColor(Color.BLUE) .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { override fun onActionItemClick(position: Int) { diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt index 15dc3d2..10eeff8 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt @@ -1,5 +1,6 @@ package com.casic.xz.meterage.fragment.entrust +import android.graphics.Color import android.graphics.Paint import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R @@ -9,7 +10,6 @@ import com.casic.xz.meterage.model.EntrustDetailModel import com.casic.xz.meterage.vm.DictionaryViewModel import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor import kotlinx.android.synthetic.main.fragment_entrust_basic_information.* class BasicInformationFragment(private val data: EntrustDetailModel.DataModel) : @@ -38,7 +38,7 @@ val textPaint = annexView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - annexView.setTextColor(R.color.themeColor.convertColor(requireContext())) + annexView.setTextColor(Color.BLUE) annexView.setOnClickListener { minioFileName.watchAttachFile(requireContext()) @@ -59,9 +59,9 @@ //加急 if (data.isUrgent == "0") { - RadioButton2.isChecked = true + radioButton2.isChecked = true } else { - RadioButton1.isChecked = true + radioButton1.isChecked = true } //样品 diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/equipment/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/equipment/BasicInformationFragment.kt index 72b523c..7bc3b01 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/equipment/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/equipment/BasicInformationFragment.kt @@ -1,5 +1,6 @@ package com.casic.xz.meterage.fragment.equipment +import android.graphics.Color import android.graphics.Paint import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R @@ -7,7 +8,6 @@ import com.casic.xz.meterage.utils.LoadingDialogHub import com.casic.xz.meterage.vm.EquipmentViewModel import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor import com.pengxh.kt.lite.vm.LoadState import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import kotlinx.android.synthetic.main.fragment_equipment_basic_information.* @@ -74,7 +74,7 @@ val textPaint = instructionsView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - instructionsView.setTextColor(R.color.themeColor.convertColor(requireContext())) + instructionsView.setTextColor(Color.BLUE) val files = ArrayList() data.fileList.forEach { file -> @@ -84,7 +84,7 @@ BottomActionSheet.Builder() .setContext(requireContext()) .setActionItemTitle(files) - .setItemTextColor(R.color.themeColor.convertColor(requireContext())) + .setItemTextColor(Color.BLUE) .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { override fun onActionItemClick(position: Int) { diff --git a/app/src/main/java/com/casic/xz/meterage/model/SampleListModel.java b/app/src/main/java/com/casic/xz/meterage/model/SampleListModel.java new file mode 100644 index 0000000..5784343 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/model/SampleListModel.java @@ -0,0 +1,193 @@ +package com.casic.xz.meterage.model; + +import java.util.List; + +public class SampleListModel { + + private int code; + private DataModel data; + private String message; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataModel getData() { + return data; + } + + public void setData(DataModel data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public static class DataModel { + private List rows; + private int total; + + public List getRows() { + return rows; + } + + public void setRows(List rows) { + this.rows = rows; + } + + public int getTotal() { + return total; + } + + public void setTotal(int total) { + this.total = total; + } + + public static class RowsModel { + private String certificationStatus; + private String customerName; + private String customerNo; + private String id; + private String manufacturingNo; + private String measureLastTime; + private String measurePeriod; + private String orderId; + private String remark; + private String sampleModel; + private String sampleName; + private String sampleNo; + private String sampleSatus; + private String sampleSatusName; + private String validDeadline; + + public String getCertificationStatus() { + return certificationStatus; + } + + public void setCertificationStatus(String certificationStatus) { + this.certificationStatus = certificationStatus; + } + + public String getCustomerName() { + return customerName; + } + + public void setCustomerName(String customerName) { + this.customerName = customerName; + } + + public String getCustomerNo() { + return customerNo; + } + + public void setCustomerNo(String customerNo) { + this.customerNo = customerNo; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getManufacturingNo() { + return manufacturingNo; + } + + public void setManufacturingNo(String manufacturingNo) { + this.manufacturingNo = manufacturingNo; + } + + public String getMeasureLastTime() { + return measureLastTime; + } + + public void setMeasureLastTime(String measureLastTime) { + this.measureLastTime = measureLastTime; + } + + public String getMeasurePeriod() { + return measurePeriod; + } + + public void setMeasurePeriod(String measurePeriod) { + this.measurePeriod = measurePeriod; + } + + public String getOrderId() { + return orderId; + } + + public void setOrderId(String orderId) { + this.orderId = orderId; + } + + public String getRemark() { + return remark; + } + + public void setRemark(String remark) { + this.remark = remark; + } + + public String getSampleModel() { + return sampleModel; + } + + public void setSampleModel(String sampleModel) { + this.sampleModel = sampleModel; + } + + public String getSampleName() { + return sampleName; + } + + public void setSampleName(String sampleName) { + this.sampleName = sampleName; + } + + public String getSampleNo() { + return sampleNo; + } + + public void setSampleNo(String sampleNo) { + this.sampleNo = sampleNo; + } + + public String getSampleSatus() { + return sampleSatus; + } + + public void setSampleSatus(String sampleSatus) { + this.sampleSatus = sampleSatus; + } + + public String getSampleSatusName() { + return sampleSatusName; + } + + public void setSampleSatusName(String sampleSatusName) { + this.sampleSatusName = sampleSatusName; + } + + public String getValidDeadline() { + return validDeadline; + } + + public void setValidDeadline(String validDeadline) { + this.validDeadline = validDeadline; + } + } + } +} diff --git a/app/src/main/java/com/casic/xz/meterage/model/UploadResultModel.java b/app/src/main/java/com/casic/xz/meterage/model/UploadResultModel.java new file mode 100644 index 0000000..f2a6a41 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/model/UploadResultModel.java @@ -0,0 +1,34 @@ +package com.casic.xz.meterage.model; + +import java.util.List; + +public class UploadResultModel { + + private int code; + private List data; + private String message; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public List getData() { + return data; + } + + public void setData(List data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } +} diff --git a/app/src/main/java/com/casic/xz/meterage/utils/FileType.kt b/app/src/main/java/com/casic/xz/meterage/utils/FileType.kt new file mode 100644 index 0000000..17e2bca --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/utils/FileType.kt @@ -0,0 +1,23 @@ +package com.casic.xz.meterage.utils + +sealed class FileType { + /** + * PDF文件 + */ + object PDF : FileType() + + /** + * WORD文件 + */ + object WORD : FileType() + + /** + * IMAGE图片 + */ + object IMAGE : FileType() + + /** + * 未知类型(Excel) + */ + object UNKNOWN : FileType() +} diff --git a/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitService.kt index bc3f8d6..8f4fe44 100644 --- a/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitService.kt @@ -1,5 +1,6 @@ package com.casic.xz.meterage.utils.retrofit +import okhttp3.MultipartBody import okhttp3.RequestBody import retrofit2.http.* @@ -35,6 +36,16 @@ ): String /** + * 上传文件 + */ + @Multipart + @POST("/minio/file/upload") + suspend fun uploadFile( + @Header("token") token: String, + @Part file: MultipartBody.Part + ): String + + /** * 获取通知公告列表 */ @POST("/system/notice/listPage") @@ -209,4 +220,24 @@ @Header("token") token: String, @Body requestBody: RequestBody ): String + + /** + * 获取样品列表 + */ + @POST("/customer/sample/listPage") + suspend fun getSampleList( + @Header("token") token: String, + @Body requestBody: RequestBody, + @QueryMap limit: Map, + @QueryMap offset: Map + ): String + + /** + * 新增委托书 + */ + @POST("/business/order/add") + suspend fun addEntrust( + @Header("token") token: String, + @Body requestBody: RequestBody + ): String } \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitServiceManager.kt index cb22e45..90abe5a 100644 --- a/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitServiceManager.kt @@ -1,13 +1,20 @@ package com.casic.xz.meterage.utils.retrofit +import com.alibaba.fastjson2.JSON +import com.alibaba.fastjson2.JSONArray +import com.alibaba.fastjson2.JSONObject +import com.casic.xz.meterage.model.SampleListModel import com.casic.xz.meterage.utils.AuthenticationHelper +import com.casic.xz.meterage.utils.FileType import com.casic.xz.meterage.utils.LocaleConstant import com.pengxh.kt.lite.utils.RetrofitFactory import com.pengxh.kt.lite.utils.SaveKeyValues import okhttp3.MediaType.Companion.toMediaType +import okhttp3.MediaType.Companion.toMediaTypeOrNull +import okhttp3.MultipartBody +import okhttp3.RequestBody.Companion.asRequestBody import okhttp3.RequestBody.Companion.toRequestBody -import org.json.JSONArray -import org.json.JSONObject +import java.io.File object RetrofitServiceManager { @@ -31,9 +38,9 @@ */ suspend fun login(sid: String, account: String, secretKey: String): String { val paramObject = JSONObject() - paramObject.put("sid", sid) - paramObject.put("username", account) - paramObject.put("password", secretKey) + paramObject["sid"] = sid + paramObject["username"] = account + paramObject["password"] = secretKey val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -55,6 +62,20 @@ } /** + * 上传文件 + */ + suspend fun uploadFile(file: File, type: FileType): String { + val requestBody = when (type) { + FileType.PDF -> file.asRequestBody("application/pdf".toMediaTypeOrNull()) + FileType.WORD -> file.asRequestBody("application/msword".toMediaTypeOrNull()) + FileType.IMAGE -> file.asRequestBody("image/png".toMediaTypeOrNull()) + else -> file.asRequestBody("application/vnd.ms-excel".toMediaTypeOrNull()) + } + val filePart = MultipartBody.Part.createFormData("multipartFile", file.name, requestBody) + return api.uploadFile(AuthenticationHelper.token!!, filePart) + } + + /** * 获取通知公告列表 */ suspend fun getNoticeList( @@ -66,11 +87,11 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("noticeNo", noticeNo) - paramObject.put("noticeTitle", noticeTitle) - paramObject.put("noticePublisher", noticePublisher) - paramObject.put("noticeStartTime", noticeStartTime) - paramObject.put("noticeEndTime", noticeEndTime) + paramObject["noticeNo"] = noticeNo + paramObject["noticeTitle"] = noticeTitle + paramObject["noticePublisher"] = noticePublisher + paramObject["noticeStartTime"] = noticeStartTime + paramObject["noticeEndTime"] = noticeEndTime val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -105,26 +126,21 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("equipmentNo", equipmentNo) - paramObject.put("equipmentName", equipmentName) - paramObject.put("mesureType", mesureType) - paramObject.put("managerState", managerState) - paramObject.put("useDept", useDept) - paramObject.put("assetType", assetType) - paramObject.put("equipmentCategory", equipmentCategory) - paramObject.put("isCalibrationTestEquipment", isCalibrationTestEquipment) - paramObject.put("isMeasureAccount", isMeasureAccount) - paramObject.put("isStandardSupportEquipment", isStandardSupportEquipment) - paramObject.put("isFixedAssets", isFixedAssets) - paramObject.put("validStartDate", validStartDate) - paramObject.put("validEndDate", validEndDate) - paramObject.put("abc", abc) - - val jsonArray = JSONArray() - ids.forEach { - jsonArray.put(it) - } - paramObject.put("ids", jsonArray) + paramObject["equipmentNo"] = equipmentNo + paramObject["equipmentName"] = equipmentName + paramObject["mesureType"] = mesureType + paramObject["managerState"] = managerState + paramObject["useDept"] = useDept + paramObject["assetType"] = assetType + paramObject["equipmentCategory"] = equipmentCategory + paramObject["isCalibrationTestEquipment"] = isCalibrationTestEquipment + paramObject["isMeasureAccount"] = isMeasureAccount + paramObject["isStandardSupportEquipment"] = isStandardSupportEquipment + paramObject["isFixedAssets"] = isFixedAssets + paramObject["validStartDate"] = validStartDate + paramObject["validEndDate"] = validEndDate + paramObject["abc"] = abc + paramObject["ids"] = JSONArray.parseArray(JSON.toJSONString(ids)) val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() @@ -143,7 +159,7 @@ */ suspend fun getEquipmentDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -164,13 +180,13 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("standardNo", standardNo) - paramObject.put("standardName", standardName) - paramObject.put("category", category) - paramObject.put("managerState", managerState) - paramObject.put("standardLaboratory", standardLaboratory) - paramObject.put("preparationDate", preparationDate) - paramObject.put("id", id) + paramObject["standardNo"] = standardNo + paramObject["standardName"] = standardName + paramObject["category"] = category + paramObject["managerState"] = managerState + paramObject["standardLaboratory"] = standardLaboratory + paramObject["preparationDate"] = preparationDate + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -193,7 +209,7 @@ */ suspend fun getStandardDeviceDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -212,11 +228,11 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("checkType", checkType) - paramObject.put("priceItem", priceItem) - paramObject.put("priceName", priceName) - paramObject.put("priceNo", priceNo) - paramObject.put("priceType", priceType) + paramObject["checkType"] = checkType + paramObject["priceItem"] = priceItem + paramObject["priceName"] = priceName + paramObject["priceNo"] = priceNo + paramObject["priceType"] = priceType val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -234,7 +250,7 @@ */ suspend fun getCapabilityDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -257,20 +273,15 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("createStartTime", createStartTime) - paramObject.put("createEndTime", createEndTime) - paramObject.put("deptId", deptId) - paramObject.put("director", director) - paramObject.put("effectiveCompany", effectiveCompany) - paramObject.put("trainStartTime", trainStartTime) - paramObject.put("trainEndTime", trainEndTime) - paramObject.put("formId", formId) - - val jsonArray = JSONArray() - ids.forEach { - jsonArray.put(it) - } - paramObject.put("ids", jsonArray) + paramObject["createStartTime"] = createStartTime + paramObject["createEndTime"] = createEndTime + paramObject["deptId"] = deptId + paramObject["director"] = director + paramObject["effectiveCompany"] = effectiveCompany + paramObject["trainStartTime"] = trainStartTime + paramObject["trainEndTime"] = trainEndTime + paramObject["formId"] = formId + paramObject["ids"] = JSONArray.parseArray(JSON.toJSONString(ids)) val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() @@ -294,7 +305,7 @@ */ suspend fun getMeterageTrainDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -308,10 +319,10 @@ bussinessSize: String, customerName: String, customerNo: String, grade: String, offset: Int ): String { val paramObject = JSONObject() - paramObject.put("bussinessSize", bussinessSize) - paramObject.put("customerName", customerName) - paramObject.put("customerNo", customerNo) - paramObject.put("grade", grade) + paramObject["bussinessSize"] = bussinessSize + paramObject["customerName"] = customerName + paramObject["customerNo"] = customerNo + paramObject["grade"] = grade val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() @@ -330,7 +341,7 @@ */ suspend fun getCustomerDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -342,7 +353,7 @@ */ suspend fun getStaffList(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -354,7 +365,7 @@ */ suspend fun getSupportEquipmentList(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -366,7 +377,7 @@ */ suspend fun getVerifyProcedureList(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -389,20 +400,15 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("customerName", customerName) - paramObject.put("customerNo", customerNo) - paramObject.put("deliverer", deliverer) - paramObject.put("orderCode", orderCode) - paramObject.put("startTime", startTime) - paramObject.put("endTime", endTime) - paramObject.put("isUrgent", isUrgent) - paramObject.put("status", status) - - val jsonArray = JSONArray() - ids.forEach { - jsonArray.put(it) - } - paramObject.put("ids", jsonArray) + paramObject["customerName"] = customerName + paramObject["customerNo"] = customerNo + paramObject["deliverer"] = deliverer + paramObject["orderCode"] = orderCode + paramObject["startTime"] = startTime + paramObject["endTime"] = endTime + paramObject["isUrgent"] = isUrgent + paramObject["status"] = status + paramObject["ids"] = JSONArray.parseArray(JSON.toJSONString(ids)) val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() @@ -421,7 +427,7 @@ */ suspend fun getEntrustDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -433,7 +439,7 @@ */ suspend fun acceptEntrust(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -446,10 +452,89 @@ */ suspend fun returnEntrust(id: String, selected: ArrayList): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) return api.returnEntrust(AuthenticationHelper.token!!, requestBody) } + + /** + * 获取样品列表 + */ + suspend fun getSampleList( + customerName: String, + customerNo: String, + startTime: String, + endTime: String, + sampleName: String, + sampleNo: String, + sampleModel: String, + sampleBelong: String, + overtimeStatus: String, + ids: Array, + offset: Int + ): String { + val paramObject = JSONObject() + paramObject["customerName"] = customerName + paramObject["customerNo"] = customerNo + paramObject["startTime"] = startTime + paramObject["endTime"] = endTime + paramObject["sampleName"] = sampleName + paramObject["sampleNo"] = sampleNo + paramObject["sampleModel"] = sampleModel + paramObject["sampleBelong"] = sampleBelong + paramObject["overtimeStatus"] = overtimeStatus + paramObject["ids"] = JSONArray.parseArray(JSON.toJSONString(ids)) + + val requestBody = paramObject.toString().toRequestBody( + "application/json;charset=UTF-8".toMediaType() + ) + + val limitMap = HashMap() + limitMap["limit"] = LocaleConstant.PAGE_LIMIT + + val offsetMap = HashMap() + offsetMap["offset"] = offset + return api.getSampleList(AuthenticationHelper.token!!, requestBody, limitMap, offsetMap) + } + + /** + * 新增委托书 + */ + suspend fun addEntrust( + deliverer: String, + delivererTel: String, + orderTime: String, + planDeliverTime: String, + requireOverTime: String, + customerName: String, + customerPhone: String, + customerAddress: String, + remark: String, + minioFileName: String, + certifications: String, + isUrgent: String, + samples: List + ): String { + val paramObject = JSONObject() + paramObject["deliverer"] = deliverer + paramObject["delivererTel"] = delivererTel + paramObject["orderTime"] = orderTime + paramObject["planDeliverTime"] = planDeliverTime + paramObject["requireOverTime"] = requireOverTime + paramObject["customerName"] = customerName + paramObject["customerPhone"] = customerPhone + paramObject["customerAddress"] = customerAddress + paramObject["remark"] = remark + paramObject["minioFileName"] = minioFileName + paramObject["certifications"] = certifications + paramObject["isUrgent"] = isUrgent + paramObject["customerSampleInfoList"] = JSONArray.parseArray(JSON.toJSONString(samples)) + + val requestBody = paramObject.toString().toRequestBody( + "application/json;charset=UTF-8".toMediaType() + ) + return api.addEntrust(AuthenticationHelper.token!!, requestBody) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/view/home/EntrustAddActivity.kt b/app/src/main/java/com/casic/xz/meterage/view/home/EntrustAddActivity.kt index 3e30095..9c8d27b 100644 --- a/app/src/main/java/com/casic/xz/meterage/view/home/EntrustAddActivity.kt +++ b/app/src/main/java/com/casic/xz/meterage/view/home/EntrustAddActivity.kt @@ -1,52 +1,211 @@ package com.casic.xz.meterage.view.home +import android.app.Activity +import android.content.Context +import android.content.Intent +import android.graphics.Color +import android.graphics.Paint import android.util.Log +import androidx.activity.result.ActivityResult +import androidx.activity.result.ActivityResultCallback +import androidx.activity.result.contract.ActivityResultContracts import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R import com.casic.xz.meterage.adapter.CertificateTypeAdapter2 -import com.casic.xz.meterage.extensions.initLayoutImmersionBar +import com.casic.xz.meterage.adapter.CustomerSampleAdapter +import com.casic.xz.meterage.callback.DateSelectedCallback +import com.casic.xz.meterage.callback.OnImageCompressListener +import com.casic.xz.meterage.extensions.* +import com.casic.xz.meterage.model.EntrustDetailModel +import com.casic.xz.meterage.model.SampleListModel +import com.casic.xz.meterage.utils.FileType +import com.casic.xz.meterage.utils.GlideLoadEngine +import com.casic.xz.meterage.utils.LoadingDialogHub import com.casic.xz.meterage.vm.DictionaryViewModel +import com.casic.xz.meterage.vm.EntrustViewModel +import com.casic.xz.meterage.vm.FileUploadViewModel +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken import com.gyf.immersionbar.ImmersionBar +import com.luck.picture.lib.basic.PictureSelector +import com.luck.picture.lib.config.SelectMimeType +import com.luck.picture.lib.entity.LocalMedia +import com.luck.picture.lib.interfaces.OnResultCallbackListener import com.pengxh.kt.lite.base.KotlinBaseActivity -import com.pengxh.kt.lite.extensions.toJson +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.vm.LoadState +import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import kotlinx.android.synthetic.main.activity_entrust_add.* +import java.io.File + class EntrustAddActivity : KotlinBaseActivity() { + private val context: Context = this@EntrustAddActivity + private val gson by lazy { Gson() } private lateinit var dictionaryViewModel: DictionaryViewModel - private var checkedItems = ArrayList() + private lateinit var fileUploadViewModel: FileUploadViewModel + private lateinit var entrustViewModel: EntrustViewModel + private lateinit var sampleAdapter: CustomerSampleAdapter + private var checkedItems = ArrayList() + private var isUrgent = "0" + private var sampleModels: ArrayList? = null + private var dataBeans = ArrayList() override fun initData() { //证书 dictionaryViewModel = ViewModelProvider(this)[DictionaryViewModel::class.java] dictionaryViewModel.getDictionaryByCode("certificationClass") - dictionaryViewModel.dictionary.observe(this) { dic -> - if (dic.code == 200) { - val typeAdapter2 = CertificateTypeAdapter2(this, dic.data) + dictionaryViewModel.dictionary.observe(this) { + if (it.code == 200) { + val typeAdapter2 = CertificateTypeAdapter2(this, it.data) typeRecyclerView.adapter = typeAdapter2 typeAdapter2.setOnItemCheckedListener(object : CertificateTypeAdapter2.OnItemCheckedListener { override fun onItemChecked(position: Int, isChecked: Boolean) { if (isChecked) { - checkedItems.add(position) + checkedItems.add(position.toString()) } else { - checkedItems.remove(position) + checkedItems.remove(position.toString()) } } }) } } + + fileUploadViewModel = ViewModelProvider(this)[FileUploadViewModel::class.java] + fileUploadViewModel.resultModel.observe(this) { + if (it.code == 200) { + val annexName = it.data[0] + annexView.text = annexName + val textPaint = annexView.paint + textPaint.flags = Paint.UNDERLINE_TEXT_FLAG + textPaint.isAntiAlias = true + annexView.setTextColor(Color.BLUE) + + annexView.setOnClickListener { + annexName.watchAttachFile(this) + } + } + } + + entrustViewModel = ViewModelProvider(this)[EntrustViewModel::class.java] + entrustViewModel.addResult.observe(this) { + if (it.code == 200) { + finish() + } + } + + //样品列表 + sampleAdapter = CustomerSampleAdapter(this, dataBeans) + sampleRecyclerView.adapter = sampleAdapter } + private val selectCustomerLauncher = + registerForActivityResult(ActivityResultContracts.StartActivityForResult(), + object : ActivityResultCallback { + override fun onActivityResult(result: ActivityResult?) { + if (result?.resultCode == Activity.RESULT_OK) { + val data = result.data ?: return + + entrustNameView.text = data.getStringExtra("entrustName") + entrustContactView.text = data.getStringExtra("entrustContact") + entrustAddressView.text = data.getStringExtra("entrustAddress") + } + } + }) + + private val selectSampleLauncher = + registerForActivityResult(ActivityResultContracts.StartActivityForResult(), + object : ActivityResultCallback { + override fun onActivityResult(result: ActivityResult?) { + if (result?.resultCode == Activity.RESULT_OK) { + val data = result.data ?: return + + val modelsJson = data.getStringExtra("sampleModels") + if (!modelsJson.isNullOrBlank()) { + sampleModels = gson.fromJson( + modelsJson, + object : + TypeToken>() {}.type + ) + } + + //刷新列表 + dataBeans.clear() + sampleModels?.forEach { + val model = + EntrustDetailModel.DataModel.CustomerSampleInfoListModel() + + model.customerName = it.customerName + model.customerNo = it.customerNo + model.id = it.id + model.manufacturingNo = it.manufacturingNo + model.measureLastTime = it.measureLastTime + model.measurePeriod = it.measurePeriod + model.orderId = it.orderId + model.remark = it.remark + model.sampleModel = it.sampleModel + model.sampleName = it.sampleName + model.sampleNo = it.sampleNo + model.validDeadline = it.validDeadline + + dataBeans.add(model) + } + sampleAdapter.notifyDataSetChanged() + } + } + }) + override fun initEvent() { + leftBackView.setOnClickListener { finish() } + + estimateTimeView.setOnClickListener { + showDatePicker(object : DateSelectedCallback { + override fun onDateSelected(date: String) { + estimateTimeView.text = date + } + }) + } + + completedView.setOnClickListener { + showDatePicker(object : DateSelectedCallback { + override fun onDateSelected(date: String) { + completedView.text = date + } + }) + } + + entrustNameView.setOnClickListener { + selectCustomerLauncher.launch(Intent(this, SelectCustomerActivity::class.java)) + } + //上传附件 uploadFileButton.setOnClickListener { + BottomActionSheet.Builder() + .setContext(this) + .setItemTextColor(Color.BLUE) + .setActionItemTitle(listOf("文件", "图片")) + .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { + override fun onActionItemClick(position: Int) { + when (position) { + 0 -> uploadFile() + 1 -> uploadImage() + } + } + }).build().show() + } + radioGroup.setOnCheckedChangeListener { _, checkedId -> + when (checkedId) { + R.id.radioButton1 -> isUrgent = "1" + R.id.radioButton2 -> isUrgent = "0" + } } //选择样品 selectSampleButton.setOnClickListener { - + selectSampleLauncher.launch(Intent(this, SelectSampleActivity::class.java)) } //写入样品信息 @@ -55,14 +214,68 @@ } pushEntrustView.setOnClickListener { - Log.d("Casic", "EntrustAddActivity => initEvent: ${checkedItems.toJson()}") + val sender = senderView.text.toString() + if (sender.isBlank()) { + "请填写送样人名字".show(this) + return@setOnClickListener + } + + val contact = contactView.text.toString() + if (contact.isBlank()) { + "请填写送样人联系方式".show(this) + return@setOnClickListener + } + + val estimateTime = estimateTimeView.text.toString() + if (estimateTime.isBlank()) { + "请选择预计送到的时间".show(this) + return@setOnClickListener + } + + val entrustName = entrustNameView.text.toString() + if (entrustName.isBlank()) { + "请选择委托方".show(this) + return@setOnClickListener + } + + if (sampleModels == null) { + "请选择样品".show(this) + return@setOnClickListener + } + entrustViewModel.addEntrust( + sender, + contact, + createEntrustDateView.text.toString(), + estimateTime, + completedView.text.toString(), + entrustName, + entrustContactView.text.toString(), + entrustAddressView.text.toString(), + remarkView.text.toString(), + annexView.text.toString(), + checkedItems.reformat(), + isUrgent, + sampleModels!! + ) } } override fun initLayoutView(): Int = R.layout.activity_entrust_add override fun observeRequestState() { + fileUploadViewModel.loadState.observe(this) { + when (it) { + LoadState.Loading -> LoadingDialogHub.show(this, "文件上传中,请稍后...") + else -> LoadingDialogHub.dismiss() + } + } + entrustViewModel.loadState.observe(this) { + when (it) { + LoadState.Loading -> LoadingDialogHub.show(this, "委托创建中,请稍后...") + else -> LoadingDialogHub.dismiss() + } + } } override fun setupTopBarLayout() { @@ -70,4 +283,62 @@ initLayoutImmersionBar(rootView) titleView.text = "委托需求" } + + private fun uploadFile() { +// val explorer = FileExplorer(this) +// explorer.setInitDir(ExplorerMode.FILE, Environment.getExternalStorageDirectory()) +// explorer.setShowHomeDir(true) +// explorer.setShowUpDir(true) +// explorer.setShowHideDir(true) +// explorer.setAllowExtensions(arrayOf(".doc", ".docx", ".xls", ".xlsx", ".pdf")) +// explorer.setOnFileClickedListener { +// val type = if (it.name.endsWith(".doc") || it.name.endsWith(".docx")) { +// FileType.WORD +// } else if (it.name.endsWith(".pdf")) { +// FileType.PDF +// } else { +// FileType.UNKNOWN +// } +// +// Log.d("Casic", "EntrustAddActivity => uploadFile: ${it.absolutePath}") +// fileUploadViewModel.uploadFile(it, type) +// } + } + + private fun uploadImage() { + PictureSelector.create(this) + .openGallery(SelectMimeType.ofImage()) + .isGif(false) + .isMaxSelectEnabledMask(true) + .setFilterMinFileSize(100) + .setMaxSelectNum(1) + .isDisplayCamera(false) + .setImageEngine(GlideLoadEngine.instance) + .forResult(object : OnResultCallbackListener { + override fun onResult(result: ArrayList?) { + if (result == null) { + "选择照片失败,请重试".show(context) + return + } + result[0].realPath.compressImage(context, object : OnImageCompressListener { + override fun onSuccess(file: File) { + Log.d( + "Casic", "EntrustAddActivity => onSuccess: ${file.absolutePath}" + ) + ///storage/emulated/0/Android/data/com.casic.xz.meterage/files/Pictures/CompressImage/1677478115391211.jpeg + //上传图片 + fileUploadViewModel.uploadFile(file, FileType.IMAGE) + } + + override fun onError(e: Throwable) { + e.printStackTrace() + } + }) + } + + override fun onCancel() { + + } + }) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/view/home/SelectCustomerActivity.kt b/app/src/main/java/com/casic/xz/meterage/view/home/SelectCustomerActivity.kt new file mode 100644 index 0000000..9bf6a1a --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/view/home/SelectCustomerActivity.kt @@ -0,0 +1,158 @@ +package com.casic.xz.meterage.view.home + +import android.content.Intent +import android.os.Handler +import androidx.lifecycle.ViewModelProvider +import androidx.recyclerview.widget.DefaultItemAnimator +import androidx.recyclerview.widget.DividerItemDecoration +import com.casic.xz.meterage.R +import com.casic.xz.meterage.adapter.SelectCustomerAdapter +import com.casic.xz.meterage.extensions.initLayoutImmersionBar +import com.casic.xz.meterage.extensions.showEmptyPage +import com.casic.xz.meterage.model.CustomerListModel +import com.casic.xz.meterage.utils.LoadingDialogHub +import com.casic.xz.meterage.vm.CustomerViewModel +import com.gyf.immersionbar.ImmersionBar +import com.pengxh.kt.lite.base.KotlinBaseActivity +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.utils.WeakReferenceHandler +import com.pengxh.kt.lite.vm.LoadState +import kotlinx.android.synthetic.main.activity_select_customer.* +import kotlinx.android.synthetic.main.include_base_title.* +import kotlinx.android.synthetic.main.include_empty_view.* + +class SelectCustomerActivity : KotlinBaseActivity() { + + private lateinit var weakReferenceHandler: WeakReferenceHandler + private lateinit var customerViewModel: CustomerViewModel + private lateinit var selectCustomerAdapter: SelectCustomerAdapter + private var dataBeans: MutableList = ArrayList() + private var pageIndex = 1 + private var isRefresh = false + private var isLoadMore = false + private var customerModel: CustomerListModel.DataModel.RowsModel? = null + + override fun initData() { + weakReferenceHandler = WeakReferenceHandler(callback) + customerViewModel = ViewModelProvider(this)[CustomerViewModel::class.java] + customerViewModel.customerList.observe(this) { + if (it.code == 200) { + val dataRows = it.data?.rows!! + when { + isRefresh -> { + dataBeans.clear() + dataBeans = dataRows + customerLayout.finishRefresh() + isRefresh = false + } + isLoadMore -> { + if (dataRows.size == 0) { + "到底了,别拉了".show(this) + } + dataBeans.addAll(dataRows) + customerLayout.finishLoadMore() + isLoadMore = false + } + else -> { + dataBeans = dataRows + } + } + weakReferenceHandler.sendEmptyMessage(2023022701) + } + } + } + + override fun initEvent() { + leftBackView.setOnClickListener { + if (customerModel == null) { + "请选择委托方".show(this) + return@setOnClickListener + } + val intent = Intent() + intent.putExtra("entrustName", customerModel!!.customerName) + intent.putExtra("entrustContact", customerModel!!.phone) + intent.putExtra("entrustAddress", customerModel!!.fullAddress) + setResult(RESULT_OK, intent) + finish() + } + + customerLayout.setOnRefreshListener { + isRefresh = true + //刷新之后页码重置 + pageIndex = 1 + getCustomerList() + } + + customerLayout.setOnLoadMoreListener { + isLoadMore = true + pageIndex++ + getCustomerList() + } + } + + override fun initLayoutView(): Int = R.layout.activity_select_customer + + override fun observeRequestState() { + customerViewModel.loadState.observe(this) { + when (it) { + LoadState.Loading -> LoadingDialogHub.show(this, "数据加载中...") + else -> LoadingDialogHub.dismiss() + } + } + } + + override fun setupTopBarLayout() { + ImmersionBar.with(this).statusBarDarkFont(true).init() + initLayoutImmersionBar(rootView) + titleView.text = "客户列表" + } + + override fun onResume() { + super.onResume() + pageIndex = 1 + getCustomerList() + } + + private fun getCustomerList() { + customerViewModel.getCustomerList( + "", + "", + "", + "", + pageIndex + ) + } + + private val callback = Handler.Callback { + when (it.what) { + 2023022701 -> { + if (isRefresh || isLoadMore) { + selectCustomerAdapter.notifyDataSetChanged() + } else { + if (dataBeans.size == 0) { + emptyView!!.showEmptyPage("无客户数据") { + pageIndex = 1 + getCustomerList() + } + } else { + emptyView!!.hide() + selectCustomerAdapter = SelectCustomerAdapter(this, dataBeans) + customerRecyclerView.addItemDecoration( + DividerItemDecoration(this, DividerItemDecoration.VERTICAL) + ) + (customerRecyclerView.itemAnimator as DefaultItemAnimator).supportsChangeAnimations = + false + customerRecyclerView.adapter = selectCustomerAdapter + selectCustomerAdapter.setOnCheckedListener(object : + SelectCustomerAdapter.OnItemCheckedListener { + override fun onItemChecked(item: CustomerListModel.DataModel.RowsModel) { + customerModel = item + } + }) + } + } + } + } + true + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/view/home/SelectSampleActivity.kt b/app/src/main/java/com/casic/xz/meterage/view/home/SelectSampleActivity.kt new file mode 100644 index 0000000..f85cb44 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/view/home/SelectSampleActivity.kt @@ -0,0 +1,152 @@ +package com.casic.xz.meterage.view.home + +import android.content.Intent +import android.os.Handler +import androidx.lifecycle.ViewModelProvider +import androidx.recyclerview.widget.DefaultItemAnimator +import androidx.recyclerview.widget.DividerItemDecoration +import com.casic.xz.meterage.R +import com.casic.xz.meterage.adapter.SelectSampleAdapter +import com.casic.xz.meterage.extensions.initLayoutImmersionBar +import com.casic.xz.meterage.extensions.showEmptyPage +import com.casic.xz.meterage.model.SampleListModel +import com.casic.xz.meterage.vm.SampleViewModel +import com.gyf.immersionbar.ImmersionBar +import com.pengxh.kt.lite.base.KotlinBaseActivity +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.extensions.toJson +import com.pengxh.kt.lite.utils.WeakReferenceHandler +import kotlinx.android.synthetic.main.activity_select_sample.* +import kotlinx.android.synthetic.main.include_base_title.* +import kotlinx.android.synthetic.main.include_empty_view.* + +class SelectSampleActivity : KotlinBaseActivity() { + + private lateinit var weakReferenceHandler: WeakReferenceHandler + private lateinit var sampleViewModel: SampleViewModel + private lateinit var selectSampleAdapter: SelectSampleAdapter + private var dataBeans: MutableList = ArrayList() + private var pageIndex = 1 + private var isRefresh = false + private var isLoadMore = false + private var sampleModels = ArrayList() + + override fun initData() { + weakReferenceHandler = WeakReferenceHandler(callback) + sampleViewModel = ViewModelProvider(this)[SampleViewModel::class.java] + sampleViewModel.sampleList.observe(this) { + if (it.code == 200) { + val dataRows = it.data?.rows!! + when { + isRefresh -> { + dataBeans.clear() + dataBeans = dataRows + sampleLayout.finishRefresh() + isRefresh = false + } + isLoadMore -> { + if (dataRows.size == 0) { + "到底了,别拉了".show(this) + } + dataBeans.addAll(dataRows) + sampleLayout.finishLoadMore() + isLoadMore = false + } + else -> { + dataBeans = dataRows + } + } + weakReferenceHandler.sendEmptyMessage(2023030101) + } + } + } + + override fun initEvent() { + leftBackView.setOnClickListener { + val intent = Intent() + intent.putExtra("sampleModels", sampleModels.toJson()) + setResult(RESULT_OK, intent) + finish() + } + + sampleLayout.setOnRefreshListener { + isRefresh = true + //刷新之后页码重置 + pageIndex = 1 + getSampleList() + } + + sampleLayout.setOnLoadMoreListener { + isLoadMore = true + pageIndex++ + getSampleList() + } + } + + override fun initLayoutView(): Int = R.layout.activity_select_sample + + override fun observeRequestState() { + + } + + override fun setupTopBarLayout() { + ImmersionBar.with(this).statusBarDarkFont(true).init() + initLayoutImmersionBar(rootView) + titleView.text = "样品列表" + } + + override fun onResume() { + super.onResume() + pageIndex = 1 + getSampleList() + } + + private fun getSampleList() { + sampleViewModel.getSampleList( + "", + "", + "", + "", + "", + "", + "", + "", + "", + arrayOf(), + pageIndex + ) + } + + private val callback = Handler.Callback { + when (it.what) { + 2023030101 -> { + if (isRefresh || isLoadMore) { + selectSampleAdapter.notifyDataSetChanged() + } else { + if (dataBeans.size == 0) { + emptyView!!.showEmptyPage("无样品数据") { + pageIndex = 1 + getSampleList() + } + } else { + emptyView!!.hide() + selectSampleAdapter = SelectSampleAdapter(this, dataBeans) + sampleRecyclerView.addItemDecoration( + DividerItemDecoration(this, DividerItemDecoration.VERTICAL) + ) + (sampleRecyclerView.itemAnimator as DefaultItemAnimator).supportsChangeAnimations = + false + sampleRecyclerView.adapter = selectSampleAdapter + selectSampleAdapter.setOnCheckedListener(object : + SelectSampleAdapter.OnItemCheckedListener { + override fun onItemChecked(items: ArrayList) { + sampleModels = items + } + }) + } + } + } + } + true + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/view/notice/NoticeDetailActivity.kt b/app/src/main/java/com/casic/xz/meterage/view/notice/NoticeDetailActivity.kt index a9d9422..9596985 100644 --- a/app/src/main/java/com/casic/xz/meterage/view/notice/NoticeDetailActivity.kt +++ b/app/src/main/java/com/casic/xz/meterage/view/notice/NoticeDetailActivity.kt @@ -1,6 +1,7 @@ package com.casic.xz.meterage.view.notice import android.annotation.SuppressLint +import android.graphics.Color import android.graphics.Paint import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R @@ -10,7 +11,6 @@ import com.casic.xz.meterage.vm.NoticeViewModel import com.gyf.immersionbar.ImmersionBar import com.pengxh.kt.lite.base.KotlinBaseActivity -import com.pengxh.kt.lite.extensions.convertColor import com.pengxh.kt.lite.extensions.obtainScreenWidth import com.pengxh.kt.lite.utils.Constant import kotlinx.android.synthetic.main.activity_notice_detail.* @@ -54,7 +54,7 @@ val textPaint = minioFileView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - minioFileView.setTextColor(R.color.themeColor.convertColor(this)) + minioFileView.setTextColor(Color.BLUE) minioFileView.setOnClickListener { minioFileName.watchAttachFile(this) diff --git a/app/src/main/java/com/casic/xz/meterage/vm/EntrustViewModel.kt b/app/src/main/java/com/casic/xz/meterage/vm/EntrustViewModel.kt index 2280f88..103c002 100644 --- a/app/src/main/java/com/casic/xz/meterage/vm/EntrustViewModel.kt +++ b/app/src/main/java/com/casic/xz/meterage/vm/EntrustViewModel.kt @@ -7,6 +7,7 @@ import com.casic.xz.meterage.model.ActionResultModel import com.casic.xz.meterage.model.EntrustDetailModel import com.casic.xz.meterage.model.EntrustListModel +import com.casic.xz.meterage.model.SampleListModel import com.casic.xz.meterage.utils.retrofit.RetrofitServiceManager import com.google.gson.Gson import com.google.gson.reflect.TypeToken @@ -25,6 +26,7 @@ val entrustDetail = MutableLiveData() val acceptResult = MutableLiveData() val returnResult = MutableLiveData() + val addResult = MutableLiveData() fun getEntrustList( customerName: String, @@ -119,4 +121,50 @@ loadState.value = LoadState.Fail it.cause.toString().show(BaseApplication.get()) }) + + fun addEntrust( + deliverer: String, + delivererTel: String, + orderTime: String, + planDeliverTime: String, + requireOverTime: String, + customerName: String, + customerPhone: String, + customerAddress: String, + remark: String, + minioFileName: String, + certifications: String, + isUrgent: String, + samples: List + ) = launch({ + loadState.value = LoadState.Loading + val response = RetrofitServiceManager.addEntrust( + deliverer, + delivererTel, + orderTime, + planDeliverTime, + requireOverTime, + customerName, + customerPhone, + customerAddress, + remark, + minioFileName, + certifications, + isUrgent, + samples + ) + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + loadState.value = LoadState.Success + addResult.value = gson.fromJson( + response, object : TypeToken() {}.type + ) + } else { + loadState.value = LoadState.Fail + response.toErrorMessage().show(BaseApplication.get()) + } + }, { + loadState.value = LoadState.Fail + it.cause.toString().show(BaseApplication.get()) + }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/vm/FileUploadViewModel.kt b/app/src/main/java/com/casic/xz/meterage/vm/FileUploadViewModel.kt new file mode 100644 index 0000000..b16c1c7 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/vm/FileUploadViewModel.kt @@ -0,0 +1,40 @@ +package com.casic.xz.meterage.vm + +import androidx.lifecycle.MutableLiveData +import com.casic.xz.meterage.base.BaseApplication +import com.casic.xz.meterage.extensions.separateResponseCode +import com.casic.xz.meterage.extensions.toErrorMessage +import com.casic.xz.meterage.model.UploadResultModel +import com.casic.xz.meterage.utils.FileType +import com.casic.xz.meterage.utils.retrofit.RetrofitServiceManager +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken +import com.pengxh.kt.lite.extensions.launch +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.vm.BaseViewModel +import com.pengxh.kt.lite.vm.LoadState +import java.io.File + +class FileUploadViewModel : BaseViewModel() { + + private val gson by lazy { Gson() } + val resultModel = MutableLiveData() + + fun uploadFile(file: File, type: FileType) = launch({ + loadState.value = LoadState.Loading + val response = RetrofitServiceManager.uploadFile(file, type) + 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(BaseApplication.get()) + } + }, { + loadState.value = LoadState.Fail + it.cause.toString().show(BaseApplication.get()) + }) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/vm/SampleViewModel.kt b/app/src/main/java/com/casic/xz/meterage/vm/SampleViewModel.kt new file mode 100644 index 0000000..182140d --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/vm/SampleViewModel.kt @@ -0,0 +1,65 @@ +package com.casic.xz.meterage.vm + +import androidx.lifecycle.MutableLiveData +import com.casic.xz.meterage.base.BaseApplication +import com.casic.xz.meterage.extensions.separateResponseCode +import com.casic.xz.meterage.extensions.toErrorMessage +import com.casic.xz.meterage.model.SampleListModel +import com.casic.xz.meterage.utils.retrofit.RetrofitServiceManager +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken +import com.pengxh.kt.lite.extensions.launch +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.vm.BaseViewModel +import com.pengxh.kt.lite.vm.LoadState + +/** + * 样品相关 VM + * */ +class SampleViewModel : BaseViewModel() { + + private val gson by lazy { Gson() } + val sampleList = MutableLiveData() + + fun getSampleList( + customerName: String, + customerNo: String, + startTime: String, + endTime: String, + sampleName: String, + sampleNo: String, + sampleModel: String, + sampleBelong: String, + overtimeStatus: String, + ids: Array, + offset: Int + ) = launch({ + loadState.value = LoadState.Loading + val response = RetrofitServiceManager.getSampleList( + customerName, + customerNo, + startTime, + endTime, + sampleName, + sampleNo, + sampleModel, + sampleBelong, + overtimeStatus, + ids, + offset + ) + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + loadState.value = LoadState.Success + sampleList.value = gson.fromJson( + response, object : TypeToken() {}.type + ) + } else { + loadState.value = LoadState.Fail + response.toErrorMessage().show(BaseApplication.get()) + } + }, { + loadState.value = LoadState.Fail + it.cause.toString().show(BaseApplication.get()) + }) +} \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_customer_selector.xml b/app/src/main/res/drawable/bg_customer_selector.xml new file mode 100644 index 0000000..e7292d5 --- /dev/null +++ b/app/src/main/res/drawable/bg_customer_selector.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_sample_selector.xml b/app/src/main/res/drawable/bg_sample_selector.xml new file mode 100644 index 0000000..6b5d5e7 --- /dev/null +++ b/app/src/main/res/drawable/bg_sample_selector.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_check_selected.xml b/app/src/main/res/drawable/ic_check_selected.xml new file mode 100644 index 0000000..4d93f9f --- /dev/null +++ b/app/src/main/res/drawable/ic_check_selected.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_entrust_add.xml b/app/src/main/res/layout/activity_entrust_add.xml index 3d00784..8450d1d 100644 --- a/app/src/main/res/layout/activity_entrust_add.xml +++ b/app/src/main/res/layout/activity_entrust_add.xml @@ -68,6 +68,7 @@ android:text="送样人" /> @@ -81,6 +82,7 @@ android:text="联系方式" /> @@ -115,10 +117,10 @@ style="@style/textViewStyle" android:text="预计送到时间" /> - + android:hint="请选择预计送到时间" /> @@ -129,10 +131,10 @@ style="@style/textViewStyle" android:text="要求检完时间" /> - + android:hint="请选择要求检完时间" /> @@ -143,10 +145,10 @@ style="@style/textViewStyle" android:text="委托方名称" /> - + android:hint="请选择委托方" /> @@ -157,10 +159,9 @@ style="@style/textViewStyle" android:text="委托方电话" /> - + @@ -171,10 +172,9 @@ style="@style/textViewStyle" android:text="委托方地址" /> - + @@ -186,9 +186,9 @@ android:text="备注" /> + android:hint="请输入" /> @@ -200,6 +200,7 @@ android:text="附件" /> diff --git a/app/src/main/res/layout/activity_select_customer.xml b/app/src/main/res/layout/activity_select_customer.xml new file mode 100644 index 0000000..01f5ca1 --- /dev/null +++ b/app/src/main/res/layout/activity_select_customer.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_select_sample.xml b/app/src/main/res/layout/activity_select_sample.xml new file mode 100644 index 0000000..f5c6693 --- /dev/null +++ b/app/src/main/res/layout/activity_select_sample.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 0ae369f..687b02b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -15,7 +15,6 @@ } compileSdkVersion 31 - buildToolsVersion "30.0.3" defaultConfig { applicationId "com.casic.xz.meterage" @@ -84,11 +83,13 @@ implementation 'top.zibin:Luban:1.1.8' //官方Json解析库 implementation 'com.google.code.gson:gson:2.9.0' + //阿里巴巴JSON库 + implementation 'com.alibaba.fastjson2:fastjson2:2.0.24' //Kotlin协程 implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.5.1' //MVVM+LiveData implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.5.1" - implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.0" + implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1" implementation "androidx.lifecycle:lifecycle-extensions:2.2.0" //返回值转换器 implementation 'com.jakewharton.retrofit:retrofit2-kotlin-coroutines-adapter:0.9.2' @@ -109,4 +110,8 @@ implementation 'com.github.barteksc:android-pdf-viewer:2.8.2' //绕过Android 11反射限制 implementation 'com.github.tiann:FreeReflection:3.1.0' + //单项/数字、二三级联动、日期/时间等滚轮选择器 + implementation 'com.github.gzu-liyujiang.AndroidPicker:WheelPicker:4.1.8' + //文件/目录选择器 + implementation 'com.github.gzu-liyujiang.AndroidPicker:FilePicker:4.1.1' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 1ccc12b..0fba91b 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -60,6 +60,8 @@ + + diff --git a/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt b/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt new file mode 100644 index 0000000..21a71d8 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt @@ -0,0 +1,70 @@ +package com.casic.xz.meterage.adapter + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import com.casic.xz.meterage.R +import com.casic.xz.meterage.extensions.toChineseGrade +import com.casic.xz.meterage.model.CustomerListModel + +class SelectCustomerAdapter( + context: Context, private val dataRows: MutableList +) : RecyclerView.Adapter() { + + private var layoutInflater = LayoutInflater.from(context) + + //选择的位置 + private var selectedPosition = 0 + + //临时记录上次选择的位置 + private var temp = -1 + + override fun getItemCount(): Int = dataRows.size + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ItemViewHolder( + layoutInflater.inflate(R.layout.item_select_customer_lv, parent, false) + ) + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + //绑定数据 + val rowsBean = dataRows[position] + holder.agreementLevelView.text = rowsBean.grade.toChineseGrade() + holder.customerNameView.text = rowsBean.customerName + holder.scaleView.text = rowsBean.companySizeName + holder.overallView.text = "公司规模:${rowsBean.evaluationName}" + holder.fullAddressView.text = "公司地址:${rowsBean.fullAddress}" + + holder.itemView.isSelected = holder.layoutPosition == selectedPosition + holder.itemView.setOnClickListener { + itemCheckedListener?.onItemChecked(rowsBean) + + holder.itemView.isSelected = true + temp = selectedPosition + //设置新的位置 + selectedPosition = holder.layoutPosition + //更新旧位置 + notifyItemChanged(temp) + } + } + + inner class ItemViewHolder(view: View) : RecyclerView.ViewHolder(view) { + var agreementLevelView: TextView = view.findViewById(R.id.agreementLevelView) + var customerNameView: TextView = view.findViewById(R.id.customerNameView) + var scaleView: TextView = view.findViewById(R.id.scaleView) + var overallView: TextView = view.findViewById(R.id.overallView) + var fullAddressView: TextView = view.findViewById(R.id.fullAddressView) + } + + private var itemCheckedListener: OnItemCheckedListener? = null + + interface OnItemCheckedListener { + fun onItemChecked(item: CustomerListModel.DataModel.RowsModel) + } + + fun setOnCheckedListener(listener: OnItemCheckedListener?) { + itemCheckedListener = listener + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt b/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt new file mode 100644 index 0000000..c29461e --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt @@ -0,0 +1,68 @@ +package com.casic.xz.meterage.adapter + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import com.casic.xz.meterage.R +import com.casic.xz.meterage.model.SampleListModel + +class SelectSampleAdapter( + context: Context, private val dataRows: MutableList +) : RecyclerView.Adapter() { + + private var layoutInflater = LayoutInflater.from(context) + private var multipleSelected = mutableSetOf() + private var sampleModes = ArrayList() + + override fun getItemCount(): Int = dataRows.size + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ItemViewHolder( + layoutInflater.inflate(R.layout.item_select_sample_lv, parent, false) + ) + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + //绑定数据 + val rowsBean = dataRows[position] + holder.sampleNameView.text = "${rowsBean.sampleName}【${rowsBean.sampleModel}】" + holder.manufacturingCodeView.text = "出厂编号:${rowsBean.manufacturingNo}" + holder.sampleCodeView.text = "样品编号:${rowsBean.sampleNo}" + holder.validDateView.text = "有效期至:${rowsBean.validDeadline}" + + holder.checkImageView.isSelected = multipleSelected.contains(position) + holder.itemView.setOnClickListener { + if (multipleSelected.contains(position)) { + multipleSelected.remove(position) + sampleModes.remove(dataRows[position]) + holder.checkImageView.isSelected = false + } else { + multipleSelected.add(position) + sampleModes.add(dataRows[position]) + holder.checkImageView.isSelected = true + } + + itemCheckedListener?.onItemChecked(sampleModes) + } + } + + inner class ItemViewHolder(view: View) : RecyclerView.ViewHolder(view) { + var sampleNameView: TextView = view.findViewById(R.id.sampleNameView) + var manufacturingCodeView: TextView = view.findViewById(R.id.manufacturingCodeView) + var sampleCodeView: TextView = view.findViewById(R.id.sampleCodeView) + var validDateView: TextView = view.findViewById(R.id.validDateView) + var checkImageView: ImageView = view.findViewById(R.id.checkImageView) + } + + private var itemCheckedListener: OnItemCheckedListener? = null + + interface OnItemCheckedListener { + fun onItemChecked(items: ArrayList) + } + + fun setOnCheckedListener(listener: OnItemCheckedListener?) { + itemCheckedListener = listener + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/callback/DateSelectedCallback.kt b/app/src/main/java/com/casic/xz/meterage/callback/DateSelectedCallback.kt new file mode 100644 index 0000000..8196110 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/callback/DateSelectedCallback.kt @@ -0,0 +1,5 @@ +package com.casic.xz.meterage.callback + +interface DateSelectedCallback { + fun onDateSelected(date: String) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/Activity.kt b/app/src/main/java/com/casic/xz/meterage/extensions/Activity.kt new file mode 100644 index 0000000..e112d1c --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/extensions/Activity.kt @@ -0,0 +1,33 @@ +package com.casic.xz.meterage.extensions + +import android.app.Activity +import com.casic.xz.meterage.R +import com.casic.xz.meterage.callback.DateSelectedCallback +import com.github.gzuliyujiang.wheelpicker.DatePicker +import com.github.gzuliyujiang.wheelpicker.annotation.DateMode +import com.github.gzuliyujiang.wheelpicker.entity.DateEntity +import com.pengxh.kt.lite.extensions.convertColor +import com.pengxh.kt.lite.extensions.sp2px + +fun Activity.showDatePicker(callback: DateSelectedCallback) { + val datePicker = DatePicker(this) + + val layout = datePicker.wheelLayout + layout.setDateMode(DateMode.YEAR_MONTH_DAY) + layout.setDateLabel("年", "月", "日"); + layout.setTextSize(14f.sp2px(this).toFloat()) + layout.setSelectedTextSize(16f.sp2px(this).toFloat()) + layout.setSelectedTextColor(R.color.themeColor.convertColor(this)) + layout.setSelectedTextBold(true) + layout.setResetWhenLinkage(false) + layout.setRange( + DateEntity.today(), + DateEntity.target(2050, 12, 31), + DateEntity.today() + ) + + datePicker.setOnDatePickedListener { year, month, day -> + callback.onDateSelected(String.format("%s-%s-%s", year, month, day)) + } + datePicker.show() +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt b/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt index 016ebcb..cf6bf49 100644 --- a/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt +++ b/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt @@ -4,7 +4,7 @@ * ArrayList扩展方法 */ -//将图片集合格式化成满足上传格式的数据 +//将集合格式化成满足上传格式的数据 fun ArrayList.reformat(): String { if (this.isEmpty()) return "" val builder = StringBuilder() diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt b/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt index 7c57643..aa9b92b 100644 --- a/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt +++ b/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt @@ -1,7 +1,6 @@ package com.casic.xz.meterage.extensions import android.content.Context -import android.util.Log import android.view.ViewGroup import com.casic.xz.meterage.base.BaseApplication import com.pengxh.kt.lite.extensions.dp2px @@ -9,9 +8,8 @@ fun Context.initLayoutImmersionBar(rootView: ViewGroup) { var statusBarHeight = QMUIDisplayHelper.getStatusBarHeight(this) - Log.d("Casic", "状态栏高度: $statusBarHeight") if (statusBarHeight == 0) { - statusBarHeight = 44f.dp2px(BaseApplication.get()) + statusBarHeight = 40f.dp2px(BaseApplication.get()) } rootView.setPadding(0, statusBarHeight, 0, 0) rootView.requestLayout() diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/String.kt b/app/src/main/java/com/casic/xz/meterage/extensions/String.kt index 28f70d8..6234d43 100644 --- a/app/src/main/java/com/casic/xz/meterage/extensions/String.kt +++ b/app/src/main/java/com/casic/xz/meterage/extensions/String.kt @@ -128,9 +128,10 @@ fun String.combineImagePath(): String { if (this.isEmpty()) return this val defaultValue = SaveKeyValues.getValue( - LocaleConstant.DEFAULT_SERVER_CONFIG, LocaleConstant.SERVER_BASE_URL + LocaleConstant.FILE_SERVER_CONFIG, LocaleConstant.File_SERVER_URL ) as String - return "$defaultValue/static/${this.replace("\\", "/")}" + //http://111.198.10.15:21408/test/1677479806059688_1677479806038.jpeg + return "$defaultValue/test/${this.replace("\\", "/")}" } fun String.isEarlier(time: String): Boolean { diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt index 25fa87b..a0e1358 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt @@ -1,18 +1,12 @@ package com.casic.xz.meterage.fragment.customer +import android.graphics.Color import android.graphics.Paint import com.casic.xz.meterage.R -import com.casic.xz.meterage.extensions.combineImagePath import com.casic.xz.meterage.extensions.toChineseGrade +import com.casic.xz.meterage.extensions.watchAttachFile import com.casic.xz.meterage.model.CustomerDetailModel -import com.casic.xz.meterage.view.BigImageActivity -import com.casic.xz.meterage.view.notice.PreviewDocumentActivity -import com.casic.xz.meterage.view.notice.PreviewPdfActivity -import com.casic.xz.meterage.view.notice.PreviewTextActivity import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.extensions.show import kotlinx.android.synthetic.main.fragment_customer_basic_information.* class BasicInformationFragment(private val data: CustomerDetailModel.DataModel) : @@ -48,30 +42,11 @@ val textPaint = minioFileView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - minioFileView.setTextColor(R.color.themeColor.convertColor(requireContext())) + minioFileView.setTextColor(Color.BLUE) minioFileView.setOnClickListener { //查看附件 - if (minioFileName.endsWith("pdf")) { - requireContext().navigatePageTo(minioFileName) - } else if ( - minioFileName.endsWith("doc") || - minioFileName.endsWith("docx") - ) { - requireContext().navigatePageTo(minioFileName) - } else if (minioFileName.endsWith("txt")) { - requireContext().navigatePageTo(minioFileName) - } else if ( - minioFileName.endsWith("png") || - minioFileName.endsWith("jpeg") || - minioFileName.endsWith("jpg") - ) { - val urls = ArrayList() - urls.add(minioFileName.combineImagePath()) - requireContext().navigatePageTo(0, urls) - } else { - "文件类型未知,无法打开附件".show(requireContext()) - } + minioFileName.watchAttachFile(requireContext()) } } } diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt index 77846b4..3a0fe2e 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt @@ -1,5 +1,6 @@ package com.casic.xz.meterage.fragment.device +import android.graphics.Color import android.graphics.Paint import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R @@ -7,7 +8,6 @@ import com.casic.xz.meterage.utils.LoadingDialogHub import com.casic.xz.meterage.vm.EquipmentViewModel import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor import com.pengxh.kt.lite.vm.LoadState import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import kotlinx.android.synthetic.main.fragment_device_basic_information.* @@ -56,7 +56,7 @@ val textPaint = documentsView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - documentsView.setTextColor(R.color.themeColor.convertColor(requireContext())) + documentsView.setTextColor(Color.BLUE) val files = ArrayList() data.fileList.forEach { file -> @@ -66,7 +66,7 @@ BottomActionSheet.Builder() .setContext(requireContext()) .setActionItemTitle(files) - .setItemTextColor(R.color.themeColor.convertColor(requireContext())) + .setItemTextColor(Color.BLUE) .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { override fun onActionItemClick(position: Int) { diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt index 15dc3d2..10eeff8 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt @@ -1,5 +1,6 @@ package com.casic.xz.meterage.fragment.entrust +import android.graphics.Color import android.graphics.Paint import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R @@ -9,7 +10,6 @@ import com.casic.xz.meterage.model.EntrustDetailModel import com.casic.xz.meterage.vm.DictionaryViewModel import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor import kotlinx.android.synthetic.main.fragment_entrust_basic_information.* class BasicInformationFragment(private val data: EntrustDetailModel.DataModel) : @@ -38,7 +38,7 @@ val textPaint = annexView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - annexView.setTextColor(R.color.themeColor.convertColor(requireContext())) + annexView.setTextColor(Color.BLUE) annexView.setOnClickListener { minioFileName.watchAttachFile(requireContext()) @@ -59,9 +59,9 @@ //加急 if (data.isUrgent == "0") { - RadioButton2.isChecked = true + radioButton2.isChecked = true } else { - RadioButton1.isChecked = true + radioButton1.isChecked = true } //样品 diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/equipment/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/equipment/BasicInformationFragment.kt index 72b523c..7bc3b01 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/equipment/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/equipment/BasicInformationFragment.kt @@ -1,5 +1,6 @@ package com.casic.xz.meterage.fragment.equipment +import android.graphics.Color import android.graphics.Paint import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R @@ -7,7 +8,6 @@ import com.casic.xz.meterage.utils.LoadingDialogHub import com.casic.xz.meterage.vm.EquipmentViewModel import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor import com.pengxh.kt.lite.vm.LoadState import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import kotlinx.android.synthetic.main.fragment_equipment_basic_information.* @@ -74,7 +74,7 @@ val textPaint = instructionsView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - instructionsView.setTextColor(R.color.themeColor.convertColor(requireContext())) + instructionsView.setTextColor(Color.BLUE) val files = ArrayList() data.fileList.forEach { file -> @@ -84,7 +84,7 @@ BottomActionSheet.Builder() .setContext(requireContext()) .setActionItemTitle(files) - .setItemTextColor(R.color.themeColor.convertColor(requireContext())) + .setItemTextColor(Color.BLUE) .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { override fun onActionItemClick(position: Int) { diff --git a/app/src/main/java/com/casic/xz/meterage/model/SampleListModel.java b/app/src/main/java/com/casic/xz/meterage/model/SampleListModel.java new file mode 100644 index 0000000..5784343 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/model/SampleListModel.java @@ -0,0 +1,193 @@ +package com.casic.xz.meterage.model; + +import java.util.List; + +public class SampleListModel { + + private int code; + private DataModel data; + private String message; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataModel getData() { + return data; + } + + public void setData(DataModel data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public static class DataModel { + private List rows; + private int total; + + public List getRows() { + return rows; + } + + public void setRows(List rows) { + this.rows = rows; + } + + public int getTotal() { + return total; + } + + public void setTotal(int total) { + this.total = total; + } + + public static class RowsModel { + private String certificationStatus; + private String customerName; + private String customerNo; + private String id; + private String manufacturingNo; + private String measureLastTime; + private String measurePeriod; + private String orderId; + private String remark; + private String sampleModel; + private String sampleName; + private String sampleNo; + private String sampleSatus; + private String sampleSatusName; + private String validDeadline; + + public String getCertificationStatus() { + return certificationStatus; + } + + public void setCertificationStatus(String certificationStatus) { + this.certificationStatus = certificationStatus; + } + + public String getCustomerName() { + return customerName; + } + + public void setCustomerName(String customerName) { + this.customerName = customerName; + } + + public String getCustomerNo() { + return customerNo; + } + + public void setCustomerNo(String customerNo) { + this.customerNo = customerNo; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getManufacturingNo() { + return manufacturingNo; + } + + public void setManufacturingNo(String manufacturingNo) { + this.manufacturingNo = manufacturingNo; + } + + public String getMeasureLastTime() { + return measureLastTime; + } + + public void setMeasureLastTime(String measureLastTime) { + this.measureLastTime = measureLastTime; + } + + public String getMeasurePeriod() { + return measurePeriod; + } + + public void setMeasurePeriod(String measurePeriod) { + this.measurePeriod = measurePeriod; + } + + public String getOrderId() { + return orderId; + } + + public void setOrderId(String orderId) { + this.orderId = orderId; + } + + public String getRemark() { + return remark; + } + + public void setRemark(String remark) { + this.remark = remark; + } + + public String getSampleModel() { + return sampleModel; + } + + public void setSampleModel(String sampleModel) { + this.sampleModel = sampleModel; + } + + public String getSampleName() { + return sampleName; + } + + public void setSampleName(String sampleName) { + this.sampleName = sampleName; + } + + public String getSampleNo() { + return sampleNo; + } + + public void setSampleNo(String sampleNo) { + this.sampleNo = sampleNo; + } + + public String getSampleSatus() { + return sampleSatus; + } + + public void setSampleSatus(String sampleSatus) { + this.sampleSatus = sampleSatus; + } + + public String getSampleSatusName() { + return sampleSatusName; + } + + public void setSampleSatusName(String sampleSatusName) { + this.sampleSatusName = sampleSatusName; + } + + public String getValidDeadline() { + return validDeadline; + } + + public void setValidDeadline(String validDeadline) { + this.validDeadline = validDeadline; + } + } + } +} diff --git a/app/src/main/java/com/casic/xz/meterage/model/UploadResultModel.java b/app/src/main/java/com/casic/xz/meterage/model/UploadResultModel.java new file mode 100644 index 0000000..f2a6a41 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/model/UploadResultModel.java @@ -0,0 +1,34 @@ +package com.casic.xz.meterage.model; + +import java.util.List; + +public class UploadResultModel { + + private int code; + private List data; + private String message; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public List getData() { + return data; + } + + public void setData(List data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } +} diff --git a/app/src/main/java/com/casic/xz/meterage/utils/FileType.kt b/app/src/main/java/com/casic/xz/meterage/utils/FileType.kt new file mode 100644 index 0000000..17e2bca --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/utils/FileType.kt @@ -0,0 +1,23 @@ +package com.casic.xz.meterage.utils + +sealed class FileType { + /** + * PDF文件 + */ + object PDF : FileType() + + /** + * WORD文件 + */ + object WORD : FileType() + + /** + * IMAGE图片 + */ + object IMAGE : FileType() + + /** + * 未知类型(Excel) + */ + object UNKNOWN : FileType() +} diff --git a/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitService.kt index bc3f8d6..8f4fe44 100644 --- a/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitService.kt @@ -1,5 +1,6 @@ package com.casic.xz.meterage.utils.retrofit +import okhttp3.MultipartBody import okhttp3.RequestBody import retrofit2.http.* @@ -35,6 +36,16 @@ ): String /** + * 上传文件 + */ + @Multipart + @POST("/minio/file/upload") + suspend fun uploadFile( + @Header("token") token: String, + @Part file: MultipartBody.Part + ): String + + /** * 获取通知公告列表 */ @POST("/system/notice/listPage") @@ -209,4 +220,24 @@ @Header("token") token: String, @Body requestBody: RequestBody ): String + + /** + * 获取样品列表 + */ + @POST("/customer/sample/listPage") + suspend fun getSampleList( + @Header("token") token: String, + @Body requestBody: RequestBody, + @QueryMap limit: Map, + @QueryMap offset: Map + ): String + + /** + * 新增委托书 + */ + @POST("/business/order/add") + suspend fun addEntrust( + @Header("token") token: String, + @Body requestBody: RequestBody + ): String } \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitServiceManager.kt index cb22e45..90abe5a 100644 --- a/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitServiceManager.kt @@ -1,13 +1,20 @@ package com.casic.xz.meterage.utils.retrofit +import com.alibaba.fastjson2.JSON +import com.alibaba.fastjson2.JSONArray +import com.alibaba.fastjson2.JSONObject +import com.casic.xz.meterage.model.SampleListModel import com.casic.xz.meterage.utils.AuthenticationHelper +import com.casic.xz.meterage.utils.FileType import com.casic.xz.meterage.utils.LocaleConstant import com.pengxh.kt.lite.utils.RetrofitFactory import com.pengxh.kt.lite.utils.SaveKeyValues import okhttp3.MediaType.Companion.toMediaType +import okhttp3.MediaType.Companion.toMediaTypeOrNull +import okhttp3.MultipartBody +import okhttp3.RequestBody.Companion.asRequestBody import okhttp3.RequestBody.Companion.toRequestBody -import org.json.JSONArray -import org.json.JSONObject +import java.io.File object RetrofitServiceManager { @@ -31,9 +38,9 @@ */ suspend fun login(sid: String, account: String, secretKey: String): String { val paramObject = JSONObject() - paramObject.put("sid", sid) - paramObject.put("username", account) - paramObject.put("password", secretKey) + paramObject["sid"] = sid + paramObject["username"] = account + paramObject["password"] = secretKey val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -55,6 +62,20 @@ } /** + * 上传文件 + */ + suspend fun uploadFile(file: File, type: FileType): String { + val requestBody = when (type) { + FileType.PDF -> file.asRequestBody("application/pdf".toMediaTypeOrNull()) + FileType.WORD -> file.asRequestBody("application/msword".toMediaTypeOrNull()) + FileType.IMAGE -> file.asRequestBody("image/png".toMediaTypeOrNull()) + else -> file.asRequestBody("application/vnd.ms-excel".toMediaTypeOrNull()) + } + val filePart = MultipartBody.Part.createFormData("multipartFile", file.name, requestBody) + return api.uploadFile(AuthenticationHelper.token!!, filePart) + } + + /** * 获取通知公告列表 */ suspend fun getNoticeList( @@ -66,11 +87,11 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("noticeNo", noticeNo) - paramObject.put("noticeTitle", noticeTitle) - paramObject.put("noticePublisher", noticePublisher) - paramObject.put("noticeStartTime", noticeStartTime) - paramObject.put("noticeEndTime", noticeEndTime) + paramObject["noticeNo"] = noticeNo + paramObject["noticeTitle"] = noticeTitle + paramObject["noticePublisher"] = noticePublisher + paramObject["noticeStartTime"] = noticeStartTime + paramObject["noticeEndTime"] = noticeEndTime val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -105,26 +126,21 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("equipmentNo", equipmentNo) - paramObject.put("equipmentName", equipmentName) - paramObject.put("mesureType", mesureType) - paramObject.put("managerState", managerState) - paramObject.put("useDept", useDept) - paramObject.put("assetType", assetType) - paramObject.put("equipmentCategory", equipmentCategory) - paramObject.put("isCalibrationTestEquipment", isCalibrationTestEquipment) - paramObject.put("isMeasureAccount", isMeasureAccount) - paramObject.put("isStandardSupportEquipment", isStandardSupportEquipment) - paramObject.put("isFixedAssets", isFixedAssets) - paramObject.put("validStartDate", validStartDate) - paramObject.put("validEndDate", validEndDate) - paramObject.put("abc", abc) - - val jsonArray = JSONArray() - ids.forEach { - jsonArray.put(it) - } - paramObject.put("ids", jsonArray) + paramObject["equipmentNo"] = equipmentNo + paramObject["equipmentName"] = equipmentName + paramObject["mesureType"] = mesureType + paramObject["managerState"] = managerState + paramObject["useDept"] = useDept + paramObject["assetType"] = assetType + paramObject["equipmentCategory"] = equipmentCategory + paramObject["isCalibrationTestEquipment"] = isCalibrationTestEquipment + paramObject["isMeasureAccount"] = isMeasureAccount + paramObject["isStandardSupportEquipment"] = isStandardSupportEquipment + paramObject["isFixedAssets"] = isFixedAssets + paramObject["validStartDate"] = validStartDate + paramObject["validEndDate"] = validEndDate + paramObject["abc"] = abc + paramObject["ids"] = JSONArray.parseArray(JSON.toJSONString(ids)) val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() @@ -143,7 +159,7 @@ */ suspend fun getEquipmentDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -164,13 +180,13 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("standardNo", standardNo) - paramObject.put("standardName", standardName) - paramObject.put("category", category) - paramObject.put("managerState", managerState) - paramObject.put("standardLaboratory", standardLaboratory) - paramObject.put("preparationDate", preparationDate) - paramObject.put("id", id) + paramObject["standardNo"] = standardNo + paramObject["standardName"] = standardName + paramObject["category"] = category + paramObject["managerState"] = managerState + paramObject["standardLaboratory"] = standardLaboratory + paramObject["preparationDate"] = preparationDate + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -193,7 +209,7 @@ */ suspend fun getStandardDeviceDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -212,11 +228,11 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("checkType", checkType) - paramObject.put("priceItem", priceItem) - paramObject.put("priceName", priceName) - paramObject.put("priceNo", priceNo) - paramObject.put("priceType", priceType) + paramObject["checkType"] = checkType + paramObject["priceItem"] = priceItem + paramObject["priceName"] = priceName + paramObject["priceNo"] = priceNo + paramObject["priceType"] = priceType val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -234,7 +250,7 @@ */ suspend fun getCapabilityDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -257,20 +273,15 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("createStartTime", createStartTime) - paramObject.put("createEndTime", createEndTime) - paramObject.put("deptId", deptId) - paramObject.put("director", director) - paramObject.put("effectiveCompany", effectiveCompany) - paramObject.put("trainStartTime", trainStartTime) - paramObject.put("trainEndTime", trainEndTime) - paramObject.put("formId", formId) - - val jsonArray = JSONArray() - ids.forEach { - jsonArray.put(it) - } - paramObject.put("ids", jsonArray) + paramObject["createStartTime"] = createStartTime + paramObject["createEndTime"] = createEndTime + paramObject["deptId"] = deptId + paramObject["director"] = director + paramObject["effectiveCompany"] = effectiveCompany + paramObject["trainStartTime"] = trainStartTime + paramObject["trainEndTime"] = trainEndTime + paramObject["formId"] = formId + paramObject["ids"] = JSONArray.parseArray(JSON.toJSONString(ids)) val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() @@ -294,7 +305,7 @@ */ suspend fun getMeterageTrainDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -308,10 +319,10 @@ bussinessSize: String, customerName: String, customerNo: String, grade: String, offset: Int ): String { val paramObject = JSONObject() - paramObject.put("bussinessSize", bussinessSize) - paramObject.put("customerName", customerName) - paramObject.put("customerNo", customerNo) - paramObject.put("grade", grade) + paramObject["bussinessSize"] = bussinessSize + paramObject["customerName"] = customerName + paramObject["customerNo"] = customerNo + paramObject["grade"] = grade val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() @@ -330,7 +341,7 @@ */ suspend fun getCustomerDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -342,7 +353,7 @@ */ suspend fun getStaffList(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -354,7 +365,7 @@ */ suspend fun getSupportEquipmentList(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -366,7 +377,7 @@ */ suspend fun getVerifyProcedureList(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -389,20 +400,15 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("customerName", customerName) - paramObject.put("customerNo", customerNo) - paramObject.put("deliverer", deliverer) - paramObject.put("orderCode", orderCode) - paramObject.put("startTime", startTime) - paramObject.put("endTime", endTime) - paramObject.put("isUrgent", isUrgent) - paramObject.put("status", status) - - val jsonArray = JSONArray() - ids.forEach { - jsonArray.put(it) - } - paramObject.put("ids", jsonArray) + paramObject["customerName"] = customerName + paramObject["customerNo"] = customerNo + paramObject["deliverer"] = deliverer + paramObject["orderCode"] = orderCode + paramObject["startTime"] = startTime + paramObject["endTime"] = endTime + paramObject["isUrgent"] = isUrgent + paramObject["status"] = status + paramObject["ids"] = JSONArray.parseArray(JSON.toJSONString(ids)) val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() @@ -421,7 +427,7 @@ */ suspend fun getEntrustDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -433,7 +439,7 @@ */ suspend fun acceptEntrust(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -446,10 +452,89 @@ */ suspend fun returnEntrust(id: String, selected: ArrayList): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) return api.returnEntrust(AuthenticationHelper.token!!, requestBody) } + + /** + * 获取样品列表 + */ + suspend fun getSampleList( + customerName: String, + customerNo: String, + startTime: String, + endTime: String, + sampleName: String, + sampleNo: String, + sampleModel: String, + sampleBelong: String, + overtimeStatus: String, + ids: Array, + offset: Int + ): String { + val paramObject = JSONObject() + paramObject["customerName"] = customerName + paramObject["customerNo"] = customerNo + paramObject["startTime"] = startTime + paramObject["endTime"] = endTime + paramObject["sampleName"] = sampleName + paramObject["sampleNo"] = sampleNo + paramObject["sampleModel"] = sampleModel + paramObject["sampleBelong"] = sampleBelong + paramObject["overtimeStatus"] = overtimeStatus + paramObject["ids"] = JSONArray.parseArray(JSON.toJSONString(ids)) + + val requestBody = paramObject.toString().toRequestBody( + "application/json;charset=UTF-8".toMediaType() + ) + + val limitMap = HashMap() + limitMap["limit"] = LocaleConstant.PAGE_LIMIT + + val offsetMap = HashMap() + offsetMap["offset"] = offset + return api.getSampleList(AuthenticationHelper.token!!, requestBody, limitMap, offsetMap) + } + + /** + * 新增委托书 + */ + suspend fun addEntrust( + deliverer: String, + delivererTel: String, + orderTime: String, + planDeliverTime: String, + requireOverTime: String, + customerName: String, + customerPhone: String, + customerAddress: String, + remark: String, + minioFileName: String, + certifications: String, + isUrgent: String, + samples: List + ): String { + val paramObject = JSONObject() + paramObject["deliverer"] = deliverer + paramObject["delivererTel"] = delivererTel + paramObject["orderTime"] = orderTime + paramObject["planDeliverTime"] = planDeliverTime + paramObject["requireOverTime"] = requireOverTime + paramObject["customerName"] = customerName + paramObject["customerPhone"] = customerPhone + paramObject["customerAddress"] = customerAddress + paramObject["remark"] = remark + paramObject["minioFileName"] = minioFileName + paramObject["certifications"] = certifications + paramObject["isUrgent"] = isUrgent + paramObject["customerSampleInfoList"] = JSONArray.parseArray(JSON.toJSONString(samples)) + + val requestBody = paramObject.toString().toRequestBody( + "application/json;charset=UTF-8".toMediaType() + ) + return api.addEntrust(AuthenticationHelper.token!!, requestBody) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/view/home/EntrustAddActivity.kt b/app/src/main/java/com/casic/xz/meterage/view/home/EntrustAddActivity.kt index 3e30095..9c8d27b 100644 --- a/app/src/main/java/com/casic/xz/meterage/view/home/EntrustAddActivity.kt +++ b/app/src/main/java/com/casic/xz/meterage/view/home/EntrustAddActivity.kt @@ -1,52 +1,211 @@ package com.casic.xz.meterage.view.home +import android.app.Activity +import android.content.Context +import android.content.Intent +import android.graphics.Color +import android.graphics.Paint import android.util.Log +import androidx.activity.result.ActivityResult +import androidx.activity.result.ActivityResultCallback +import androidx.activity.result.contract.ActivityResultContracts import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R import com.casic.xz.meterage.adapter.CertificateTypeAdapter2 -import com.casic.xz.meterage.extensions.initLayoutImmersionBar +import com.casic.xz.meterage.adapter.CustomerSampleAdapter +import com.casic.xz.meterage.callback.DateSelectedCallback +import com.casic.xz.meterage.callback.OnImageCompressListener +import com.casic.xz.meterage.extensions.* +import com.casic.xz.meterage.model.EntrustDetailModel +import com.casic.xz.meterage.model.SampleListModel +import com.casic.xz.meterage.utils.FileType +import com.casic.xz.meterage.utils.GlideLoadEngine +import com.casic.xz.meterage.utils.LoadingDialogHub import com.casic.xz.meterage.vm.DictionaryViewModel +import com.casic.xz.meterage.vm.EntrustViewModel +import com.casic.xz.meterage.vm.FileUploadViewModel +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken import com.gyf.immersionbar.ImmersionBar +import com.luck.picture.lib.basic.PictureSelector +import com.luck.picture.lib.config.SelectMimeType +import com.luck.picture.lib.entity.LocalMedia +import com.luck.picture.lib.interfaces.OnResultCallbackListener import com.pengxh.kt.lite.base.KotlinBaseActivity -import com.pengxh.kt.lite.extensions.toJson +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.vm.LoadState +import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import kotlinx.android.synthetic.main.activity_entrust_add.* +import java.io.File + class EntrustAddActivity : KotlinBaseActivity() { + private val context: Context = this@EntrustAddActivity + private val gson by lazy { Gson() } private lateinit var dictionaryViewModel: DictionaryViewModel - private var checkedItems = ArrayList() + private lateinit var fileUploadViewModel: FileUploadViewModel + private lateinit var entrustViewModel: EntrustViewModel + private lateinit var sampleAdapter: CustomerSampleAdapter + private var checkedItems = ArrayList() + private var isUrgent = "0" + private var sampleModels: ArrayList? = null + private var dataBeans = ArrayList() override fun initData() { //证书 dictionaryViewModel = ViewModelProvider(this)[DictionaryViewModel::class.java] dictionaryViewModel.getDictionaryByCode("certificationClass") - dictionaryViewModel.dictionary.observe(this) { dic -> - if (dic.code == 200) { - val typeAdapter2 = CertificateTypeAdapter2(this, dic.data) + dictionaryViewModel.dictionary.observe(this) { + if (it.code == 200) { + val typeAdapter2 = CertificateTypeAdapter2(this, it.data) typeRecyclerView.adapter = typeAdapter2 typeAdapter2.setOnItemCheckedListener(object : CertificateTypeAdapter2.OnItemCheckedListener { override fun onItemChecked(position: Int, isChecked: Boolean) { if (isChecked) { - checkedItems.add(position) + checkedItems.add(position.toString()) } else { - checkedItems.remove(position) + checkedItems.remove(position.toString()) } } }) } } + + fileUploadViewModel = ViewModelProvider(this)[FileUploadViewModel::class.java] + fileUploadViewModel.resultModel.observe(this) { + if (it.code == 200) { + val annexName = it.data[0] + annexView.text = annexName + val textPaint = annexView.paint + textPaint.flags = Paint.UNDERLINE_TEXT_FLAG + textPaint.isAntiAlias = true + annexView.setTextColor(Color.BLUE) + + annexView.setOnClickListener { + annexName.watchAttachFile(this) + } + } + } + + entrustViewModel = ViewModelProvider(this)[EntrustViewModel::class.java] + entrustViewModel.addResult.observe(this) { + if (it.code == 200) { + finish() + } + } + + //样品列表 + sampleAdapter = CustomerSampleAdapter(this, dataBeans) + sampleRecyclerView.adapter = sampleAdapter } + private val selectCustomerLauncher = + registerForActivityResult(ActivityResultContracts.StartActivityForResult(), + object : ActivityResultCallback { + override fun onActivityResult(result: ActivityResult?) { + if (result?.resultCode == Activity.RESULT_OK) { + val data = result.data ?: return + + entrustNameView.text = data.getStringExtra("entrustName") + entrustContactView.text = data.getStringExtra("entrustContact") + entrustAddressView.text = data.getStringExtra("entrustAddress") + } + } + }) + + private val selectSampleLauncher = + registerForActivityResult(ActivityResultContracts.StartActivityForResult(), + object : ActivityResultCallback { + override fun onActivityResult(result: ActivityResult?) { + if (result?.resultCode == Activity.RESULT_OK) { + val data = result.data ?: return + + val modelsJson = data.getStringExtra("sampleModels") + if (!modelsJson.isNullOrBlank()) { + sampleModels = gson.fromJson( + modelsJson, + object : + TypeToken>() {}.type + ) + } + + //刷新列表 + dataBeans.clear() + sampleModels?.forEach { + val model = + EntrustDetailModel.DataModel.CustomerSampleInfoListModel() + + model.customerName = it.customerName + model.customerNo = it.customerNo + model.id = it.id + model.manufacturingNo = it.manufacturingNo + model.measureLastTime = it.measureLastTime + model.measurePeriod = it.measurePeriod + model.orderId = it.orderId + model.remark = it.remark + model.sampleModel = it.sampleModel + model.sampleName = it.sampleName + model.sampleNo = it.sampleNo + model.validDeadline = it.validDeadline + + dataBeans.add(model) + } + sampleAdapter.notifyDataSetChanged() + } + } + }) + override fun initEvent() { + leftBackView.setOnClickListener { finish() } + + estimateTimeView.setOnClickListener { + showDatePicker(object : DateSelectedCallback { + override fun onDateSelected(date: String) { + estimateTimeView.text = date + } + }) + } + + completedView.setOnClickListener { + showDatePicker(object : DateSelectedCallback { + override fun onDateSelected(date: String) { + completedView.text = date + } + }) + } + + entrustNameView.setOnClickListener { + selectCustomerLauncher.launch(Intent(this, SelectCustomerActivity::class.java)) + } + //上传附件 uploadFileButton.setOnClickListener { + BottomActionSheet.Builder() + .setContext(this) + .setItemTextColor(Color.BLUE) + .setActionItemTitle(listOf("文件", "图片")) + .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { + override fun onActionItemClick(position: Int) { + when (position) { + 0 -> uploadFile() + 1 -> uploadImage() + } + } + }).build().show() + } + radioGroup.setOnCheckedChangeListener { _, checkedId -> + when (checkedId) { + R.id.radioButton1 -> isUrgent = "1" + R.id.radioButton2 -> isUrgent = "0" + } } //选择样品 selectSampleButton.setOnClickListener { - + selectSampleLauncher.launch(Intent(this, SelectSampleActivity::class.java)) } //写入样品信息 @@ -55,14 +214,68 @@ } pushEntrustView.setOnClickListener { - Log.d("Casic", "EntrustAddActivity => initEvent: ${checkedItems.toJson()}") + val sender = senderView.text.toString() + if (sender.isBlank()) { + "请填写送样人名字".show(this) + return@setOnClickListener + } + + val contact = contactView.text.toString() + if (contact.isBlank()) { + "请填写送样人联系方式".show(this) + return@setOnClickListener + } + + val estimateTime = estimateTimeView.text.toString() + if (estimateTime.isBlank()) { + "请选择预计送到的时间".show(this) + return@setOnClickListener + } + + val entrustName = entrustNameView.text.toString() + if (entrustName.isBlank()) { + "请选择委托方".show(this) + return@setOnClickListener + } + + if (sampleModels == null) { + "请选择样品".show(this) + return@setOnClickListener + } + entrustViewModel.addEntrust( + sender, + contact, + createEntrustDateView.text.toString(), + estimateTime, + completedView.text.toString(), + entrustName, + entrustContactView.text.toString(), + entrustAddressView.text.toString(), + remarkView.text.toString(), + annexView.text.toString(), + checkedItems.reformat(), + isUrgent, + sampleModels!! + ) } } override fun initLayoutView(): Int = R.layout.activity_entrust_add override fun observeRequestState() { + fileUploadViewModel.loadState.observe(this) { + when (it) { + LoadState.Loading -> LoadingDialogHub.show(this, "文件上传中,请稍后...") + else -> LoadingDialogHub.dismiss() + } + } + entrustViewModel.loadState.observe(this) { + when (it) { + LoadState.Loading -> LoadingDialogHub.show(this, "委托创建中,请稍后...") + else -> LoadingDialogHub.dismiss() + } + } } override fun setupTopBarLayout() { @@ -70,4 +283,62 @@ initLayoutImmersionBar(rootView) titleView.text = "委托需求" } + + private fun uploadFile() { +// val explorer = FileExplorer(this) +// explorer.setInitDir(ExplorerMode.FILE, Environment.getExternalStorageDirectory()) +// explorer.setShowHomeDir(true) +// explorer.setShowUpDir(true) +// explorer.setShowHideDir(true) +// explorer.setAllowExtensions(arrayOf(".doc", ".docx", ".xls", ".xlsx", ".pdf")) +// explorer.setOnFileClickedListener { +// val type = if (it.name.endsWith(".doc") || it.name.endsWith(".docx")) { +// FileType.WORD +// } else if (it.name.endsWith(".pdf")) { +// FileType.PDF +// } else { +// FileType.UNKNOWN +// } +// +// Log.d("Casic", "EntrustAddActivity => uploadFile: ${it.absolutePath}") +// fileUploadViewModel.uploadFile(it, type) +// } + } + + private fun uploadImage() { + PictureSelector.create(this) + .openGallery(SelectMimeType.ofImage()) + .isGif(false) + .isMaxSelectEnabledMask(true) + .setFilterMinFileSize(100) + .setMaxSelectNum(1) + .isDisplayCamera(false) + .setImageEngine(GlideLoadEngine.instance) + .forResult(object : OnResultCallbackListener { + override fun onResult(result: ArrayList?) { + if (result == null) { + "选择照片失败,请重试".show(context) + return + } + result[0].realPath.compressImage(context, object : OnImageCompressListener { + override fun onSuccess(file: File) { + Log.d( + "Casic", "EntrustAddActivity => onSuccess: ${file.absolutePath}" + ) + ///storage/emulated/0/Android/data/com.casic.xz.meterage/files/Pictures/CompressImage/1677478115391211.jpeg + //上传图片 + fileUploadViewModel.uploadFile(file, FileType.IMAGE) + } + + override fun onError(e: Throwable) { + e.printStackTrace() + } + }) + } + + override fun onCancel() { + + } + }) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/view/home/SelectCustomerActivity.kt b/app/src/main/java/com/casic/xz/meterage/view/home/SelectCustomerActivity.kt new file mode 100644 index 0000000..9bf6a1a --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/view/home/SelectCustomerActivity.kt @@ -0,0 +1,158 @@ +package com.casic.xz.meterage.view.home + +import android.content.Intent +import android.os.Handler +import androidx.lifecycle.ViewModelProvider +import androidx.recyclerview.widget.DefaultItemAnimator +import androidx.recyclerview.widget.DividerItemDecoration +import com.casic.xz.meterage.R +import com.casic.xz.meterage.adapter.SelectCustomerAdapter +import com.casic.xz.meterage.extensions.initLayoutImmersionBar +import com.casic.xz.meterage.extensions.showEmptyPage +import com.casic.xz.meterage.model.CustomerListModel +import com.casic.xz.meterage.utils.LoadingDialogHub +import com.casic.xz.meterage.vm.CustomerViewModel +import com.gyf.immersionbar.ImmersionBar +import com.pengxh.kt.lite.base.KotlinBaseActivity +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.utils.WeakReferenceHandler +import com.pengxh.kt.lite.vm.LoadState +import kotlinx.android.synthetic.main.activity_select_customer.* +import kotlinx.android.synthetic.main.include_base_title.* +import kotlinx.android.synthetic.main.include_empty_view.* + +class SelectCustomerActivity : KotlinBaseActivity() { + + private lateinit var weakReferenceHandler: WeakReferenceHandler + private lateinit var customerViewModel: CustomerViewModel + private lateinit var selectCustomerAdapter: SelectCustomerAdapter + private var dataBeans: MutableList = ArrayList() + private var pageIndex = 1 + private var isRefresh = false + private var isLoadMore = false + private var customerModel: CustomerListModel.DataModel.RowsModel? = null + + override fun initData() { + weakReferenceHandler = WeakReferenceHandler(callback) + customerViewModel = ViewModelProvider(this)[CustomerViewModel::class.java] + customerViewModel.customerList.observe(this) { + if (it.code == 200) { + val dataRows = it.data?.rows!! + when { + isRefresh -> { + dataBeans.clear() + dataBeans = dataRows + customerLayout.finishRefresh() + isRefresh = false + } + isLoadMore -> { + if (dataRows.size == 0) { + "到底了,别拉了".show(this) + } + dataBeans.addAll(dataRows) + customerLayout.finishLoadMore() + isLoadMore = false + } + else -> { + dataBeans = dataRows + } + } + weakReferenceHandler.sendEmptyMessage(2023022701) + } + } + } + + override fun initEvent() { + leftBackView.setOnClickListener { + if (customerModel == null) { + "请选择委托方".show(this) + return@setOnClickListener + } + val intent = Intent() + intent.putExtra("entrustName", customerModel!!.customerName) + intent.putExtra("entrustContact", customerModel!!.phone) + intent.putExtra("entrustAddress", customerModel!!.fullAddress) + setResult(RESULT_OK, intent) + finish() + } + + customerLayout.setOnRefreshListener { + isRefresh = true + //刷新之后页码重置 + pageIndex = 1 + getCustomerList() + } + + customerLayout.setOnLoadMoreListener { + isLoadMore = true + pageIndex++ + getCustomerList() + } + } + + override fun initLayoutView(): Int = R.layout.activity_select_customer + + override fun observeRequestState() { + customerViewModel.loadState.observe(this) { + when (it) { + LoadState.Loading -> LoadingDialogHub.show(this, "数据加载中...") + else -> LoadingDialogHub.dismiss() + } + } + } + + override fun setupTopBarLayout() { + ImmersionBar.with(this).statusBarDarkFont(true).init() + initLayoutImmersionBar(rootView) + titleView.text = "客户列表" + } + + override fun onResume() { + super.onResume() + pageIndex = 1 + getCustomerList() + } + + private fun getCustomerList() { + customerViewModel.getCustomerList( + "", + "", + "", + "", + pageIndex + ) + } + + private val callback = Handler.Callback { + when (it.what) { + 2023022701 -> { + if (isRefresh || isLoadMore) { + selectCustomerAdapter.notifyDataSetChanged() + } else { + if (dataBeans.size == 0) { + emptyView!!.showEmptyPage("无客户数据") { + pageIndex = 1 + getCustomerList() + } + } else { + emptyView!!.hide() + selectCustomerAdapter = SelectCustomerAdapter(this, dataBeans) + customerRecyclerView.addItemDecoration( + DividerItemDecoration(this, DividerItemDecoration.VERTICAL) + ) + (customerRecyclerView.itemAnimator as DefaultItemAnimator).supportsChangeAnimations = + false + customerRecyclerView.adapter = selectCustomerAdapter + selectCustomerAdapter.setOnCheckedListener(object : + SelectCustomerAdapter.OnItemCheckedListener { + override fun onItemChecked(item: CustomerListModel.DataModel.RowsModel) { + customerModel = item + } + }) + } + } + } + } + true + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/view/home/SelectSampleActivity.kt b/app/src/main/java/com/casic/xz/meterage/view/home/SelectSampleActivity.kt new file mode 100644 index 0000000..f85cb44 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/view/home/SelectSampleActivity.kt @@ -0,0 +1,152 @@ +package com.casic.xz.meterage.view.home + +import android.content.Intent +import android.os.Handler +import androidx.lifecycle.ViewModelProvider +import androidx.recyclerview.widget.DefaultItemAnimator +import androidx.recyclerview.widget.DividerItemDecoration +import com.casic.xz.meterage.R +import com.casic.xz.meterage.adapter.SelectSampleAdapter +import com.casic.xz.meterage.extensions.initLayoutImmersionBar +import com.casic.xz.meterage.extensions.showEmptyPage +import com.casic.xz.meterage.model.SampleListModel +import com.casic.xz.meterage.vm.SampleViewModel +import com.gyf.immersionbar.ImmersionBar +import com.pengxh.kt.lite.base.KotlinBaseActivity +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.extensions.toJson +import com.pengxh.kt.lite.utils.WeakReferenceHandler +import kotlinx.android.synthetic.main.activity_select_sample.* +import kotlinx.android.synthetic.main.include_base_title.* +import kotlinx.android.synthetic.main.include_empty_view.* + +class SelectSampleActivity : KotlinBaseActivity() { + + private lateinit var weakReferenceHandler: WeakReferenceHandler + private lateinit var sampleViewModel: SampleViewModel + private lateinit var selectSampleAdapter: SelectSampleAdapter + private var dataBeans: MutableList = ArrayList() + private var pageIndex = 1 + private var isRefresh = false + private var isLoadMore = false + private var sampleModels = ArrayList() + + override fun initData() { + weakReferenceHandler = WeakReferenceHandler(callback) + sampleViewModel = ViewModelProvider(this)[SampleViewModel::class.java] + sampleViewModel.sampleList.observe(this) { + if (it.code == 200) { + val dataRows = it.data?.rows!! + when { + isRefresh -> { + dataBeans.clear() + dataBeans = dataRows + sampleLayout.finishRefresh() + isRefresh = false + } + isLoadMore -> { + if (dataRows.size == 0) { + "到底了,别拉了".show(this) + } + dataBeans.addAll(dataRows) + sampleLayout.finishLoadMore() + isLoadMore = false + } + else -> { + dataBeans = dataRows + } + } + weakReferenceHandler.sendEmptyMessage(2023030101) + } + } + } + + override fun initEvent() { + leftBackView.setOnClickListener { + val intent = Intent() + intent.putExtra("sampleModels", sampleModels.toJson()) + setResult(RESULT_OK, intent) + finish() + } + + sampleLayout.setOnRefreshListener { + isRefresh = true + //刷新之后页码重置 + pageIndex = 1 + getSampleList() + } + + sampleLayout.setOnLoadMoreListener { + isLoadMore = true + pageIndex++ + getSampleList() + } + } + + override fun initLayoutView(): Int = R.layout.activity_select_sample + + override fun observeRequestState() { + + } + + override fun setupTopBarLayout() { + ImmersionBar.with(this).statusBarDarkFont(true).init() + initLayoutImmersionBar(rootView) + titleView.text = "样品列表" + } + + override fun onResume() { + super.onResume() + pageIndex = 1 + getSampleList() + } + + private fun getSampleList() { + sampleViewModel.getSampleList( + "", + "", + "", + "", + "", + "", + "", + "", + "", + arrayOf(), + pageIndex + ) + } + + private val callback = Handler.Callback { + when (it.what) { + 2023030101 -> { + if (isRefresh || isLoadMore) { + selectSampleAdapter.notifyDataSetChanged() + } else { + if (dataBeans.size == 0) { + emptyView!!.showEmptyPage("无样品数据") { + pageIndex = 1 + getSampleList() + } + } else { + emptyView!!.hide() + selectSampleAdapter = SelectSampleAdapter(this, dataBeans) + sampleRecyclerView.addItemDecoration( + DividerItemDecoration(this, DividerItemDecoration.VERTICAL) + ) + (sampleRecyclerView.itemAnimator as DefaultItemAnimator).supportsChangeAnimations = + false + sampleRecyclerView.adapter = selectSampleAdapter + selectSampleAdapter.setOnCheckedListener(object : + SelectSampleAdapter.OnItemCheckedListener { + override fun onItemChecked(items: ArrayList) { + sampleModels = items + } + }) + } + } + } + } + true + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/view/notice/NoticeDetailActivity.kt b/app/src/main/java/com/casic/xz/meterage/view/notice/NoticeDetailActivity.kt index a9d9422..9596985 100644 --- a/app/src/main/java/com/casic/xz/meterage/view/notice/NoticeDetailActivity.kt +++ b/app/src/main/java/com/casic/xz/meterage/view/notice/NoticeDetailActivity.kt @@ -1,6 +1,7 @@ package com.casic.xz.meterage.view.notice import android.annotation.SuppressLint +import android.graphics.Color import android.graphics.Paint import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R @@ -10,7 +11,6 @@ import com.casic.xz.meterage.vm.NoticeViewModel import com.gyf.immersionbar.ImmersionBar import com.pengxh.kt.lite.base.KotlinBaseActivity -import com.pengxh.kt.lite.extensions.convertColor import com.pengxh.kt.lite.extensions.obtainScreenWidth import com.pengxh.kt.lite.utils.Constant import kotlinx.android.synthetic.main.activity_notice_detail.* @@ -54,7 +54,7 @@ val textPaint = minioFileView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - minioFileView.setTextColor(R.color.themeColor.convertColor(this)) + minioFileView.setTextColor(Color.BLUE) minioFileView.setOnClickListener { minioFileName.watchAttachFile(this) diff --git a/app/src/main/java/com/casic/xz/meterage/vm/EntrustViewModel.kt b/app/src/main/java/com/casic/xz/meterage/vm/EntrustViewModel.kt index 2280f88..103c002 100644 --- a/app/src/main/java/com/casic/xz/meterage/vm/EntrustViewModel.kt +++ b/app/src/main/java/com/casic/xz/meterage/vm/EntrustViewModel.kt @@ -7,6 +7,7 @@ import com.casic.xz.meterage.model.ActionResultModel import com.casic.xz.meterage.model.EntrustDetailModel import com.casic.xz.meterage.model.EntrustListModel +import com.casic.xz.meterage.model.SampleListModel import com.casic.xz.meterage.utils.retrofit.RetrofitServiceManager import com.google.gson.Gson import com.google.gson.reflect.TypeToken @@ -25,6 +26,7 @@ val entrustDetail = MutableLiveData() val acceptResult = MutableLiveData() val returnResult = MutableLiveData() + val addResult = MutableLiveData() fun getEntrustList( customerName: String, @@ -119,4 +121,50 @@ loadState.value = LoadState.Fail it.cause.toString().show(BaseApplication.get()) }) + + fun addEntrust( + deliverer: String, + delivererTel: String, + orderTime: String, + planDeliverTime: String, + requireOverTime: String, + customerName: String, + customerPhone: String, + customerAddress: String, + remark: String, + minioFileName: String, + certifications: String, + isUrgent: String, + samples: List + ) = launch({ + loadState.value = LoadState.Loading + val response = RetrofitServiceManager.addEntrust( + deliverer, + delivererTel, + orderTime, + planDeliverTime, + requireOverTime, + customerName, + customerPhone, + customerAddress, + remark, + minioFileName, + certifications, + isUrgent, + samples + ) + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + loadState.value = LoadState.Success + addResult.value = gson.fromJson( + response, object : TypeToken() {}.type + ) + } else { + loadState.value = LoadState.Fail + response.toErrorMessage().show(BaseApplication.get()) + } + }, { + loadState.value = LoadState.Fail + it.cause.toString().show(BaseApplication.get()) + }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/vm/FileUploadViewModel.kt b/app/src/main/java/com/casic/xz/meterage/vm/FileUploadViewModel.kt new file mode 100644 index 0000000..b16c1c7 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/vm/FileUploadViewModel.kt @@ -0,0 +1,40 @@ +package com.casic.xz.meterage.vm + +import androidx.lifecycle.MutableLiveData +import com.casic.xz.meterage.base.BaseApplication +import com.casic.xz.meterage.extensions.separateResponseCode +import com.casic.xz.meterage.extensions.toErrorMessage +import com.casic.xz.meterage.model.UploadResultModel +import com.casic.xz.meterage.utils.FileType +import com.casic.xz.meterage.utils.retrofit.RetrofitServiceManager +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken +import com.pengxh.kt.lite.extensions.launch +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.vm.BaseViewModel +import com.pengxh.kt.lite.vm.LoadState +import java.io.File + +class FileUploadViewModel : BaseViewModel() { + + private val gson by lazy { Gson() } + val resultModel = MutableLiveData() + + fun uploadFile(file: File, type: FileType) = launch({ + loadState.value = LoadState.Loading + val response = RetrofitServiceManager.uploadFile(file, type) + 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(BaseApplication.get()) + } + }, { + loadState.value = LoadState.Fail + it.cause.toString().show(BaseApplication.get()) + }) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/vm/SampleViewModel.kt b/app/src/main/java/com/casic/xz/meterage/vm/SampleViewModel.kt new file mode 100644 index 0000000..182140d --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/vm/SampleViewModel.kt @@ -0,0 +1,65 @@ +package com.casic.xz.meterage.vm + +import androidx.lifecycle.MutableLiveData +import com.casic.xz.meterage.base.BaseApplication +import com.casic.xz.meterage.extensions.separateResponseCode +import com.casic.xz.meterage.extensions.toErrorMessage +import com.casic.xz.meterage.model.SampleListModel +import com.casic.xz.meterage.utils.retrofit.RetrofitServiceManager +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken +import com.pengxh.kt.lite.extensions.launch +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.vm.BaseViewModel +import com.pengxh.kt.lite.vm.LoadState + +/** + * 样品相关 VM + * */ +class SampleViewModel : BaseViewModel() { + + private val gson by lazy { Gson() } + val sampleList = MutableLiveData() + + fun getSampleList( + customerName: String, + customerNo: String, + startTime: String, + endTime: String, + sampleName: String, + sampleNo: String, + sampleModel: String, + sampleBelong: String, + overtimeStatus: String, + ids: Array, + offset: Int + ) = launch({ + loadState.value = LoadState.Loading + val response = RetrofitServiceManager.getSampleList( + customerName, + customerNo, + startTime, + endTime, + sampleName, + sampleNo, + sampleModel, + sampleBelong, + overtimeStatus, + ids, + offset + ) + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + loadState.value = LoadState.Success + sampleList.value = gson.fromJson( + response, object : TypeToken() {}.type + ) + } else { + loadState.value = LoadState.Fail + response.toErrorMessage().show(BaseApplication.get()) + } + }, { + loadState.value = LoadState.Fail + it.cause.toString().show(BaseApplication.get()) + }) +} \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_customer_selector.xml b/app/src/main/res/drawable/bg_customer_selector.xml new file mode 100644 index 0000000..e7292d5 --- /dev/null +++ b/app/src/main/res/drawable/bg_customer_selector.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_sample_selector.xml b/app/src/main/res/drawable/bg_sample_selector.xml new file mode 100644 index 0000000..6b5d5e7 --- /dev/null +++ b/app/src/main/res/drawable/bg_sample_selector.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_check_selected.xml b/app/src/main/res/drawable/ic_check_selected.xml new file mode 100644 index 0000000..4d93f9f --- /dev/null +++ b/app/src/main/res/drawable/ic_check_selected.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_entrust_add.xml b/app/src/main/res/layout/activity_entrust_add.xml index 3d00784..8450d1d 100644 --- a/app/src/main/res/layout/activity_entrust_add.xml +++ b/app/src/main/res/layout/activity_entrust_add.xml @@ -68,6 +68,7 @@ android:text="送样人" /> @@ -81,6 +82,7 @@ android:text="联系方式" /> @@ -115,10 +117,10 @@ style="@style/textViewStyle" android:text="预计送到时间" /> - + android:hint="请选择预计送到时间" /> @@ -129,10 +131,10 @@ style="@style/textViewStyle" android:text="要求检完时间" /> - + android:hint="请选择要求检完时间" /> @@ -143,10 +145,10 @@ style="@style/textViewStyle" android:text="委托方名称" /> - + android:hint="请选择委托方" /> @@ -157,10 +159,9 @@ style="@style/textViewStyle" android:text="委托方电话" /> - + @@ -171,10 +172,9 @@ style="@style/textViewStyle" android:text="委托方地址" /> - + @@ -186,9 +186,9 @@ android:text="备注" /> + android:hint="请输入" /> @@ -200,6 +200,7 @@ android:text="附件" /> diff --git a/app/src/main/res/layout/activity_select_customer.xml b/app/src/main/res/layout/activity_select_customer.xml new file mode 100644 index 0000000..01f5ca1 --- /dev/null +++ b/app/src/main/res/layout/activity_select_customer.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_select_sample.xml b/app/src/main/res/layout/activity_select_sample.xml new file mode 100644 index 0000000..f5c6693 --- /dev/null +++ b/app/src/main/res/layout/activity_select_sample.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_entrust_basic_information.xml b/app/src/main/res/layout/fragment_entrust_basic_information.xml index a37e381..07fbc24 100644 --- a/app/src/main/res/layout/fragment_entrust_basic_information.xml +++ b/app/src/main/res/layout/fragment_entrust_basic_information.xml @@ -199,7 +199,7 @@ android:orientation="horizontal"> + + diff --git a/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt b/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt new file mode 100644 index 0000000..21a71d8 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt @@ -0,0 +1,70 @@ +package com.casic.xz.meterage.adapter + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import com.casic.xz.meterage.R +import com.casic.xz.meterage.extensions.toChineseGrade +import com.casic.xz.meterage.model.CustomerListModel + +class SelectCustomerAdapter( + context: Context, private val dataRows: MutableList +) : RecyclerView.Adapter() { + + private var layoutInflater = LayoutInflater.from(context) + + //选择的位置 + private var selectedPosition = 0 + + //临时记录上次选择的位置 + private var temp = -1 + + override fun getItemCount(): Int = dataRows.size + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ItemViewHolder( + layoutInflater.inflate(R.layout.item_select_customer_lv, parent, false) + ) + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + //绑定数据 + val rowsBean = dataRows[position] + holder.agreementLevelView.text = rowsBean.grade.toChineseGrade() + holder.customerNameView.text = rowsBean.customerName + holder.scaleView.text = rowsBean.companySizeName + holder.overallView.text = "公司规模:${rowsBean.evaluationName}" + holder.fullAddressView.text = "公司地址:${rowsBean.fullAddress}" + + holder.itemView.isSelected = holder.layoutPosition == selectedPosition + holder.itemView.setOnClickListener { + itemCheckedListener?.onItemChecked(rowsBean) + + holder.itemView.isSelected = true + temp = selectedPosition + //设置新的位置 + selectedPosition = holder.layoutPosition + //更新旧位置 + notifyItemChanged(temp) + } + } + + inner class ItemViewHolder(view: View) : RecyclerView.ViewHolder(view) { + var agreementLevelView: TextView = view.findViewById(R.id.agreementLevelView) + var customerNameView: TextView = view.findViewById(R.id.customerNameView) + var scaleView: TextView = view.findViewById(R.id.scaleView) + var overallView: TextView = view.findViewById(R.id.overallView) + var fullAddressView: TextView = view.findViewById(R.id.fullAddressView) + } + + private var itemCheckedListener: OnItemCheckedListener? = null + + interface OnItemCheckedListener { + fun onItemChecked(item: CustomerListModel.DataModel.RowsModel) + } + + fun setOnCheckedListener(listener: OnItemCheckedListener?) { + itemCheckedListener = listener + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt b/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt new file mode 100644 index 0000000..c29461e --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt @@ -0,0 +1,68 @@ +package com.casic.xz.meterage.adapter + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import com.casic.xz.meterage.R +import com.casic.xz.meterage.model.SampleListModel + +class SelectSampleAdapter( + context: Context, private val dataRows: MutableList +) : RecyclerView.Adapter() { + + private var layoutInflater = LayoutInflater.from(context) + private var multipleSelected = mutableSetOf() + private var sampleModes = ArrayList() + + override fun getItemCount(): Int = dataRows.size + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ItemViewHolder( + layoutInflater.inflate(R.layout.item_select_sample_lv, parent, false) + ) + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + //绑定数据 + val rowsBean = dataRows[position] + holder.sampleNameView.text = "${rowsBean.sampleName}【${rowsBean.sampleModel}】" + holder.manufacturingCodeView.text = "出厂编号:${rowsBean.manufacturingNo}" + holder.sampleCodeView.text = "样品编号:${rowsBean.sampleNo}" + holder.validDateView.text = "有效期至:${rowsBean.validDeadline}" + + holder.checkImageView.isSelected = multipleSelected.contains(position) + holder.itemView.setOnClickListener { + if (multipleSelected.contains(position)) { + multipleSelected.remove(position) + sampleModes.remove(dataRows[position]) + holder.checkImageView.isSelected = false + } else { + multipleSelected.add(position) + sampleModes.add(dataRows[position]) + holder.checkImageView.isSelected = true + } + + itemCheckedListener?.onItemChecked(sampleModes) + } + } + + inner class ItemViewHolder(view: View) : RecyclerView.ViewHolder(view) { + var sampleNameView: TextView = view.findViewById(R.id.sampleNameView) + var manufacturingCodeView: TextView = view.findViewById(R.id.manufacturingCodeView) + var sampleCodeView: TextView = view.findViewById(R.id.sampleCodeView) + var validDateView: TextView = view.findViewById(R.id.validDateView) + var checkImageView: ImageView = view.findViewById(R.id.checkImageView) + } + + private var itemCheckedListener: OnItemCheckedListener? = null + + interface OnItemCheckedListener { + fun onItemChecked(items: ArrayList) + } + + fun setOnCheckedListener(listener: OnItemCheckedListener?) { + itemCheckedListener = listener + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/callback/DateSelectedCallback.kt b/app/src/main/java/com/casic/xz/meterage/callback/DateSelectedCallback.kt new file mode 100644 index 0000000..8196110 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/callback/DateSelectedCallback.kt @@ -0,0 +1,5 @@ +package com.casic.xz.meterage.callback + +interface DateSelectedCallback { + fun onDateSelected(date: String) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/Activity.kt b/app/src/main/java/com/casic/xz/meterage/extensions/Activity.kt new file mode 100644 index 0000000..e112d1c --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/extensions/Activity.kt @@ -0,0 +1,33 @@ +package com.casic.xz.meterage.extensions + +import android.app.Activity +import com.casic.xz.meterage.R +import com.casic.xz.meterage.callback.DateSelectedCallback +import com.github.gzuliyujiang.wheelpicker.DatePicker +import com.github.gzuliyujiang.wheelpicker.annotation.DateMode +import com.github.gzuliyujiang.wheelpicker.entity.DateEntity +import com.pengxh.kt.lite.extensions.convertColor +import com.pengxh.kt.lite.extensions.sp2px + +fun Activity.showDatePicker(callback: DateSelectedCallback) { + val datePicker = DatePicker(this) + + val layout = datePicker.wheelLayout + layout.setDateMode(DateMode.YEAR_MONTH_DAY) + layout.setDateLabel("年", "月", "日"); + layout.setTextSize(14f.sp2px(this).toFloat()) + layout.setSelectedTextSize(16f.sp2px(this).toFloat()) + layout.setSelectedTextColor(R.color.themeColor.convertColor(this)) + layout.setSelectedTextBold(true) + layout.setResetWhenLinkage(false) + layout.setRange( + DateEntity.today(), + DateEntity.target(2050, 12, 31), + DateEntity.today() + ) + + datePicker.setOnDatePickedListener { year, month, day -> + callback.onDateSelected(String.format("%s-%s-%s", year, month, day)) + } + datePicker.show() +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt b/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt index 016ebcb..cf6bf49 100644 --- a/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt +++ b/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt @@ -4,7 +4,7 @@ * ArrayList扩展方法 */ -//将图片集合格式化成满足上传格式的数据 +//将集合格式化成满足上传格式的数据 fun ArrayList.reformat(): String { if (this.isEmpty()) return "" val builder = StringBuilder() diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt b/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt index 7c57643..aa9b92b 100644 --- a/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt +++ b/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt @@ -1,7 +1,6 @@ package com.casic.xz.meterage.extensions import android.content.Context -import android.util.Log import android.view.ViewGroup import com.casic.xz.meterage.base.BaseApplication import com.pengxh.kt.lite.extensions.dp2px @@ -9,9 +8,8 @@ fun Context.initLayoutImmersionBar(rootView: ViewGroup) { var statusBarHeight = QMUIDisplayHelper.getStatusBarHeight(this) - Log.d("Casic", "状态栏高度: $statusBarHeight") if (statusBarHeight == 0) { - statusBarHeight = 44f.dp2px(BaseApplication.get()) + statusBarHeight = 40f.dp2px(BaseApplication.get()) } rootView.setPadding(0, statusBarHeight, 0, 0) rootView.requestLayout() diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/String.kt b/app/src/main/java/com/casic/xz/meterage/extensions/String.kt index 28f70d8..6234d43 100644 --- a/app/src/main/java/com/casic/xz/meterage/extensions/String.kt +++ b/app/src/main/java/com/casic/xz/meterage/extensions/String.kt @@ -128,9 +128,10 @@ fun String.combineImagePath(): String { if (this.isEmpty()) return this val defaultValue = SaveKeyValues.getValue( - LocaleConstant.DEFAULT_SERVER_CONFIG, LocaleConstant.SERVER_BASE_URL + LocaleConstant.FILE_SERVER_CONFIG, LocaleConstant.File_SERVER_URL ) as String - return "$defaultValue/static/${this.replace("\\", "/")}" + //http://111.198.10.15:21408/test/1677479806059688_1677479806038.jpeg + return "$defaultValue/test/${this.replace("\\", "/")}" } fun String.isEarlier(time: String): Boolean { diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt index 25fa87b..a0e1358 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt @@ -1,18 +1,12 @@ package com.casic.xz.meterage.fragment.customer +import android.graphics.Color import android.graphics.Paint import com.casic.xz.meterage.R -import com.casic.xz.meterage.extensions.combineImagePath import com.casic.xz.meterage.extensions.toChineseGrade +import com.casic.xz.meterage.extensions.watchAttachFile import com.casic.xz.meterage.model.CustomerDetailModel -import com.casic.xz.meterage.view.BigImageActivity -import com.casic.xz.meterage.view.notice.PreviewDocumentActivity -import com.casic.xz.meterage.view.notice.PreviewPdfActivity -import com.casic.xz.meterage.view.notice.PreviewTextActivity import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.extensions.show import kotlinx.android.synthetic.main.fragment_customer_basic_information.* class BasicInformationFragment(private val data: CustomerDetailModel.DataModel) : @@ -48,30 +42,11 @@ val textPaint = minioFileView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - minioFileView.setTextColor(R.color.themeColor.convertColor(requireContext())) + minioFileView.setTextColor(Color.BLUE) minioFileView.setOnClickListener { //查看附件 - if (minioFileName.endsWith("pdf")) { - requireContext().navigatePageTo(minioFileName) - } else if ( - minioFileName.endsWith("doc") || - minioFileName.endsWith("docx") - ) { - requireContext().navigatePageTo(minioFileName) - } else if (minioFileName.endsWith("txt")) { - requireContext().navigatePageTo(minioFileName) - } else if ( - minioFileName.endsWith("png") || - minioFileName.endsWith("jpeg") || - minioFileName.endsWith("jpg") - ) { - val urls = ArrayList() - urls.add(minioFileName.combineImagePath()) - requireContext().navigatePageTo(0, urls) - } else { - "文件类型未知,无法打开附件".show(requireContext()) - } + minioFileName.watchAttachFile(requireContext()) } } } diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt index 77846b4..3a0fe2e 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt @@ -1,5 +1,6 @@ package com.casic.xz.meterage.fragment.device +import android.graphics.Color import android.graphics.Paint import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R @@ -7,7 +8,6 @@ import com.casic.xz.meterage.utils.LoadingDialogHub import com.casic.xz.meterage.vm.EquipmentViewModel import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor import com.pengxh.kt.lite.vm.LoadState import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import kotlinx.android.synthetic.main.fragment_device_basic_information.* @@ -56,7 +56,7 @@ val textPaint = documentsView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - documentsView.setTextColor(R.color.themeColor.convertColor(requireContext())) + documentsView.setTextColor(Color.BLUE) val files = ArrayList() data.fileList.forEach { file -> @@ -66,7 +66,7 @@ BottomActionSheet.Builder() .setContext(requireContext()) .setActionItemTitle(files) - .setItemTextColor(R.color.themeColor.convertColor(requireContext())) + .setItemTextColor(Color.BLUE) .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { override fun onActionItemClick(position: Int) { diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt index 15dc3d2..10eeff8 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt @@ -1,5 +1,6 @@ package com.casic.xz.meterage.fragment.entrust +import android.graphics.Color import android.graphics.Paint import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R @@ -9,7 +10,6 @@ import com.casic.xz.meterage.model.EntrustDetailModel import com.casic.xz.meterage.vm.DictionaryViewModel import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor import kotlinx.android.synthetic.main.fragment_entrust_basic_information.* class BasicInformationFragment(private val data: EntrustDetailModel.DataModel) : @@ -38,7 +38,7 @@ val textPaint = annexView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - annexView.setTextColor(R.color.themeColor.convertColor(requireContext())) + annexView.setTextColor(Color.BLUE) annexView.setOnClickListener { minioFileName.watchAttachFile(requireContext()) @@ -59,9 +59,9 @@ //加急 if (data.isUrgent == "0") { - RadioButton2.isChecked = true + radioButton2.isChecked = true } else { - RadioButton1.isChecked = true + radioButton1.isChecked = true } //样品 diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/equipment/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/equipment/BasicInformationFragment.kt index 72b523c..7bc3b01 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/equipment/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/equipment/BasicInformationFragment.kt @@ -1,5 +1,6 @@ package com.casic.xz.meterage.fragment.equipment +import android.graphics.Color import android.graphics.Paint import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R @@ -7,7 +8,6 @@ import com.casic.xz.meterage.utils.LoadingDialogHub import com.casic.xz.meterage.vm.EquipmentViewModel import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor import com.pengxh.kt.lite.vm.LoadState import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import kotlinx.android.synthetic.main.fragment_equipment_basic_information.* @@ -74,7 +74,7 @@ val textPaint = instructionsView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - instructionsView.setTextColor(R.color.themeColor.convertColor(requireContext())) + instructionsView.setTextColor(Color.BLUE) val files = ArrayList() data.fileList.forEach { file -> @@ -84,7 +84,7 @@ BottomActionSheet.Builder() .setContext(requireContext()) .setActionItemTitle(files) - .setItemTextColor(R.color.themeColor.convertColor(requireContext())) + .setItemTextColor(Color.BLUE) .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { override fun onActionItemClick(position: Int) { diff --git a/app/src/main/java/com/casic/xz/meterage/model/SampleListModel.java b/app/src/main/java/com/casic/xz/meterage/model/SampleListModel.java new file mode 100644 index 0000000..5784343 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/model/SampleListModel.java @@ -0,0 +1,193 @@ +package com.casic.xz.meterage.model; + +import java.util.List; + +public class SampleListModel { + + private int code; + private DataModel data; + private String message; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataModel getData() { + return data; + } + + public void setData(DataModel data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public static class DataModel { + private List rows; + private int total; + + public List getRows() { + return rows; + } + + public void setRows(List rows) { + this.rows = rows; + } + + public int getTotal() { + return total; + } + + public void setTotal(int total) { + this.total = total; + } + + public static class RowsModel { + private String certificationStatus; + private String customerName; + private String customerNo; + private String id; + private String manufacturingNo; + private String measureLastTime; + private String measurePeriod; + private String orderId; + private String remark; + private String sampleModel; + private String sampleName; + private String sampleNo; + private String sampleSatus; + private String sampleSatusName; + private String validDeadline; + + public String getCertificationStatus() { + return certificationStatus; + } + + public void setCertificationStatus(String certificationStatus) { + this.certificationStatus = certificationStatus; + } + + public String getCustomerName() { + return customerName; + } + + public void setCustomerName(String customerName) { + this.customerName = customerName; + } + + public String getCustomerNo() { + return customerNo; + } + + public void setCustomerNo(String customerNo) { + this.customerNo = customerNo; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getManufacturingNo() { + return manufacturingNo; + } + + public void setManufacturingNo(String manufacturingNo) { + this.manufacturingNo = manufacturingNo; + } + + public String getMeasureLastTime() { + return measureLastTime; + } + + public void setMeasureLastTime(String measureLastTime) { + this.measureLastTime = measureLastTime; + } + + public String getMeasurePeriod() { + return measurePeriod; + } + + public void setMeasurePeriod(String measurePeriod) { + this.measurePeriod = measurePeriod; + } + + public String getOrderId() { + return orderId; + } + + public void setOrderId(String orderId) { + this.orderId = orderId; + } + + public String getRemark() { + return remark; + } + + public void setRemark(String remark) { + this.remark = remark; + } + + public String getSampleModel() { + return sampleModel; + } + + public void setSampleModel(String sampleModel) { + this.sampleModel = sampleModel; + } + + public String getSampleName() { + return sampleName; + } + + public void setSampleName(String sampleName) { + this.sampleName = sampleName; + } + + public String getSampleNo() { + return sampleNo; + } + + public void setSampleNo(String sampleNo) { + this.sampleNo = sampleNo; + } + + public String getSampleSatus() { + return sampleSatus; + } + + public void setSampleSatus(String sampleSatus) { + this.sampleSatus = sampleSatus; + } + + public String getSampleSatusName() { + return sampleSatusName; + } + + public void setSampleSatusName(String sampleSatusName) { + this.sampleSatusName = sampleSatusName; + } + + public String getValidDeadline() { + return validDeadline; + } + + public void setValidDeadline(String validDeadline) { + this.validDeadline = validDeadline; + } + } + } +} diff --git a/app/src/main/java/com/casic/xz/meterage/model/UploadResultModel.java b/app/src/main/java/com/casic/xz/meterage/model/UploadResultModel.java new file mode 100644 index 0000000..f2a6a41 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/model/UploadResultModel.java @@ -0,0 +1,34 @@ +package com.casic.xz.meterage.model; + +import java.util.List; + +public class UploadResultModel { + + private int code; + private List data; + private String message; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public List getData() { + return data; + } + + public void setData(List data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } +} diff --git a/app/src/main/java/com/casic/xz/meterage/utils/FileType.kt b/app/src/main/java/com/casic/xz/meterage/utils/FileType.kt new file mode 100644 index 0000000..17e2bca --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/utils/FileType.kt @@ -0,0 +1,23 @@ +package com.casic.xz.meterage.utils + +sealed class FileType { + /** + * PDF文件 + */ + object PDF : FileType() + + /** + * WORD文件 + */ + object WORD : FileType() + + /** + * IMAGE图片 + */ + object IMAGE : FileType() + + /** + * 未知类型(Excel) + */ + object UNKNOWN : FileType() +} diff --git a/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitService.kt index bc3f8d6..8f4fe44 100644 --- a/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitService.kt @@ -1,5 +1,6 @@ package com.casic.xz.meterage.utils.retrofit +import okhttp3.MultipartBody import okhttp3.RequestBody import retrofit2.http.* @@ -35,6 +36,16 @@ ): String /** + * 上传文件 + */ + @Multipart + @POST("/minio/file/upload") + suspend fun uploadFile( + @Header("token") token: String, + @Part file: MultipartBody.Part + ): String + + /** * 获取通知公告列表 */ @POST("/system/notice/listPage") @@ -209,4 +220,24 @@ @Header("token") token: String, @Body requestBody: RequestBody ): String + + /** + * 获取样品列表 + */ + @POST("/customer/sample/listPage") + suspend fun getSampleList( + @Header("token") token: String, + @Body requestBody: RequestBody, + @QueryMap limit: Map, + @QueryMap offset: Map + ): String + + /** + * 新增委托书 + */ + @POST("/business/order/add") + suspend fun addEntrust( + @Header("token") token: String, + @Body requestBody: RequestBody + ): String } \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitServiceManager.kt index cb22e45..90abe5a 100644 --- a/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitServiceManager.kt @@ -1,13 +1,20 @@ package com.casic.xz.meterage.utils.retrofit +import com.alibaba.fastjson2.JSON +import com.alibaba.fastjson2.JSONArray +import com.alibaba.fastjson2.JSONObject +import com.casic.xz.meterage.model.SampleListModel import com.casic.xz.meterage.utils.AuthenticationHelper +import com.casic.xz.meterage.utils.FileType import com.casic.xz.meterage.utils.LocaleConstant import com.pengxh.kt.lite.utils.RetrofitFactory import com.pengxh.kt.lite.utils.SaveKeyValues import okhttp3.MediaType.Companion.toMediaType +import okhttp3.MediaType.Companion.toMediaTypeOrNull +import okhttp3.MultipartBody +import okhttp3.RequestBody.Companion.asRequestBody import okhttp3.RequestBody.Companion.toRequestBody -import org.json.JSONArray -import org.json.JSONObject +import java.io.File object RetrofitServiceManager { @@ -31,9 +38,9 @@ */ suspend fun login(sid: String, account: String, secretKey: String): String { val paramObject = JSONObject() - paramObject.put("sid", sid) - paramObject.put("username", account) - paramObject.put("password", secretKey) + paramObject["sid"] = sid + paramObject["username"] = account + paramObject["password"] = secretKey val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -55,6 +62,20 @@ } /** + * 上传文件 + */ + suspend fun uploadFile(file: File, type: FileType): String { + val requestBody = when (type) { + FileType.PDF -> file.asRequestBody("application/pdf".toMediaTypeOrNull()) + FileType.WORD -> file.asRequestBody("application/msword".toMediaTypeOrNull()) + FileType.IMAGE -> file.asRequestBody("image/png".toMediaTypeOrNull()) + else -> file.asRequestBody("application/vnd.ms-excel".toMediaTypeOrNull()) + } + val filePart = MultipartBody.Part.createFormData("multipartFile", file.name, requestBody) + return api.uploadFile(AuthenticationHelper.token!!, filePart) + } + + /** * 获取通知公告列表 */ suspend fun getNoticeList( @@ -66,11 +87,11 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("noticeNo", noticeNo) - paramObject.put("noticeTitle", noticeTitle) - paramObject.put("noticePublisher", noticePublisher) - paramObject.put("noticeStartTime", noticeStartTime) - paramObject.put("noticeEndTime", noticeEndTime) + paramObject["noticeNo"] = noticeNo + paramObject["noticeTitle"] = noticeTitle + paramObject["noticePublisher"] = noticePublisher + paramObject["noticeStartTime"] = noticeStartTime + paramObject["noticeEndTime"] = noticeEndTime val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -105,26 +126,21 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("equipmentNo", equipmentNo) - paramObject.put("equipmentName", equipmentName) - paramObject.put("mesureType", mesureType) - paramObject.put("managerState", managerState) - paramObject.put("useDept", useDept) - paramObject.put("assetType", assetType) - paramObject.put("equipmentCategory", equipmentCategory) - paramObject.put("isCalibrationTestEquipment", isCalibrationTestEquipment) - paramObject.put("isMeasureAccount", isMeasureAccount) - paramObject.put("isStandardSupportEquipment", isStandardSupportEquipment) - paramObject.put("isFixedAssets", isFixedAssets) - paramObject.put("validStartDate", validStartDate) - paramObject.put("validEndDate", validEndDate) - paramObject.put("abc", abc) - - val jsonArray = JSONArray() - ids.forEach { - jsonArray.put(it) - } - paramObject.put("ids", jsonArray) + paramObject["equipmentNo"] = equipmentNo + paramObject["equipmentName"] = equipmentName + paramObject["mesureType"] = mesureType + paramObject["managerState"] = managerState + paramObject["useDept"] = useDept + paramObject["assetType"] = assetType + paramObject["equipmentCategory"] = equipmentCategory + paramObject["isCalibrationTestEquipment"] = isCalibrationTestEquipment + paramObject["isMeasureAccount"] = isMeasureAccount + paramObject["isStandardSupportEquipment"] = isStandardSupportEquipment + paramObject["isFixedAssets"] = isFixedAssets + paramObject["validStartDate"] = validStartDate + paramObject["validEndDate"] = validEndDate + paramObject["abc"] = abc + paramObject["ids"] = JSONArray.parseArray(JSON.toJSONString(ids)) val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() @@ -143,7 +159,7 @@ */ suspend fun getEquipmentDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -164,13 +180,13 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("standardNo", standardNo) - paramObject.put("standardName", standardName) - paramObject.put("category", category) - paramObject.put("managerState", managerState) - paramObject.put("standardLaboratory", standardLaboratory) - paramObject.put("preparationDate", preparationDate) - paramObject.put("id", id) + paramObject["standardNo"] = standardNo + paramObject["standardName"] = standardName + paramObject["category"] = category + paramObject["managerState"] = managerState + paramObject["standardLaboratory"] = standardLaboratory + paramObject["preparationDate"] = preparationDate + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -193,7 +209,7 @@ */ suspend fun getStandardDeviceDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -212,11 +228,11 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("checkType", checkType) - paramObject.put("priceItem", priceItem) - paramObject.put("priceName", priceName) - paramObject.put("priceNo", priceNo) - paramObject.put("priceType", priceType) + paramObject["checkType"] = checkType + paramObject["priceItem"] = priceItem + paramObject["priceName"] = priceName + paramObject["priceNo"] = priceNo + paramObject["priceType"] = priceType val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -234,7 +250,7 @@ */ suspend fun getCapabilityDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -257,20 +273,15 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("createStartTime", createStartTime) - paramObject.put("createEndTime", createEndTime) - paramObject.put("deptId", deptId) - paramObject.put("director", director) - paramObject.put("effectiveCompany", effectiveCompany) - paramObject.put("trainStartTime", trainStartTime) - paramObject.put("trainEndTime", trainEndTime) - paramObject.put("formId", formId) - - val jsonArray = JSONArray() - ids.forEach { - jsonArray.put(it) - } - paramObject.put("ids", jsonArray) + paramObject["createStartTime"] = createStartTime + paramObject["createEndTime"] = createEndTime + paramObject["deptId"] = deptId + paramObject["director"] = director + paramObject["effectiveCompany"] = effectiveCompany + paramObject["trainStartTime"] = trainStartTime + paramObject["trainEndTime"] = trainEndTime + paramObject["formId"] = formId + paramObject["ids"] = JSONArray.parseArray(JSON.toJSONString(ids)) val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() @@ -294,7 +305,7 @@ */ suspend fun getMeterageTrainDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -308,10 +319,10 @@ bussinessSize: String, customerName: String, customerNo: String, grade: String, offset: Int ): String { val paramObject = JSONObject() - paramObject.put("bussinessSize", bussinessSize) - paramObject.put("customerName", customerName) - paramObject.put("customerNo", customerNo) - paramObject.put("grade", grade) + paramObject["bussinessSize"] = bussinessSize + paramObject["customerName"] = customerName + paramObject["customerNo"] = customerNo + paramObject["grade"] = grade val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() @@ -330,7 +341,7 @@ */ suspend fun getCustomerDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -342,7 +353,7 @@ */ suspend fun getStaffList(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -354,7 +365,7 @@ */ suspend fun getSupportEquipmentList(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -366,7 +377,7 @@ */ suspend fun getVerifyProcedureList(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -389,20 +400,15 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("customerName", customerName) - paramObject.put("customerNo", customerNo) - paramObject.put("deliverer", deliverer) - paramObject.put("orderCode", orderCode) - paramObject.put("startTime", startTime) - paramObject.put("endTime", endTime) - paramObject.put("isUrgent", isUrgent) - paramObject.put("status", status) - - val jsonArray = JSONArray() - ids.forEach { - jsonArray.put(it) - } - paramObject.put("ids", jsonArray) + paramObject["customerName"] = customerName + paramObject["customerNo"] = customerNo + paramObject["deliverer"] = deliverer + paramObject["orderCode"] = orderCode + paramObject["startTime"] = startTime + paramObject["endTime"] = endTime + paramObject["isUrgent"] = isUrgent + paramObject["status"] = status + paramObject["ids"] = JSONArray.parseArray(JSON.toJSONString(ids)) val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() @@ -421,7 +427,7 @@ */ suspend fun getEntrustDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -433,7 +439,7 @@ */ suspend fun acceptEntrust(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -446,10 +452,89 @@ */ suspend fun returnEntrust(id: String, selected: ArrayList): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) return api.returnEntrust(AuthenticationHelper.token!!, requestBody) } + + /** + * 获取样品列表 + */ + suspend fun getSampleList( + customerName: String, + customerNo: String, + startTime: String, + endTime: String, + sampleName: String, + sampleNo: String, + sampleModel: String, + sampleBelong: String, + overtimeStatus: String, + ids: Array, + offset: Int + ): String { + val paramObject = JSONObject() + paramObject["customerName"] = customerName + paramObject["customerNo"] = customerNo + paramObject["startTime"] = startTime + paramObject["endTime"] = endTime + paramObject["sampleName"] = sampleName + paramObject["sampleNo"] = sampleNo + paramObject["sampleModel"] = sampleModel + paramObject["sampleBelong"] = sampleBelong + paramObject["overtimeStatus"] = overtimeStatus + paramObject["ids"] = JSONArray.parseArray(JSON.toJSONString(ids)) + + val requestBody = paramObject.toString().toRequestBody( + "application/json;charset=UTF-8".toMediaType() + ) + + val limitMap = HashMap() + limitMap["limit"] = LocaleConstant.PAGE_LIMIT + + val offsetMap = HashMap() + offsetMap["offset"] = offset + return api.getSampleList(AuthenticationHelper.token!!, requestBody, limitMap, offsetMap) + } + + /** + * 新增委托书 + */ + suspend fun addEntrust( + deliverer: String, + delivererTel: String, + orderTime: String, + planDeliverTime: String, + requireOverTime: String, + customerName: String, + customerPhone: String, + customerAddress: String, + remark: String, + minioFileName: String, + certifications: String, + isUrgent: String, + samples: List + ): String { + val paramObject = JSONObject() + paramObject["deliverer"] = deliverer + paramObject["delivererTel"] = delivererTel + paramObject["orderTime"] = orderTime + paramObject["planDeliverTime"] = planDeliverTime + paramObject["requireOverTime"] = requireOverTime + paramObject["customerName"] = customerName + paramObject["customerPhone"] = customerPhone + paramObject["customerAddress"] = customerAddress + paramObject["remark"] = remark + paramObject["minioFileName"] = minioFileName + paramObject["certifications"] = certifications + paramObject["isUrgent"] = isUrgent + paramObject["customerSampleInfoList"] = JSONArray.parseArray(JSON.toJSONString(samples)) + + val requestBody = paramObject.toString().toRequestBody( + "application/json;charset=UTF-8".toMediaType() + ) + return api.addEntrust(AuthenticationHelper.token!!, requestBody) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/view/home/EntrustAddActivity.kt b/app/src/main/java/com/casic/xz/meterage/view/home/EntrustAddActivity.kt index 3e30095..9c8d27b 100644 --- a/app/src/main/java/com/casic/xz/meterage/view/home/EntrustAddActivity.kt +++ b/app/src/main/java/com/casic/xz/meterage/view/home/EntrustAddActivity.kt @@ -1,52 +1,211 @@ package com.casic.xz.meterage.view.home +import android.app.Activity +import android.content.Context +import android.content.Intent +import android.graphics.Color +import android.graphics.Paint import android.util.Log +import androidx.activity.result.ActivityResult +import androidx.activity.result.ActivityResultCallback +import androidx.activity.result.contract.ActivityResultContracts import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R import com.casic.xz.meterage.adapter.CertificateTypeAdapter2 -import com.casic.xz.meterage.extensions.initLayoutImmersionBar +import com.casic.xz.meterage.adapter.CustomerSampleAdapter +import com.casic.xz.meterage.callback.DateSelectedCallback +import com.casic.xz.meterage.callback.OnImageCompressListener +import com.casic.xz.meterage.extensions.* +import com.casic.xz.meterage.model.EntrustDetailModel +import com.casic.xz.meterage.model.SampleListModel +import com.casic.xz.meterage.utils.FileType +import com.casic.xz.meterage.utils.GlideLoadEngine +import com.casic.xz.meterage.utils.LoadingDialogHub import com.casic.xz.meterage.vm.DictionaryViewModel +import com.casic.xz.meterage.vm.EntrustViewModel +import com.casic.xz.meterage.vm.FileUploadViewModel +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken import com.gyf.immersionbar.ImmersionBar +import com.luck.picture.lib.basic.PictureSelector +import com.luck.picture.lib.config.SelectMimeType +import com.luck.picture.lib.entity.LocalMedia +import com.luck.picture.lib.interfaces.OnResultCallbackListener import com.pengxh.kt.lite.base.KotlinBaseActivity -import com.pengxh.kt.lite.extensions.toJson +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.vm.LoadState +import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import kotlinx.android.synthetic.main.activity_entrust_add.* +import java.io.File + class EntrustAddActivity : KotlinBaseActivity() { + private val context: Context = this@EntrustAddActivity + private val gson by lazy { Gson() } private lateinit var dictionaryViewModel: DictionaryViewModel - private var checkedItems = ArrayList() + private lateinit var fileUploadViewModel: FileUploadViewModel + private lateinit var entrustViewModel: EntrustViewModel + private lateinit var sampleAdapter: CustomerSampleAdapter + private var checkedItems = ArrayList() + private var isUrgent = "0" + private var sampleModels: ArrayList? = null + private var dataBeans = ArrayList() override fun initData() { //证书 dictionaryViewModel = ViewModelProvider(this)[DictionaryViewModel::class.java] dictionaryViewModel.getDictionaryByCode("certificationClass") - dictionaryViewModel.dictionary.observe(this) { dic -> - if (dic.code == 200) { - val typeAdapter2 = CertificateTypeAdapter2(this, dic.data) + dictionaryViewModel.dictionary.observe(this) { + if (it.code == 200) { + val typeAdapter2 = CertificateTypeAdapter2(this, it.data) typeRecyclerView.adapter = typeAdapter2 typeAdapter2.setOnItemCheckedListener(object : CertificateTypeAdapter2.OnItemCheckedListener { override fun onItemChecked(position: Int, isChecked: Boolean) { if (isChecked) { - checkedItems.add(position) + checkedItems.add(position.toString()) } else { - checkedItems.remove(position) + checkedItems.remove(position.toString()) } } }) } } + + fileUploadViewModel = ViewModelProvider(this)[FileUploadViewModel::class.java] + fileUploadViewModel.resultModel.observe(this) { + if (it.code == 200) { + val annexName = it.data[0] + annexView.text = annexName + val textPaint = annexView.paint + textPaint.flags = Paint.UNDERLINE_TEXT_FLAG + textPaint.isAntiAlias = true + annexView.setTextColor(Color.BLUE) + + annexView.setOnClickListener { + annexName.watchAttachFile(this) + } + } + } + + entrustViewModel = ViewModelProvider(this)[EntrustViewModel::class.java] + entrustViewModel.addResult.observe(this) { + if (it.code == 200) { + finish() + } + } + + //样品列表 + sampleAdapter = CustomerSampleAdapter(this, dataBeans) + sampleRecyclerView.adapter = sampleAdapter } + private val selectCustomerLauncher = + registerForActivityResult(ActivityResultContracts.StartActivityForResult(), + object : ActivityResultCallback { + override fun onActivityResult(result: ActivityResult?) { + if (result?.resultCode == Activity.RESULT_OK) { + val data = result.data ?: return + + entrustNameView.text = data.getStringExtra("entrustName") + entrustContactView.text = data.getStringExtra("entrustContact") + entrustAddressView.text = data.getStringExtra("entrustAddress") + } + } + }) + + private val selectSampleLauncher = + registerForActivityResult(ActivityResultContracts.StartActivityForResult(), + object : ActivityResultCallback { + override fun onActivityResult(result: ActivityResult?) { + if (result?.resultCode == Activity.RESULT_OK) { + val data = result.data ?: return + + val modelsJson = data.getStringExtra("sampleModels") + if (!modelsJson.isNullOrBlank()) { + sampleModels = gson.fromJson( + modelsJson, + object : + TypeToken>() {}.type + ) + } + + //刷新列表 + dataBeans.clear() + sampleModels?.forEach { + val model = + EntrustDetailModel.DataModel.CustomerSampleInfoListModel() + + model.customerName = it.customerName + model.customerNo = it.customerNo + model.id = it.id + model.manufacturingNo = it.manufacturingNo + model.measureLastTime = it.measureLastTime + model.measurePeriod = it.measurePeriod + model.orderId = it.orderId + model.remark = it.remark + model.sampleModel = it.sampleModel + model.sampleName = it.sampleName + model.sampleNo = it.sampleNo + model.validDeadline = it.validDeadline + + dataBeans.add(model) + } + sampleAdapter.notifyDataSetChanged() + } + } + }) + override fun initEvent() { + leftBackView.setOnClickListener { finish() } + + estimateTimeView.setOnClickListener { + showDatePicker(object : DateSelectedCallback { + override fun onDateSelected(date: String) { + estimateTimeView.text = date + } + }) + } + + completedView.setOnClickListener { + showDatePicker(object : DateSelectedCallback { + override fun onDateSelected(date: String) { + completedView.text = date + } + }) + } + + entrustNameView.setOnClickListener { + selectCustomerLauncher.launch(Intent(this, SelectCustomerActivity::class.java)) + } + //上传附件 uploadFileButton.setOnClickListener { + BottomActionSheet.Builder() + .setContext(this) + .setItemTextColor(Color.BLUE) + .setActionItemTitle(listOf("文件", "图片")) + .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { + override fun onActionItemClick(position: Int) { + when (position) { + 0 -> uploadFile() + 1 -> uploadImage() + } + } + }).build().show() + } + radioGroup.setOnCheckedChangeListener { _, checkedId -> + when (checkedId) { + R.id.radioButton1 -> isUrgent = "1" + R.id.radioButton2 -> isUrgent = "0" + } } //选择样品 selectSampleButton.setOnClickListener { - + selectSampleLauncher.launch(Intent(this, SelectSampleActivity::class.java)) } //写入样品信息 @@ -55,14 +214,68 @@ } pushEntrustView.setOnClickListener { - Log.d("Casic", "EntrustAddActivity => initEvent: ${checkedItems.toJson()}") + val sender = senderView.text.toString() + if (sender.isBlank()) { + "请填写送样人名字".show(this) + return@setOnClickListener + } + + val contact = contactView.text.toString() + if (contact.isBlank()) { + "请填写送样人联系方式".show(this) + return@setOnClickListener + } + + val estimateTime = estimateTimeView.text.toString() + if (estimateTime.isBlank()) { + "请选择预计送到的时间".show(this) + return@setOnClickListener + } + + val entrustName = entrustNameView.text.toString() + if (entrustName.isBlank()) { + "请选择委托方".show(this) + return@setOnClickListener + } + + if (sampleModels == null) { + "请选择样品".show(this) + return@setOnClickListener + } + entrustViewModel.addEntrust( + sender, + contact, + createEntrustDateView.text.toString(), + estimateTime, + completedView.text.toString(), + entrustName, + entrustContactView.text.toString(), + entrustAddressView.text.toString(), + remarkView.text.toString(), + annexView.text.toString(), + checkedItems.reformat(), + isUrgent, + sampleModels!! + ) } } override fun initLayoutView(): Int = R.layout.activity_entrust_add override fun observeRequestState() { + fileUploadViewModel.loadState.observe(this) { + when (it) { + LoadState.Loading -> LoadingDialogHub.show(this, "文件上传中,请稍后...") + else -> LoadingDialogHub.dismiss() + } + } + entrustViewModel.loadState.observe(this) { + when (it) { + LoadState.Loading -> LoadingDialogHub.show(this, "委托创建中,请稍后...") + else -> LoadingDialogHub.dismiss() + } + } } override fun setupTopBarLayout() { @@ -70,4 +283,62 @@ initLayoutImmersionBar(rootView) titleView.text = "委托需求" } + + private fun uploadFile() { +// val explorer = FileExplorer(this) +// explorer.setInitDir(ExplorerMode.FILE, Environment.getExternalStorageDirectory()) +// explorer.setShowHomeDir(true) +// explorer.setShowUpDir(true) +// explorer.setShowHideDir(true) +// explorer.setAllowExtensions(arrayOf(".doc", ".docx", ".xls", ".xlsx", ".pdf")) +// explorer.setOnFileClickedListener { +// val type = if (it.name.endsWith(".doc") || it.name.endsWith(".docx")) { +// FileType.WORD +// } else if (it.name.endsWith(".pdf")) { +// FileType.PDF +// } else { +// FileType.UNKNOWN +// } +// +// Log.d("Casic", "EntrustAddActivity => uploadFile: ${it.absolutePath}") +// fileUploadViewModel.uploadFile(it, type) +// } + } + + private fun uploadImage() { + PictureSelector.create(this) + .openGallery(SelectMimeType.ofImage()) + .isGif(false) + .isMaxSelectEnabledMask(true) + .setFilterMinFileSize(100) + .setMaxSelectNum(1) + .isDisplayCamera(false) + .setImageEngine(GlideLoadEngine.instance) + .forResult(object : OnResultCallbackListener { + override fun onResult(result: ArrayList?) { + if (result == null) { + "选择照片失败,请重试".show(context) + return + } + result[0].realPath.compressImage(context, object : OnImageCompressListener { + override fun onSuccess(file: File) { + Log.d( + "Casic", "EntrustAddActivity => onSuccess: ${file.absolutePath}" + ) + ///storage/emulated/0/Android/data/com.casic.xz.meterage/files/Pictures/CompressImage/1677478115391211.jpeg + //上传图片 + fileUploadViewModel.uploadFile(file, FileType.IMAGE) + } + + override fun onError(e: Throwable) { + e.printStackTrace() + } + }) + } + + override fun onCancel() { + + } + }) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/view/home/SelectCustomerActivity.kt b/app/src/main/java/com/casic/xz/meterage/view/home/SelectCustomerActivity.kt new file mode 100644 index 0000000..9bf6a1a --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/view/home/SelectCustomerActivity.kt @@ -0,0 +1,158 @@ +package com.casic.xz.meterage.view.home + +import android.content.Intent +import android.os.Handler +import androidx.lifecycle.ViewModelProvider +import androidx.recyclerview.widget.DefaultItemAnimator +import androidx.recyclerview.widget.DividerItemDecoration +import com.casic.xz.meterage.R +import com.casic.xz.meterage.adapter.SelectCustomerAdapter +import com.casic.xz.meterage.extensions.initLayoutImmersionBar +import com.casic.xz.meterage.extensions.showEmptyPage +import com.casic.xz.meterage.model.CustomerListModel +import com.casic.xz.meterage.utils.LoadingDialogHub +import com.casic.xz.meterage.vm.CustomerViewModel +import com.gyf.immersionbar.ImmersionBar +import com.pengxh.kt.lite.base.KotlinBaseActivity +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.utils.WeakReferenceHandler +import com.pengxh.kt.lite.vm.LoadState +import kotlinx.android.synthetic.main.activity_select_customer.* +import kotlinx.android.synthetic.main.include_base_title.* +import kotlinx.android.synthetic.main.include_empty_view.* + +class SelectCustomerActivity : KotlinBaseActivity() { + + private lateinit var weakReferenceHandler: WeakReferenceHandler + private lateinit var customerViewModel: CustomerViewModel + private lateinit var selectCustomerAdapter: SelectCustomerAdapter + private var dataBeans: MutableList = ArrayList() + private var pageIndex = 1 + private var isRefresh = false + private var isLoadMore = false + private var customerModel: CustomerListModel.DataModel.RowsModel? = null + + override fun initData() { + weakReferenceHandler = WeakReferenceHandler(callback) + customerViewModel = ViewModelProvider(this)[CustomerViewModel::class.java] + customerViewModel.customerList.observe(this) { + if (it.code == 200) { + val dataRows = it.data?.rows!! + when { + isRefresh -> { + dataBeans.clear() + dataBeans = dataRows + customerLayout.finishRefresh() + isRefresh = false + } + isLoadMore -> { + if (dataRows.size == 0) { + "到底了,别拉了".show(this) + } + dataBeans.addAll(dataRows) + customerLayout.finishLoadMore() + isLoadMore = false + } + else -> { + dataBeans = dataRows + } + } + weakReferenceHandler.sendEmptyMessage(2023022701) + } + } + } + + override fun initEvent() { + leftBackView.setOnClickListener { + if (customerModel == null) { + "请选择委托方".show(this) + return@setOnClickListener + } + val intent = Intent() + intent.putExtra("entrustName", customerModel!!.customerName) + intent.putExtra("entrustContact", customerModel!!.phone) + intent.putExtra("entrustAddress", customerModel!!.fullAddress) + setResult(RESULT_OK, intent) + finish() + } + + customerLayout.setOnRefreshListener { + isRefresh = true + //刷新之后页码重置 + pageIndex = 1 + getCustomerList() + } + + customerLayout.setOnLoadMoreListener { + isLoadMore = true + pageIndex++ + getCustomerList() + } + } + + override fun initLayoutView(): Int = R.layout.activity_select_customer + + override fun observeRequestState() { + customerViewModel.loadState.observe(this) { + when (it) { + LoadState.Loading -> LoadingDialogHub.show(this, "数据加载中...") + else -> LoadingDialogHub.dismiss() + } + } + } + + override fun setupTopBarLayout() { + ImmersionBar.with(this).statusBarDarkFont(true).init() + initLayoutImmersionBar(rootView) + titleView.text = "客户列表" + } + + override fun onResume() { + super.onResume() + pageIndex = 1 + getCustomerList() + } + + private fun getCustomerList() { + customerViewModel.getCustomerList( + "", + "", + "", + "", + pageIndex + ) + } + + private val callback = Handler.Callback { + when (it.what) { + 2023022701 -> { + if (isRefresh || isLoadMore) { + selectCustomerAdapter.notifyDataSetChanged() + } else { + if (dataBeans.size == 0) { + emptyView!!.showEmptyPage("无客户数据") { + pageIndex = 1 + getCustomerList() + } + } else { + emptyView!!.hide() + selectCustomerAdapter = SelectCustomerAdapter(this, dataBeans) + customerRecyclerView.addItemDecoration( + DividerItemDecoration(this, DividerItemDecoration.VERTICAL) + ) + (customerRecyclerView.itemAnimator as DefaultItemAnimator).supportsChangeAnimations = + false + customerRecyclerView.adapter = selectCustomerAdapter + selectCustomerAdapter.setOnCheckedListener(object : + SelectCustomerAdapter.OnItemCheckedListener { + override fun onItemChecked(item: CustomerListModel.DataModel.RowsModel) { + customerModel = item + } + }) + } + } + } + } + true + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/view/home/SelectSampleActivity.kt b/app/src/main/java/com/casic/xz/meterage/view/home/SelectSampleActivity.kt new file mode 100644 index 0000000..f85cb44 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/view/home/SelectSampleActivity.kt @@ -0,0 +1,152 @@ +package com.casic.xz.meterage.view.home + +import android.content.Intent +import android.os.Handler +import androidx.lifecycle.ViewModelProvider +import androidx.recyclerview.widget.DefaultItemAnimator +import androidx.recyclerview.widget.DividerItemDecoration +import com.casic.xz.meterage.R +import com.casic.xz.meterage.adapter.SelectSampleAdapter +import com.casic.xz.meterage.extensions.initLayoutImmersionBar +import com.casic.xz.meterage.extensions.showEmptyPage +import com.casic.xz.meterage.model.SampleListModel +import com.casic.xz.meterage.vm.SampleViewModel +import com.gyf.immersionbar.ImmersionBar +import com.pengxh.kt.lite.base.KotlinBaseActivity +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.extensions.toJson +import com.pengxh.kt.lite.utils.WeakReferenceHandler +import kotlinx.android.synthetic.main.activity_select_sample.* +import kotlinx.android.synthetic.main.include_base_title.* +import kotlinx.android.synthetic.main.include_empty_view.* + +class SelectSampleActivity : KotlinBaseActivity() { + + private lateinit var weakReferenceHandler: WeakReferenceHandler + private lateinit var sampleViewModel: SampleViewModel + private lateinit var selectSampleAdapter: SelectSampleAdapter + private var dataBeans: MutableList = ArrayList() + private var pageIndex = 1 + private var isRefresh = false + private var isLoadMore = false + private var sampleModels = ArrayList() + + override fun initData() { + weakReferenceHandler = WeakReferenceHandler(callback) + sampleViewModel = ViewModelProvider(this)[SampleViewModel::class.java] + sampleViewModel.sampleList.observe(this) { + if (it.code == 200) { + val dataRows = it.data?.rows!! + when { + isRefresh -> { + dataBeans.clear() + dataBeans = dataRows + sampleLayout.finishRefresh() + isRefresh = false + } + isLoadMore -> { + if (dataRows.size == 0) { + "到底了,别拉了".show(this) + } + dataBeans.addAll(dataRows) + sampleLayout.finishLoadMore() + isLoadMore = false + } + else -> { + dataBeans = dataRows + } + } + weakReferenceHandler.sendEmptyMessage(2023030101) + } + } + } + + override fun initEvent() { + leftBackView.setOnClickListener { + val intent = Intent() + intent.putExtra("sampleModels", sampleModels.toJson()) + setResult(RESULT_OK, intent) + finish() + } + + sampleLayout.setOnRefreshListener { + isRefresh = true + //刷新之后页码重置 + pageIndex = 1 + getSampleList() + } + + sampleLayout.setOnLoadMoreListener { + isLoadMore = true + pageIndex++ + getSampleList() + } + } + + override fun initLayoutView(): Int = R.layout.activity_select_sample + + override fun observeRequestState() { + + } + + override fun setupTopBarLayout() { + ImmersionBar.with(this).statusBarDarkFont(true).init() + initLayoutImmersionBar(rootView) + titleView.text = "样品列表" + } + + override fun onResume() { + super.onResume() + pageIndex = 1 + getSampleList() + } + + private fun getSampleList() { + sampleViewModel.getSampleList( + "", + "", + "", + "", + "", + "", + "", + "", + "", + arrayOf(), + pageIndex + ) + } + + private val callback = Handler.Callback { + when (it.what) { + 2023030101 -> { + if (isRefresh || isLoadMore) { + selectSampleAdapter.notifyDataSetChanged() + } else { + if (dataBeans.size == 0) { + emptyView!!.showEmptyPage("无样品数据") { + pageIndex = 1 + getSampleList() + } + } else { + emptyView!!.hide() + selectSampleAdapter = SelectSampleAdapter(this, dataBeans) + sampleRecyclerView.addItemDecoration( + DividerItemDecoration(this, DividerItemDecoration.VERTICAL) + ) + (sampleRecyclerView.itemAnimator as DefaultItemAnimator).supportsChangeAnimations = + false + sampleRecyclerView.adapter = selectSampleAdapter + selectSampleAdapter.setOnCheckedListener(object : + SelectSampleAdapter.OnItemCheckedListener { + override fun onItemChecked(items: ArrayList) { + sampleModels = items + } + }) + } + } + } + } + true + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/view/notice/NoticeDetailActivity.kt b/app/src/main/java/com/casic/xz/meterage/view/notice/NoticeDetailActivity.kt index a9d9422..9596985 100644 --- a/app/src/main/java/com/casic/xz/meterage/view/notice/NoticeDetailActivity.kt +++ b/app/src/main/java/com/casic/xz/meterage/view/notice/NoticeDetailActivity.kt @@ -1,6 +1,7 @@ package com.casic.xz.meterage.view.notice import android.annotation.SuppressLint +import android.graphics.Color import android.graphics.Paint import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R @@ -10,7 +11,6 @@ import com.casic.xz.meterage.vm.NoticeViewModel import com.gyf.immersionbar.ImmersionBar import com.pengxh.kt.lite.base.KotlinBaseActivity -import com.pengxh.kt.lite.extensions.convertColor import com.pengxh.kt.lite.extensions.obtainScreenWidth import com.pengxh.kt.lite.utils.Constant import kotlinx.android.synthetic.main.activity_notice_detail.* @@ -54,7 +54,7 @@ val textPaint = minioFileView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - minioFileView.setTextColor(R.color.themeColor.convertColor(this)) + minioFileView.setTextColor(Color.BLUE) minioFileView.setOnClickListener { minioFileName.watchAttachFile(this) diff --git a/app/src/main/java/com/casic/xz/meterage/vm/EntrustViewModel.kt b/app/src/main/java/com/casic/xz/meterage/vm/EntrustViewModel.kt index 2280f88..103c002 100644 --- a/app/src/main/java/com/casic/xz/meterage/vm/EntrustViewModel.kt +++ b/app/src/main/java/com/casic/xz/meterage/vm/EntrustViewModel.kt @@ -7,6 +7,7 @@ import com.casic.xz.meterage.model.ActionResultModel import com.casic.xz.meterage.model.EntrustDetailModel import com.casic.xz.meterage.model.EntrustListModel +import com.casic.xz.meterage.model.SampleListModel import com.casic.xz.meterage.utils.retrofit.RetrofitServiceManager import com.google.gson.Gson import com.google.gson.reflect.TypeToken @@ -25,6 +26,7 @@ val entrustDetail = MutableLiveData() val acceptResult = MutableLiveData() val returnResult = MutableLiveData() + val addResult = MutableLiveData() fun getEntrustList( customerName: String, @@ -119,4 +121,50 @@ loadState.value = LoadState.Fail it.cause.toString().show(BaseApplication.get()) }) + + fun addEntrust( + deliverer: String, + delivererTel: String, + orderTime: String, + planDeliverTime: String, + requireOverTime: String, + customerName: String, + customerPhone: String, + customerAddress: String, + remark: String, + minioFileName: String, + certifications: String, + isUrgent: String, + samples: List + ) = launch({ + loadState.value = LoadState.Loading + val response = RetrofitServiceManager.addEntrust( + deliverer, + delivererTel, + orderTime, + planDeliverTime, + requireOverTime, + customerName, + customerPhone, + customerAddress, + remark, + minioFileName, + certifications, + isUrgent, + samples + ) + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + loadState.value = LoadState.Success + addResult.value = gson.fromJson( + response, object : TypeToken() {}.type + ) + } else { + loadState.value = LoadState.Fail + response.toErrorMessage().show(BaseApplication.get()) + } + }, { + loadState.value = LoadState.Fail + it.cause.toString().show(BaseApplication.get()) + }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/vm/FileUploadViewModel.kt b/app/src/main/java/com/casic/xz/meterage/vm/FileUploadViewModel.kt new file mode 100644 index 0000000..b16c1c7 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/vm/FileUploadViewModel.kt @@ -0,0 +1,40 @@ +package com.casic.xz.meterage.vm + +import androidx.lifecycle.MutableLiveData +import com.casic.xz.meterage.base.BaseApplication +import com.casic.xz.meterage.extensions.separateResponseCode +import com.casic.xz.meterage.extensions.toErrorMessage +import com.casic.xz.meterage.model.UploadResultModel +import com.casic.xz.meterage.utils.FileType +import com.casic.xz.meterage.utils.retrofit.RetrofitServiceManager +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken +import com.pengxh.kt.lite.extensions.launch +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.vm.BaseViewModel +import com.pengxh.kt.lite.vm.LoadState +import java.io.File + +class FileUploadViewModel : BaseViewModel() { + + private val gson by lazy { Gson() } + val resultModel = MutableLiveData() + + fun uploadFile(file: File, type: FileType) = launch({ + loadState.value = LoadState.Loading + val response = RetrofitServiceManager.uploadFile(file, type) + 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(BaseApplication.get()) + } + }, { + loadState.value = LoadState.Fail + it.cause.toString().show(BaseApplication.get()) + }) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/vm/SampleViewModel.kt b/app/src/main/java/com/casic/xz/meterage/vm/SampleViewModel.kt new file mode 100644 index 0000000..182140d --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/vm/SampleViewModel.kt @@ -0,0 +1,65 @@ +package com.casic.xz.meterage.vm + +import androidx.lifecycle.MutableLiveData +import com.casic.xz.meterage.base.BaseApplication +import com.casic.xz.meterage.extensions.separateResponseCode +import com.casic.xz.meterage.extensions.toErrorMessage +import com.casic.xz.meterage.model.SampleListModel +import com.casic.xz.meterage.utils.retrofit.RetrofitServiceManager +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken +import com.pengxh.kt.lite.extensions.launch +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.vm.BaseViewModel +import com.pengxh.kt.lite.vm.LoadState + +/** + * 样品相关 VM + * */ +class SampleViewModel : BaseViewModel() { + + private val gson by lazy { Gson() } + val sampleList = MutableLiveData() + + fun getSampleList( + customerName: String, + customerNo: String, + startTime: String, + endTime: String, + sampleName: String, + sampleNo: String, + sampleModel: String, + sampleBelong: String, + overtimeStatus: String, + ids: Array, + offset: Int + ) = launch({ + loadState.value = LoadState.Loading + val response = RetrofitServiceManager.getSampleList( + customerName, + customerNo, + startTime, + endTime, + sampleName, + sampleNo, + sampleModel, + sampleBelong, + overtimeStatus, + ids, + offset + ) + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + loadState.value = LoadState.Success + sampleList.value = gson.fromJson( + response, object : TypeToken() {}.type + ) + } else { + loadState.value = LoadState.Fail + response.toErrorMessage().show(BaseApplication.get()) + } + }, { + loadState.value = LoadState.Fail + it.cause.toString().show(BaseApplication.get()) + }) +} \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_customer_selector.xml b/app/src/main/res/drawable/bg_customer_selector.xml new file mode 100644 index 0000000..e7292d5 --- /dev/null +++ b/app/src/main/res/drawable/bg_customer_selector.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_sample_selector.xml b/app/src/main/res/drawable/bg_sample_selector.xml new file mode 100644 index 0000000..6b5d5e7 --- /dev/null +++ b/app/src/main/res/drawable/bg_sample_selector.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_check_selected.xml b/app/src/main/res/drawable/ic_check_selected.xml new file mode 100644 index 0000000..4d93f9f --- /dev/null +++ b/app/src/main/res/drawable/ic_check_selected.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_entrust_add.xml b/app/src/main/res/layout/activity_entrust_add.xml index 3d00784..8450d1d 100644 --- a/app/src/main/res/layout/activity_entrust_add.xml +++ b/app/src/main/res/layout/activity_entrust_add.xml @@ -68,6 +68,7 @@ android:text="送样人" /> @@ -81,6 +82,7 @@ android:text="联系方式" /> @@ -115,10 +117,10 @@ style="@style/textViewStyle" android:text="预计送到时间" /> - + android:hint="请选择预计送到时间" /> @@ -129,10 +131,10 @@ style="@style/textViewStyle" android:text="要求检完时间" /> - + android:hint="请选择要求检完时间" /> @@ -143,10 +145,10 @@ style="@style/textViewStyle" android:text="委托方名称" /> - + android:hint="请选择委托方" /> @@ -157,10 +159,9 @@ style="@style/textViewStyle" android:text="委托方电话" /> - + @@ -171,10 +172,9 @@ style="@style/textViewStyle" android:text="委托方地址" /> - + @@ -186,9 +186,9 @@ android:text="备注" /> + android:hint="请输入" /> @@ -200,6 +200,7 @@ android:text="附件" /> diff --git a/app/src/main/res/layout/activity_select_customer.xml b/app/src/main/res/layout/activity_select_customer.xml new file mode 100644 index 0000000..01f5ca1 --- /dev/null +++ b/app/src/main/res/layout/activity_select_customer.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_select_sample.xml b/app/src/main/res/layout/activity_select_sample.xml new file mode 100644 index 0000000..f5c6693 --- /dev/null +++ b/app/src/main/res/layout/activity_select_sample.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_entrust_basic_information.xml b/app/src/main/res/layout/fragment_entrust_basic_information.xml index a37e381..07fbc24 100644 --- a/app/src/main/res/layout/fragment_entrust_basic_information.xml +++ b/app/src/main/res/layout/fragment_entrust_basic_information.xml @@ -199,7 +199,7 @@ android:orientation="horizontal"> + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 0ae369f..687b02b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -15,7 +15,6 @@ } compileSdkVersion 31 - buildToolsVersion "30.0.3" defaultConfig { applicationId "com.casic.xz.meterage" @@ -84,11 +83,13 @@ implementation 'top.zibin:Luban:1.1.8' //官方Json解析库 implementation 'com.google.code.gson:gson:2.9.0' + //阿里巴巴JSON库 + implementation 'com.alibaba.fastjson2:fastjson2:2.0.24' //Kotlin协程 implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.5.1' //MVVM+LiveData implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.5.1" - implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.0" + implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1" implementation "androidx.lifecycle:lifecycle-extensions:2.2.0" //返回值转换器 implementation 'com.jakewharton.retrofit:retrofit2-kotlin-coroutines-adapter:0.9.2' @@ -109,4 +110,8 @@ implementation 'com.github.barteksc:android-pdf-viewer:2.8.2' //绕过Android 11反射限制 implementation 'com.github.tiann:FreeReflection:3.1.0' + //单项/数字、二三级联动、日期/时间等滚轮选择器 + implementation 'com.github.gzu-liyujiang.AndroidPicker:WheelPicker:4.1.8' + //文件/目录选择器 + implementation 'com.github.gzu-liyujiang.AndroidPicker:FilePicker:4.1.1' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 1ccc12b..0fba91b 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -60,6 +60,8 @@ + + diff --git a/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt b/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt new file mode 100644 index 0000000..21a71d8 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/adapter/SelectCustomerAdapter.kt @@ -0,0 +1,70 @@ +package com.casic.xz.meterage.adapter + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import com.casic.xz.meterage.R +import com.casic.xz.meterage.extensions.toChineseGrade +import com.casic.xz.meterage.model.CustomerListModel + +class SelectCustomerAdapter( + context: Context, private val dataRows: MutableList +) : RecyclerView.Adapter() { + + private var layoutInflater = LayoutInflater.from(context) + + //选择的位置 + private var selectedPosition = 0 + + //临时记录上次选择的位置 + private var temp = -1 + + override fun getItemCount(): Int = dataRows.size + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ItemViewHolder( + layoutInflater.inflate(R.layout.item_select_customer_lv, parent, false) + ) + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + //绑定数据 + val rowsBean = dataRows[position] + holder.agreementLevelView.text = rowsBean.grade.toChineseGrade() + holder.customerNameView.text = rowsBean.customerName + holder.scaleView.text = rowsBean.companySizeName + holder.overallView.text = "公司规模:${rowsBean.evaluationName}" + holder.fullAddressView.text = "公司地址:${rowsBean.fullAddress}" + + holder.itemView.isSelected = holder.layoutPosition == selectedPosition + holder.itemView.setOnClickListener { + itemCheckedListener?.onItemChecked(rowsBean) + + holder.itemView.isSelected = true + temp = selectedPosition + //设置新的位置 + selectedPosition = holder.layoutPosition + //更新旧位置 + notifyItemChanged(temp) + } + } + + inner class ItemViewHolder(view: View) : RecyclerView.ViewHolder(view) { + var agreementLevelView: TextView = view.findViewById(R.id.agreementLevelView) + var customerNameView: TextView = view.findViewById(R.id.customerNameView) + var scaleView: TextView = view.findViewById(R.id.scaleView) + var overallView: TextView = view.findViewById(R.id.overallView) + var fullAddressView: TextView = view.findViewById(R.id.fullAddressView) + } + + private var itemCheckedListener: OnItemCheckedListener? = null + + interface OnItemCheckedListener { + fun onItemChecked(item: CustomerListModel.DataModel.RowsModel) + } + + fun setOnCheckedListener(listener: OnItemCheckedListener?) { + itemCheckedListener = listener + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt b/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt new file mode 100644 index 0000000..c29461e --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/adapter/SelectSampleAdapter.kt @@ -0,0 +1,68 @@ +package com.casic.xz.meterage.adapter + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import com.casic.xz.meterage.R +import com.casic.xz.meterage.model.SampleListModel + +class SelectSampleAdapter( + context: Context, private val dataRows: MutableList +) : RecyclerView.Adapter() { + + private var layoutInflater = LayoutInflater.from(context) + private var multipleSelected = mutableSetOf() + private var sampleModes = ArrayList() + + override fun getItemCount(): Int = dataRows.size + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ItemViewHolder( + layoutInflater.inflate(R.layout.item_select_sample_lv, parent, false) + ) + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + //绑定数据 + val rowsBean = dataRows[position] + holder.sampleNameView.text = "${rowsBean.sampleName}【${rowsBean.sampleModel}】" + holder.manufacturingCodeView.text = "出厂编号:${rowsBean.manufacturingNo}" + holder.sampleCodeView.text = "样品编号:${rowsBean.sampleNo}" + holder.validDateView.text = "有效期至:${rowsBean.validDeadline}" + + holder.checkImageView.isSelected = multipleSelected.contains(position) + holder.itemView.setOnClickListener { + if (multipleSelected.contains(position)) { + multipleSelected.remove(position) + sampleModes.remove(dataRows[position]) + holder.checkImageView.isSelected = false + } else { + multipleSelected.add(position) + sampleModes.add(dataRows[position]) + holder.checkImageView.isSelected = true + } + + itemCheckedListener?.onItemChecked(sampleModes) + } + } + + inner class ItemViewHolder(view: View) : RecyclerView.ViewHolder(view) { + var sampleNameView: TextView = view.findViewById(R.id.sampleNameView) + var manufacturingCodeView: TextView = view.findViewById(R.id.manufacturingCodeView) + var sampleCodeView: TextView = view.findViewById(R.id.sampleCodeView) + var validDateView: TextView = view.findViewById(R.id.validDateView) + var checkImageView: ImageView = view.findViewById(R.id.checkImageView) + } + + private var itemCheckedListener: OnItemCheckedListener? = null + + interface OnItemCheckedListener { + fun onItemChecked(items: ArrayList) + } + + fun setOnCheckedListener(listener: OnItemCheckedListener?) { + itemCheckedListener = listener + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/callback/DateSelectedCallback.kt b/app/src/main/java/com/casic/xz/meterage/callback/DateSelectedCallback.kt new file mode 100644 index 0000000..8196110 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/callback/DateSelectedCallback.kt @@ -0,0 +1,5 @@ +package com.casic.xz.meterage.callback + +interface DateSelectedCallback { + fun onDateSelected(date: String) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/Activity.kt b/app/src/main/java/com/casic/xz/meterage/extensions/Activity.kt new file mode 100644 index 0000000..e112d1c --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/extensions/Activity.kt @@ -0,0 +1,33 @@ +package com.casic.xz.meterage.extensions + +import android.app.Activity +import com.casic.xz.meterage.R +import com.casic.xz.meterage.callback.DateSelectedCallback +import com.github.gzuliyujiang.wheelpicker.DatePicker +import com.github.gzuliyujiang.wheelpicker.annotation.DateMode +import com.github.gzuliyujiang.wheelpicker.entity.DateEntity +import com.pengxh.kt.lite.extensions.convertColor +import com.pengxh.kt.lite.extensions.sp2px + +fun Activity.showDatePicker(callback: DateSelectedCallback) { + val datePicker = DatePicker(this) + + val layout = datePicker.wheelLayout + layout.setDateMode(DateMode.YEAR_MONTH_DAY) + layout.setDateLabel("年", "月", "日"); + layout.setTextSize(14f.sp2px(this).toFloat()) + layout.setSelectedTextSize(16f.sp2px(this).toFloat()) + layout.setSelectedTextColor(R.color.themeColor.convertColor(this)) + layout.setSelectedTextBold(true) + layout.setResetWhenLinkage(false) + layout.setRange( + DateEntity.today(), + DateEntity.target(2050, 12, 31), + DateEntity.today() + ) + + datePicker.setOnDatePickedListener { year, month, day -> + callback.onDateSelected(String.format("%s-%s-%s", year, month, day)) + } + datePicker.show() +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt b/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt index 016ebcb..cf6bf49 100644 --- a/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt +++ b/app/src/main/java/com/casic/xz/meterage/extensions/ArrayList.kt @@ -4,7 +4,7 @@ * ArrayList扩展方法 */ -//将图片集合格式化成满足上传格式的数据 +//将集合格式化成满足上传格式的数据 fun ArrayList.reformat(): String { if (this.isEmpty()) return "" val builder = StringBuilder() diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt b/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt index 7c57643..aa9b92b 100644 --- a/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt +++ b/app/src/main/java/com/casic/xz/meterage/extensions/Context.kt @@ -1,7 +1,6 @@ package com.casic.xz.meterage.extensions import android.content.Context -import android.util.Log import android.view.ViewGroup import com.casic.xz.meterage.base.BaseApplication import com.pengxh.kt.lite.extensions.dp2px @@ -9,9 +8,8 @@ fun Context.initLayoutImmersionBar(rootView: ViewGroup) { var statusBarHeight = QMUIDisplayHelper.getStatusBarHeight(this) - Log.d("Casic", "状态栏高度: $statusBarHeight") if (statusBarHeight == 0) { - statusBarHeight = 44f.dp2px(BaseApplication.get()) + statusBarHeight = 40f.dp2px(BaseApplication.get()) } rootView.setPadding(0, statusBarHeight, 0, 0) rootView.requestLayout() diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/String.kt b/app/src/main/java/com/casic/xz/meterage/extensions/String.kt index 28f70d8..6234d43 100644 --- a/app/src/main/java/com/casic/xz/meterage/extensions/String.kt +++ b/app/src/main/java/com/casic/xz/meterage/extensions/String.kt @@ -128,9 +128,10 @@ fun String.combineImagePath(): String { if (this.isEmpty()) return this val defaultValue = SaveKeyValues.getValue( - LocaleConstant.DEFAULT_SERVER_CONFIG, LocaleConstant.SERVER_BASE_URL + LocaleConstant.FILE_SERVER_CONFIG, LocaleConstant.File_SERVER_URL ) as String - return "$defaultValue/static/${this.replace("\\", "/")}" + //http://111.198.10.15:21408/test/1677479806059688_1677479806038.jpeg + return "$defaultValue/test/${this.replace("\\", "/")}" } fun String.isEarlier(time: String): Boolean { diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt index 25fa87b..a0e1358 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/customer/BasicInformationFragment.kt @@ -1,18 +1,12 @@ package com.casic.xz.meterage.fragment.customer +import android.graphics.Color import android.graphics.Paint import com.casic.xz.meterage.R -import com.casic.xz.meterage.extensions.combineImagePath import com.casic.xz.meterage.extensions.toChineseGrade +import com.casic.xz.meterage.extensions.watchAttachFile import com.casic.xz.meterage.model.CustomerDetailModel -import com.casic.xz.meterage.view.BigImageActivity -import com.casic.xz.meterage.view.notice.PreviewDocumentActivity -import com.casic.xz.meterage.view.notice.PreviewPdfActivity -import com.casic.xz.meterage.view.notice.PreviewTextActivity import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor -import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.extensions.show import kotlinx.android.synthetic.main.fragment_customer_basic_information.* class BasicInformationFragment(private val data: CustomerDetailModel.DataModel) : @@ -48,30 +42,11 @@ val textPaint = minioFileView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - minioFileView.setTextColor(R.color.themeColor.convertColor(requireContext())) + minioFileView.setTextColor(Color.BLUE) minioFileView.setOnClickListener { //查看附件 - if (minioFileName.endsWith("pdf")) { - requireContext().navigatePageTo(minioFileName) - } else if ( - minioFileName.endsWith("doc") || - minioFileName.endsWith("docx") - ) { - requireContext().navigatePageTo(minioFileName) - } else if (minioFileName.endsWith("txt")) { - requireContext().navigatePageTo(minioFileName) - } else if ( - minioFileName.endsWith("png") || - minioFileName.endsWith("jpeg") || - minioFileName.endsWith("jpg") - ) { - val urls = ArrayList() - urls.add(minioFileName.combineImagePath()) - requireContext().navigatePageTo(0, urls) - } else { - "文件类型未知,无法打开附件".show(requireContext()) - } + minioFileName.watchAttachFile(requireContext()) } } } diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt index 77846b4..3a0fe2e 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/device/BasicInformationFragment.kt @@ -1,5 +1,6 @@ package com.casic.xz.meterage.fragment.device +import android.graphics.Color import android.graphics.Paint import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R @@ -7,7 +8,6 @@ import com.casic.xz.meterage.utils.LoadingDialogHub import com.casic.xz.meterage.vm.EquipmentViewModel import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor import com.pengxh.kt.lite.vm.LoadState import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import kotlinx.android.synthetic.main.fragment_device_basic_information.* @@ -56,7 +56,7 @@ val textPaint = documentsView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - documentsView.setTextColor(R.color.themeColor.convertColor(requireContext())) + documentsView.setTextColor(Color.BLUE) val files = ArrayList() data.fileList.forEach { file -> @@ -66,7 +66,7 @@ BottomActionSheet.Builder() .setContext(requireContext()) .setActionItemTitle(files) - .setItemTextColor(R.color.themeColor.convertColor(requireContext())) + .setItemTextColor(Color.BLUE) .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { override fun onActionItemClick(position: Int) { diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt index 15dc3d2..10eeff8 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/entrust/BasicInformationFragment.kt @@ -1,5 +1,6 @@ package com.casic.xz.meterage.fragment.entrust +import android.graphics.Color import android.graphics.Paint import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R @@ -9,7 +10,6 @@ import com.casic.xz.meterage.model.EntrustDetailModel import com.casic.xz.meterage.vm.DictionaryViewModel import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor import kotlinx.android.synthetic.main.fragment_entrust_basic_information.* class BasicInformationFragment(private val data: EntrustDetailModel.DataModel) : @@ -38,7 +38,7 @@ val textPaint = annexView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - annexView.setTextColor(R.color.themeColor.convertColor(requireContext())) + annexView.setTextColor(Color.BLUE) annexView.setOnClickListener { minioFileName.watchAttachFile(requireContext()) @@ -59,9 +59,9 @@ //加急 if (data.isUrgent == "0") { - RadioButton2.isChecked = true + radioButton2.isChecked = true } else { - RadioButton1.isChecked = true + radioButton1.isChecked = true } //样品 diff --git a/app/src/main/java/com/casic/xz/meterage/fragment/equipment/BasicInformationFragment.kt b/app/src/main/java/com/casic/xz/meterage/fragment/equipment/BasicInformationFragment.kt index 72b523c..7bc3b01 100644 --- a/app/src/main/java/com/casic/xz/meterage/fragment/equipment/BasicInformationFragment.kt +++ b/app/src/main/java/com/casic/xz/meterage/fragment/equipment/BasicInformationFragment.kt @@ -1,5 +1,6 @@ package com.casic.xz.meterage.fragment.equipment +import android.graphics.Color import android.graphics.Paint import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R @@ -7,7 +8,6 @@ import com.casic.xz.meterage.utils.LoadingDialogHub import com.casic.xz.meterage.vm.EquipmentViewModel import com.pengxh.kt.lite.base.KotlinBaseFragment -import com.pengxh.kt.lite.extensions.convertColor import com.pengxh.kt.lite.vm.LoadState import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import kotlinx.android.synthetic.main.fragment_equipment_basic_information.* @@ -74,7 +74,7 @@ val textPaint = instructionsView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - instructionsView.setTextColor(R.color.themeColor.convertColor(requireContext())) + instructionsView.setTextColor(Color.BLUE) val files = ArrayList() data.fileList.forEach { file -> @@ -84,7 +84,7 @@ BottomActionSheet.Builder() .setContext(requireContext()) .setActionItemTitle(files) - .setItemTextColor(R.color.themeColor.convertColor(requireContext())) + .setItemTextColor(Color.BLUE) .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { override fun onActionItemClick(position: Int) { diff --git a/app/src/main/java/com/casic/xz/meterage/model/SampleListModel.java b/app/src/main/java/com/casic/xz/meterage/model/SampleListModel.java new file mode 100644 index 0000000..5784343 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/model/SampleListModel.java @@ -0,0 +1,193 @@ +package com.casic.xz.meterage.model; + +import java.util.List; + +public class SampleListModel { + + private int code; + private DataModel data; + private String message; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataModel getData() { + return data; + } + + public void setData(DataModel data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public static class DataModel { + private List rows; + private int total; + + public List getRows() { + return rows; + } + + public void setRows(List rows) { + this.rows = rows; + } + + public int getTotal() { + return total; + } + + public void setTotal(int total) { + this.total = total; + } + + public static class RowsModel { + private String certificationStatus; + private String customerName; + private String customerNo; + private String id; + private String manufacturingNo; + private String measureLastTime; + private String measurePeriod; + private String orderId; + private String remark; + private String sampleModel; + private String sampleName; + private String sampleNo; + private String sampleSatus; + private String sampleSatusName; + private String validDeadline; + + public String getCertificationStatus() { + return certificationStatus; + } + + public void setCertificationStatus(String certificationStatus) { + this.certificationStatus = certificationStatus; + } + + public String getCustomerName() { + return customerName; + } + + public void setCustomerName(String customerName) { + this.customerName = customerName; + } + + public String getCustomerNo() { + return customerNo; + } + + public void setCustomerNo(String customerNo) { + this.customerNo = customerNo; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getManufacturingNo() { + return manufacturingNo; + } + + public void setManufacturingNo(String manufacturingNo) { + this.manufacturingNo = manufacturingNo; + } + + public String getMeasureLastTime() { + return measureLastTime; + } + + public void setMeasureLastTime(String measureLastTime) { + this.measureLastTime = measureLastTime; + } + + public String getMeasurePeriod() { + return measurePeriod; + } + + public void setMeasurePeriod(String measurePeriod) { + this.measurePeriod = measurePeriod; + } + + public String getOrderId() { + return orderId; + } + + public void setOrderId(String orderId) { + this.orderId = orderId; + } + + public String getRemark() { + return remark; + } + + public void setRemark(String remark) { + this.remark = remark; + } + + public String getSampleModel() { + return sampleModel; + } + + public void setSampleModel(String sampleModel) { + this.sampleModel = sampleModel; + } + + public String getSampleName() { + return sampleName; + } + + public void setSampleName(String sampleName) { + this.sampleName = sampleName; + } + + public String getSampleNo() { + return sampleNo; + } + + public void setSampleNo(String sampleNo) { + this.sampleNo = sampleNo; + } + + public String getSampleSatus() { + return sampleSatus; + } + + public void setSampleSatus(String sampleSatus) { + this.sampleSatus = sampleSatus; + } + + public String getSampleSatusName() { + return sampleSatusName; + } + + public void setSampleSatusName(String sampleSatusName) { + this.sampleSatusName = sampleSatusName; + } + + public String getValidDeadline() { + return validDeadline; + } + + public void setValidDeadline(String validDeadline) { + this.validDeadline = validDeadline; + } + } + } +} diff --git a/app/src/main/java/com/casic/xz/meterage/model/UploadResultModel.java b/app/src/main/java/com/casic/xz/meterage/model/UploadResultModel.java new file mode 100644 index 0000000..f2a6a41 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/model/UploadResultModel.java @@ -0,0 +1,34 @@ +package com.casic.xz.meterage.model; + +import java.util.List; + +public class UploadResultModel { + + private int code; + private List data; + private String message; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public List getData() { + return data; + } + + public void setData(List data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } +} diff --git a/app/src/main/java/com/casic/xz/meterage/utils/FileType.kt b/app/src/main/java/com/casic/xz/meterage/utils/FileType.kt new file mode 100644 index 0000000..17e2bca --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/utils/FileType.kt @@ -0,0 +1,23 @@ +package com.casic.xz.meterage.utils + +sealed class FileType { + /** + * PDF文件 + */ + object PDF : FileType() + + /** + * WORD文件 + */ + object WORD : FileType() + + /** + * IMAGE图片 + */ + object IMAGE : FileType() + + /** + * 未知类型(Excel) + */ + object UNKNOWN : FileType() +} diff --git a/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitService.kt index bc3f8d6..8f4fe44 100644 --- a/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitService.kt @@ -1,5 +1,6 @@ package com.casic.xz.meterage.utils.retrofit +import okhttp3.MultipartBody import okhttp3.RequestBody import retrofit2.http.* @@ -35,6 +36,16 @@ ): String /** + * 上传文件 + */ + @Multipart + @POST("/minio/file/upload") + suspend fun uploadFile( + @Header("token") token: String, + @Part file: MultipartBody.Part + ): String + + /** * 获取通知公告列表 */ @POST("/system/notice/listPage") @@ -209,4 +220,24 @@ @Header("token") token: String, @Body requestBody: RequestBody ): String + + /** + * 获取样品列表 + */ + @POST("/customer/sample/listPage") + suspend fun getSampleList( + @Header("token") token: String, + @Body requestBody: RequestBody, + @QueryMap limit: Map, + @QueryMap offset: Map + ): String + + /** + * 新增委托书 + */ + @POST("/business/order/add") + suspend fun addEntrust( + @Header("token") token: String, + @Body requestBody: RequestBody + ): String } \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitServiceManager.kt index cb22e45..90abe5a 100644 --- a/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/xz/meterage/utils/retrofit/RetrofitServiceManager.kt @@ -1,13 +1,20 @@ package com.casic.xz.meterage.utils.retrofit +import com.alibaba.fastjson2.JSON +import com.alibaba.fastjson2.JSONArray +import com.alibaba.fastjson2.JSONObject +import com.casic.xz.meterage.model.SampleListModel import com.casic.xz.meterage.utils.AuthenticationHelper +import com.casic.xz.meterage.utils.FileType import com.casic.xz.meterage.utils.LocaleConstant import com.pengxh.kt.lite.utils.RetrofitFactory import com.pengxh.kt.lite.utils.SaveKeyValues import okhttp3.MediaType.Companion.toMediaType +import okhttp3.MediaType.Companion.toMediaTypeOrNull +import okhttp3.MultipartBody +import okhttp3.RequestBody.Companion.asRequestBody import okhttp3.RequestBody.Companion.toRequestBody -import org.json.JSONArray -import org.json.JSONObject +import java.io.File object RetrofitServiceManager { @@ -31,9 +38,9 @@ */ suspend fun login(sid: String, account: String, secretKey: String): String { val paramObject = JSONObject() - paramObject.put("sid", sid) - paramObject.put("username", account) - paramObject.put("password", secretKey) + paramObject["sid"] = sid + paramObject["username"] = account + paramObject["password"] = secretKey val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -55,6 +62,20 @@ } /** + * 上传文件 + */ + suspend fun uploadFile(file: File, type: FileType): String { + val requestBody = when (type) { + FileType.PDF -> file.asRequestBody("application/pdf".toMediaTypeOrNull()) + FileType.WORD -> file.asRequestBody("application/msword".toMediaTypeOrNull()) + FileType.IMAGE -> file.asRequestBody("image/png".toMediaTypeOrNull()) + else -> file.asRequestBody("application/vnd.ms-excel".toMediaTypeOrNull()) + } + val filePart = MultipartBody.Part.createFormData("multipartFile", file.name, requestBody) + return api.uploadFile(AuthenticationHelper.token!!, filePart) + } + + /** * 获取通知公告列表 */ suspend fun getNoticeList( @@ -66,11 +87,11 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("noticeNo", noticeNo) - paramObject.put("noticeTitle", noticeTitle) - paramObject.put("noticePublisher", noticePublisher) - paramObject.put("noticeStartTime", noticeStartTime) - paramObject.put("noticeEndTime", noticeEndTime) + paramObject["noticeNo"] = noticeNo + paramObject["noticeTitle"] = noticeTitle + paramObject["noticePublisher"] = noticePublisher + paramObject["noticeStartTime"] = noticeStartTime + paramObject["noticeEndTime"] = noticeEndTime val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -105,26 +126,21 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("equipmentNo", equipmentNo) - paramObject.put("equipmentName", equipmentName) - paramObject.put("mesureType", mesureType) - paramObject.put("managerState", managerState) - paramObject.put("useDept", useDept) - paramObject.put("assetType", assetType) - paramObject.put("equipmentCategory", equipmentCategory) - paramObject.put("isCalibrationTestEquipment", isCalibrationTestEquipment) - paramObject.put("isMeasureAccount", isMeasureAccount) - paramObject.put("isStandardSupportEquipment", isStandardSupportEquipment) - paramObject.put("isFixedAssets", isFixedAssets) - paramObject.put("validStartDate", validStartDate) - paramObject.put("validEndDate", validEndDate) - paramObject.put("abc", abc) - - val jsonArray = JSONArray() - ids.forEach { - jsonArray.put(it) - } - paramObject.put("ids", jsonArray) + paramObject["equipmentNo"] = equipmentNo + paramObject["equipmentName"] = equipmentName + paramObject["mesureType"] = mesureType + paramObject["managerState"] = managerState + paramObject["useDept"] = useDept + paramObject["assetType"] = assetType + paramObject["equipmentCategory"] = equipmentCategory + paramObject["isCalibrationTestEquipment"] = isCalibrationTestEquipment + paramObject["isMeasureAccount"] = isMeasureAccount + paramObject["isStandardSupportEquipment"] = isStandardSupportEquipment + paramObject["isFixedAssets"] = isFixedAssets + paramObject["validStartDate"] = validStartDate + paramObject["validEndDate"] = validEndDate + paramObject["abc"] = abc + paramObject["ids"] = JSONArray.parseArray(JSON.toJSONString(ids)) val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() @@ -143,7 +159,7 @@ */ suspend fun getEquipmentDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -164,13 +180,13 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("standardNo", standardNo) - paramObject.put("standardName", standardName) - paramObject.put("category", category) - paramObject.put("managerState", managerState) - paramObject.put("standardLaboratory", standardLaboratory) - paramObject.put("preparationDate", preparationDate) - paramObject.put("id", id) + paramObject["standardNo"] = standardNo + paramObject["standardName"] = standardName + paramObject["category"] = category + paramObject["managerState"] = managerState + paramObject["standardLaboratory"] = standardLaboratory + paramObject["preparationDate"] = preparationDate + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -193,7 +209,7 @@ */ suspend fun getStandardDeviceDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -212,11 +228,11 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("checkType", checkType) - paramObject.put("priceItem", priceItem) - paramObject.put("priceName", priceName) - paramObject.put("priceNo", priceNo) - paramObject.put("priceType", priceType) + paramObject["checkType"] = checkType + paramObject["priceItem"] = priceItem + paramObject["priceName"] = priceName + paramObject["priceNo"] = priceNo + paramObject["priceType"] = priceType val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -234,7 +250,7 @@ */ suspend fun getCapabilityDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -257,20 +273,15 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("createStartTime", createStartTime) - paramObject.put("createEndTime", createEndTime) - paramObject.put("deptId", deptId) - paramObject.put("director", director) - paramObject.put("effectiveCompany", effectiveCompany) - paramObject.put("trainStartTime", trainStartTime) - paramObject.put("trainEndTime", trainEndTime) - paramObject.put("formId", formId) - - val jsonArray = JSONArray() - ids.forEach { - jsonArray.put(it) - } - paramObject.put("ids", jsonArray) + paramObject["createStartTime"] = createStartTime + paramObject["createEndTime"] = createEndTime + paramObject["deptId"] = deptId + paramObject["director"] = director + paramObject["effectiveCompany"] = effectiveCompany + paramObject["trainStartTime"] = trainStartTime + paramObject["trainEndTime"] = trainEndTime + paramObject["formId"] = formId + paramObject["ids"] = JSONArray.parseArray(JSON.toJSONString(ids)) val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() @@ -294,7 +305,7 @@ */ suspend fun getMeterageTrainDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -308,10 +319,10 @@ bussinessSize: String, customerName: String, customerNo: String, grade: String, offset: Int ): String { val paramObject = JSONObject() - paramObject.put("bussinessSize", bussinessSize) - paramObject.put("customerName", customerName) - paramObject.put("customerNo", customerNo) - paramObject.put("grade", grade) + paramObject["bussinessSize"] = bussinessSize + paramObject["customerName"] = customerName + paramObject["customerNo"] = customerNo + paramObject["grade"] = grade val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() @@ -330,7 +341,7 @@ */ suspend fun getCustomerDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -342,7 +353,7 @@ */ suspend fun getStaffList(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -354,7 +365,7 @@ */ suspend fun getSupportEquipmentList(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -366,7 +377,7 @@ */ suspend fun getVerifyProcedureList(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -389,20 +400,15 @@ offset: Int ): String { val paramObject = JSONObject() - paramObject.put("customerName", customerName) - paramObject.put("customerNo", customerNo) - paramObject.put("deliverer", deliverer) - paramObject.put("orderCode", orderCode) - paramObject.put("startTime", startTime) - paramObject.put("endTime", endTime) - paramObject.put("isUrgent", isUrgent) - paramObject.put("status", status) - - val jsonArray = JSONArray() - ids.forEach { - jsonArray.put(it) - } - paramObject.put("ids", jsonArray) + paramObject["customerName"] = customerName + paramObject["customerNo"] = customerNo + paramObject["deliverer"] = deliverer + paramObject["orderCode"] = orderCode + paramObject["startTime"] = startTime + paramObject["endTime"] = endTime + paramObject["isUrgent"] = isUrgent + paramObject["status"] = status + paramObject["ids"] = JSONArray.parseArray(JSON.toJSONString(ids)) val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() @@ -421,7 +427,7 @@ */ suspend fun getEntrustDetail(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -433,7 +439,7 @@ */ suspend fun acceptEntrust(id: String): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) @@ -446,10 +452,89 @@ */ suspend fun returnEntrust(id: String, selected: ArrayList): String { val paramObject = JSONObject() - paramObject.put("id", id) + paramObject["id"] = id val requestBody = paramObject.toString().toRequestBody( "application/json;charset=UTF-8".toMediaType() ) return api.returnEntrust(AuthenticationHelper.token!!, requestBody) } + + /** + * 获取样品列表 + */ + suspend fun getSampleList( + customerName: String, + customerNo: String, + startTime: String, + endTime: String, + sampleName: String, + sampleNo: String, + sampleModel: String, + sampleBelong: String, + overtimeStatus: String, + ids: Array, + offset: Int + ): String { + val paramObject = JSONObject() + paramObject["customerName"] = customerName + paramObject["customerNo"] = customerNo + paramObject["startTime"] = startTime + paramObject["endTime"] = endTime + paramObject["sampleName"] = sampleName + paramObject["sampleNo"] = sampleNo + paramObject["sampleModel"] = sampleModel + paramObject["sampleBelong"] = sampleBelong + paramObject["overtimeStatus"] = overtimeStatus + paramObject["ids"] = JSONArray.parseArray(JSON.toJSONString(ids)) + + val requestBody = paramObject.toString().toRequestBody( + "application/json;charset=UTF-8".toMediaType() + ) + + val limitMap = HashMap() + limitMap["limit"] = LocaleConstant.PAGE_LIMIT + + val offsetMap = HashMap() + offsetMap["offset"] = offset + return api.getSampleList(AuthenticationHelper.token!!, requestBody, limitMap, offsetMap) + } + + /** + * 新增委托书 + */ + suspend fun addEntrust( + deliverer: String, + delivererTel: String, + orderTime: String, + planDeliverTime: String, + requireOverTime: String, + customerName: String, + customerPhone: String, + customerAddress: String, + remark: String, + minioFileName: String, + certifications: String, + isUrgent: String, + samples: List + ): String { + val paramObject = JSONObject() + paramObject["deliverer"] = deliverer + paramObject["delivererTel"] = delivererTel + paramObject["orderTime"] = orderTime + paramObject["planDeliverTime"] = planDeliverTime + paramObject["requireOverTime"] = requireOverTime + paramObject["customerName"] = customerName + paramObject["customerPhone"] = customerPhone + paramObject["customerAddress"] = customerAddress + paramObject["remark"] = remark + paramObject["minioFileName"] = minioFileName + paramObject["certifications"] = certifications + paramObject["isUrgent"] = isUrgent + paramObject["customerSampleInfoList"] = JSONArray.parseArray(JSON.toJSONString(samples)) + + val requestBody = paramObject.toString().toRequestBody( + "application/json;charset=UTF-8".toMediaType() + ) + return api.addEntrust(AuthenticationHelper.token!!, requestBody) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/view/home/EntrustAddActivity.kt b/app/src/main/java/com/casic/xz/meterage/view/home/EntrustAddActivity.kt index 3e30095..9c8d27b 100644 --- a/app/src/main/java/com/casic/xz/meterage/view/home/EntrustAddActivity.kt +++ b/app/src/main/java/com/casic/xz/meterage/view/home/EntrustAddActivity.kt @@ -1,52 +1,211 @@ package com.casic.xz.meterage.view.home +import android.app.Activity +import android.content.Context +import android.content.Intent +import android.graphics.Color +import android.graphics.Paint import android.util.Log +import androidx.activity.result.ActivityResult +import androidx.activity.result.ActivityResultCallback +import androidx.activity.result.contract.ActivityResultContracts import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R import com.casic.xz.meterage.adapter.CertificateTypeAdapter2 -import com.casic.xz.meterage.extensions.initLayoutImmersionBar +import com.casic.xz.meterage.adapter.CustomerSampleAdapter +import com.casic.xz.meterage.callback.DateSelectedCallback +import com.casic.xz.meterage.callback.OnImageCompressListener +import com.casic.xz.meterage.extensions.* +import com.casic.xz.meterage.model.EntrustDetailModel +import com.casic.xz.meterage.model.SampleListModel +import com.casic.xz.meterage.utils.FileType +import com.casic.xz.meterage.utils.GlideLoadEngine +import com.casic.xz.meterage.utils.LoadingDialogHub import com.casic.xz.meterage.vm.DictionaryViewModel +import com.casic.xz.meterage.vm.EntrustViewModel +import com.casic.xz.meterage.vm.FileUploadViewModel +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken import com.gyf.immersionbar.ImmersionBar +import com.luck.picture.lib.basic.PictureSelector +import com.luck.picture.lib.config.SelectMimeType +import com.luck.picture.lib.entity.LocalMedia +import com.luck.picture.lib.interfaces.OnResultCallbackListener import com.pengxh.kt.lite.base.KotlinBaseActivity -import com.pengxh.kt.lite.extensions.toJson +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.vm.LoadState +import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import kotlinx.android.synthetic.main.activity_entrust_add.* +import java.io.File + class EntrustAddActivity : KotlinBaseActivity() { + private val context: Context = this@EntrustAddActivity + private val gson by lazy { Gson() } private lateinit var dictionaryViewModel: DictionaryViewModel - private var checkedItems = ArrayList() + private lateinit var fileUploadViewModel: FileUploadViewModel + private lateinit var entrustViewModel: EntrustViewModel + private lateinit var sampleAdapter: CustomerSampleAdapter + private var checkedItems = ArrayList() + private var isUrgent = "0" + private var sampleModels: ArrayList? = null + private var dataBeans = ArrayList() override fun initData() { //证书 dictionaryViewModel = ViewModelProvider(this)[DictionaryViewModel::class.java] dictionaryViewModel.getDictionaryByCode("certificationClass") - dictionaryViewModel.dictionary.observe(this) { dic -> - if (dic.code == 200) { - val typeAdapter2 = CertificateTypeAdapter2(this, dic.data) + dictionaryViewModel.dictionary.observe(this) { + if (it.code == 200) { + val typeAdapter2 = CertificateTypeAdapter2(this, it.data) typeRecyclerView.adapter = typeAdapter2 typeAdapter2.setOnItemCheckedListener(object : CertificateTypeAdapter2.OnItemCheckedListener { override fun onItemChecked(position: Int, isChecked: Boolean) { if (isChecked) { - checkedItems.add(position) + checkedItems.add(position.toString()) } else { - checkedItems.remove(position) + checkedItems.remove(position.toString()) } } }) } } + + fileUploadViewModel = ViewModelProvider(this)[FileUploadViewModel::class.java] + fileUploadViewModel.resultModel.observe(this) { + if (it.code == 200) { + val annexName = it.data[0] + annexView.text = annexName + val textPaint = annexView.paint + textPaint.flags = Paint.UNDERLINE_TEXT_FLAG + textPaint.isAntiAlias = true + annexView.setTextColor(Color.BLUE) + + annexView.setOnClickListener { + annexName.watchAttachFile(this) + } + } + } + + entrustViewModel = ViewModelProvider(this)[EntrustViewModel::class.java] + entrustViewModel.addResult.observe(this) { + if (it.code == 200) { + finish() + } + } + + //样品列表 + sampleAdapter = CustomerSampleAdapter(this, dataBeans) + sampleRecyclerView.adapter = sampleAdapter } + private val selectCustomerLauncher = + registerForActivityResult(ActivityResultContracts.StartActivityForResult(), + object : ActivityResultCallback { + override fun onActivityResult(result: ActivityResult?) { + if (result?.resultCode == Activity.RESULT_OK) { + val data = result.data ?: return + + entrustNameView.text = data.getStringExtra("entrustName") + entrustContactView.text = data.getStringExtra("entrustContact") + entrustAddressView.text = data.getStringExtra("entrustAddress") + } + } + }) + + private val selectSampleLauncher = + registerForActivityResult(ActivityResultContracts.StartActivityForResult(), + object : ActivityResultCallback { + override fun onActivityResult(result: ActivityResult?) { + if (result?.resultCode == Activity.RESULT_OK) { + val data = result.data ?: return + + val modelsJson = data.getStringExtra("sampleModels") + if (!modelsJson.isNullOrBlank()) { + sampleModels = gson.fromJson( + modelsJson, + object : + TypeToken>() {}.type + ) + } + + //刷新列表 + dataBeans.clear() + sampleModels?.forEach { + val model = + EntrustDetailModel.DataModel.CustomerSampleInfoListModel() + + model.customerName = it.customerName + model.customerNo = it.customerNo + model.id = it.id + model.manufacturingNo = it.manufacturingNo + model.measureLastTime = it.measureLastTime + model.measurePeriod = it.measurePeriod + model.orderId = it.orderId + model.remark = it.remark + model.sampleModel = it.sampleModel + model.sampleName = it.sampleName + model.sampleNo = it.sampleNo + model.validDeadline = it.validDeadline + + dataBeans.add(model) + } + sampleAdapter.notifyDataSetChanged() + } + } + }) + override fun initEvent() { + leftBackView.setOnClickListener { finish() } + + estimateTimeView.setOnClickListener { + showDatePicker(object : DateSelectedCallback { + override fun onDateSelected(date: String) { + estimateTimeView.text = date + } + }) + } + + completedView.setOnClickListener { + showDatePicker(object : DateSelectedCallback { + override fun onDateSelected(date: String) { + completedView.text = date + } + }) + } + + entrustNameView.setOnClickListener { + selectCustomerLauncher.launch(Intent(this, SelectCustomerActivity::class.java)) + } + //上传附件 uploadFileButton.setOnClickListener { + BottomActionSheet.Builder() + .setContext(this) + .setItemTextColor(Color.BLUE) + .setActionItemTitle(listOf("文件", "图片")) + .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { + override fun onActionItemClick(position: Int) { + when (position) { + 0 -> uploadFile() + 1 -> uploadImage() + } + } + }).build().show() + } + radioGroup.setOnCheckedChangeListener { _, checkedId -> + when (checkedId) { + R.id.radioButton1 -> isUrgent = "1" + R.id.radioButton2 -> isUrgent = "0" + } } //选择样品 selectSampleButton.setOnClickListener { - + selectSampleLauncher.launch(Intent(this, SelectSampleActivity::class.java)) } //写入样品信息 @@ -55,14 +214,68 @@ } pushEntrustView.setOnClickListener { - Log.d("Casic", "EntrustAddActivity => initEvent: ${checkedItems.toJson()}") + val sender = senderView.text.toString() + if (sender.isBlank()) { + "请填写送样人名字".show(this) + return@setOnClickListener + } + + val contact = contactView.text.toString() + if (contact.isBlank()) { + "请填写送样人联系方式".show(this) + return@setOnClickListener + } + + val estimateTime = estimateTimeView.text.toString() + if (estimateTime.isBlank()) { + "请选择预计送到的时间".show(this) + return@setOnClickListener + } + + val entrustName = entrustNameView.text.toString() + if (entrustName.isBlank()) { + "请选择委托方".show(this) + return@setOnClickListener + } + + if (sampleModels == null) { + "请选择样品".show(this) + return@setOnClickListener + } + entrustViewModel.addEntrust( + sender, + contact, + createEntrustDateView.text.toString(), + estimateTime, + completedView.text.toString(), + entrustName, + entrustContactView.text.toString(), + entrustAddressView.text.toString(), + remarkView.text.toString(), + annexView.text.toString(), + checkedItems.reformat(), + isUrgent, + sampleModels!! + ) } } override fun initLayoutView(): Int = R.layout.activity_entrust_add override fun observeRequestState() { + fileUploadViewModel.loadState.observe(this) { + when (it) { + LoadState.Loading -> LoadingDialogHub.show(this, "文件上传中,请稍后...") + else -> LoadingDialogHub.dismiss() + } + } + entrustViewModel.loadState.observe(this) { + when (it) { + LoadState.Loading -> LoadingDialogHub.show(this, "委托创建中,请稍后...") + else -> LoadingDialogHub.dismiss() + } + } } override fun setupTopBarLayout() { @@ -70,4 +283,62 @@ initLayoutImmersionBar(rootView) titleView.text = "委托需求" } + + private fun uploadFile() { +// val explorer = FileExplorer(this) +// explorer.setInitDir(ExplorerMode.FILE, Environment.getExternalStorageDirectory()) +// explorer.setShowHomeDir(true) +// explorer.setShowUpDir(true) +// explorer.setShowHideDir(true) +// explorer.setAllowExtensions(arrayOf(".doc", ".docx", ".xls", ".xlsx", ".pdf")) +// explorer.setOnFileClickedListener { +// val type = if (it.name.endsWith(".doc") || it.name.endsWith(".docx")) { +// FileType.WORD +// } else if (it.name.endsWith(".pdf")) { +// FileType.PDF +// } else { +// FileType.UNKNOWN +// } +// +// Log.d("Casic", "EntrustAddActivity => uploadFile: ${it.absolutePath}") +// fileUploadViewModel.uploadFile(it, type) +// } + } + + private fun uploadImage() { + PictureSelector.create(this) + .openGallery(SelectMimeType.ofImage()) + .isGif(false) + .isMaxSelectEnabledMask(true) + .setFilterMinFileSize(100) + .setMaxSelectNum(1) + .isDisplayCamera(false) + .setImageEngine(GlideLoadEngine.instance) + .forResult(object : OnResultCallbackListener { + override fun onResult(result: ArrayList?) { + if (result == null) { + "选择照片失败,请重试".show(context) + return + } + result[0].realPath.compressImage(context, object : OnImageCompressListener { + override fun onSuccess(file: File) { + Log.d( + "Casic", "EntrustAddActivity => onSuccess: ${file.absolutePath}" + ) + ///storage/emulated/0/Android/data/com.casic.xz.meterage/files/Pictures/CompressImage/1677478115391211.jpeg + //上传图片 + fileUploadViewModel.uploadFile(file, FileType.IMAGE) + } + + override fun onError(e: Throwable) { + e.printStackTrace() + } + }) + } + + override fun onCancel() { + + } + }) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/view/home/SelectCustomerActivity.kt b/app/src/main/java/com/casic/xz/meterage/view/home/SelectCustomerActivity.kt new file mode 100644 index 0000000..9bf6a1a --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/view/home/SelectCustomerActivity.kt @@ -0,0 +1,158 @@ +package com.casic.xz.meterage.view.home + +import android.content.Intent +import android.os.Handler +import androidx.lifecycle.ViewModelProvider +import androidx.recyclerview.widget.DefaultItemAnimator +import androidx.recyclerview.widget.DividerItemDecoration +import com.casic.xz.meterage.R +import com.casic.xz.meterage.adapter.SelectCustomerAdapter +import com.casic.xz.meterage.extensions.initLayoutImmersionBar +import com.casic.xz.meterage.extensions.showEmptyPage +import com.casic.xz.meterage.model.CustomerListModel +import com.casic.xz.meterage.utils.LoadingDialogHub +import com.casic.xz.meterage.vm.CustomerViewModel +import com.gyf.immersionbar.ImmersionBar +import com.pengxh.kt.lite.base.KotlinBaseActivity +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.utils.WeakReferenceHandler +import com.pengxh.kt.lite.vm.LoadState +import kotlinx.android.synthetic.main.activity_select_customer.* +import kotlinx.android.synthetic.main.include_base_title.* +import kotlinx.android.synthetic.main.include_empty_view.* + +class SelectCustomerActivity : KotlinBaseActivity() { + + private lateinit var weakReferenceHandler: WeakReferenceHandler + private lateinit var customerViewModel: CustomerViewModel + private lateinit var selectCustomerAdapter: SelectCustomerAdapter + private var dataBeans: MutableList = ArrayList() + private var pageIndex = 1 + private var isRefresh = false + private var isLoadMore = false + private var customerModel: CustomerListModel.DataModel.RowsModel? = null + + override fun initData() { + weakReferenceHandler = WeakReferenceHandler(callback) + customerViewModel = ViewModelProvider(this)[CustomerViewModel::class.java] + customerViewModel.customerList.observe(this) { + if (it.code == 200) { + val dataRows = it.data?.rows!! + when { + isRefresh -> { + dataBeans.clear() + dataBeans = dataRows + customerLayout.finishRefresh() + isRefresh = false + } + isLoadMore -> { + if (dataRows.size == 0) { + "到底了,别拉了".show(this) + } + dataBeans.addAll(dataRows) + customerLayout.finishLoadMore() + isLoadMore = false + } + else -> { + dataBeans = dataRows + } + } + weakReferenceHandler.sendEmptyMessage(2023022701) + } + } + } + + override fun initEvent() { + leftBackView.setOnClickListener { + if (customerModel == null) { + "请选择委托方".show(this) + return@setOnClickListener + } + val intent = Intent() + intent.putExtra("entrustName", customerModel!!.customerName) + intent.putExtra("entrustContact", customerModel!!.phone) + intent.putExtra("entrustAddress", customerModel!!.fullAddress) + setResult(RESULT_OK, intent) + finish() + } + + customerLayout.setOnRefreshListener { + isRefresh = true + //刷新之后页码重置 + pageIndex = 1 + getCustomerList() + } + + customerLayout.setOnLoadMoreListener { + isLoadMore = true + pageIndex++ + getCustomerList() + } + } + + override fun initLayoutView(): Int = R.layout.activity_select_customer + + override fun observeRequestState() { + customerViewModel.loadState.observe(this) { + when (it) { + LoadState.Loading -> LoadingDialogHub.show(this, "数据加载中...") + else -> LoadingDialogHub.dismiss() + } + } + } + + override fun setupTopBarLayout() { + ImmersionBar.with(this).statusBarDarkFont(true).init() + initLayoutImmersionBar(rootView) + titleView.text = "客户列表" + } + + override fun onResume() { + super.onResume() + pageIndex = 1 + getCustomerList() + } + + private fun getCustomerList() { + customerViewModel.getCustomerList( + "", + "", + "", + "", + pageIndex + ) + } + + private val callback = Handler.Callback { + when (it.what) { + 2023022701 -> { + if (isRefresh || isLoadMore) { + selectCustomerAdapter.notifyDataSetChanged() + } else { + if (dataBeans.size == 0) { + emptyView!!.showEmptyPage("无客户数据") { + pageIndex = 1 + getCustomerList() + } + } else { + emptyView!!.hide() + selectCustomerAdapter = SelectCustomerAdapter(this, dataBeans) + customerRecyclerView.addItemDecoration( + DividerItemDecoration(this, DividerItemDecoration.VERTICAL) + ) + (customerRecyclerView.itemAnimator as DefaultItemAnimator).supportsChangeAnimations = + false + customerRecyclerView.adapter = selectCustomerAdapter + selectCustomerAdapter.setOnCheckedListener(object : + SelectCustomerAdapter.OnItemCheckedListener { + override fun onItemChecked(item: CustomerListModel.DataModel.RowsModel) { + customerModel = item + } + }) + } + } + } + } + true + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/view/home/SelectSampleActivity.kt b/app/src/main/java/com/casic/xz/meterage/view/home/SelectSampleActivity.kt new file mode 100644 index 0000000..f85cb44 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/view/home/SelectSampleActivity.kt @@ -0,0 +1,152 @@ +package com.casic.xz.meterage.view.home + +import android.content.Intent +import android.os.Handler +import androidx.lifecycle.ViewModelProvider +import androidx.recyclerview.widget.DefaultItemAnimator +import androidx.recyclerview.widget.DividerItemDecoration +import com.casic.xz.meterage.R +import com.casic.xz.meterage.adapter.SelectSampleAdapter +import com.casic.xz.meterage.extensions.initLayoutImmersionBar +import com.casic.xz.meterage.extensions.showEmptyPage +import com.casic.xz.meterage.model.SampleListModel +import com.casic.xz.meterage.vm.SampleViewModel +import com.gyf.immersionbar.ImmersionBar +import com.pengxh.kt.lite.base.KotlinBaseActivity +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.extensions.toJson +import com.pengxh.kt.lite.utils.WeakReferenceHandler +import kotlinx.android.synthetic.main.activity_select_sample.* +import kotlinx.android.synthetic.main.include_base_title.* +import kotlinx.android.synthetic.main.include_empty_view.* + +class SelectSampleActivity : KotlinBaseActivity() { + + private lateinit var weakReferenceHandler: WeakReferenceHandler + private lateinit var sampleViewModel: SampleViewModel + private lateinit var selectSampleAdapter: SelectSampleAdapter + private var dataBeans: MutableList = ArrayList() + private var pageIndex = 1 + private var isRefresh = false + private var isLoadMore = false + private var sampleModels = ArrayList() + + override fun initData() { + weakReferenceHandler = WeakReferenceHandler(callback) + sampleViewModel = ViewModelProvider(this)[SampleViewModel::class.java] + sampleViewModel.sampleList.observe(this) { + if (it.code == 200) { + val dataRows = it.data?.rows!! + when { + isRefresh -> { + dataBeans.clear() + dataBeans = dataRows + sampleLayout.finishRefresh() + isRefresh = false + } + isLoadMore -> { + if (dataRows.size == 0) { + "到底了,别拉了".show(this) + } + dataBeans.addAll(dataRows) + sampleLayout.finishLoadMore() + isLoadMore = false + } + else -> { + dataBeans = dataRows + } + } + weakReferenceHandler.sendEmptyMessage(2023030101) + } + } + } + + override fun initEvent() { + leftBackView.setOnClickListener { + val intent = Intent() + intent.putExtra("sampleModels", sampleModels.toJson()) + setResult(RESULT_OK, intent) + finish() + } + + sampleLayout.setOnRefreshListener { + isRefresh = true + //刷新之后页码重置 + pageIndex = 1 + getSampleList() + } + + sampleLayout.setOnLoadMoreListener { + isLoadMore = true + pageIndex++ + getSampleList() + } + } + + override fun initLayoutView(): Int = R.layout.activity_select_sample + + override fun observeRequestState() { + + } + + override fun setupTopBarLayout() { + ImmersionBar.with(this).statusBarDarkFont(true).init() + initLayoutImmersionBar(rootView) + titleView.text = "样品列表" + } + + override fun onResume() { + super.onResume() + pageIndex = 1 + getSampleList() + } + + private fun getSampleList() { + sampleViewModel.getSampleList( + "", + "", + "", + "", + "", + "", + "", + "", + "", + arrayOf(), + pageIndex + ) + } + + private val callback = Handler.Callback { + when (it.what) { + 2023030101 -> { + if (isRefresh || isLoadMore) { + selectSampleAdapter.notifyDataSetChanged() + } else { + if (dataBeans.size == 0) { + emptyView!!.showEmptyPage("无样品数据") { + pageIndex = 1 + getSampleList() + } + } else { + emptyView!!.hide() + selectSampleAdapter = SelectSampleAdapter(this, dataBeans) + sampleRecyclerView.addItemDecoration( + DividerItemDecoration(this, DividerItemDecoration.VERTICAL) + ) + (sampleRecyclerView.itemAnimator as DefaultItemAnimator).supportsChangeAnimations = + false + sampleRecyclerView.adapter = selectSampleAdapter + selectSampleAdapter.setOnCheckedListener(object : + SelectSampleAdapter.OnItemCheckedListener { + override fun onItemChecked(items: ArrayList) { + sampleModels = items + } + }) + } + } + } + } + true + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/view/notice/NoticeDetailActivity.kt b/app/src/main/java/com/casic/xz/meterage/view/notice/NoticeDetailActivity.kt index a9d9422..9596985 100644 --- a/app/src/main/java/com/casic/xz/meterage/view/notice/NoticeDetailActivity.kt +++ b/app/src/main/java/com/casic/xz/meterage/view/notice/NoticeDetailActivity.kt @@ -1,6 +1,7 @@ package com.casic.xz.meterage.view.notice import android.annotation.SuppressLint +import android.graphics.Color import android.graphics.Paint import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R @@ -10,7 +11,6 @@ import com.casic.xz.meterage.vm.NoticeViewModel import com.gyf.immersionbar.ImmersionBar import com.pengxh.kt.lite.base.KotlinBaseActivity -import com.pengxh.kt.lite.extensions.convertColor import com.pengxh.kt.lite.extensions.obtainScreenWidth import com.pengxh.kt.lite.utils.Constant import kotlinx.android.synthetic.main.activity_notice_detail.* @@ -54,7 +54,7 @@ val textPaint = minioFileView.paint textPaint.flags = Paint.UNDERLINE_TEXT_FLAG textPaint.isAntiAlias = true - minioFileView.setTextColor(R.color.themeColor.convertColor(this)) + minioFileView.setTextColor(Color.BLUE) minioFileView.setOnClickListener { minioFileName.watchAttachFile(this) diff --git a/app/src/main/java/com/casic/xz/meterage/vm/EntrustViewModel.kt b/app/src/main/java/com/casic/xz/meterage/vm/EntrustViewModel.kt index 2280f88..103c002 100644 --- a/app/src/main/java/com/casic/xz/meterage/vm/EntrustViewModel.kt +++ b/app/src/main/java/com/casic/xz/meterage/vm/EntrustViewModel.kt @@ -7,6 +7,7 @@ import com.casic.xz.meterage.model.ActionResultModel import com.casic.xz.meterage.model.EntrustDetailModel import com.casic.xz.meterage.model.EntrustListModel +import com.casic.xz.meterage.model.SampleListModel import com.casic.xz.meterage.utils.retrofit.RetrofitServiceManager import com.google.gson.Gson import com.google.gson.reflect.TypeToken @@ -25,6 +26,7 @@ val entrustDetail = MutableLiveData() val acceptResult = MutableLiveData() val returnResult = MutableLiveData() + val addResult = MutableLiveData() fun getEntrustList( customerName: String, @@ -119,4 +121,50 @@ loadState.value = LoadState.Fail it.cause.toString().show(BaseApplication.get()) }) + + fun addEntrust( + deliverer: String, + delivererTel: String, + orderTime: String, + planDeliverTime: String, + requireOverTime: String, + customerName: String, + customerPhone: String, + customerAddress: String, + remark: String, + minioFileName: String, + certifications: String, + isUrgent: String, + samples: List + ) = launch({ + loadState.value = LoadState.Loading + val response = RetrofitServiceManager.addEntrust( + deliverer, + delivererTel, + orderTime, + planDeliverTime, + requireOverTime, + customerName, + customerPhone, + customerAddress, + remark, + minioFileName, + certifications, + isUrgent, + samples + ) + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + loadState.value = LoadState.Success + addResult.value = gson.fromJson( + response, object : TypeToken() {}.type + ) + } else { + loadState.value = LoadState.Fail + response.toErrorMessage().show(BaseApplication.get()) + } + }, { + loadState.value = LoadState.Fail + it.cause.toString().show(BaseApplication.get()) + }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/vm/FileUploadViewModel.kt b/app/src/main/java/com/casic/xz/meterage/vm/FileUploadViewModel.kt new file mode 100644 index 0000000..b16c1c7 --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/vm/FileUploadViewModel.kt @@ -0,0 +1,40 @@ +package com.casic.xz.meterage.vm + +import androidx.lifecycle.MutableLiveData +import com.casic.xz.meterage.base.BaseApplication +import com.casic.xz.meterage.extensions.separateResponseCode +import com.casic.xz.meterage.extensions.toErrorMessage +import com.casic.xz.meterage.model.UploadResultModel +import com.casic.xz.meterage.utils.FileType +import com.casic.xz.meterage.utils.retrofit.RetrofitServiceManager +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken +import com.pengxh.kt.lite.extensions.launch +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.vm.BaseViewModel +import com.pengxh.kt.lite.vm.LoadState +import java.io.File + +class FileUploadViewModel : BaseViewModel() { + + private val gson by lazy { Gson() } + val resultModel = MutableLiveData() + + fun uploadFile(file: File, type: FileType) = launch({ + loadState.value = LoadState.Loading + val response = RetrofitServiceManager.uploadFile(file, type) + 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(BaseApplication.get()) + } + }, { + loadState.value = LoadState.Fail + it.cause.toString().show(BaseApplication.get()) + }) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/vm/SampleViewModel.kt b/app/src/main/java/com/casic/xz/meterage/vm/SampleViewModel.kt new file mode 100644 index 0000000..182140d --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/vm/SampleViewModel.kt @@ -0,0 +1,65 @@ +package com.casic.xz.meterage.vm + +import androidx.lifecycle.MutableLiveData +import com.casic.xz.meterage.base.BaseApplication +import com.casic.xz.meterage.extensions.separateResponseCode +import com.casic.xz.meterage.extensions.toErrorMessage +import com.casic.xz.meterage.model.SampleListModel +import com.casic.xz.meterage.utils.retrofit.RetrofitServiceManager +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken +import com.pengxh.kt.lite.extensions.launch +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.vm.BaseViewModel +import com.pengxh.kt.lite.vm.LoadState + +/** + * 样品相关 VM + * */ +class SampleViewModel : BaseViewModel() { + + private val gson by lazy { Gson() } + val sampleList = MutableLiveData() + + fun getSampleList( + customerName: String, + customerNo: String, + startTime: String, + endTime: String, + sampleName: String, + sampleNo: String, + sampleModel: String, + sampleBelong: String, + overtimeStatus: String, + ids: Array, + offset: Int + ) = launch({ + loadState.value = LoadState.Loading + val response = RetrofitServiceManager.getSampleList( + customerName, + customerNo, + startTime, + endTime, + sampleName, + sampleNo, + sampleModel, + sampleBelong, + overtimeStatus, + ids, + offset + ) + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + loadState.value = LoadState.Success + sampleList.value = gson.fromJson( + response, object : TypeToken() {}.type + ) + } else { + loadState.value = LoadState.Fail + response.toErrorMessage().show(BaseApplication.get()) + } + }, { + loadState.value = LoadState.Fail + it.cause.toString().show(BaseApplication.get()) + }) +} \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_customer_selector.xml b/app/src/main/res/drawable/bg_customer_selector.xml new file mode 100644 index 0000000..e7292d5 --- /dev/null +++ b/app/src/main/res/drawable/bg_customer_selector.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_sample_selector.xml b/app/src/main/res/drawable/bg_sample_selector.xml new file mode 100644 index 0000000..6b5d5e7 --- /dev/null +++ b/app/src/main/res/drawable/bg_sample_selector.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_check_selected.xml b/app/src/main/res/drawable/ic_check_selected.xml new file mode 100644 index 0000000..4d93f9f --- /dev/null +++ b/app/src/main/res/drawable/ic_check_selected.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_entrust_add.xml b/app/src/main/res/layout/activity_entrust_add.xml index 3d00784..8450d1d 100644 --- a/app/src/main/res/layout/activity_entrust_add.xml +++ b/app/src/main/res/layout/activity_entrust_add.xml @@ -68,6 +68,7 @@ android:text="送样人" /> @@ -81,6 +82,7 @@ android:text="联系方式" /> @@ -115,10 +117,10 @@ style="@style/textViewStyle" android:text="预计送到时间" /> - + android:hint="请选择预计送到时间" /> @@ -129,10 +131,10 @@ style="@style/textViewStyle" android:text="要求检完时间" /> - + android:hint="请选择要求检完时间" /> @@ -143,10 +145,10 @@ style="@style/textViewStyle" android:text="委托方名称" /> - + android:hint="请选择委托方" /> @@ -157,10 +159,9 @@ style="@style/textViewStyle" android:text="委托方电话" /> - + @@ -171,10 +172,9 @@ style="@style/textViewStyle" android:text="委托方地址" /> - + @@ -186,9 +186,9 @@ android:text="备注" /> + android:hint="请输入" /> @@ -200,6 +200,7 @@ android:text="附件" /> diff --git a/app/src/main/res/layout/activity_select_customer.xml b/app/src/main/res/layout/activity_select_customer.xml new file mode 100644 index 0000000..01f5ca1 --- /dev/null +++ b/app/src/main/res/layout/activity_select_customer.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_select_sample.xml b/app/src/main/res/layout/activity_select_sample.xml new file mode 100644 index 0000000..f5c6693 --- /dev/null +++ b/app/src/main/res/layout/activity_select_sample.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_entrust_basic_information.xml b/app/src/main/res/layout/fragment_entrust_basic_information.xml index a37e381..07fbc24 100644 --- a/app/src/main/res/layout/fragment_entrust_basic_information.xml +++ b/app/src/main/res/layout/fragment_entrust_basic_information.xml @@ -199,7 +199,7 @@ android:orientation="horizontal"> + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_select_sample_lv.xml b/app/src/main/res/layout/item_select_sample_lv.xml new file mode 100644 index 0000000..223e4fc --- /dev/null +++ b/app/src/main/res/layout/item_select_sample_lv.xml @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file