feat: 任务管理模块 - 列表+详情+抢单/打卡/完成
新增: - TaskListFragment 分段控件+RecyclerView+下拉刷新 - TaskDetailFragment 信息展示+底部固定操作按钮(foot-btn) - TaskListAdapter 任务卡片适配器 - TaskItem/TaskDetail 数据类 - TaskApi 新增5个接口(pageList/detail/grab/assign/complete) - 分段控件/底部按钮/状态标签 drawable 修改: - nav_main.xml 添加参数和action - HomeFragment 快捷区点击→任务列表(传tableStatus) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
33
app/src/main/java/com/xiaoqu/watch/data/task/TaskDetail.kt
Normal file
33
app/src/main/java/com/xiaoqu/watch/data/task/TaskDetail.kt
Normal file
@@ -0,0 +1,33 @@
|
||||
package com.xiaoqu.watch.data.task
|
||||
|
||||
import com.google.gson.annotations.SerializedName
|
||||
|
||||
/**
|
||||
* 任务详情数据类
|
||||
* 对应 watchTask/lookTaskDetail API 返回
|
||||
*/
|
||||
data class TaskDetail(
|
||||
@SerializedName("id") val id: Long = 0,
|
||||
/** 任务编号 */
|
||||
@SerializedName("no") val no: String = "",
|
||||
/** 任务名称 */
|
||||
@SerializedName("taskName") val taskName: String = "",
|
||||
/** 地点名称 */
|
||||
@SerializedName("positionName") val positionName: String = "",
|
||||
/** 积分 */
|
||||
@SerializedName("point") val point: Int = 0,
|
||||
/** 状态:2=待抢单, 3=待打卡, 4=进行中, 1=已完成 */
|
||||
@SerializedName("status") val status: Int = 0,
|
||||
/** 任务类型 */
|
||||
@SerializedName("taskType") val taskType: Int = 0,
|
||||
/** 开始时间 */
|
||||
@SerializedName("beginTime") val beginTime: String = "",
|
||||
/** 结束时间 */
|
||||
@SerializedName("endTime") val endTime: String = "",
|
||||
/** 任务描述 */
|
||||
@SerializedName("description") val description: String = "",
|
||||
/** 协作人 */
|
||||
@SerializedName("executorName") val executorName: String = "",
|
||||
/** 是否有打卡地点(决定打卡方式:有=NFC打卡,无=直接确认) */
|
||||
@SerializedName("hasPosition") val hasPosition: Boolean = false
|
||||
)
|
||||
27
app/src/main/java/com/xiaoqu/watch/data/task/TaskItem.kt
Normal file
27
app/src/main/java/com/xiaoqu/watch/data/task/TaskItem.kt
Normal file
@@ -0,0 +1,27 @@
|
||||
package com.xiaoqu.watch.data.task
|
||||
|
||||
import com.google.gson.annotations.SerializedName
|
||||
|
||||
/**
|
||||
* 任务列表项数据类
|
||||
* 对应 watchTask/pageList API 返回
|
||||
*/
|
||||
data class TaskItem(
|
||||
@SerializedName("id") val id: Long = 0,
|
||||
/** 任务编号 */
|
||||
@SerializedName("no") val no: String = "",
|
||||
/** 任务名称 */
|
||||
@SerializedName("taskName") val taskName: String = "",
|
||||
/** 地点名称 */
|
||||
@SerializedName("positionName") val positionName: String = "",
|
||||
/** 积分 */
|
||||
@SerializedName("point") val point: Int = 0,
|
||||
/** 状态:2=待抢单, 3=待打卡, 4=进行中, 1=已完成 */
|
||||
@SerializedName("status") val status: Int = 0,
|
||||
/** 任务类型:0=计划, 1=监控, 2=指派, 3=用户上报, 4=巡检上报, 5=巡检任务 */
|
||||
@SerializedName("taskType") val taskType: Int = 0,
|
||||
/** 开始时间 */
|
||||
@SerializedName("beginTime") val beginTime: String = "",
|
||||
/** 结束时间 */
|
||||
@SerializedName("endTime") val endTime: String = ""
|
||||
)
|
||||
@@ -1,9 +1,14 @@
|
||||
package com.xiaoqu.watch.network.api
|
||||
|
||||
import com.xiaoqu.watch.data.task.AttendanceInfo
|
||||
import com.xiaoqu.watch.data.task.TaskDetail
|
||||
import com.xiaoqu.watch.data.task.TaskItem
|
||||
import com.xiaoqu.watch.data.task.TaskStatistics
|
||||
import com.xiaoqu.watch.network.ApiResponse
|
||||
import retrofit2.http.Body
|
||||
import retrofit2.http.GET
|
||||
import retrofit2.http.POST
|
||||
import retrofit2.http.Query
|
||||
|
||||
/**
|
||||
* 任务相关 API 接口
|
||||
@@ -17,4 +22,24 @@ interface TaskApi {
|
||||
/** 查询当前考勤状态 */
|
||||
@GET("watchTask/myCurrentAttendance")
|
||||
suspend fun getAttendance(): ApiResponse<AttendanceInfo>
|
||||
|
||||
/** 任务列表(按状态筛选) */
|
||||
@GET("watchTask/pageList")
|
||||
suspend fun getTaskList(@Query("status") status: Int): ApiResponse<List<TaskItem>>
|
||||
|
||||
/** 任务详情 */
|
||||
@GET("watchTask/lookTaskDetail")
|
||||
suspend fun getTaskDetail(@Query("id") taskId: Long): ApiResponse<TaskDetail>
|
||||
|
||||
/** 抢单 */
|
||||
@POST("task/grabTask")
|
||||
suspend fun grabTask(@Body params: HashMap<String, Any>): ApiResponse<Any>
|
||||
|
||||
/** 无场景打卡(直接确认) */
|
||||
@POST("task/assignToBeginTask")
|
||||
suspend fun assignToBeginTask(@Body params: HashMap<String, Any>): ApiResponse<Any>
|
||||
|
||||
/** 确认完成 */
|
||||
@POST("task/completeTask")
|
||||
suspend fun completeTask(@Body params: HashMap<String, Any>): ApiResponse<Any>
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.TextView
|
||||
import androidx.core.os.bundleOf
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import com.xiaoqu.watch.BuildConfig
|
||||
@@ -106,18 +107,15 @@ class HomeFragment : BaseFragment<FragmentHomeBinding>() {
|
||||
tvPunchNum = page.findViewById(R.id.tvPunchNum)
|
||||
tvCompleteNum = page.findViewById(R.id.tvCompleteNum)
|
||||
|
||||
// 快捷区卡片点击 → 跳转任务列表(后续实现)
|
||||
// 快捷区卡片点击 → 跳转任务列表(传 tableStatus 参数)
|
||||
page.findViewById<View>(R.id.cardPool)?.setOnClickListener {
|
||||
Timber.d("点击接单池")
|
||||
// TODO: navigate to TaskListFragment with tableStatus=2
|
||||
navigateToTaskList(2)
|
||||
}
|
||||
page.findViewById<View>(R.id.cardPunch)?.setOnClickListener {
|
||||
Timber.d("点击待打卡")
|
||||
// TODO: navigate to TaskListFragment with tableStatus=3
|
||||
navigateToTaskList(3)
|
||||
}
|
||||
page.findViewById<View>(R.id.cardComplete)?.setOnClickListener {
|
||||
Timber.d("点击待完成")
|
||||
// TODO: navigate to TaskListFragment with tableStatus=4
|
||||
navigateToTaskList(4)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -261,4 +259,10 @@ class HomeFragment : BaseFragment<FragmentHomeBinding>() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** 跳转到任务列表(传 tableStatus 参数) */
|
||||
private fun navigateToTaskList(tableStatus: Int) {
|
||||
val bundle = bundleOf("tableStatus" to tableStatus)
|
||||
findNavController().navigate(R.id.action_home_to_taskList, bundle)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +1,247 @@
|
||||
package com.xiaoqu.watch.ui.task
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.FrameLayout
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import com.xiaoqu.watch.R
|
||||
import com.xiaoqu.watch.data.task.TaskDetail
|
||||
import com.xiaoqu.watch.databinding.FragmentTaskDetailBinding
|
||||
import com.xiaoqu.watch.network.ApiResult
|
||||
import com.xiaoqu.watch.network.api.TaskApi
|
||||
import com.xiaoqu.watch.network.safeApiCall
|
||||
import com.xiaoqu.watch.ui.common.BaseFragment
|
||||
import com.xiaoqu.watch.ui.widget.QuTipDialog
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
/**
|
||||
* 任务详情页
|
||||
* 显示任务信息 + 底部固定操作按钮(按状态不同显示不同操作)
|
||||
*/
|
||||
@AndroidEntryPoint
|
||||
class TaskDetailFragment : BaseFragment<FragmentTaskDetailBinding>() {
|
||||
|
||||
@Inject lateinit var taskApi: TaskApi
|
||||
|
||||
/** 当前任务数据 */
|
||||
private var taskDetail: TaskDetail? = null
|
||||
|
||||
/** 提示弹窗 */
|
||||
private lateinit var tipDialog: QuTipDialog
|
||||
|
||||
override fun createBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentTaskDetailBinding {
|
||||
return FragmentTaskDetailBinding.inflate(inflater, container, false)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
// 初始化弹窗
|
||||
val dialogContainer = requireActivity().findViewById<FrameLayout>(R.id.dialog_container)
|
||||
tipDialog = QuTipDialog(dialogContainer)
|
||||
|
||||
// 返回按钮
|
||||
binding.btnBack.setOnClickListener {
|
||||
findNavController().popBackStack()
|
||||
}
|
||||
|
||||
// 从导航参数获取任务 ID
|
||||
val taskId = arguments?.getLong("taskId", 0) ?: 0
|
||||
if (taskId > 0) {
|
||||
fetchDetail(taskId)
|
||||
}
|
||||
}
|
||||
|
||||
/** 获取任务详情 */
|
||||
private fun fetchDetail(taskId: Long) {
|
||||
viewLifecycleOwner.lifecycleScope.launch {
|
||||
val result = safeApiCall { taskApi.getTaskDetail(taskId) }
|
||||
when (result) {
|
||||
is ApiResult.Success -> {
|
||||
result.data?.let { detail ->
|
||||
taskDetail = detail
|
||||
displayDetail(detail)
|
||||
setupActionButton(detail)
|
||||
}
|
||||
}
|
||||
is ApiResult.Error -> {
|
||||
Timber.w("任务详情: API 错误 ${result.code}")
|
||||
}
|
||||
is ApiResult.NetworkError -> {
|
||||
Timber.w("任务详情: 网络异常")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** 展示任务信息 */
|
||||
private fun displayDetail(detail: TaskDetail) {
|
||||
binding.tvTaskName.text = detail.taskName
|
||||
binding.tvTaskNo.text = detail.no
|
||||
binding.tvPosition.text = detail.positionName.ifEmpty { "无" }
|
||||
binding.tvPoints.text = if (detail.point > 0) "+${detail.point}" else "0"
|
||||
binding.tvTime.text = detail.beginTime
|
||||
|
||||
// 状态标签
|
||||
when (detail.status) {
|
||||
2 -> binding.tvStatus.text = "待抢单"
|
||||
3 -> binding.tvStatus.text = "待打卡"
|
||||
4 -> binding.tvStatus.text = "进行中"
|
||||
else -> binding.tvStatus.text = "已完成"
|
||||
}
|
||||
|
||||
// 提示条(待打卡+有场景时显示)
|
||||
if (detail.status == 3 && detail.hasPosition) {
|
||||
binding.tvHint.visibility = View.VISIBLE
|
||||
}
|
||||
}
|
||||
|
||||
/** 根据任务状态设置底部操作按钮 */
|
||||
private fun setupActionButton(detail: TaskDetail) {
|
||||
val btn = binding.btnAction
|
||||
when (detail.status) {
|
||||
// 待抢单 → 蓝色「抢 单」
|
||||
2 -> {
|
||||
btn.text = "抢 单"
|
||||
btn.setBackgroundResource(R.drawable.bg_foot_btn_blue)
|
||||
btn.setOnClickListener { doGrabTask(detail.id) }
|
||||
}
|
||||
// 待打卡
|
||||
3 -> {
|
||||
if (detail.hasPosition) {
|
||||
// 有场景 → 橙色「开启打卡」(NFC,后续实现)
|
||||
btn.text = "开启打卡"
|
||||
btn.setBackgroundResource(R.drawable.bg_foot_btn_orange)
|
||||
btn.setTextColor(requireContext().getColor(R.color.background))
|
||||
btn.setOnClickListener {
|
||||
// TODO: NFC 打卡流程
|
||||
Timber.d("任务详情: NFC 打卡(后续实现)")
|
||||
}
|
||||
} else {
|
||||
// 无场景 → 绿色「确认打卡」
|
||||
btn.text = "确认打卡"
|
||||
btn.setBackgroundResource(R.drawable.bg_foot_btn_green)
|
||||
btn.setOnClickListener { doAssignBeginTask(detail.id) }
|
||||
}
|
||||
}
|
||||
// 进行中 → 绿色「确认完成」
|
||||
4 -> {
|
||||
btn.text = "确认完成"
|
||||
btn.setBackgroundResource(R.drawable.bg_foot_btn_green)
|
||||
btn.setOnClickListener { doCompleteTask(detail.id) }
|
||||
}
|
||||
// 已完成 → 隐藏按钮
|
||||
else -> {
|
||||
btn.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** 抢单操作 */
|
||||
private fun doGrabTask(taskId: Long) {
|
||||
viewLifecycleOwner.lifecycleScope.launch {
|
||||
val params = hashMapOf<String, Any>("id" to taskId)
|
||||
val result = safeApiCall { taskApi.grabTask(params) }
|
||||
when (result) {
|
||||
is ApiResult.Success -> {
|
||||
Timber.d("任务详情: 抢单成功")
|
||||
tipDialog.show(
|
||||
status = QuTipDialog.Status.SUCCESS,
|
||||
title = "抢单成功",
|
||||
back = true, step = 1, countdown = 2,
|
||||
onBack = { findNavController().popBackStack() }
|
||||
)
|
||||
}
|
||||
is ApiResult.Error -> {
|
||||
tipDialog.show(
|
||||
status = QuTipDialog.Status.ERROR,
|
||||
title = "抢单失败",
|
||||
desc = result.message,
|
||||
back = true, step = 0, countdown = 3
|
||||
)
|
||||
}
|
||||
is ApiResult.NetworkError -> {
|
||||
tipDialog.show(
|
||||
status = QuTipDialog.Status.ERROR,
|
||||
title = "网络异常",
|
||||
back = true, step = 0, countdown = 3
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** 无场景打卡操作 */
|
||||
private fun doAssignBeginTask(taskId: Long) {
|
||||
viewLifecycleOwner.lifecycleScope.launch {
|
||||
val params = hashMapOf<String, Any>("id" to taskId)
|
||||
val result = safeApiCall { taskApi.assignToBeginTask(params) }
|
||||
when (result) {
|
||||
is ApiResult.Success -> {
|
||||
Timber.d("任务详情: 打卡成功")
|
||||
tipDialog.show(
|
||||
status = QuTipDialog.Status.SUCCESS,
|
||||
title = "打卡成功",
|
||||
back = true, step = 1, countdown = 2,
|
||||
onBack = { findNavController().popBackStack() }
|
||||
)
|
||||
}
|
||||
is ApiResult.Error -> {
|
||||
tipDialog.show(
|
||||
status = QuTipDialog.Status.ERROR,
|
||||
title = "打卡失败",
|
||||
desc = result.message,
|
||||
back = true, step = 0, countdown = 3
|
||||
)
|
||||
}
|
||||
is ApiResult.NetworkError -> {
|
||||
tipDialog.show(
|
||||
status = QuTipDialog.Status.ERROR,
|
||||
title = "网络异常",
|
||||
back = true, step = 0, countdown = 3
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** 确认完成操作 */
|
||||
private fun doCompleteTask(taskId: Long) {
|
||||
viewLifecycleOwner.lifecycleScope.launch {
|
||||
val params = hashMapOf<String, Any>("id" to taskId)
|
||||
val result = safeApiCall { taskApi.completeTask(params) }
|
||||
when (result) {
|
||||
is ApiResult.Success -> {
|
||||
Timber.d("任务详情: 完成成功")
|
||||
tipDialog.show(
|
||||
status = QuTipDialog.Status.SUCCESS,
|
||||
title = "任务已完成",
|
||||
back = true, step = 1, countdown = 2,
|
||||
onBack = { findNavController().popBackStack() }
|
||||
)
|
||||
}
|
||||
is ApiResult.Error -> {
|
||||
tipDialog.show(
|
||||
status = QuTipDialog.Status.ERROR,
|
||||
title = "操作失败",
|
||||
desc = result.message,
|
||||
back = true, step = 0, countdown = 3
|
||||
)
|
||||
}
|
||||
is ApiResult.NetworkError -> {
|
||||
tipDialog.show(
|
||||
status = QuTipDialog.Status.ERROR,
|
||||
title = "网络异常",
|
||||
back = true, step = 0, countdown = 3
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
package com.xiaoqu.watch.ui.task
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.TextView
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.xiaoqu.watch.R
|
||||
import com.xiaoqu.watch.data.task.TaskItem
|
||||
|
||||
/**
|
||||
* 任务列表 RecyclerView 适配器
|
||||
* 显示任务卡片:任务名 + 地点+时间 + 积分+状态标签
|
||||
*/
|
||||
class TaskListAdapter(
|
||||
private val onItemClick: (TaskItem) -> Unit
|
||||
) : RecyclerView.Adapter<TaskListAdapter.TaskViewHolder>() {
|
||||
|
||||
private val tasks = mutableListOf<TaskItem>()
|
||||
|
||||
/** 更新数据 */
|
||||
fun submitList(newTasks: List<TaskItem>) {
|
||||
tasks.clear()
|
||||
tasks.addAll(newTasks)
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TaskViewHolder {
|
||||
val view = LayoutInflater.from(parent.context)
|
||||
.inflate(R.layout.item_task_card, parent, false)
|
||||
return TaskViewHolder(view)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: TaskViewHolder, position: Int) {
|
||||
holder.bind(tasks[position])
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int = tasks.size
|
||||
|
||||
inner class TaskViewHolder(view: View) : RecyclerView.ViewHolder(view) {
|
||||
private val tvTaskName: TextView = view.findViewById(R.id.tvTaskName)
|
||||
private val tvTaskSub: TextView = view.findViewById(R.id.tvTaskSub)
|
||||
private val tvPoints: TextView = view.findViewById(R.id.tvPoints)
|
||||
private val tvStatus: TextView = view.findViewById(R.id.tvStatus)
|
||||
|
||||
fun bind(task: TaskItem) {
|
||||
// 任务名
|
||||
tvTaskName.text = task.taskName
|
||||
|
||||
// 地点 + 时间
|
||||
val sub = StringBuilder()
|
||||
if (task.positionName.isNotEmpty()) sub.appendLine(task.positionName)
|
||||
if (task.beginTime.isNotEmpty()) sub.append(task.beginTime)
|
||||
tvTaskSub.text = sub.toString()
|
||||
|
||||
// 积分
|
||||
tvPoints.text = if (task.point > 0) "+${task.point}" else ""
|
||||
|
||||
// 状态标签
|
||||
val context = itemView.context
|
||||
when (task.status) {
|
||||
2 -> {
|
||||
tvStatus.text = "待抢单"
|
||||
tvStatus.setTextColor(context.getColor(R.color.primary))
|
||||
tvStatus.setBackgroundResource(R.drawable.bg_pill_blue)
|
||||
}
|
||||
3 -> {
|
||||
tvStatus.text = "待打卡"
|
||||
tvStatus.setTextColor(context.getColor(R.color.warning))
|
||||
tvStatus.setBackgroundResource(R.drawable.bg_pill_orange)
|
||||
}
|
||||
4 -> {
|
||||
tvStatus.text = "进行中"
|
||||
tvStatus.setTextColor(context.getColor(R.color.success))
|
||||
tvStatus.setBackgroundResource(R.drawable.bg_pill_green)
|
||||
}
|
||||
else -> {
|
||||
tvStatus.text = "已完成"
|
||||
tvStatus.setTextColor(context.getColor(R.color.text_secondary))
|
||||
tvStatus.background = null
|
||||
}
|
||||
}
|
||||
|
||||
// 点击事件
|
||||
itemView.setOnClickListener { onItemClick(task) }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,15 +1,141 @@
|
||||
package com.xiaoqu.watch.ui.task
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.TextView
|
||||
import androidx.core.os.bundleOf
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import com.xiaoqu.watch.R
|
||||
import com.xiaoqu.watch.databinding.FragmentTaskListBinding
|
||||
import com.xiaoqu.watch.network.ApiResult
|
||||
import com.xiaoqu.watch.network.api.TaskApi
|
||||
import com.xiaoqu.watch.network.safeApiCall
|
||||
import com.xiaoqu.watch.ui.common.BaseFragment
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
/**
|
||||
* 任务列表页
|
||||
* 分段控件切换状态(接单池2/待打卡3/待完成4)
|
||||
* RecyclerView 显示任务卡片,点击进入详情
|
||||
*/
|
||||
@AndroidEntryPoint
|
||||
class TaskListFragment : BaseFragment<FragmentTaskListBinding>() {
|
||||
|
||||
@Inject lateinit var taskApi: TaskApi
|
||||
|
||||
/** 当前选中的状态 */
|
||||
private var currentStatus = 2
|
||||
|
||||
/** 列表适配器 */
|
||||
private lateinit var adapter: TaskListAdapter
|
||||
|
||||
/** 分段控件的 3 个 Tab */
|
||||
private lateinit var segTabs: List<TextView>
|
||||
|
||||
override fun createBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentTaskListBinding {
|
||||
return FragmentTaskListBinding.inflate(inflater, container, false)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
// 从导航参数获取初始状态(首页快捷区传入)
|
||||
currentStatus = arguments?.getInt("tableStatus", 2) ?: 2
|
||||
|
||||
// 返回按钮
|
||||
binding.btnBack.setOnClickListener {
|
||||
findNavController().popBackStack()
|
||||
}
|
||||
|
||||
// 初始化 RecyclerView
|
||||
adapter = TaskListAdapter { task ->
|
||||
// 点击任务卡片 → 跳转详情
|
||||
val bundle = bundleOf("taskId" to task.id)
|
||||
findNavController().navigate(R.id.action_taskList_to_detail, bundle)
|
||||
}
|
||||
binding.rvTasks.layoutManager = LinearLayoutManager(requireContext())
|
||||
binding.rvTasks.adapter = adapter
|
||||
|
||||
// 初始化分段控件
|
||||
segTabs = listOf(binding.segPool, binding.segPunch, binding.segComplete)
|
||||
binding.segPool.setOnClickListener { switchStatus(2) }
|
||||
binding.segPunch.setOnClickListener { switchStatus(3) }
|
||||
binding.segComplete.setOnClickListener { switchStatus(4) }
|
||||
|
||||
// 下拉刷新
|
||||
binding.swipeRefresh.setOnRefreshListener { fetchTasks() }
|
||||
|
||||
// 设置初始状态并加载数据
|
||||
switchStatus(currentStatus)
|
||||
}
|
||||
|
||||
/** 从详情页返回时自动刷新 */
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
fetchTasks()
|
||||
}
|
||||
|
||||
/** 切换状态 Tab */
|
||||
private fun switchStatus(status: Int) {
|
||||
currentStatus = status
|
||||
updateSegmentUI()
|
||||
updateTitle()
|
||||
fetchTasks()
|
||||
}
|
||||
|
||||
/** 更新分段控件高亮 */
|
||||
private fun updateSegmentUI() {
|
||||
val statusList = listOf(2, 3, 4)
|
||||
for (i in segTabs.indices) {
|
||||
if (statusList[i] == currentStatus) {
|
||||
segTabs[i].setBackgroundResource(R.drawable.bg_seg_active)
|
||||
segTabs[i].setTextColor(requireContext().getColor(R.color.text_primary))
|
||||
} else {
|
||||
segTabs[i].background = null
|
||||
segTabs[i].setTextColor(requireContext().getColor(R.color.text_secondary))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** 更新页面标题 */
|
||||
private fun updateTitle() {
|
||||
binding.tvTitle.text = when (currentStatus) {
|
||||
2 -> "接单池"
|
||||
3 -> "待打卡"
|
||||
4 -> "待完成"
|
||||
else -> "任务列表"
|
||||
}
|
||||
}
|
||||
|
||||
/** 从 API 获取任务列表 */
|
||||
private fun fetchTasks() {
|
||||
viewLifecycleOwner.lifecycleScope.launch {
|
||||
binding.swipeRefresh.isRefreshing = true
|
||||
val result = safeApiCall { taskApi.getTaskList(currentStatus) }
|
||||
binding.swipeRefresh.isRefreshing = false
|
||||
|
||||
when (result) {
|
||||
is ApiResult.Success -> {
|
||||
val tasks = result.data ?: emptyList()
|
||||
Timber.d("任务列表: status=$currentStatus, count=${tasks.size}")
|
||||
adapter.submitList(tasks)
|
||||
}
|
||||
is ApiResult.Error -> {
|
||||
Timber.w("任务列表: API 错误 code=${result.code} ${result.message}")
|
||||
adapter.submitList(emptyList())
|
||||
}
|
||||
is ApiResult.NetworkError -> {
|
||||
Timber.w("任务列表: 网络异常")
|
||||
adapter.submitList(emptyList())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user