日报2025520
团队作业开发
完成任务导出栏和巡检任务派发
package com.example.sanpaias.adapter
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.cardview.widget.CardView
import androidx.recyclerview.widget.RecyclerView
import com.example.sanpaias.R
import com.example.sanpaias.entity.RepairOrder
class MyTaskAdapter(
private val onItemClick: (RepairOrder) -> Unit
) : RecyclerView.Adapter<MyTaskAdapter.TaskViewHolder>() {
private var tasks: List<RepairOrder> = emptyList()
class TaskViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val cardView: CardView = itemView.findViewById(R.id.cardView)
val tvOrderId: TextView = itemView.findViewById(R.id.tvOrderId)
val tvFaultId: TextView = itemView.findViewById(R.id.tvFaultId)
val tvStatus: TextView = itemView.findViewById(R.id.tvStatus)
val tvRepairDesc: TextView = itemView.findViewById(R.id.tvRepairDesc)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TaskViewHolder {
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.item_my_task, parent, false)
return TaskViewHolder(view)
}
override fun onBindViewHolder(holder: TaskViewHolder, position: Int) {
val task = tasks[position]
holder.tvOrderId.text = "工单编号: ${task.orderId}"
holder.tvFaultId.text = "故障编号: ${task.faultId}"
holder.tvStatus.text = "状态: ${task.status}"
holder.tvRepairDesc.text = "维修描述: ${task.repairDesc ?: "暂无"}"
holder.cardView.setOnClickListener {
onItemClick(task)
}
}
override fun getItemCount() = tasks.size
fun updateData(newTasks: List<RepairOrder>) {
tasks = newTasks
notifyDataSetChanged()
}
}
package com.example.sanpaias.activity
import android.Manifest
import android.app.Activity
import android.content.Intent
import android.content.pm.PackageManager
import android.graphics.Bitmap
import android.location.Location
import android.location.LocationManager
import android.os.Bundle
import android.provider.MediaStore
import android.util.Base64
import android.util.Log
import android.view.MenuItem
import android.view.View
import android.widget.Button
import android.widget.EditText
import android.widget.ImageView
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.Toolbar
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.example.sanpaias.R
import com.example.sanpaias.adapter.PhotoAdapter
import com.example.sanpaias.entity.RepairOrder
import com.example.sanpaias.network.RetrofitClient
import kotlinx.coroutines.launch
import java.io.ByteArrayOutputStream
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.Rect
import android.location.Geocoder
import android.net.Uri
import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.content.FileProvider
import com.example.sanpaias.entity.DeviceFault
import com.example.sanpaias.entity.FaultStatusUpdate
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
import com.google.android.gms.location.FusedLocationProviderClient
import com.google.android.gms.location.LocationServices
import java.io.File
class TaskEditActivity : AppCompatActivity() {
private lateinit var toolbar: Toolbar
private lateinit var tvOrderId: TextView
private lateinit var tvFaultId: TextView
private lateinit var tvStatus: TextView
private lateinit var etRepairDesc: EditText
private lateinit var btnTakePhoto: Button
private lateinit var btnSave: Button
private lateinit var btnSubmit: Button // 添加提交按钮引用
private lateinit var recyclerViewPhotos: RecyclerView
private lateinit var photoAdapter: PhotoAdapter
private var repairOrder: RepairOrder? = null
private val photoList = mutableListOf<String>()
// 添加位置相关变量
private lateinit var fusedLocationClient: FusedLocationProviderClient
private var currentLocation: Location? = null
companion object {
private const val REQUEST_CAMERA_PERMISSION = 100
private const val REQUEST_IMAGE_CAPTURE = 101
private const val REQUEST_LOCATION_PERMISSION = 102
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_task_edit)
// 初始化位置服务
fusedLocationClient = LocationServices.getFusedLocationProviderClient(this)
// 初始化视图
initViews()
// 获取传递的维修工单
repairOrder = intent.getParcelableExtra("repair_order")
// 显示工单信息
displayOrderInfo()
// 设置按钮点击事件
setupButtonListeners()
// 获取当前位置
getCurrentLocation()
}
private fun initViews() {
toolbar = findViewById(R.id.toolbar)
setSupportActionBar(toolbar)
supportActionBar?.setDisplayHomeAsUpEnabled(true)
supportActionBar?.title = "维修工单"
tvOrderId = findViewById(R.id.tvOrderId)
tvFaultId = findViewById(R.id.tvFaultId)
tvStatus = findViewById(R.id.tvStatus)
etRepairDesc = findViewById(R.id.etRepairDesc)
btnTakePhoto = findViewById(R.id.btnTakePhoto)
btnSave = findViewById(R.id.btnSave)
btnSubmit = findViewById(R.id.btnSubmit) // 初始化提交按钮
// 初始化照片RecyclerView
recyclerViewPhotos = findViewById(R.id.recyclerViewPhotos)
recyclerViewPhotos.layoutManager = LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false)
photoAdapter = PhotoAdapter(
photoList = photoList,
onDeleteClick = { position ->
photoList.removeAt(position)
photoAdapter.notifyItemRemoved(position)
}
)
recyclerViewPhotos.adapter = photoAdapter
}
private fun displayOrderInfo() {
repairOrder?.let { order ->
tvOrderId.text = "工单编号: ${order.orderId}"
tvFaultId.text = "故障编号: ${order.faultId}"
tvStatus.text = "状态: ${order.status}"
etRepairDesc.setText(order.repairDesc)
// 加载已有照片
order.photos?.let { photosStr ->
if (photosStr.isNotEmpty()) {
val photos = photosStr.split(",").filter { it.isNotEmpty() }
photoList.addAll(photos)
photoAdapter.notifyDataSetChanged()
}
}
}
}
private fun setupButtonListeners() {
btnTakePhoto.setOnClickListener {
requestPermissions()
}
btnSave.setOnClickListener {
saveRepairOrder()
}
btnSubmit.setOnClickListener {
submitRepairOrder()
}
}
// 修改权限请求方法,同时请求相机和位置权限
private fun requestPermissions() {
val permissionsNeeded = mutableListOf<String>()
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
permissionsNeeded.add(Manifest.permission.CAMERA)
}
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
permissionsNeeded.add(Manifest.permission.ACCESS_FINE_LOCATION)
}
if (permissionsNeeded.isNotEmpty()) {
ActivityCompat.requestPermissions(this, permissionsNeeded.toTypedArray(), REQUEST_CAMERA_PERMISSION)
} else {
dispatchTakePictureIntent()
}
}
// 获取当前位置
private fun getCurrentLocation() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
fusedLocationClient.lastLocation
.addOnSuccessListener { location: Location? ->
currentLocation = location
if (location == null) {
Log.w("TaskEditActivity", "无法获取位置信息")
}
}
.addOnFailureListener { e ->
Log.e("TaskEditActivity", "获取位置失败", e)
}
}
}
private fun dispatchTakePictureIntent() {
Intent(MediaStore.ACTION_IMAGE_CAPTURE).also { takePictureIntent ->
takePictureIntent.resolveActivity(packageManager)?.also {
currentPhotoFile = createImageFile()
currentPhotoFile?.also {
val photoURI: Uri = FileProvider.getUriForFile(
this,
"com.example.sanpaias.fileprovider",
it
)
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI)
cameraLauncher.launch(takePictureIntent)
}
}
}
}
private fun createImageFile(): File {
val timeStamp: String = SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(Date())
val storageDir: File = getExternalFilesDir("Pictures")!!
return File.createTempFile(
"JPEG_${timeStamp}_",
".jpg",
storageDir
)
}
// 添加文件相关变量
private var currentPhotoFile: File? = null
// 替换原有的拍照方式
private val cameraLauncher = registerForActivityResult(
ActivityResultContracts.StartActivityForResult()
) { result ->
if (result.resultCode == RESULT_OK) {
currentPhotoFile?.let { file ->
if (file.exists()) {
val bitmap = MediaStore.Images.Media.getBitmap(contentResolver, Uri.fromFile(file))
val watermarkedBitmap = addWatermark(bitmap)
val base64Image = bitmapToBase64(watermarkedBitmap)
photoList.add(base64Image)
photoAdapter.notifyItemInserted(photoList.size - 1)
}
}
}
}
// 修改水印方法,添加位置信息
private fun addWatermark(src: Bitmap): Bitmap {
val width = src.width
val height = src.height
// 创建一个新的Bitmap,与原图大小相同
val config = src.config ?: Bitmap.Config.ARGB_8888
val result = Bitmap.createBitmap(width, height, config)
// 创建Canvas对象
val canvas = Canvas(result)
// 绘制原始图片
canvas.drawBitmap(src, 0f, 0f, null)
// 设置水印文本
val timestamp = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault()).format(Date())
val locationText = getLocationText()
// 创建画笔
val paint = Paint().apply {
color = Color.WHITE
textSize = width / 35f // 稍微调小字体
isAntiAlias = true
style = Paint.Style.FILL
setShadowLayer(3f, 1f, 1f, Color.BLACK) // 添加阴影使文字更清晰
}
// 计算时间文本位置(右下角)
val timeBounds = Rect()
paint.getTextBounds(timestamp, 0, timestamp.length, timeBounds)
val timeTextWidth = paint.measureText(timestamp)
val timeTextHeight = timeBounds.height()
val timeX = width - timeTextWidth - width / 50f
val timeY = height - timeTextHeight - height / 50f
// 绘制时间文本
canvas.drawText(timestamp, timeX, timeY, paint)
// 如果有位置信息,绘制位置文本(时间上方)
if (locationText.isNotEmpty()) {
val locationBounds = Rect()
paint.getTextBounds(locationText, 0, locationText.length, locationBounds)
val locationTextWidth = paint.measureText(locationText)
val locationTextHeight = locationBounds.height()
val locationX = width - locationTextWidth - width / 50f
val locationY = timeY - locationTextHeight - height / 100f // 在时间上方,留出间距
// 绘制位置文本
canvas.drawText(locationText, locationX, locationY, paint)
}
return result
}
// 获取位置文本 - 修改为返回具体地址
private fun getLocationText(): String {
return currentLocation?.let { location ->
try {
val geocoder = Geocoder(this, Locale.getDefault())
val addresses = geocoder.getFromLocation(location.latitude, location.longitude, 1)
if (addresses?.isNotEmpty() == true) {
val address = addresses[0]
// 构建地址字符串,优先显示详细地址
val addressParts = mutableListOf<String>()
// 添加街道地址
address.getAddressLine(0)?.let { line: String -> addressParts.add(line) }
// 如果没有详细地址,则使用行政区划信息
if (addressParts.isEmpty()) {
address.locality?.let { city: String -> addressParts.add(city) } // 城市
address.subLocality?.let { district: String -> addressParts.add(district) } // 区县
address.thoroughfare?.let { street: String -> addressParts.add(street) } // 街道
}
val locationText = if (addressParts.isNotEmpty()) {
addressParts.joinToString(" ")
} else {
"${address.locality ?: ""} ${address.subAdminArea ?: ""}".trim()
}
if (locationText.isNotEmpty()) "位置: $locationText" else ""
} else {
// 如果地理编码失败,显示经纬度作为备选
val latitude = String.format("%.4f", location.latitude)
val longitude = String.format("%.4f", location.longitude)
"位置: $latitude, $longitude"
}
} catch (e: Exception) {
// 地理编码异常时,显示经纬度作为备选
val latitude = String.format("%.4f", location.latitude)
val longitude = String.format("%.4f", location.longitude)
"位置: $latitude, $longitude"
}
} ?: ""
}
private fun bitmapToBase64(bitmap: Bitmap): String {
val byteArrayOutputStream = ByteArrayOutputStream()
bitmap.compress(Bitmap.CompressFormat.JPEG, 95, byteArrayOutputStream)
val byteArray = byteArrayOutputStream.toByteArray()
return Base64.encodeToString(byteArray, Base64.DEFAULT)
}
private fun saveRepairOrder() {
repairOrder?.let { order ->
// 更新维修描述
order.repairDesc = etRepairDesc.text.toString()
// 更新照片
order.photos = photoList.joinToString(",")
// 显示加载进度
val progressBar = findViewById<View>(R.id.progressBar)
progressBar.visibility = View.VISIBLE
lifecycleScope.launch {
try {
val response = RetrofitClient.instance.updateRepairOrder(order)
progressBar.visibility = View.GONE
if (response.isSuccessful) {
val apiResponse = response.body()
if (apiResponse?.code == 200) {
Toast.makeText(this@TaskEditActivity, "保存成功", Toast.LENGTH_SHORT).show()
setResult(Activity.RESULT_OK)
finish()
} else {
Toast.makeText(this@TaskEditActivity,
apiResponse?.msg ?: "保存失败",
Toast.LENGTH_SHORT).show()
}
} else {
Toast.makeText(this@TaskEditActivity,
"网络请求失败: ${response.code()}",
Toast.LENGTH_SHORT).show()
}
} catch (e: Exception) {
progressBar.visibility = View.GONE
Toast.makeText(this@TaskEditActivity,
"保存异常: ${e.message}",
Toast.LENGTH_SHORT).show()
Log.e("TaskEditActivity", "保存异常", e)
}
}
}
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
if (item.itemId == android.R.id.home) {
onBackPressed()
return true
}
return super.onOptionsItemSelected(item)
}
// 添加提交工单的方法
private fun submitRepairOrder() {
repairOrder?.let { order ->
// 更新维修描述
order.repairDesc = etRepairDesc.text.toString()
// 更新照片
order.photos = photoList.joinToString(",")
// 更新状态为待审批
order.status = "待审批"
// 显示加载进度
val progressBar = findViewById<View>(R.id.progressBar)
progressBar.visibility = View.VISIBLE
lifecycleScope.launch {
try {
// 更新维修工单
val response = RetrofitClient.instance.updateRepairOrder(order)
if (response.isSuccessful) {
val apiResponse = response.body()
if (apiResponse?.code == 200) {
// 更新故障状态为待审批
try {
val faultStatusUpdate = FaultStatusUpdate(
faultId = order.faultId.toString(),
status = "待审批"
)
val faultResponse = RetrofitClient.instance.updateFaultStatus(faultStatusUpdate)
progressBar.visibility = View.GONE
if (faultResponse.isSuccessful && faultResponse.body()?.code == 200) {
Toast.makeText(this@TaskEditActivity,
"工单已提交审批", Toast.LENGTH_SHORT).show()
setResult(Activity.RESULT_OK)
finish()
} else {
Toast.makeText(this@TaskEditActivity,
"工单已提交,但故障状态更新失败", Toast.LENGTH_SHORT).show()
}
} catch (e: Exception) {
progressBar.visibility = View.GONE
Toast.makeText(this@TaskEditActivity,
"工单已提交,但故障状态更新失败: ${e.message}", Toast.LENGTH_SHORT).show()
Log.e("TaskEditActivity", "故障状态更新异常", e)
}
} else {
progressBar.visibility = View.GONE
Toast.makeText(this@TaskEditActivity,
apiResponse?.msg ?: "提交失败",
Toast.LENGTH_SHORT).show()
}
} else {
progressBar.visibility = View.GONE
Toast.makeText(this@TaskEditActivity,
"网络请求失败: ${response.code()}",
Toast.LENGTH_SHORT).show()
}
} catch (e: Exception) {
progressBar.visibility = View.GONE
Toast.makeText(this@TaskEditActivity,
"提交异常: ${e.message}",
Toast.LENGTH_SHORT).show()
Log.e("TaskEditActivity", "提交异常", e)
}
} // 这里可能缺少了lifecycleScope.launch的右花括号
} // 这里可能缺少了repairOrder?.let的右花括号
} // 这里是submitRepairOrder方法的右花括号
}
package com.example.sanpaias.entity
import android.os.Parcelable
import kotlinx.parcelize.Parcelize
@Parcelize
data class InspectionOrder(
val orderId: String,
val planId: Int,
val engineerId: String?,
val planTime: String?,
val inspectionDesc: String?,
val status: String,
val photos: String?,
// 添加缺失的属性
val deviceId: String? = null,
val location: String? = null,
val engineerName: String? = null
) : Parcelable
package com.example.sanpaias.fragment
import android.app.Activity
import android.content.Intent
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.AdapterView
import android.widget.ArrayAdapter
import android.widget.Spinner
import android.widget.TextView
import android.widget.Toast
import androidx.fragment.app.Fragment
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import com.example.sanpaias.R
import com.example.sanpaias.activity.TaskEditActivity
import com.example.sanpaias.adapter.MyTaskAdapter
import com.example.sanpaias.adapter.InspectionTaskAdapter
import com.example.sanpaias.adapter.MaintenanceTaskAdapter
import com.example.sanpaias.adapter.TestingTaskAdapter
import com.example.sanpaias.entity.RepairOrder
import com.example.sanpaias.entity.InspectionOrder
import com.example.sanpaias.entity.MaintenanceOrder
import com.example.sanpaias.entity.TestingOrder
import com.example.sanpaias.entity.User
import com.example.sanpaias.network.RetrofitClient
import kotlinx.coroutines.launch
class MyTasksFragment : Fragment() {
private lateinit var recyclerView: RecyclerView
private lateinit var swipeRefreshLayout: SwipeRefreshLayout
private lateinit var tvEmpty: TextView
private lateinit var taskTypeSpinner: Spinner
// 多个适配器
private lateinit var repairAdapter: MyTaskAdapter
private lateinit var inspectionAdapter: InspectionTaskAdapter
private lateinit var maintenanceAdapter: MaintenanceTaskAdapter
private lateinit var testingAdapter: TestingTaskAdapter
private var currentUser: User? = null
private var taskType: String = "repair" // 默认显示维修工单
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val view = inflater.inflate(R.layout.fragment_my_tasks, container, false)
recyclerView = view.findViewById(R.id.recyclerView)
swipeRefreshLayout = view.findViewById(R.id.swipeRefreshLayout)
tvEmpty = view.findViewById(R.id.tvEmpty)
taskTypeSpinner = view.findViewById(R.id.taskTypeSpinner)
// 设置工单类型选择下拉框
val taskTypes = arrayOf("维修工单", "巡检工单", "保养工单", "检测工单")
val spinnerAdapter = ArrayAdapter(requireContext(), android.R.layout.simple_spinner_item, taskTypes)
spinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
taskTypeSpinner.adapter = spinnerAdapter
// 设置RecyclerView
recyclerView.layoutManager = LinearLayoutManager(requireContext())
// 获取当前用户
currentUser = arguments?.getParcelable("current_user")
// 初始化所有适配器
repairAdapter = MyTaskAdapter { task ->
val intent = Intent(requireContext(), TaskEditActivity::class.java).apply {
putExtra("repair_order", task)
}
startActivityForResult(intent, REQUEST_EDIT_TASK)
}
inspectionAdapter = InspectionTaskAdapter { order ->
// 处理巡检工单点击事件
// 可以跳转到相应的编辑页面
}
maintenanceAdapter = MaintenanceTaskAdapter { order ->
// 处理保养工单点击事件
}
testingAdapter = TestingTaskAdapter { order ->
// 处理检测工单点击事件
}
// 默认显示维修工单
recyclerView.adapter = repairAdapter
// 设置下拉刷新
swipeRefreshLayout.setOnRefreshListener {
fetchMyTasks()
}
// 设置工单类型选择监听
taskTypeSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
when (position) {
0 -> { // 维修工单
recyclerView.adapter = repairAdapter
taskType = "repair"
}
1 -> { // 巡检工单
recyclerView.adapter = inspectionAdapter
taskType = "inspection"
}
2 -> { // 保养工单
recyclerView.adapter = maintenanceAdapter
taskType = "maintenance"
}
3 -> { // 检测工单
recyclerView.adapter = testingAdapter
taskType = "testing"
}
}
fetchMyTasks()
}
override fun onNothingSelected(parent: AdapterView<*>?) {
// 不处理
}
}
// 加载我的任务
fetchMyTasks()
return view
}
fun fetchMyTasks() {
when (taskType) {
"repair" -> fetchMyRepairOrders()
"inspection" -> fetchMyInspectionOrders()
"maintenance" -> fetchMyMaintenanceOrders()
"testing" -> fetchMyTestingOrders()
}
}
private fun fetchMyRepairOrders() {
// 检查视图是否已初始化
if (!this::swipeRefreshLayout.isInitialized || !isAdded) {
return
}
if (currentUser == null) {
tvEmpty.text = "请先登录"
tvEmpty.visibility = View.VISIBLE
return
}
// 显示加载进度
if (!swipeRefreshLayout.isRefreshing) {
(activity as? ProgressListener)?.showProgress(true)
}
tvEmpty.visibility = View.GONE
lifecycleScope.launch {
try {
val response = RetrofitClient.instance.getEngineerOrders(currentUser!!.id)
if (!isAdded) return@launch
(activity as? ProgressListener)?.showProgress(false)
swipeRefreshLayout.isRefreshing = false
if (response.isSuccessful) {
val apiResponse = response.body()
if (apiResponse?.code == 200) {
val allTasks = apiResponse.data ?: emptyList()
val filteredTasks = allTasks.filter {
it.status == "处理中" || it.status == "待审批"
}
repairAdapter.updateData(filteredTasks)
if (filteredTasks.isEmpty()) {
tvEmpty.text = "暂无处理中或待审批的维修工单"
tvEmpty.visibility = View.VISIBLE
} else {
tvEmpty.visibility = View.GONE
}
} else {
Toast.makeText(requireContext(),
apiResponse?.msg ?: "获取维修工单失败",
Toast.LENGTH_SHORT).show()
tvEmpty.visibility = View.VISIBLE
}
} else {
Toast.makeText(requireContext(),
"网络请求失败: ${response.code()}",
Toast.LENGTH_SHORT).show()
tvEmpty.visibility = View.VISIBLE
}
} catch (e: Exception) {
if (!isAdded) return@launch
(activity as? ProgressListener)?.showProgress(false)
swipeRefreshLayout.isRefreshing = false
Toast.makeText(requireContext(),
"获取维修工单异常: ${e.message}",
Toast.LENGTH_SHORT).show()
tvEmpty.visibility = View.VISIBLE
}
}
}
private fun fetchMyInspectionOrders() {
if (!this::swipeRefreshLayout.isInitialized || !isAdded) {
return
}
if (currentUser == null) {
tvEmpty.text = "请先登录"
tvEmpty.visibility = View.VISIBLE
return
}
if (!swipeRefreshLayout.isRefreshing) {
(activity as? ProgressListener)?.showProgress(true)
}
tvEmpty.visibility = View.GONE
lifecycleScope.launch {
try {
// 获取当前用户的巡检工单
val response = RetrofitClient.instance.getInspectionOrderList()
if (!isAdded) return@launch
(activity as? ProgressListener)?.showProgress(false)
swipeRefreshLayout.isRefreshing = false
if (response.isSuccessful) {
val apiResponse = response.body()
if (apiResponse?.code == 200) {
val allOrders = apiResponse.data ?: emptyList()
// 过滤出当前用户负责的且状态为处理中或待审批的工单
val myOrders = allOrders.filter {
it.engineerId == currentUser!!.id &&
(it.status == "处理中" || it.status == "待审批")
}
inspectionAdapter.updateData(myOrders)
if (myOrders.isEmpty()) {
tvEmpty.text = "暂无处理中或待审批的巡检工单"
tvEmpty.visibility = View.VISIBLE
} else {
tvEmpty.visibility = View.GONE
}
} else {
Toast.makeText(requireContext(),
apiResponse?.msg ?: "获取巡检工单失败",
Toast.LENGTH_SHORT).show()
tvEmpty.visibility = View.VISIBLE
}
} else {
Toast.makeText(requireContext(),
"网络请求失败: ${response.code()}",
Toast.LENGTH_SHORT).show()
tvEmpty.visibility = View.VISIBLE
}
} catch (e: Exception) {
if (!isAdded) return@launch
(activity as? ProgressListener)?.showProgress(false)
swipeRefreshLayout.isRefreshing = false
Toast.makeText(requireContext(),
"获取巡检工单异常: ${e.message}",
Toast.LENGTH_SHORT).show()
tvEmpty.visibility = View.VISIBLE
}
}
}
private fun fetchMyMaintenanceOrders() {
// 类似于 fetchMyInspectionOrders 的实现
// 获取保养工单数据
if (!this::swipeRefreshLayout.isInitialized || !isAdded) {
return
}
if (currentUser == null) {
tvEmpty.text = "请先登录"
tvEmpty.visibility = View.VISIBLE
return
}
if (!swipeRefreshLayout.isRefreshing) {
(activity as? ProgressListener)?.showProgress(true)
}
tvEmpty.visibility = View.GONE
lifecycleScope.launch {
try {
val response = RetrofitClient.instance.getMaintenanceOrderList()
if (!isAdded) return@launch
(activity as? ProgressListener)?.showProgress(false)
swipeRefreshLayout.isRefreshing = false
if (response.isSuccessful) {
val apiResponse = response.body()
if (apiResponse?.code == 200) {
val allOrders = apiResponse.data ?: emptyList()
val myOrders = allOrders.filter {
it.engineerId == currentUser!!.id &&
(it.status == "处理中" || it.status == "待审批")
}
maintenanceAdapter.updateData(myOrders)
if (myOrders.isEmpty()) {
tvEmpty.text = "暂无处理中或待审批的保养工单"
tvEmpty.visibility = View.VISIBLE
} else {
tvEmpty.visibility = View.GONE
}
} else {
Toast.makeText(requireContext(),
apiResponse?.msg ?: "获取保养工单失败",
Toast.LENGTH_SHORT).show()
tvEmpty.visibility = View.VISIBLE
}
} else {
Toast.makeText(requireContext(),
"网络请求失败: ${response.code()}",
Toast.LENGTH_SHORT).show()
tvEmpty.visibility = View.VISIBLE
}
} catch (e: Exception) {
if (!isAdded) return@launch
(activity as? ProgressListener)?.showProgress(false)
swipeRefreshLayout.isRefreshing = false
Toast.makeText(requireContext(),
"获取保养工单异常: ${e.message}",
Toast.LENGTH_SHORT).show()
tvEmpty.visibility = View.VISIBLE
}
}
}
private fun fetchMyTestingOrders() {
// 类似于其他方法的实现
// 获取检测工单数据
if (!this::swipeRefreshLayout.isInitialized || !isAdded) {
return
}
if (currentUser == null) {
tvEmpty.text = "请先登录"
tvEmpty.visibility = View.VISIBLE
return
}
if (!swipeRefreshLayout.isRefreshing) {
(activity as? ProgressListener)?.showProgress(true)
}
tvEmpty.visibility = View.GONE
lifecycleScope.launch {
try {
val response = RetrofitClient.instance.getTestingOrderList()
if (!isAdded) return@launch
(activity as? ProgressListener)?.showProgress(false)
swipeRefreshLayout.isRefreshing = false
if (response.isSuccessful) {
val apiResponse = response.body()
if (apiResponse?.code == 200) {
val allOrders = apiResponse.data ?: emptyList()
// 过滤出当前用户负责的且状态为处理中或待审批的工单
val myOrders = allOrders.filter {
it.engineerId == currentUser!!.id &&
(it.status == "处理中" || it.status == "待审批")
}
testingAdapter.updateData(myOrders)
if (myOrders.isEmpty()) {
tvEmpty.text = "暂无处理中或待审批的检测工单"
tvEmpty.visibility = View.VISIBLE
} else {
tvEmpty.visibility = View.GONE
}
} else {
Toast.makeText(requireContext(),
apiResponse?.msg ?: "获取检测工单失败",
Toast.LENGTH_SHORT).show()
tvEmpty.visibility = View.VISIBLE
}
} else {
Toast.makeText(requireContext(),
"网络请求失败: ${response.code()}",
Toast.LENGTH_SHORT).show()
tvEmpty.visibility = View.VISIBLE
}
} catch (e: Exception) {
if (!isAdded) return@launch
(activity as? ProgressListener)?.showProgress(false)
swipeRefreshLayout.isRefreshing = false
Toast.makeText(requireContext(),
"获取检测工单异常: ${e.message}",
Toast.LENGTH_SHORT).show()
tvEmpty.visibility = View.VISIBLE
}
}
}
// 添加refreshTasks方法作为fetchMyTasks的别名,保持接口一致性
fun refreshTasks() {
fetchMyTasks()
}
interface ProgressListener {
fun showProgress(show: Boolean)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == REQUEST_EDIT_TASK && resultCode == Activity.RESULT_OK) {
// 任务编辑成功后刷新列表
fetchMyTasks()
}
}
companion object {
private const val REQUEST_EDIT_TASK = 1001
fun newInstance(user: User): MyTasksFragment {
val fragment = MyTasksFragment()
val args = Bundle()
args.putParcelable("current_user", user)
fragment.arguments = args
return fragment
}
}
}
package com.example.sanpaias.fragment
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.AdapterView
import android.widget.ArrayAdapter
import android.widget.Spinner
import android.widget.TextView
import androidx.fragment.app.Fragment
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import com.example.sanpaias.R
import com.example.sanpaias.adapter.InspectionTaskAdapter
import com.example.sanpaias.adapter.MaintenanceTaskAdapter
import com.example.sanpaias.adapter.PendingTaskAdapter
import com.example.sanpaias.adapter.TestingTaskAdapter
import com.example.sanpaias.entity.DeviceFault
import com.example.sanpaias.entity.InspectionOrder
import com.example.sanpaias.entity.MaintenanceOrder
import com.example.sanpaias.entity.TestingOrder
import com.example.sanpaias.entity.User
import com.example.sanpaias.network.RetrofitClient
import kotlinx.coroutines.launch
// 在导入部分添加新的适配器
import com.example.sanpaias.adapter.PendingInspectionTaskAdapter
import com.example.sanpaias.adapter.PendingMaintenanceTaskAdapter
import com.example.sanpaias.adapter.PendingTestingTaskAdapter
class PendingTasksFragment : Fragment() {
private lateinit var recyclerView: RecyclerView
private lateinit var swipeRefreshLayout: SwipeRefreshLayout
private lateinit var tvEmpty: TextView
private lateinit var faultAdapter: PendingTaskAdapter
private lateinit var inspectionAdapter: PendingInspectionTaskAdapter
private lateinit var maintenanceAdapter: PendingMaintenanceTaskAdapter
private lateinit var testingAdapter: PendingTestingTaskAdapter
private lateinit var taskTypeSpinner: Spinner
private var currentUser: User? = null
private var taskType: String = "fault" // 默认显示故障工单
// 定义接口用于与Activity通信
interface TaskActionListener {
fun showProgress(show: Boolean)
fun takeTask(fault: DeviceFault)
fun takeInspectionTask(order: InspectionOrder)
fun takeMaintenanceTask(order: MaintenanceOrder)
fun takeTestingTask(order: TestingOrder)
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val view = inflater.inflate(R.layout.fragment_pending_tasks, container, false)
// 初始化视图
recyclerView = view.findViewById(R.id.recyclerView)
swipeRefreshLayout = view.findViewById(R.id.swipeRefreshLayout)
tvEmpty = view.findViewById(R.id.tvEmpty)
// 添加工单类型选择下拉框
taskTypeSpinner = view.findViewById(R.id.taskTypeSpinner)
val taskTypes = arrayOf("维修工单", "巡检工单", "保养工单", "检测工单")
val adapter = ArrayAdapter(requireContext(), android.R.layout.simple_spinner_item, taskTypes)
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
taskTypeSpinner.adapter = adapter
// 获取传递的用户信息
arguments?.let {
val userJson = it.getString("user")
if (!userJson.isNullOrEmpty()) {
currentUser = com.google.gson.Gson().fromJson(userJson, User::class.java)
}
}
// 设置RecyclerView
recyclerView.layoutManager = LinearLayoutManager(context)
// 初始化适配器
faultAdapter = PendingTaskAdapter { fault ->
(activity as? TaskActionListener)?.takeTask(fault)
}
inspectionAdapter = PendingInspectionTaskAdapter { order ->
(activity as? TaskActionListener)?.takeInspectionTask(order)
}
maintenanceAdapter = PendingMaintenanceTaskAdapter { order ->
(activity as? TaskActionListener)?.takeMaintenanceTask(order)
}
testingAdapter = PendingTestingTaskAdapter { order ->
(activity as? TaskActionListener)?.takeTestingTask(order)
}
// 默认显示故障工单
recyclerView.adapter = faultAdapter
// 设置下拉刷新
swipeRefreshLayout.setOnRefreshListener {
fetchPendingTasks()
}
// 设置工单类型选择监听
taskTypeSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
when (position) {
0 -> { // 故障工单
recyclerView.adapter = faultAdapter
taskType = "fault"
}
1 -> { // 巡检工单
recyclerView.adapter = inspectionAdapter
taskType = "inspection"
}
2 -> { // 维修工单
recyclerView.adapter = maintenanceAdapter
taskType = "maintenance"
}
3 -> { // 检测工单
recyclerView.adapter = testingAdapter
taskType = "testing"
}
}
fetchPendingTasks()
}
override fun onNothingSelected(parent: AdapterView<*>?) {
// 不处理
}
}
return view
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
fetchPendingTasks()
}
fun fetchPendingTasks() {
when (taskType) {
"fault" -> fetchPendingFaults()
"inspection" -> fetchPendingInspectionOrders()
"maintenance" -> fetchPendingMaintenanceOrders()
"testing" -> fetchPendingTestingOrders()
}
}
private fun fetchPendingFaults() {
// 检查视图是否已初始化
if (!this::swipeRefreshLayout.isInitialized || !isAdded) {
return
}
// 显示加载进度
if (!swipeRefreshLayout.isRefreshing) {
(activity as? TaskActionListener)?.showProgress(true)
}
tvEmpty.visibility = View.GONE
// 原有的获取故障工单代码...
lifecycleScope.launch {
try {
val response = RetrofitClient.instance.getPendingFaults()
// 检查Fragment是否仍然附加到Activity
if (!isAdded) return@launch
// 隐藏加载进度
(activity as? TaskActionListener)?.showProgress(false)
swipeRefreshLayout.isRefreshing = false
if (response.isSuccessful) {
val apiResponse = response.body()
if (apiResponse?.code == 200) {
val faults = apiResponse.data ?: emptyList()
// 更新适配器数据
faultAdapter.updateData(faults)
// 显示空视图(如果没有数据)
if (faults.isEmpty()) {
tvEmpty.visibility = View.VISIBLE
tvEmpty.text = "暂无待处理故障"
} else {
tvEmpty.visibility = View.GONE
}
} else {
tvEmpty.visibility = View.VISIBLE
tvEmpty.text = apiResponse?.msg ?: "获取数据失败"
}
} else {
tvEmpty.visibility = View.VISIBLE
tvEmpty.text = "网络请求失败: ${response.code()}"
}
} catch (e: Exception) {
// 检查Fragment是否仍然附加到Activity
if (!isAdded) return@launch
// 隐藏加载进度
(activity as? TaskActionListener)?.showProgress(false)
swipeRefreshLayout.isRefreshing = false
// 显示错误信息
tvEmpty.visibility = View.VISIBLE
tvEmpty.text = "加载异常: ${e.message}"
e.printStackTrace()
}
}
}
private fun fetchPendingInspectionOrders() {
// 检查视图是否已初始化
if (!this::swipeRefreshLayout.isInitialized || !isAdded) {
return
}
// 显示加载进度
if (!swipeRefreshLayout.isRefreshing) {
(activity as? TaskActionListener)?.showProgress(true)
}
tvEmpty.visibility = View.GONE
lifecycleScope.launch {
try {
// 修改为获取所有巡检工单,不指定状态参数
val response = RetrofitClient.instance.getInspectionOrderList()
// 检查Fragment是否仍然附加到Activity
if (!isAdded) return@launch
// 隐藏加载进度
(activity as? TaskActionListener)?.showProgress(false)
swipeRefreshLayout.isRefreshing = false
if (response.isSuccessful) {
val apiResponse = response.body()
if (apiResponse?.code == 200) {
val allOrders = apiResponse.data ?: emptyList()
// 在前端过滤状态为"待接取"的工单
val pendingOrders = allOrders.filter { it.status == "待处理" }
// 更新适配器数据
inspectionAdapter.updateData(pendingOrders)
// 显示空视图(如果没有数据)
if (pendingOrders.isEmpty()) {
tvEmpty.visibility = View.VISIBLE
tvEmpty.text = "暂无待接取巡检工单"
} else {
tvEmpty.visibility = View.GONE
}
} else {
tvEmpty.visibility = View.VISIBLE
tvEmpty.text = apiResponse?.msg ?: "获取数据失败"
}
} else {
tvEmpty.visibility = View.VISIBLE
tvEmpty.text = "网络请求失败: ${response.code()}"
}
} catch (e: Exception) {
// 检查Fragment是否仍然附加到Activity
if (!isAdded) return@launch
// 隐藏加载进度
(activity as? TaskActionListener)?.showProgress(false)
swipeRefreshLayout.isRefreshing = false
// 显示错误信息
tvEmpty.visibility = View.VISIBLE
tvEmpty.text = "加载异常: ${e.message}"
e.printStackTrace()
}
}
}
private fun fetchPendingMaintenanceOrders() {
// 检查视图是否已初始化
if (!this::swipeRefreshLayout.isInitialized || !isAdded) {
return
}
// 显示加载进度
if (!swipeRefreshLayout.isRefreshing) {
(activity as? TaskActionListener)?.showProgress(true)
}
tvEmpty.visibility = View.GONE
lifecycleScope.launch {
try {
// 修改为获取所有保养工单,不指定状态参数
val response = RetrofitClient.instance.getMaintenanceOrderList()
// 检查Fragment是否仍然附加到Activity
if (!isAdded) return@launch
// 隐藏加载进度
(activity as? TaskActionListener)?.showProgress(false)
swipeRefreshLayout.isRefreshing = false
if (response.isSuccessful) {
val apiResponse = response.body()
if (apiResponse?.code == 200) {
val allOrders = apiResponse.data ?: emptyList()
// 在前端过滤状态为"待处理"的工单
val pendingOrders = allOrders.filter { it.status == "待处理" }
// 更新适配器数据
maintenanceAdapter.updateData(pendingOrders)
// 显示空视图(如果没有数据)
if (pendingOrders.isEmpty()) {
tvEmpty.visibility = View.VISIBLE
tvEmpty.text = "暂无待处理保养工单"
} else {
tvEmpty.visibility = View.GONE
}
} else {
tvEmpty.visibility = View.VISIBLE
tvEmpty.text = apiResponse?.msg ?: "获取数据失败"
}
} else {
tvEmpty.visibility = View.VISIBLE
tvEmpty.text = "网络请求失败: ${response.code()}"
}
} catch (e: Exception) {
// 检查Fragment是否仍然附加到Activity
if (!isAdded) return@launch
// 隐藏加载进度
(activity as? TaskActionListener)?.showProgress(false)
swipeRefreshLayout.isRefreshing = false
// 显示错误信息
tvEmpty.visibility = View.VISIBLE
tvEmpty.text = "加载异常: ${e.message}"
e.printStackTrace()
}
}
}
private fun fetchPendingTestingOrders() {
// 检查视图是否已初始化
if (!this::swipeRefreshLayout.isInitialized || !isAdded) {
return
}
// 显示加载进度
if (!swipeRefreshLayout.isRefreshing) {
(activity as? TaskActionListener)?.showProgress(true)
}
tvEmpty.visibility = View.GONE
lifecycleScope.launch {
try {
// 修改为获取所有检测工单,不指定状态参数
val response = RetrofitClient.instance.getTestingOrderList()
// 检查Fragment是否仍然附加到Activity
if (!isAdded) return@launch
// 隐藏加载进度
(activity as? TaskActionListener)?.showProgress(false)
swipeRefreshLayout.isRefreshing = false
if (response.isSuccessful) {
val apiResponse = response.body()
if (apiResponse?.code == 200) {
val allOrders = apiResponse.data ?: emptyList()
// 在前端过滤状态为"待处理"的工单
val pendingOrders = allOrders.filter { it.status == "待处理" }
// 更新适配器数据
testingAdapter.updateData(pendingOrders)
// 显示空视图(如果没有数据)
if (pendingOrders.isEmpty()) {
tvEmpty.visibility = View.VISIBLE
tvEmpty.text = "暂无待处理检测工单"
} else {
tvEmpty.visibility = View.GONE
}
} else {
tvEmpty.visibility = View.VISIBLE
tvEmpty.text = apiResponse?.msg ?: "获取数据失败"
}
} else {
tvEmpty.visibility = View.VISIBLE
tvEmpty.text = "网络请求失败: ${response.code()}"
}
} catch (e: Exception) {
// 检查Fragment是否仍然附加到Activity
if (!isAdded) return@launch
// 隐藏加载进度
(activity as? TaskActionListener)?.showProgress(false)
swipeRefreshLayout.isRefreshing = false
// 显示错误信息
tvEmpty.visibility = View.VISIBLE
tvEmpty.text = "加载异常: ${e.message}"
e.printStackTrace()
}
}
}
// 添加刷新任务的公共方法
fun refreshTasks() {
fetchPendingTasks()
}
companion object {
fun newInstance(user: User): PendingTasksFragment {
val fragment = PendingTasksFragment()
val args = Bundle()
args.putString("user", com.google.gson.Gson().toJson(user))
fragment.arguments = args
return fragment
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".activity.PendingTasksActivity">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:elevation="4dp"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
app:title="任务管理" />
<com.google.android.material.tabs.TabLayout
android:id="@+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@+id/toolbar"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent">
<com.google.android.material.tabs.TabItem
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="待处理任务" />
<com.google.android.material.tabs.TabItem
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="我的任务" />
</com.google.android.material.tabs.TabLayout>
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/viewPager"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintTop_toBottomOf="@+id/tabLayout"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
<ProgressBar
android:id="@+id/progressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".activity.InspectionListActivity">
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/swipeRefreshLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="8dp"
android:clipToPadding="false" />
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
<ProgressBar
android:id="@+id/progressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tvEmpty"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="暂无巡检任务"
android:textSize="18sp"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/cardView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp"
app:cardCornerRadius="8dp"
app:cardElevation="4dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
<TextView
android:id="@+id/tvOrderId"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="工单编号: INS001"
android:textSize="16sp"
android:textStyle="bold" />
<TextView
android:id="@+id/tvPlanId"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="计划编号: 1" />
<TextView
android:id="@+id/tvDeviceId"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="设备编号: ELEV001" />
<TextView
android:id="@+id/tvLocation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="位置: 1号楼大厅" />
<TextView
android:id="@+id/tvStatus"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="状态: 待处理" />
<TextView
android:id="@+id/tvEngineer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="工程师: 张三" />
</LinearLayout>
</androidx.cardview.widget.CardView>
package com.example.sanpaias.adapter
import android.content.Intent
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.TextView
import androidx.cardview.widget.CardView
import androidx.recyclerview.widget.RecyclerView
import com.example.sanpaias.R
import com.example.sanpaias.activity.InspectionTaskEditActivity
import com.example.sanpaias.entity.InspectionOrder
class InspectionTaskAdapter(
private val onTakeTask: (InspectionOrder) -> Unit
) : RecyclerView.Adapter<InspectionTaskAdapter.TaskViewHolder>() {
private var tasks: List<InspectionOrder> = emptyList()
class TaskViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val cardView: CardView = itemView.findViewById(R.id.cardView)
val tvOrderId: TextView = itemView.findViewById(R.id.tvOrderId)
val tvFaultId: TextView = itemView.findViewById(R.id.tvFaultId)
val tvStatus: TextView = itemView.findViewById(R.id.tvStatus)
val tvRepairDesc: TextView = itemView.findViewById(R.id.tvRepairDesc)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TaskViewHolder {
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.item_my_task, parent, false)
return TaskViewHolder(view)
}
override fun onBindViewHolder(holder: TaskViewHolder, position: Int) {
val task = tasks[position]
// 设置工单信息
holder.tvOrderId.text = "工单编号: ${task.orderId}"
holder.tvFaultId.text = "计划编号: ${task.planId}"
holder.tvStatus.text = "状态: ${task.status ?: "待处理"}"
holder.tvRepairDesc.text = "巡检描述: ${task.inspectionDesc ?: "暂无描述"}"
// 设置点击事件 - 跳转到巡检工单编辑页面
holder.cardView.setOnClickListener {
val context = holder.itemView.context
val intent = Intent(context, InspectionTaskEditActivity::class.java)
intent.putExtra("inspection_order", task)
context.startActivity(intent)
}
}
override fun getItemCount() = tasks.size
fun updateData(newTasks: List<InspectionOrder>) {
tasks = newTasks
notifyDataSetChanged()
}
}
fun getItemCount(): Int {
TODO("Not yet implemented")
}
package com.example.sanpaias.activity
import android.app.DatePickerDialog
import android.app.Dialog
import android.app.TimePickerDialog
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import android.widget.*
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.example.sanpaias.R
import com.example.sanpaias.entity.Device
import com.example.sanpaias.entity.InspectionPlan
import com.example.sanpaias.network.RetrofitClient
import com.google.gson.Gson
import kotlinx.coroutines.launch
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.RequestBody
import okhttp3.RequestBody.Companion.toRequestBody
import java.text.SimpleDateFormat
import java.util.*
class InspectionPlanListActivity : AppCompatActivity() {
private lateinit var rvInspectionPlans: RecyclerView
private lateinit var tvNoData: TextView
private lateinit var btnAddPlan: Button
private val planList = mutableListOf<InspectionPlan>()
private val deviceList = mutableListOf<Device>()
private lateinit var adapter: InspectionPlanAdapter
private val TAG = "InspectionPlanActivity"
private val dateFormat = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault())
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_inspection_plan_list)
// 设置返回按钮
supportActionBar?.setDisplayHomeAsUpEnabled(true)
supportActionBar?.title = "巡检计划列表"
// 初始化视图
rvInspectionPlans = findViewById(R.id.rvInspectionPlans)
tvNoData = findViewById(R.id.tvNoData)
btnAddPlan = findViewById(R.id.btnAddPlan)
// 设置RecyclerView
rvInspectionPlans.layoutManager = LinearLayoutManager(this)
adapter = InspectionPlanAdapter(planList)
rvInspectionPlans.adapter = adapter
// 设置新增计划按钮点击事件
btnAddPlan.setOnClickListener {
showAddPlanDialog()
}
// 加载设备列表
loadDevices()
// 加载巡检计划数据
loadInspectionPlans()
}
private fun loadDevices() {
lifecycleScope.launch {
try {
val response = RetrofitClient.instance.getAllDevices()
if (response.isSuccessful && response.body()?.code == 200) {
deviceList.clear()
deviceList.addAll(response.body()?.data ?: emptyList())
Log.d(TAG, "加载设备列表成功: ${deviceList.size}个设备")
} else {
Log.e(TAG, "加载设备列表失败: ${response.message()}")
}
} catch (e: Exception) {
Log.e(TAG, "加载设备列表异常", e)
}
}
}
private fun loadInspectionPlans() {
lifecycleScope.launch {
try {
val response = RetrofitClient.instance.getInspectionPlanList()
if (response.isSuccessful && response.body()?.code == 200) {
val plans = response.body()?.data ?: emptyList()
if (plans.isNotEmpty()) {
planList.clear()
planList.addAll(plans)
adapter.notifyDataSetChanged()
tvNoData.visibility = View.GONE
} else {
tvNoData.visibility = View.VISIBLE
}
} else {
Toast.makeText(this@InspectionPlanListActivity, "获取巡检计划失败", Toast.LENGTH_SHORT).show()
tvNoData.visibility = View.VISIBLE
}
} catch (e: Exception) {
Log.e(TAG, "加载巡检计划异常", e)
Toast.makeText(this@InspectionPlanListActivity, "加载异常: ${e.message}", Toast.LENGTH_SHORT).show()
tvNoData.visibility = View.VISIBLE
}
}
}
private fun showAddPlanDialog() {
val dialog = Dialog(this)
dialog.setContentView(R.layout.dialog_add_inspection_plan)
dialog.window?.setLayout(
(resources.displayMetrics.widthPixels * 0.9).toInt(),
ViewGroup.LayoutParams.WRAP_CONTENT
)
// 初始化对话框控件
val spinnerDeviceId = dialog.findViewById<Spinner>(R.id.spinnerDeviceId)
val etLocation = dialog.findViewById<EditText>(R.id.etLocation)
val spinnerFrequency = dialog.findViewById<Spinner>(R.id.spinnerFrequency)
val etStartTime = dialog.findViewById<EditText>(R.id.etStartTime)
val etEndTime = dialog.findViewById<EditText>(R.id.etEndTime)
val btnCancel = dialog.findViewById<Button>(R.id.btnCancel)
val btnConfirm = dialog.findViewById<Button>(R.id.btnConfirm)
// 设置设备下拉列表
val deviceAdapter = ArrayAdapter(
this,
android.R.layout.simple_spinner_item,
deviceList.map { it.deviceId }
)
deviceAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
spinnerDeviceId.adapter = deviceAdapter
// 设置设备选择监听器,自动填充位置
spinnerDeviceId.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
if (position >= 0 && position < deviceList.size) {
// 获取选中设备的位置信息并填充
val selectedDevice = deviceList[position]
etLocation.setText(selectedDevice.location)
}
}
override fun onNothingSelected(parent: AdapterView<*>?) {
// 不做任何操作
}
}
// 设置频率下拉列表
val frequencyAdapter = ArrayAdapter(
this,
android.R.layout.simple_spinner_item,
arrayOf("日", "周", "月", "季度", "半年", "年")
)
frequencyAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
spinnerFrequency.adapter = frequencyAdapter
// 设置时间选择
etStartTime.setOnClickListener {
showDateTimePicker { dateTime ->
etStartTime.setText(dateFormat.format(dateTime.time))
}
}
etEndTime.setOnClickListener {
showDateTimePicker { dateTime ->
etEndTime.setText(dateFormat.format(dateTime.time))
}
}
// 设置按钮点击事件
btnCancel.setOnClickListener {
dialog.dismiss()
}
btnConfirm.setOnClickListener {
// 验证输入
if (spinnerDeviceId.selectedItem == null) {
Toast.makeText(this, "请选择设备", Toast.LENGTH_SHORT).show()
return@setOnClickListener
}
if (etLocation.text.toString().trim().isEmpty()) {
Toast.makeText(this, "请输入巡检位置", Toast.LENGTH_SHORT).show()
return@setOnClickListener
}
if (etStartTime.text.toString().trim().isEmpty()) {
Toast.makeText(this, "请选择开始时间", Toast.LENGTH_SHORT).show()
return@setOnClickListener
}
// 创建巡检计划对象 - 修改日期格式
val isoDateFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.getDefault())
isoDateFormat.timeZone = TimeZone.getTimeZone("UTC")
val startTimeStr = etStartTime.text.toString().trim()
val endTimeStr = etEndTime.text.toString().trim()
// 解析日期并转换为ISO格式
val startTimeDate = dateFormat.parse(startTimeStr)
val startTimeIso = if (startTimeDate != null) isoDateFormat.format(startTimeDate) else startTimeStr
val endTimeIso = if (endTimeStr.isNotEmpty()) {
val endTimeDate = dateFormat.parse(endTimeStr)
if (endTimeDate != null) isoDateFormat.format(endTimeDate) else endTimeStr
} else null
val newPlan = InspectionPlan(
planId = 0, // 后端会自动生成ID
deviceId = spinnerDeviceId.selectedItem.toString(),
location = etLocation.text.toString().trim(),
frequency = spinnerFrequency.selectedItem.toString(),
status = "待启用",
startTime = startTimeIso,
endTime = endTimeIso
)
// 提交新计划
addInspectionPlan(newPlan)
dialog.dismiss()
}
dialog.show()
}
private fun showDateTimePicker(callback: (Calendar) -> Unit) {
val calendar = Calendar.getInstance()
// 日期选择器
DatePickerDialog(
this,
{ _, year, month, dayOfMonth ->
calendar.set(Calendar.YEAR, year)
calendar.set(Calendar.MONTH, month)
calendar.set(Calendar.DAY_OF_MONTH, dayOfMonth)
// 时间选择器
TimePickerDialog(
this,
{ _, hourOfDay, minute ->
calendar.set(Calendar.HOUR_OF_DAY, hourOfDay)
calendar.set(Calendar.MINUTE, minute)
calendar.set(Calendar.SECOND, 0)
callback(calendar)
},
calendar.get(Calendar.HOUR_OF_DAY),
calendar.get(Calendar.MINUTE),
true
).show()
},
calendar.get(Calendar.YEAR),
calendar.get(Calendar.MONTH),
calendar.get(Calendar.DAY_OF_MONTH)
).show()
}
private fun addInspectionPlan(plan: InspectionPlan) {
lifecycleScope.launch {
try {
// 打印请求体,便于调试
Log.d(TAG, "发送的巡检计划数据: $plan")
val response = RetrofitClient.instance.addInspectionPlan(plan)
if (response.isSuccessful) {
Toast.makeText(this@InspectionPlanListActivity, "添加巡检计划成功", Toast.LENGTH_SHORT).show()
// 重新加载巡检计划列表
loadInspectionPlans()
} else {
// 获取详细错误信息
val errorBody = response.errorBody()?.string() ?: "未知错误"
Log.e(TAG, "添加巡检计划失败: $errorBody")
// 尝试提取更有用的错误信息
val errorMessage = if (errorBody.startsWith("{")) {
try {
// 如果是JSON格式,尝试提取message字段
val errorJson = org.json.JSONObject(errorBody)
errorJson.optString("message", errorBody.take(100))
} catch (e: Exception) {
// JSON解析失败,显示前100个字符
errorBody.take(100)
}
} else {
// 不是JSON格式,显示前100个字符
errorBody.take(100)
}
Toast.makeText(this@InspectionPlanListActivity, "添加巡检计划失败: $errorMessage", Toast.LENGTH_LONG).show()
}
} catch (e: Exception) {
Log.e(TAG, "添加巡检计划异常", e)
Toast.makeText(this@InspectionPlanListActivity, "添加巡检计划异常: ${e.message}", Toast.LENGTH_SHORT).show()
}
}
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
if (item.itemId == android.R.id.home) {
finish()
return true
}
return super.onOptionsItemSelected(item)
}
// 巡检计划适配器
inner class InspectionPlanAdapter(private val plans: List<InspectionPlan>) :
RecyclerView.Adapter<InspectionPlanAdapter.ViewHolder>() {
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val tvPlanId: TextView = itemView.findViewById(R.id.tvPlanId)
val tvDeviceId: TextView = itemView.findViewById(R.id.tvDeviceId)
val tvLocation: TextView = itemView.findViewById(R.id.tvLocation)
val tvFrequency: TextView = itemView.findViewById(R.id.tvFrequency)
val tvStatus: TextView = itemView.findViewById(R.id.tvStatus)
val tvTimeRange: TextView = itemView.findViewById(R.id.tvTimeRange)
// 添加按钮引用
val btnEnable: Button = itemView.findViewById(R.id.btnEnable)
val btnDisable: Button = itemView.findViewById(R.id.btnDisable)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.item_inspection_plan, parent, false)
return ViewHolder(view)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val plan = plans[position]
holder.tvPlanId.text = "计划ID: ${plan.planId}"
holder.tvDeviceId.text = "设备ID: ${plan.deviceId}"
holder.tvLocation.text = "巡检位置: ${plan.location}"
holder.tvFrequency.text = "巡检频率: ${plan.frequency}"
holder.tvStatus.text = "状态: ${plan.status}"
// 根据状态设置文字颜色
when (plan.status) {
"启用" -> holder.tvStatus.setTextColor(0xFF4CAF50.toInt())
"停用" -> holder.tvStatus.setTextColor(0xFFF44336.toInt())
"待启用" -> holder.tvStatus.setTextColor(0xFFFF9800.toInt())
}
val timeRange = if (plan.endTime != null) {
"${plan.startTime} ~ ${plan.endTime}"
} else {
"${plan.startTime} 起"
}
holder.tvTimeRange.text = "时间范围: $timeRange"
// 根据当前状态设置按钮可用性
if (plan.status == "启用") {
holder.btnEnable.isEnabled = false
holder.btnDisable.isEnabled = true
} else {
holder.btnEnable.isEnabled = true
holder.btnDisable.isEnabled = false
}
// 设置启用按钮点击事件
holder.btnEnable.setOnClickListener {
updatePlanStatus(plan.planId, "启用")
}
// 设置停用按钮点击事件
holder.btnDisable.setOnClickListener {
updatePlanStatus(plan.planId, "停用")
}
// 设置整个项目的点击事件,打开编辑对话框
holder.itemView.setOnClickListener {
showEditPlanDialog(plan)
}
}
override fun getItemCount() = plans.size
}
// 更新巡检计划状态
private fun updatePlanStatus(planId: Int, status: String) {
lifecycleScope.launch {
try {
val response = RetrofitClient.instance.updateInspectionPlanStatus(planId, status)
if (response.isSuccessful) {
// 如果是启用操作,生成对应的巡检工单
if (status == "启用") {
generateInspectionOrder(planId)
} else {
Toast.makeText(this@InspectionPlanListActivity, "更新状态成功", Toast.LENGTH_SHORT).show()
loadInspectionPlans()
}
} else {
val errorBody = response.errorBody()?.string() ?: "未知错误"
Log.e(TAG, "更新状态失败: $errorBody")
Toast.makeText(this@InspectionPlanListActivity, "更新状态失败", Toast.LENGTH_SHORT).show()
}
} catch (e: Exception) {
Log.e(TAG, "更新状态异常", e)
Toast.makeText(this@InspectionPlanListActivity, "更新状态异常: ${e.message}", Toast.LENGTH_SHORT).show()
}
}
}
// 生成巡检工单
private fun generateInspectionOrder(planId: Int) {
lifecycleScope.launch {
try {
val request = mapOf("planIds" to listOf(planId))
val gson = Gson()
val json = gson.toJson(request)
val requestBody = json.toRequestBody("application/json".toMediaTypeOrNull())
val response = RetrofitClient.instance.generateInspectionOrders(requestBody)
if (response.isSuccessful) {
Toast.makeText(this@InspectionPlanListActivity, "启用成功,已生成巡检工单", Toast.LENGTH_SHORT).show()
} else {
Toast.makeText(this@InspectionPlanListActivity, "启用成功,但工单生成失败", Toast.LENGTH_LONG).show()
}
// 重新加载巡检计划列表
loadInspectionPlans()
} catch (e: Exception) {
Log.e(TAG, "生成工单异常", e)
Toast.makeText(this@InspectionPlanListActivity, "启用成功,但工单生成异常: ${e.message}", Toast.LENGTH_LONG).show()
loadInspectionPlans()
}
}
}
// 显示编辑巡检计划对话框
private fun showEditPlanDialog(plan: InspectionPlan) {
val dialog = Dialog(this)
dialog.setContentView(R.layout.dialog_add_inspection_plan)
dialog.window?.setLayout(
(resources.displayMetrics.widthPixels * 0.9).toInt(),
ViewGroup.LayoutParams.WRAP_CONTENT
)
// 修改对话框标题
dialog.setTitle("编辑巡检计划")
// 初始化对话框控件
val spinnerDeviceId = dialog.findViewById<Spinner>(R.id.spinnerDeviceId)
val etLocation = dialog.findViewById<EditText>(R.id.etLocation)
val spinnerFrequency = dialog.findViewById<Spinner>(R.id.spinnerFrequency)
val etStartTime = dialog.findViewById<EditText>(R.id.etStartTime)
val etEndTime = dialog.findViewById<EditText>(R.id.etEndTime)
val btnCancel = dialog.findViewById<Button>(R.id.btnCancel)
val btnConfirm = dialog.findViewById<Button>(R.id.btnConfirm)
// 设置设备下拉列表
val deviceAdapter = ArrayAdapter(
this,
android.R.layout.simple_spinner_item,
deviceList.map { it.deviceId }
)
deviceAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
spinnerDeviceId.adapter = deviceAdapter
// 设置频率下拉列表
val frequencyAdapter = ArrayAdapter(
this,
android.R.layout.simple_spinner_item,
arrayOf("日", "周", "月", "季度", "半年", "年")
)
frequencyAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
spinnerFrequency.adapter = frequencyAdapter
// 填充现有数据
val devicePosition = deviceList.indexOfFirst { it.deviceId == plan.deviceId }
if (devicePosition >= 0) {
spinnerDeviceId.setSelection(devicePosition)
}
etLocation.setText(plan.location)
val frequencyPosition = arrayOf("日", "周", "月", "季度", "半年", "年").indexOf(plan.frequency)
if (frequencyPosition >= 0) {
spinnerFrequency.setSelection(frequencyPosition)
}
// 转换日期格式回显示格式
try {
// 创建多种日期格式解析器
val isoDateFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.getDefault())
isoDateFormat.timeZone = TimeZone.getTimeZone("UTC")
val isoDateFormatNoMillis = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.getDefault())
val isoDateFormatWithZ = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.getDefault())
isoDateFormatWithZ.timeZone = TimeZone.getTimeZone("UTC")
// 处理开始时间
var startDate: Date? = null
// 尝试使用不同的格式解析日期
if (plan.startTime.contains("T")) {
try {
if (plan.startTime.contains(".")) {
startDate = isoDateFormat.parse(plan.startTime)
} else if (plan.startTime.endsWith("Z")) {
startDate = isoDateFormatWithZ.parse(plan.startTime)
} else {
startDate = isoDateFormatNoMillis.parse(plan.startTime)
}
} catch (e: Exception) {
Log.e(TAG, "解析ISO日期失败: ${e.message}")
}
} else {
try {
startDate = dateFormat.parse(plan.startTime)
} catch (e: Exception) {
Log.e(TAG, "解析标准日期失败: ${e.message}")
}
}
if (startDate != null) {
etStartTime.setText(dateFormat.format(startDate))
} else {
etStartTime.setText(plan.startTime)
}
// 处理结束时间
if (plan.endTime != null) {
var endDate: Date? = null
// 尝试使用不同的格式解析日期
if (plan.endTime.contains("T")) {
try {
if (plan.endTime.contains(".")) {
endDate = isoDateFormat.parse(plan.endTime)
} else if (plan.endTime.endsWith("Z")) {
endDate = isoDateFormatWithZ.parse(plan.endTime)
} else {
endDate = isoDateFormatNoMillis.parse(plan.endTime)
}
} catch (e: Exception) {
Log.e(TAG, "解析ISO结束日期失败: ${e.message}")
}
} else {
try {
endDate = dateFormat.parse(plan.endTime)
} catch (e: Exception) {
Log.e(TAG, "解析标准结束日期失败: ${e.message}")
}
}
if (endDate != null) {
etEndTime.setText(dateFormat.format(endDate))
} else {
etEndTime.setText(plan.endTime)
}
}
} catch (e: Exception) {
Log.e(TAG, "日期格式转换异常", e)
// 如果转换失败,直接显示原始值
etStartTime.setText(plan.startTime)
if (plan.endTime != null) {
etEndTime.setText(plan.endTime)
}
}
// 设置时间选择
etStartTime.setOnClickListener {
showDateTimePicker { dateTime ->
etStartTime.setText(dateFormat.format(dateTime.time))
}
}
etEndTime.setOnClickListener {
showDateTimePicker { dateTime ->
etEndTime.setText(dateFormat.format(dateTime.time))
}
}
// 设置按钮点击事件
btnCancel.setOnClickListener {
dialog.dismiss()
}
btnConfirm.setOnClickListener {
// 验证输入
if (spinnerDeviceId.selectedItem == null) {
Toast.makeText(this, "请选择设备", Toast.LENGTH_SHORT).show()
return@setOnClickListener
}
if (etLocation.text.toString().trim().isEmpty()) {
Toast.makeText(this, "请输入巡检位置", Toast.LENGTH_SHORT).show()
return@setOnClickListener
}
if (etStartTime.text.toString().trim().isEmpty()) {
Toast.makeText(this, "请选择开始时间", Toast.LENGTH_SHORT).show()
return@setOnClickListener
}
// 创建巡检计划对象 - 修改日期格式
val isoDateFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.getDefault())
isoDateFormat.timeZone = TimeZone.getTimeZone("UTC")
val startTimeStr = etStartTime.text.toString().trim()
val endTimeStr = etEndTime.text.toString().trim()
// 解析日期并转换为ISO格式
val startTimeDate = dateFormat.parse(startTimeStr)
val startTimeIso = if (startTimeDate != null) isoDateFormat.format(startTimeDate) else startTimeStr
val endTimeIso = if (endTimeStr.isNotEmpty()) {
val endTimeDate = dateFormat.parse(endTimeStr)
if (endTimeDate != null) isoDateFormat.format(endTimeDate) else endTimeStr
} else null
// 创建更新后的计划对象
val updatedPlan = InspectionPlan(
planId = plan.planId, // 保持原有ID
deviceId = spinnerDeviceId.selectedItem.toString(),
location = etLocation.text.toString().trim(),
frequency = spinnerFrequency.selectedItem.toString(),
status = plan.status, // 保持原有状态
startTime = startTimeIso,
endTime = endTimeIso
)
// 更新计划
updateInspectionPlan(updatedPlan)
dialog.dismiss()
}
dialog.show()
}
// 更新巡检计划
private fun updateInspectionPlan(plan: InspectionPlan) {
lifecycleScope.launch {
try {
Log.d(TAG, "更新的巡检计划数据: $plan")
val response = RetrofitClient.instance.updateInspectionPlan(plan)
if (response.isSuccessful) {
Toast.makeText(this@InspectionPlanListActivity, "更新巡检计划成功", Toast.LENGTH_SHORT).show()
// 重新加载巡检计划列表
loadInspectionPlans()
} else {
val errorBody = response.errorBody()?.string() ?: "未知错误"
Log.e(TAG, "更新巡检计划失败: $errorBody")
val errorMessage = if (errorBody.startsWith("{")) {
try {
val errorJson = org.json.JSONObject(errorBody)
errorJson.optString("message", errorBody.take(100))
} catch (e: Exception) {
errorBody.take(100)
}
} else {
errorBody.take(100)
}
Toast.makeText(this@InspectionPlanListActivity, "更新巡检计划失败: $errorMessage", Toast.LENGTH_LONG).show()
}
} catch (e: Exception) {
Log.e(TAG, "更新巡检计划异常", e)
Toast.makeText(this@InspectionPlanListActivity, "更新巡检计划异常: ${e.message}", Toast.LENGTH_SHORT).show()
}
}
}
}

浙公网安备 33010602011771号