feat(task): 添加组配任务功能模块
- 新增组配任务列表页面和详情页面 - 实现组配任务查询、搜索和分页功能 - 添加组配任务详情展示和状态管理 - 集成溯源码获取功能到任务详情页面 - 添加组配任务相关的API接口定义和实现 - 创建组配任务数据模型和适配器 - 在设置页面添加组配任务入口 - 重构食材物料列表项布局和显示逻辑 - 更新应用启动时的设备ID初始化逻辑 - 生成配比秤终端接口文档
This commit is contained in:
@@ -79,6 +79,16 @@
|
||||
android:screenOrientation="portrait"
|
||||
tools:ignore="DiscouragedApi,LockedOrientationActivity" />
|
||||
|
||||
<activity android:name=".ui.TaskActivity"
|
||||
android:theme="@style/Theme.DishMatch.NoSplash"
|
||||
android:screenOrientation="portrait"
|
||||
tools:ignore="DiscouragedApi,LockedOrientationActivity" />
|
||||
|
||||
<activity android:name=".ui.TaskDetailActivity"
|
||||
android:theme="@style/Theme.DishMatch.NoSplash"
|
||||
android:screenOrientation="portrait"
|
||||
tools:ignore="DiscouragedApi,LockedOrientationActivity" />
|
||||
|
||||
<activity
|
||||
android:name=".ui.CookingModeActivity"
|
||||
android:theme="@style/Theme.DishMatch.NoSplash"
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
package com.shuwei.dish.match.adapter
|
||||
|
||||
import android.content.Context
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import com.chad.library.adapter4.BaseQuickAdapter
|
||||
import com.chad.library.adapter4.viewholder.QuickViewHolder
|
||||
import com.shuwei.dish.match.R
|
||||
import com.shuwei.dish.match.databinding.ListItemTaskBinding
|
||||
import com.shuwei.dish.match.model.NutComboTaskVO
|
||||
|
||||
/**
|
||||
* 组配任务列表适配器
|
||||
*/
|
||||
class TaskAdapter(list: MutableList<NutComboTaskVO>) :
|
||||
BaseQuickAdapter<NutComboTaskVO, TaskAdapter.VH>(list) {
|
||||
|
||||
inner class VH(var binding: ListItemTaskBinding) : QuickViewHolder(binding.root)
|
||||
|
||||
override fun onBindViewHolder(
|
||||
holder: VH,
|
||||
position: Int,
|
||||
item: NutComboTaskVO?
|
||||
) {
|
||||
holder.binding.apply {
|
||||
tvTaskNo.text = "任务编号:${item?.taskNo}"
|
||||
tvTargetDish.text = item?.targetDish
|
||||
tvSpec.text = item?.spec
|
||||
tvPlanDate.text = "计划日期:${item?.planDate}"
|
||||
tvPortions.text = "总份数:${item?.portions}"
|
||||
tvOwnerName.text = "负责人:${item?.ownerName}"
|
||||
|
||||
// 状态文本映射
|
||||
val statusText = when (item?.comboStatus) {
|
||||
0 -> "待组配"
|
||||
1 -> "组配中"
|
||||
2 -> "已完成"
|
||||
else -> "未知"
|
||||
}
|
||||
tvStatus.text = statusText
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(
|
||||
context: Context,
|
||||
parent: ViewGroup,
|
||||
viewType: Int
|
||||
): VH {
|
||||
val inflater = LayoutInflater.from(context)
|
||||
val binding = ListItemTaskBinding.inflate(inflater, parent, false)
|
||||
return VH(binding)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
package com.shuwei.dish.match.adapter
|
||||
|
||||
import android.content.Context
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import com.chad.library.adapter4.BaseQuickAdapter
|
||||
import com.chad.library.adapter4.viewholder.QuickViewHolder
|
||||
import com.shuwei.dish.match.R
|
||||
import com.shuwei.dish.match.databinding.ListItemTaskDetailBinding
|
||||
import com.shuwei.dish.match.model.NutComboTaskItemDetail
|
||||
import com.shuwei.dish.match.utils.ext.gone
|
||||
import com.shuwei.dish.match.utils.ext.visible
|
||||
import java.math.BigDecimal
|
||||
|
||||
/**
|
||||
* 组配任务详情食材列表适配器
|
||||
*/
|
||||
class TaskDetailAdapter(list: MutableList<NutComboTaskItemDetail>) :
|
||||
BaseQuickAdapter<NutComboTaskItemDetail, TaskDetailAdapter.VH>(list) {
|
||||
|
||||
inner class VH(var binding: ListItemTaskDetailBinding) : QuickViewHolder(binding.root)
|
||||
|
||||
/**
|
||||
* 格式化用量字符串,去掉小数点后末尾的0
|
||||
*/
|
||||
private fun formatQty(value: String?): String {
|
||||
if (value.isNullOrBlank()) return "0"
|
||||
return try {
|
||||
BigDecimal(value).stripTrailingZeros().toPlainString()
|
||||
} catch (e: Exception) {
|
||||
value
|
||||
}
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(
|
||||
holder: VH,
|
||||
position: Int,
|
||||
item: NutComboTaskItemDetail?
|
||||
) {
|
||||
holder.binding.apply {
|
||||
tvIngredientName.text = item?.ingredientName
|
||||
|
||||
// 食材类别
|
||||
val classText = when (item?.ingredientClass) {
|
||||
1 -> "主材"
|
||||
2 -> "辅材"
|
||||
3 -> "调料"
|
||||
else -> "未知"
|
||||
}
|
||||
tvIngredientClass.text = classText
|
||||
|
||||
val unit = item?.unit ?: "g"
|
||||
tvPerPortionQty.text = "每份用量:${formatQty(item?.perPortionQty)}${unit}"
|
||||
tvActualQty.text = "实际用量:${formatQty(item?.actualQty)}${unit}"
|
||||
tvTotalQty.text = "合计用量:${formatQty(item?.totalQty)}${unit}"
|
||||
|
||||
tvTraceCode.visible()
|
||||
tvTraceCode.text = "溯源码:${(item?.traceCode ?:"").ifBlank { "-" }}"
|
||||
|
||||
root.setBackgroundResource(
|
||||
if (item?.isClicked == true) R.drawable.shape_item_cook_dish
|
||||
else R.drawable.shape_white_fb_15_corners
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(
|
||||
context: Context,
|
||||
parent: ViewGroup,
|
||||
viewType: Int
|
||||
): VH {
|
||||
val inflater = LayoutInflater.from(context)
|
||||
val binding = ListItemTaskDetailBinding.inflate(inflater, parent, false)
|
||||
return VH(binding)
|
||||
}
|
||||
}
|
||||
@@ -31,6 +31,9 @@ class BaseApp : Application() {
|
||||
GlobalData.appBaseUrl = savedBaseUrl
|
||||
}
|
||||
CrashHandler.init(this)
|
||||
|
||||
GlobalData.deviceId = AppUtil.getUDID(this)
|
||||
|
||||
// val deviceId = if (BuildConfig.IS_TEST_DEVICE) ScaleDeviceConfig.DEVICE_ID_2 else AppUtil.getUDID(this)
|
||||
// Log.d(TAG, "onCreate: deviceId=$deviceId, isTestDevice=${BuildConfig.IS_TEST_DEVICE}")
|
||||
// GlobalData.deviceId = deviceId
|
||||
|
||||
@@ -183,6 +183,61 @@ data class NutSupMealPackageIngredient(
|
||||
val traceCode: String
|
||||
)
|
||||
|
||||
/**
|
||||
* 组配任务VO - 未完成组配任务列表响应
|
||||
*/
|
||||
@Parcelize
|
||||
data class NutComboTaskVO(
|
||||
val id: Long?,
|
||||
val taskNo: String?,
|
||||
val planDate: String?,
|
||||
val canteenId: Long?,
|
||||
val mealType: Int?,
|
||||
val foodId: Long?,
|
||||
val targetDish: String?,
|
||||
val spec: String?,
|
||||
val portions: Int?,
|
||||
var comboStatus: Int?,
|
||||
val ownerName: String?,
|
||||
val createTime: String?
|
||||
) : Parcelable
|
||||
|
||||
/**
|
||||
* 组配任务详情VO - 组配任务详情响应
|
||||
*/
|
||||
@Parcelize
|
||||
data class NutComboTaskDetailVO(
|
||||
val id: Long?,
|
||||
val taskNo: String?,
|
||||
val planDate: String?,
|
||||
val canteenId: Long?,
|
||||
val mealType: Int?,
|
||||
val foodId: Long?,
|
||||
val targetDish: String?,
|
||||
val spec: String?,
|
||||
val portions: Int?,
|
||||
val comboStatus: Int?,
|
||||
val ownerName: String?,
|
||||
val items: List<NutComboTaskItemDetail>?
|
||||
) : Parcelable
|
||||
|
||||
/**
|
||||
* 组配任务食材明细
|
||||
*/
|
||||
@Parcelize
|
||||
data class NutComboTaskItemDetail(
|
||||
val id: Long?,
|
||||
val ingredientCode: String?,
|
||||
val ingredientName: String?,
|
||||
val ingredientClass: Int?,
|
||||
var traceCode: String?,
|
||||
val perPortionQty: String?,
|
||||
val actualQty: String?,
|
||||
val totalQty: String?,
|
||||
val unit: String?,
|
||||
var isClicked: Boolean? = false,
|
||||
) : Parcelable
|
||||
|
||||
/**
|
||||
* ID通用DTO - 用于开始/完成组配等需要id参数的接口
|
||||
*/
|
||||
|
||||
@@ -24,6 +24,7 @@ data class SettingItem(
|
||||
WEIGHT_CONFIG("减重配置"),
|
||||
CLEAN_PACKAGE("净菜包"),
|
||||
MEAL_PACKAGE("餐品净菜包"),
|
||||
GROUP_TASK("组配任务"),
|
||||
MEAL_PACKAGE_TEST("餐品净菜包-测试"),
|
||||
DB_INSPECT("数据库查看"),
|
||||
SCALE_OBSERVE("秤数据监控"),
|
||||
|
||||
@@ -10,6 +10,8 @@ import com.shuwei.dish.match.model.NutSupHygieneIngredientOptionVO
|
||||
import com.shuwei.dish.match.model.NutProdComboVideoVO
|
||||
import com.shuwei.dish.match.model.NutProdComboTaskDTO
|
||||
import com.shuwei.dish.match.model.IdDTO
|
||||
import com.shuwei.dish.match.model.NutComboTaskDetailVO
|
||||
import com.shuwei.dish.match.model.NutComboTaskVO
|
||||
import retrofit2.http.Body
|
||||
import retrofit2.http.GET
|
||||
import retrofit2.http.POST
|
||||
@@ -135,4 +137,27 @@ interface ApiServiceV2 {
|
||||
@Body param: Map<String, @JvmSuppressWildcards Any>
|
||||
): ApiResponse<Unit>
|
||||
|
||||
// ========== 五、组配任务接口 ==========
|
||||
|
||||
/**
|
||||
* 查询未完成组配任务(分页)
|
||||
*/
|
||||
@GET
|
||||
suspend fun getIncompleteComboTasks(
|
||||
@Url url: String = "${GlobalData.appBaseUrl}/nutrition/neglect/combo-task/incomplete",
|
||||
@Query("deviceCode") deviceCode: String? = null,
|
||||
@Query("keyword") keyword: String? = null,
|
||||
@Query("pageNum") pageNum: Int = 1,
|
||||
@Query("pageSize") pageSize: Int = 10
|
||||
): ApiResponse<Page<NutComboTaskVO>>
|
||||
|
||||
/**
|
||||
* 获取组配任务详情
|
||||
*/
|
||||
@GET
|
||||
suspend fun getComboTaskDetail(
|
||||
@Url url: String = "${GlobalData.appBaseUrl}/nutrition/neglect/combo-task/detail",
|
||||
@Query("id") id: Long
|
||||
): ApiResponse<NutComboTaskDetailVO>
|
||||
|
||||
}
|
||||
|
||||
@@ -3,6 +3,8 @@ package com.shuwei.dish.match.net
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.shuwei.dish.match.model.NutCanteenVO
|
||||
import com.shuwei.dish.match.model.NutComboTaskDetailVO
|
||||
import com.shuwei.dish.match.model.NutComboTaskVO
|
||||
import com.shuwei.dish.match.model.NutDictItemVO
|
||||
import com.shuwei.dish.match.model.NutFoodOptionVO
|
||||
import com.shuwei.dish.match.model.NutMaterOptionVO
|
||||
@@ -203,4 +205,37 @@ class NetViewModelV2(
|
||||
}
|
||||
}
|
||||
|
||||
// ========== 组配任务接口 ==========
|
||||
|
||||
/**
|
||||
* 查询未完成组配任务(回调版本)
|
||||
*/
|
||||
fun getIncompleteComboTasksWithCallback(
|
||||
deviceCode: String? = null,
|
||||
keyword: String? = null,
|
||||
pageNum: Int = 1,
|
||||
pageSize: Int = 10,
|
||||
onLoading: () -> Unit = {},
|
||||
onResult: (UiState<Page<NutComboTaskVO>?>) -> Unit
|
||||
) {
|
||||
viewModelScope.launch {
|
||||
onLoading()
|
||||
onResult(repository.getIncompleteComboTasks(deviceCode = deviceCode, keyword = keyword, pageNum = pageNum, pageSize = pageSize))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取组配任务详情(回调版本)
|
||||
*/
|
||||
fun getComboTaskDetailWithCallback(
|
||||
id: Long,
|
||||
onLoading: () -> Unit = {},
|
||||
onResult: (UiState<NutComboTaskDetailVO?>) -> Unit
|
||||
) {
|
||||
viewModelScope.launch {
|
||||
onLoading()
|
||||
onResult(repository.getComboTaskDetail(id))
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,6 +2,8 @@ package com.shuwei.dish.match.net
|
||||
|
||||
import com.shuwei.dish.match.model.IdDTO
|
||||
import com.shuwei.dish.match.model.NutCanteenVO
|
||||
import com.shuwei.dish.match.model.NutComboTaskDetailVO
|
||||
import com.shuwei.dish.match.model.NutComboTaskVO
|
||||
import com.shuwei.dish.match.model.NutDictItemVO
|
||||
import com.shuwei.dish.match.model.NutFoodOptionVO
|
||||
import com.shuwei.dish.match.model.NutMaterOptionVO
|
||||
@@ -87,4 +89,17 @@ class RemoteRepositoryV2 {
|
||||
suspend fun addMealPackage(param: Map<String, Any>): UiState<Unit?> =
|
||||
safeApiCall { apiService.addMealPackage(param = param) }
|
||||
|
||||
// ========== 组配任务接口 ==========
|
||||
|
||||
suspend fun getIncompleteComboTasks(
|
||||
deviceCode: String? = null,
|
||||
keyword: String? = null,
|
||||
pageNum: Int = 1,
|
||||
pageSize: Int = 10
|
||||
): UiState<Page<NutComboTaskVO>?> =
|
||||
safeApiCall { apiService.getIncompleteComboTasks(deviceCode = deviceCode, keyword = keyword, pageNum = pageNum, pageSize = pageSize) }
|
||||
|
||||
suspend fun getComboTaskDetail(id: Long): UiState<NutComboTaskDetailVO?> =
|
||||
safeApiCall { apiService.getComboTaskDetail(id = id) }
|
||||
|
||||
}
|
||||
|
||||
@@ -109,6 +109,8 @@ class PackActivity : BaseActivity() {
|
||||
binding.etInputDish.isFocusableInTouchMode = false
|
||||
binding.ivDishSearch.gone()
|
||||
|
||||
binding.tvGoodsName.text = "食材名称"
|
||||
|
||||
addViewClickListener()
|
||||
addBackKeyListener()
|
||||
initCamera(binding.flCameraContainer)
|
||||
@@ -206,7 +208,7 @@ class PackActivity : BaseActivity() {
|
||||
materialAdapter.notifyItemChanged(clickIndex)
|
||||
}
|
||||
}
|
||||
binding.btnGetCode.clickWithDebounce {
|
||||
binding.btnGetTraceCode.clickWithDebounce {
|
||||
val item = list.getOrNull(clickIndex)?:return@clickWithDebounce
|
||||
//viewModelV2.getCode
|
||||
}
|
||||
@@ -367,12 +369,19 @@ class PackActivity : BaseActivity() {
|
||||
private var clickIndex = -1
|
||||
private val materialAdapter by lazy {
|
||||
FoodMaterialAdapter(list).apply {
|
||||
onItemClick = { positon ->
|
||||
onItemClick = onItemClick@{ positon ->
|
||||
val item = getItem(positon) ?: return@onItemClick
|
||||
this@PackActivity.clickIndex = positon
|
||||
list.forEachIndexed { index, entity ->
|
||||
entity.isClicked = index == positon
|
||||
}
|
||||
notifyDataSetChanged()
|
||||
binding.tvGoodsName.text = item.goodsName
|
||||
binding.tvMaterialType.text = when (item.materialType) {
|
||||
1 -> "主材"
|
||||
2 -> "辅材"
|
||||
else -> "未知"
|
||||
}
|
||||
}
|
||||
addOnItemChildClickListener(R.id.ivClearIcon) { _, _, position ->
|
||||
val item = list.getOrNull(position) ?: return@addOnItemChildClickListener
|
||||
|
||||
@@ -116,6 +116,12 @@ class SettingActivity : BaseActivity() {
|
||||
startActivity<MealListActivity> { }
|
||||
}
|
||||
),
|
||||
SettingItem(
|
||||
type = SettingItem.Type.GROUP_TASK,
|
||||
onClick = {
|
||||
startActivity<TaskActivity> { }
|
||||
}
|
||||
),
|
||||
SettingItem(
|
||||
type = SettingItem.Type.MEAL_PACKAGE_TEST,
|
||||
onClick = {
|
||||
|
||||
@@ -0,0 +1,207 @@
|
||||
package com.shuwei.dish.match.ui
|
||||
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import com.shuwei.dish.match.adapter.TaskAdapter
|
||||
import com.shuwei.dish.match.base.BaseActivity
|
||||
import com.shuwei.dish.match.base.GlobalData
|
||||
import com.shuwei.dish.match.databinding.ActivityTaskBinding
|
||||
import com.shuwei.dish.match.model.NutComboTaskVO
|
||||
import com.shuwei.dish.match.net.NetViewModelV2
|
||||
import com.shuwei.dish.match.net.UiState
|
||||
import com.shuwei.dish.match.utils.ext.addOnActionSearchListener
|
||||
import com.shuwei.dish.match.utils.ext.clickWithDebounce
|
||||
import com.shuwei.dish.match.utils.ext.gone
|
||||
import com.shuwei.dish.match.utils.ext.startActivity
|
||||
import com.shuwei.dish.match.utils.ext.toast
|
||||
import com.shuwei.dish.match.utils.ext.visible
|
||||
|
||||
/**
|
||||
* 组配任务列表页面
|
||||
*/
|
||||
class TaskActivity : BaseActivity() {
|
||||
|
||||
companion object {
|
||||
const val TAG = "TaskActivity"
|
||||
const val TASK_ITEM = "taskItem"
|
||||
}
|
||||
|
||||
private val binding by lazy { ActivityTaskBinding.inflate(layoutInflater) }
|
||||
private val viewModelV2 by lazy { NetViewModelV2() }
|
||||
|
||||
private val taskList = mutableListOf<NutComboTaskVO>()
|
||||
private val taskAdapter by lazy {
|
||||
TaskAdapter(taskList).apply {
|
||||
setOnItemClickListener { adapter, view, position ->
|
||||
startActivity<TaskDetailActivity> {
|
||||
putExtra(TaskDetailActivity.TASK_ITEM, taskList[position])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private var currentPage = 1
|
||||
private var keyword: String? = null
|
||||
private var isLoading = false
|
||||
private var hasMore = true
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(binding.root)
|
||||
setHeaderBackground()
|
||||
setTitleBar(titleBarAction = {
|
||||
it.visible()
|
||||
}, titleAction = {
|
||||
it.text = "组配任务"
|
||||
}, rightIconAction = {
|
||||
it.gone()
|
||||
}, backAction = {
|
||||
it.setOnClickListener {
|
||||
finish()
|
||||
}
|
||||
})
|
||||
|
||||
initRecyclerView()
|
||||
initRefreshLayout()
|
||||
initSearchListener()
|
||||
loadTaskList()
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化 RecyclerView
|
||||
*/
|
||||
private fun initRecyclerView() {
|
||||
binding.rvTaskList.layoutManager = LinearLayoutManager(this)
|
||||
binding.rvTaskList.adapter = taskAdapter
|
||||
taskAdapter.setOnItemClickListener { _, _, position ->
|
||||
val item = taskList.getOrNull(position) ?: return@setOnItemClickListener
|
||||
val intent = Intent(this, TaskDetailActivity::class.java).apply {
|
||||
putExtra(TASK_ITEM, item)
|
||||
}
|
||||
startActivity(intent)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化 SmartRefreshLayout 下拉刷新和上拉加载
|
||||
*/
|
||||
private fun initRefreshLayout() {
|
||||
binding.refreshLayout.apply {
|
||||
// 下拉刷新
|
||||
setOnRefreshListener {
|
||||
currentPage = 1
|
||||
hasMore = true
|
||||
loadTaskList()
|
||||
}
|
||||
// 上拉加载
|
||||
setOnLoadMoreListener { refreshLayout ->
|
||||
if (isLoading || !hasMore) {
|
||||
refreshLayout.finishLoadMoreWithNoMoreData()
|
||||
return@setOnLoadMoreListener
|
||||
}
|
||||
currentPage++
|
||||
loadTaskList()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 搜索栏交互
|
||||
*/
|
||||
private fun initSearchListener() {
|
||||
binding.ivSearch.clickWithDebounce {
|
||||
performSearch()
|
||||
}
|
||||
binding.etInputKeyword.addOnActionSearchListener {
|
||||
performSearch()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行搜索
|
||||
*/
|
||||
private fun performSearch() {
|
||||
keyword = binding.etInputKeyword.text.toString().trim()
|
||||
if (keyword.isNullOrBlank()) {
|
||||
toast("请输入搜索关键字")
|
||||
return
|
||||
}
|
||||
currentPage = 1
|
||||
hasMore = true
|
||||
taskList.clear()
|
||||
taskAdapter.notifyDataSetChanged()
|
||||
binding.rvTaskList.visible()
|
||||
binding.tvEmpty.gone()
|
||||
loadTaskList()
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载组配任务列表
|
||||
*/
|
||||
private fun loadTaskList() {
|
||||
isLoading = true
|
||||
viewModelV2.getIncompleteComboTasksWithCallback(
|
||||
deviceCode = GlobalData.deviceId,
|
||||
keyword = keyword,
|
||||
pageNum = currentPage,
|
||||
pageSize = 10,
|
||||
onLoading = {
|
||||
if (currentPage == 1) {
|
||||
showLoading("加载中……")
|
||||
}
|
||||
},
|
||||
onResult = onResult@{ state ->
|
||||
dismissLoading()
|
||||
isLoading = false
|
||||
when (state) {
|
||||
is UiState.Success -> {
|
||||
val records = state.data?.records
|
||||
if (currentPage == 1 && records.isNullOrEmpty()) {
|
||||
binding.rvTaskList.gone()
|
||||
binding.tvEmpty.visible()
|
||||
binding.refreshLayout.finishRefresh()
|
||||
binding.refreshLayout.finishLoadMoreWithNoMoreData()
|
||||
return@onResult
|
||||
}
|
||||
if (!records.isNullOrEmpty()) {
|
||||
binding.rvTaskList.visible()
|
||||
binding.tvEmpty.gone()
|
||||
if (currentPage == 1) {
|
||||
taskList.clear()
|
||||
}
|
||||
taskList.addAll(records)
|
||||
taskAdapter.notifyDataSetChanged()
|
||||
|
||||
// 判断是否还有更多数据
|
||||
if (records.size < 10) {
|
||||
hasMore = false
|
||||
binding.refreshLayout.finishLoadMoreWithNoMoreData()
|
||||
}
|
||||
} else {
|
||||
hasMore = false
|
||||
binding.refreshLayout.finishLoadMoreWithNoMoreData()
|
||||
}
|
||||
binding.refreshLayout.finishRefresh()
|
||||
binding.refreshLayout.finishLoadMore()
|
||||
}
|
||||
|
||||
is UiState.Error -> {
|
||||
toast(state.msg)
|
||||
if (currentPage > 1) {
|
||||
currentPage--
|
||||
}
|
||||
if (currentPage == 1 && taskList.isEmpty()) {
|
||||
binding.rvTaskList.gone()
|
||||
binding.tvEmpty.visible()
|
||||
}
|
||||
binding.refreshLayout.finishRefresh()
|
||||
binding.refreshLayout.finishLoadMore(false)
|
||||
}
|
||||
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,192 @@
|
||||
package com.shuwei.dish.match.ui
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.core.content.IntentCompat
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import com.shuwei.dish.match.adapter.TaskDetailAdapter
|
||||
import com.shuwei.dish.match.base.BaseActivity
|
||||
import com.shuwei.dish.match.databinding.ActivityTaskDetailBinding
|
||||
import com.shuwei.dish.match.model.NutComboTaskDetailVO
|
||||
import com.shuwei.dish.match.model.NutComboTaskVO
|
||||
import com.shuwei.dish.match.net.NetViewModelV2
|
||||
import com.shuwei.dish.match.net.UiState
|
||||
import com.shuwei.dish.match.utils.ext.clickWithDebounce
|
||||
import com.shuwei.dish.match.utils.ext.gone
|
||||
import com.shuwei.dish.match.utils.ext.toast
|
||||
import com.shuwei.dish.match.utils.ext.visible
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
/**
|
||||
* 组配任务详情页面
|
||||
*/
|
||||
class TaskDetailActivity : BaseActivity() {
|
||||
|
||||
companion object {
|
||||
const val TAG = "TaskDetailActivity"
|
||||
const val TASK_ITEM = "taskItem"
|
||||
}
|
||||
|
||||
private val binding by lazy { ActivityTaskDetailBinding.inflate(layoutInflater) }
|
||||
private val viewModelV2 by lazy { NetViewModelV2() }
|
||||
|
||||
private var taskItem: NutComboTaskVO? = null
|
||||
private val itemList = mutableListOf<com.shuwei.dish.match.model.NutComboTaskItemDetail>()
|
||||
private val itemAdapter by lazy {
|
||||
TaskDetailAdapter(itemList).apply {
|
||||
setOnItemClickListener { adapter, view, position ->
|
||||
getItem(position) ?: return@setOnItemClickListener
|
||||
itemList.forEachIndexed { index, detail ->
|
||||
detail.isClicked = index == position
|
||||
}
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(binding.root)
|
||||
setHeaderBackground()
|
||||
|
||||
taskItem = IntentCompat.getParcelableExtra(intent, TASK_ITEM, NutComboTaskVO::class.java)
|
||||
|
||||
setTitleBar(titleBarAction = {
|
||||
it.visible()
|
||||
}, titleAction = {
|
||||
it.text = "任务详情"
|
||||
}, rightIconAction = {
|
||||
it.gone()
|
||||
}, backAction = {
|
||||
it.setOnClickListener {
|
||||
finish()
|
||||
}
|
||||
})
|
||||
|
||||
initRecyclerView()
|
||||
initView()
|
||||
loadDetail()
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化任务概要信息
|
||||
*/
|
||||
private fun initView() {
|
||||
taskItem?.let {
|
||||
binding.tvTaskNo.text = "任务编号:${it.taskNo}"
|
||||
binding.tvTargetDish.text = it.targetDish
|
||||
binding.tvSpec.text = it.spec
|
||||
binding.tvPlanDate.text = "计划日期:${it.planDate}"
|
||||
binding.tvPortions.text = "总份数:${it.portions}"
|
||||
binding.tvOwnerName.text = "负责人:${it.ownerName}"
|
||||
binding.tvStatus.text = getStatusText(it.comboStatus)
|
||||
|
||||
// 仅待组配状态显示"开始组配"按钮
|
||||
if (it.comboStatus == 0) {
|
||||
binding.btnStart.visible()
|
||||
binding.btnStart.clickWithDebounce {
|
||||
startComboTask(it.id ?: return@clickWithDebounce)
|
||||
}
|
||||
} else {
|
||||
binding.btnStart.gone()
|
||||
}
|
||||
}
|
||||
binding.btnGetTraceCode.clickWithDebounce {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化 RecyclerView
|
||||
*/
|
||||
private fun initRecyclerView() {
|
||||
binding.rvItemList.layoutManager = LinearLayoutManager(this)
|
||||
binding.rvItemList.adapter = itemAdapter
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载任务详情(食材清单)
|
||||
*/
|
||||
private fun loadDetail() {
|
||||
val taskId = taskItem?.id ?: return
|
||||
viewModelV2.getComboTaskDetailWithCallback(
|
||||
id = taskId,
|
||||
onLoading = {
|
||||
showLoading("加载中……")
|
||||
},
|
||||
onResult = onResult@{ state ->
|
||||
dismissLoading()
|
||||
when (state) {
|
||||
is UiState.Success -> {
|
||||
val detail = state.data
|
||||
if (detail == null) {
|
||||
toast("详情为空")
|
||||
return@onResult
|
||||
}
|
||||
// 更新状态(可能已被其他设备修改)
|
||||
binding.tvStatus.text = getStatusText(detail.comboStatus)
|
||||
if (detail.comboStatus != 0) {
|
||||
binding.btnStart.gone()
|
||||
}
|
||||
|
||||
// 加载食材列表
|
||||
val items = detail.items
|
||||
if (!items.isNullOrEmpty()) {
|
||||
itemList.clear()
|
||||
itemList.addAll(items)
|
||||
itemAdapter.notifyDataSetChanged()
|
||||
} else {
|
||||
toast("该任务无食材信息")
|
||||
}
|
||||
}
|
||||
|
||||
is UiState.Error -> toast(state.msg)
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* 开始组配
|
||||
*/
|
||||
private fun startComboTask(taskId: Long) {
|
||||
showLoading("正在开始组配……")
|
||||
lifecycleScope.launch {
|
||||
viewModelV2.startComboTask(taskId)
|
||||
}
|
||||
lifecycleScope.launch {
|
||||
viewModelV2.startComboTaskState.collect { state ->
|
||||
when (state) {
|
||||
is UiState.Success -> {
|
||||
dismissLoading()
|
||||
toast("已开始组配")
|
||||
// 刷新详情
|
||||
loadDetail()
|
||||
// 更新本地状态
|
||||
taskItem?.comboStatus = 1
|
||||
}
|
||||
|
||||
is UiState.Error -> {
|
||||
dismissLoading()
|
||||
toast(state.msg)
|
||||
}
|
||||
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 状态文本映射
|
||||
*/
|
||||
private fun getStatusText(status: Int?): String {
|
||||
return when (status) {
|
||||
0 -> "待组配"
|
||||
1 -> "组配中"
|
||||
2 -> "已完成"
|
||||
else -> "未知"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -70,31 +70,22 @@
|
||||
android:layout_marginStart="30dp"
|
||||
android:textColor="@color/black"
|
||||
android:textSize="30sp"
|
||||
android:maxLines="1"
|
||||
android:ellipsize="end"
|
||||
android:maxLength="12"
|
||||
android:textStyle="bold"
|
||||
tools:text="豆腐" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvMaterialType"
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="30dp"
|
||||
android:layout_marginEnd="30dp"
|
||||
android:textColor="@color/black999"
|
||||
android:textSize="26sp"
|
||||
tools:text="主材" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/btnGetCode"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="50dp"
|
||||
android:layout_marginEnd="30dp"
|
||||
android:paddingHorizontal="20dp"
|
||||
android:text="获取溯源码"
|
||||
android:textSize="18sp"
|
||||
android:gravity="center"
|
||||
android:textColor="@color/dish_green"
|
||||
android:background="@drawable/ripple_effect_light"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<com.google.android.material.divider.MaterialDivider
|
||||
@@ -196,6 +187,20 @@
|
||||
android:textSize="28sp" />
|
||||
-->
|
||||
|
||||
<TextView
|
||||
android:id="@+id/btnGetTraceCode"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="50dp"
|
||||
android:layout_marginEnd="30dp"
|
||||
android:paddingHorizontal="20dp"
|
||||
android:layout_gravity="end|center_vertical"
|
||||
android:text="获取溯源码"
|
||||
android:textSize="18sp"
|
||||
android:gravity="center"
|
||||
android:textColor="@color/dish_green"
|
||||
android:background="@drawable/ripple_effect_light"/>
|
||||
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/flCameraContainer"
|
||||
android:layout_width="1dp"
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout 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"
|
||||
android:orientation="vertical"
|
||||
tools:background="@drawable/bg_other_page">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/llSearchBar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="100dp"
|
||||
android:layout_margin="30dp"
|
||||
android:background="@drawable/shape_white_30_corners"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<EditText
|
||||
android:id="@+id/etInputKeyword"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="80dp"
|
||||
android:layout_marginHorizontal="28dp"
|
||||
android:layout_weight="1"
|
||||
android:autofillHints=""
|
||||
android:background="@color/white"
|
||||
android:gravity="center"
|
||||
android:hint="请输入菜品名称"
|
||||
android:inputType="text"
|
||||
android:imeOptions="actionSearch"
|
||||
android:paddingStart="3dp"
|
||||
android:paddingEnd="3dp"
|
||||
android:maxLines="1"
|
||||
android:ellipsize="end"
|
||||
android:textColor="@color/black333"
|
||||
android:textColorHint="@color/gray_c8"
|
||||
android:textSize="40sp"
|
||||
tools:ignore="TextFields" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/ivSearch"
|
||||
android:layout_width="60dp"
|
||||
android:layout_height="60dp"
|
||||
android:layout_marginStart="20dp"
|
||||
android:layout_marginEnd="20dp"
|
||||
android:paddingStart="10dp"
|
||||
android:paddingEnd="10dp"
|
||||
android:src="@drawable/ic_search_gray"
|
||||
tools:ignore="ContentDescription" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_marginHorizontal="30dp"
|
||||
android:layout_weight="1"
|
||||
android:background="@drawable/shape_white_30_corners"
|
||||
android:orientation="vertical">
|
||||
|
||||
<com.scwang.smart.refresh.layout.SmartRefreshLayout
|
||||
android:id="@+id/refreshLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<com.scwang.smart.refresh.header.ClassicsHeader
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/rvTaskList"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginBottom="20dp"
|
||||
android:overScrollMode="never"
|
||||
android:scrollbars="vertical"
|
||||
tools:itemCount="3"
|
||||
tools:listitem="@layout/list_item_task" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvEmpty"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:text="暂无数据"
|
||||
android:textColor="@color/black999"
|
||||
android:textSize="26sp"
|
||||
android:visibility="gone" />
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
<com.scwang.smart.refresh.footer.ClassicsFooter
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
</com.scwang.smart.refresh.layout.SmartRefreshLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,163 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout 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"
|
||||
android:orientation="vertical"
|
||||
tools:background="@drawable/bg_other_page">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/llTaskInfo"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="30dp"
|
||||
android:background="@drawable/shape_white_30_corners"
|
||||
android:orientation="vertical"
|
||||
android:padding="20dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvTaskNo"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="@color/black999"
|
||||
android:textSize="20sp"
|
||||
tools:text="任务编号:RW20260601001" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvTargetDish"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="10dp"
|
||||
android:textColor="@color/black"
|
||||
android:textSize="32sp"
|
||||
android:textStyle="bold"
|
||||
tools:text="红烧肉" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="10dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvSpec"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="@color/black666"
|
||||
android:textSize="24sp"
|
||||
tools:text="中组(8份)·50组" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvStatus"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:gravity="end"
|
||||
android:textColor="@color/dish_green"
|
||||
android:textSize="24sp"
|
||||
tools:text="待组配" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="10dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvPlanDate"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="@color/black999"
|
||||
android:textSize="20sp"
|
||||
tools:text="计划日期:2026-06-01" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvPortions"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="20dp"
|
||||
android:textColor="@color/black999"
|
||||
android:textSize="20sp"
|
||||
tools:text="总份数:400" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvOwnerName"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="20dp"
|
||||
android:textColor="@color/black999"
|
||||
android:textSize="20sp"
|
||||
tools:text="负责人:张三" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_marginHorizontal="30dp"
|
||||
android:layout_weight="1"
|
||||
android:background="@drawable/shape_white_30_corners"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="100dp"
|
||||
android:gravity="center_vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="20dp"
|
||||
android:layout_weight="1"
|
||||
android:padding="10dp"
|
||||
android:text="食材明细"
|
||||
android:textColor="@color/black666"
|
||||
android:textSize="28sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/btnGetTraceCode"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="50dp"
|
||||
android:layout_marginEnd="30dp"
|
||||
android:background="@drawable/ripple_effect_light"
|
||||
android:gravity="center"
|
||||
android:paddingHorizontal="20dp"
|
||||
android:text="获取溯源码"
|
||||
android:textColor="@color/dish_green"
|
||||
android:textSize="18sp" />
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/rvItemList"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginBottom="20dp"
|
||||
android:overScrollMode="never"
|
||||
android:scrollbars="vertical"
|
||||
tools:itemCount="3"
|
||||
tools:listitem="@layout/list_item_task_detail" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/btnStart"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="90dp"
|
||||
android:layout_margin="30dp"
|
||||
android:background="@drawable/shape_green_bg"
|
||||
android:foreground="?android:attr/selectableItemBackground"
|
||||
android:gravity="center"
|
||||
android:text="开始组配"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="32sp"
|
||||
android:textStyle="bold"
|
||||
android:visibility="gone" />
|
||||
|
||||
</LinearLayout>
|
||||
@@ -4,7 +4,7 @@
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/clBlock"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="120dp"
|
||||
android:layout_height="140dp"
|
||||
android:layout_marginStart="30dp"
|
||||
android:layout_marginEnd="30dp"
|
||||
android:layout_marginBottom="15dp"
|
||||
@@ -21,41 +21,41 @@
|
||||
android:textColor="@color/black"
|
||||
android:textSize="30sp"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintBottom_toTopOf="@+id/tvGoodsCode"
|
||||
app:layout_constraintBottom_toTopOf="@+id/tvDishType"
|
||||
app:layout_constraintEnd_toStartOf="@+id/tvDishWeight"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintVertical_chainStyle="packed"
|
||||
tools:text="雪菜" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvGoodsCode"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:layout_marginVertical="3dp"
|
||||
android:textColor="@color/black999"
|
||||
android:textSize="20sp"
|
||||
app:layout_constraintBottom_toTopOf="@+id/tvDishType"
|
||||
app:layout_constraintEnd_toEndOf="@id/tvDishName"
|
||||
app:layout_constraintStart_toStartOf="@id/tvDishName"
|
||||
app:layout_constraintTop_toBottomOf="@id/tvDishName"
|
||||
android:text="溯源码:-" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvDishType"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:layout_marginVertical="5dp"
|
||||
android:textColor="@color/black999"
|
||||
android:textSize="23sp"
|
||||
android:textSize="22sp"
|
||||
app:layout_constraintBottom_toTopOf="@id/tvGoodsCode"
|
||||
app:layout_constraintEnd_toEndOf="@id/tvDishName"
|
||||
app:layout_constraintStart_toStartOf="@id/tvDishName"
|
||||
app:layout_constraintTop_toBottomOf="@id/tvDishName"
|
||||
tools:text="主辅材:主材" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvGoodsCode"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:textColor="@color/black999"
|
||||
android:textSize="18sp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="@id/tvDishName"
|
||||
app:layout_constraintStart_toStartOf="@id/tvDishName"
|
||||
app:layout_constraintTop_toBottomOf="@id/tvGoodsCode"
|
||||
tools:text="主辅材:主材" />
|
||||
app:layout_constraintTop_toBottomOf="@id/tvDishType"
|
||||
android:text="溯源码:-" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/ivOperateIcon"
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
<?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="160dp"
|
||||
android:layout_margin="15dp"
|
||||
android:background="@drawable/shape_white_12_corners"
|
||||
android:paddingHorizontal="20dp"
|
||||
android:paddingVertical="15dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvTaskNo"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="@color/black999"
|
||||
android:textSize="18sp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:text="任务编号:RW20260601001" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvTargetDish"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="@color/black"
|
||||
android:textSize="28sp"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintBottom_toTopOf="@id/tvPlanDate"
|
||||
app:layout_constraintStart_toStartOf="@id/tvTaskNo"
|
||||
app:layout_constraintTop_toBottomOf="@id/tvTaskNo"
|
||||
tools:text="红烧肉" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvSpec"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="15dp"
|
||||
android:textColor="@color/black666"
|
||||
android:textSize="22sp"
|
||||
app:layout_constraintBottom_toBottomOf="@id/tvTargetDish"
|
||||
app:layout_constraintStart_toEndOf="@id/tvTargetDish"
|
||||
app:layout_constraintTop_toTopOf="@id/tvTargetDish"
|
||||
tools:text="中组(8份)·50组" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvPlanDate"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="@color/black999"
|
||||
android:textSize="20sp"
|
||||
app:layout_constraintBottom_toTopOf="@id/tvPortions"
|
||||
app:layout_constraintStart_toStartOf="@id/tvTargetDish"
|
||||
app:layout_constraintTop_toBottomOf="@id/tvTargetDish"
|
||||
tools:text="计划日期:2026-06-01" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvPortions"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="@color/black999"
|
||||
android:textSize="20sp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="@id/tvTargetDish"
|
||||
app:layout_constraintTop_toBottomOf="@id/tvPlanDate"
|
||||
tools:text="总份数:400" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvOwnerName"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="10dp"
|
||||
android:textColor="@color/black999"
|
||||
android:textSize="20sp"
|
||||
app:layout_constraintBottom_toBottomOf="@id/tvPortions"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@id/tvPortions"
|
||||
tools:text="负责人:张三" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvStatus"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="10dp"
|
||||
android:textColor="@color/dish_green"
|
||||
android:textSize="22sp"
|
||||
app:layout_constraintBottom_toBottomOf="@id/tvTargetDish"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@id/tvTargetDish"
|
||||
tools:text="待组配" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -0,0 +1,80 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="15dp"
|
||||
android:layout_marginBottom="15dp"
|
||||
android:background="@drawable/shape_white_fb_15_corners"
|
||||
android:orientation="vertical"
|
||||
android:padding="15dp">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvIngredientName"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="@color/black"
|
||||
android:textSize="26sp"
|
||||
android:textStyle="bold"
|
||||
tools:text="五花肉" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvIngredientClass"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="20dp"
|
||||
android:textColor="@color/black999"
|
||||
android:textSize="20sp"
|
||||
tools:text="主材" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvPerPortionQty"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="@color/black666"
|
||||
android:textSize="20sp"
|
||||
tools:text="每份用量:200g" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvActualQty"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="20dp"
|
||||
android:textColor="@color/black666"
|
||||
android:textSize="20sp"
|
||||
tools:text="实际用量:200g" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvTotalQty"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="20dp"
|
||||
android:textColor="@color/black666"
|
||||
android:textSize="20sp"
|
||||
tools:text="合计用量:80000g" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvTraceCode"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="5dp"
|
||||
android:textColor="@color/black999"
|
||||
android:textSize="18sp"
|
||||
android:visibility="gone"
|
||||
tools:text="溯源码:TRACE-20260601001"
|
||||
tools:visibility="visible" />
|
||||
|
||||
</LinearLayout>
|
||||
Reference in New Issue
Block a user