From 8f15c0efb7b0cb9b9d2cef92c52a20debdda3612 Mon Sep 17 00:00:00 2001 From: lvmeng <848755140@qq.com> Date: Mon, 11 May 2026 11:10:45 +0800 Subject: [PATCH] =?UTF-8?q?refactor(network):=20=E8=8F=9C=E5=93=81?= =?UTF-8?q?=E8=AF=A6=E6=83=85=E6=8E=A5=E5=8F=A3=E6=94=B9=E7=94=A8=20DTO=20?= =?UTF-8?q?=E4=B8=8E=20Room=20=E5=AE=9E=E4=BD=93=E8=A7=A3=E8=80=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../shuwei/dish/match/entity/CookFoodDTO.kt | 41 ++++++ .../dish/match/entity/CookFoodGoodsDTO.kt | 117 ++++++++++++++++++ .../com/shuwei/dish/match/net/ApiService.kt | 6 +- .../com/shuwei/dish/match/net/NetViewModel.kt | 13 +- .../shuwei/dish/match/net/RemoteRepository.kt | 6 +- .../dish/match/ui/PrepareFoodActivity.kt | 4 +- .../dish/match/ui/SubmitFoodActivity.kt | 4 +- 7 files changed, 176 insertions(+), 15 deletions(-) create mode 100644 app/src/main/java/com/shuwei/dish/match/entity/CookFoodDTO.kt create mode 100644 app/src/main/java/com/shuwei/dish/match/entity/CookFoodGoodsDTO.kt diff --git a/app/src/main/java/com/shuwei/dish/match/entity/CookFoodDTO.kt b/app/src/main/java/com/shuwei/dish/match/entity/CookFoodDTO.kt new file mode 100644 index 0000000..dd889f3 --- /dev/null +++ b/app/src/main/java/com/shuwei/dish/match/entity/CookFoodDTO.kt @@ -0,0 +1,41 @@ +package com.shuwei.dish.match.entity + +import java.io.Serializable + +/** + * 菜品详情接口传输对象(DTO),不依赖 Room + * 对应接口:getConstituteByFoodId / saveConstitute + */ +data class CookFoodDTO( + var foodId: String = "", + var foodName: String? = null, + var canteenId: String? = null, + var foodWeight: Double = 0.0, + // 0-制作模式,1-采样模式,2-品控模式 + var cookMode: Int = 0, + var dinnerType: String? = "0", + // 接口返回的食材构成列表 + var matchingConstituteInfoList: MutableList? = null, + var foodConstituteList: MutableList? = null +) : Serializable { + + /** + * 转换为 Room 实体,用于写入本地数据库 + * id/isDel/createTime 由 Room 自行管理,不从 DTO 携带 + */ + fun toEntity(): CookFoodEntity = CookFoodEntity( + foodId = foodId, + foodName = foodName, + canteenId = canteenId, + foodWeight = foodWeight, + cookMode = cookMode, + dinnerType = dinnerType + ).also { entity -> + entity.matchingConstituteInfoList = matchingConstituteInfoList + ?.map { it.toEntity() } + ?.toMutableList() + entity.foodConstituteList = foodConstituteList + ?.map { it.toEntity() } + ?.toMutableList() + } +} diff --git a/app/src/main/java/com/shuwei/dish/match/entity/CookFoodGoodsDTO.kt b/app/src/main/java/com/shuwei/dish/match/entity/CookFoodGoodsDTO.kt new file mode 100644 index 0000000..58cc988 --- /dev/null +++ b/app/src/main/java/com/shuwei/dish/match/entity/CookFoodGoodsDTO.kt @@ -0,0 +1,117 @@ +package com.shuwei.dish.match.entity + +import java.io.Serializable + +/** + * 菜品构成(主辅料/调料)接口传输对象(DTO),不依赖 Room + * 对应 CookFoodDTO 中 foodConstituteList、matchingConstituteInfoList 的元素 + */ +data class CookFoodGoodsDTO( + var goodsId: String = "", + var goodsName: String? = null, + var foodId: String? = "", + var goodsOrRelationCode: String? = "", + // 调料数据顺序 + var sort: Int = 0, + // 食材原材料:1,预制品:2 + var relateionType: Int = 0, + // 物品类型:1主料 2辅料 3调料 + var materialType: Int = 0, + // 物品 是否全部可食:true-全部可食,false-部分可食 + var allEdible: Boolean = true, + // 物品 用料重量 + var useWeight: Double? = 0.0, + var popularName: String? = "", + var canteenId: String? = "", + var relateionType_dictText: String? = "", + var zjmCode: String? = "", + var materId: String? = "", + // 物料编码 + var goodsCode: String? = "", + // 净材种类 + var rawMaterialsType: String? = null +) : Serializable { + + /** + * 转换为 GoodsItem,用于 UI 层 + */ + fun toGoodsItem(): GoodsItem = GoodsItem( + goodsId = goodsId, + goodsName = goodsName, + popularName = popularName, + zjmCode = zjmCode, + materId = materId, + materCode = goodsCode, + materialType = materialType, + useWeight = useWeight, + relateionType = relateionType, + allEdible = allEdible, + goodsOrRelationCode = goodsOrRelationCode, + rawMaterialsType = rawMaterialsType + ) + + /** + * 转换为 Room 实体,用于写入本地数据库 + * id/pid/isDel/createTime 由 Room 自行管理,不从 DTO 携带 + */ + fun toEntity(): CookFoodGoodsEntity = CookFoodGoodsEntity( + goodsId = goodsId, + goodsName = goodsName, + foodId = foodId, + goodsOrRelationCode = goodsOrRelationCode, + sort = sort, + relateionType = relateionType, + materialType = materialType, + allEdible = allEdible, + useWeight = useWeight, + popularName = popularName, + canteenId = canteenId, + relateionType_dictText = relateionType_dictText, + zjmCode = zjmCode, + materId = materId, + goodsCode = goodsCode, + rawMaterialsType = rawMaterialsType + ) +} + +/** + * Room 实体 → DTO 反向映射,用于将本地数据转为接口提交格式 + * id/pid/isDel/createTime 为本地数据库字段,不参与提交 + */ +fun CookFoodGoodsEntity.toDTO(): CookFoodGoodsDTO = CookFoodGoodsDTO( + goodsId = goodsId, + goodsName = goodsName, + foodId = foodId, + goodsOrRelationCode = goodsOrRelationCode, + sort = sort, + relateionType = relateionType, + materialType = materialType, + allEdible = allEdible, + useWeight = useWeight, + popularName = popularName, + canteenId = canteenId, + relateionType_dictText = relateionType_dictText, + zjmCode = zjmCode, + materId = materId, + goodsCode = goodsCode, + rawMaterialsType = rawMaterialsType +) + +/** + * Room 实体 → DTO 反向映射,用于将本地数据转为接口提交格式 + * id/isDel/createTime 为本地数据库字段,不参与提交 + */ +fun CookFoodEntity.toDTO(): CookFoodDTO = CookFoodDTO( + foodId = foodId, + foodName = foodName, + canteenId = canteenId, + foodWeight = foodWeight, + cookMode = cookMode, + dinnerType = dinnerType, + matchingConstituteInfoList = matchingConstituteInfoList + ?.map { it.toDTO() } + ?.toMutableList(), + foodConstituteList = foodConstituteList + ?.map { it.toDTO() } + ?.toMutableList() +) diff --git a/app/src/main/java/com/shuwei/dish/match/net/ApiService.kt b/app/src/main/java/com/shuwei/dish/match/net/ApiService.kt index e9a023f..d25ae7a 100644 --- a/app/src/main/java/com/shuwei/dish/match/net/ApiService.kt +++ b/app/src/main/java/com/shuwei/dish/match/net/ApiService.kt @@ -1,7 +1,7 @@ package com.shuwei.dish.match.net import com.shuwei.dish.match.base.GlobalData -import com.shuwei.dish.match.entity.CookFoodEntity +import com.shuwei.dish.match.entity.CookFoodDTO import com.shuwei.dish.match.entity.FoodRecord import com.shuwei.dish.match.entity.GoodsItem import okhttp3.MultipartBody @@ -24,7 +24,7 @@ interface ApiService { suspend fun getFoodDetail( @Url url: String = "${GlobalData.appBaseUrl}/terminal/neglect/matching/app/getConstituteByFoodId", @Query("foodId") foodId: String - ): ApiResponse + ): ApiResponse /** @@ -33,7 +33,7 @@ interface ApiService { @POST suspend fun submitCookFood( @Url url: String = "${GlobalData.appBaseUrl}/terminal/neglect/matching/app/saveConstitute", - @Body param: CookFoodEntity + @Body param: CookFoodDTO ): ApiResponse /** diff --git a/app/src/main/java/com/shuwei/dish/match/net/NetViewModel.kt b/app/src/main/java/com/shuwei/dish/match/net/NetViewModel.kt index 5bcaa6c..059dabf 100644 --- a/app/src/main/java/com/shuwei/dish/match/net/NetViewModel.kt +++ b/app/src/main/java/com/shuwei/dish/match/net/NetViewModel.kt @@ -3,9 +3,10 @@ package com.shuwei.dish.match.net import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.shuwei.dish.match.base.BaseApp -import com.shuwei.dish.match.entity.CookFoodEntity +import com.shuwei.dish.match.entity.CookFoodDTO import com.shuwei.dish.match.entity.FoodRecord import com.shuwei.dish.match.entity.GoodsItem +import com.shuwei.dish.match.entity.GoodsNameQueryDTO import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow @@ -33,7 +34,7 @@ class NetViewModel( /** * 提交制作菜品 */ - fun submitCookFood(entity: CookFoodEntity) { + fun submitCookFood(entity: CookFoodDTO) { viewModelScope.launch { _submitCookFoodState.value = UiState.Loading _submitCookFoodState.value = repository.submitCookFood(entity) @@ -43,8 +44,8 @@ class NetViewModel( /** * 查询菜品详情的 UI 状态流,UI 层通过 collect 监听 */ - private val _foodDetailState = MutableStateFlow>(UiState.Idle) - val foodDetailState: StateFlow> = _foodDetailState.asStateFlow() + private val _foodDetailState = MutableStateFlow>(UiState.Idle) + val foodDetailState: StateFlow> = _foodDetailState.asStateFlow() /** * 查询菜品详情 @@ -108,7 +109,7 @@ class NetViewModel( * @param pageNum 页码,默认第 1 页 * @param pageSize 每页条数,默认 50 * @param goodsName 按名称模糊搜索,为 null 时不传该字段 - * @param goodsNames 按名称列表批量查询,为 null 时不传该字段 + * @param goodsNames 按名称+净材种类列表批量查询,为 null 时不传该字段 */ fun queryGoodsList( goodsType: String, @@ -116,7 +117,7 @@ class NetViewModel( pageNum: Int = 1, pageSize: Int = 50, goodsName: String? = null, - goodsNames: List? = null + goodsNames: List? = null ) { val param = mutableMapOf( "goodsType" to goodsType, diff --git a/app/src/main/java/com/shuwei/dish/match/net/RemoteRepository.kt b/app/src/main/java/com/shuwei/dish/match/net/RemoteRepository.kt index 4f5712c..44f41b4 100644 --- a/app/src/main/java/com/shuwei/dish/match/net/RemoteRepository.kt +++ b/app/src/main/java/com/shuwei/dish/match/net/RemoteRepository.kt @@ -1,6 +1,6 @@ package com.shuwei.dish.match.net -import com.shuwei.dish.match.entity.CookFoodEntity +import com.shuwei.dish.match.entity.CookFoodDTO import com.shuwei.dish.match.entity.FoodRecord import com.shuwei.dish.match.entity.GoodsItem import okhttp3.MultipartBody @@ -18,7 +18,7 @@ class RemoteRepository { * @param entity 菜品实体 * @return UiState 包装的结果,Success 表示提交成功,Error 携带错误信息 */ - suspend fun submitCookFood(entity: CookFoodEntity): UiState { + suspend fun submitCookFood(entity: CookFoodDTO): UiState { return try { val resp = apiService.submitCookFood(param = entity) if (resp.isSuccess()) UiState.Success(resp.data) @@ -34,7 +34,7 @@ class RemoteRepository { * @param foodId 菜品 ID * @return UiState 包装的结果,Success 携带详情数据,Error 携带错误信息 */ - suspend fun getFoodDetail(foodId: String): UiState { + suspend fun getFoodDetail(foodId: String): UiState { return try { val resp = apiService.getFoodDetail(foodId = foodId) if (resp.isSuccess()) UiState.Success(resp.data) diff --git a/app/src/main/java/com/shuwei/dish/match/ui/PrepareFoodActivity.kt b/app/src/main/java/com/shuwei/dish/match/ui/PrepareFoodActivity.kt index 55b6ca8..0b4621c 100644 --- a/app/src/main/java/com/shuwei/dish/match/ui/PrepareFoodActivity.kt +++ b/app/src/main/java/com/shuwei/dish/match/ui/PrepareFoodActivity.kt @@ -19,7 +19,7 @@ import com.shuwei.dish.match.base.BaseActivity import com.shuwei.dish.match.databinding.ActivityPrepareFoodBinding import com.shuwei.dish.match.databinding.LayoutCameraPreviewBinding import com.shuwei.dish.match.dialog.CommonDialog -import com.shuwei.dish.match.entity.CookFoodEntity +import com.shuwei.dish.match.entity.CookFoodDTO import com.shuwei.dish.match.entity.CookFoodGoodsEntity import com.shuwei.dish.match.entity.FoodRecord import com.shuwei.dish.match.entity.GoodsItem @@ -349,7 +349,7 @@ class PrepareFoodActivity : BaseActivity() { } - private fun loadDishDetail(detail: CookFoodEntity) { + private fun loadDishDetail(detail: CookFoodDTO) { // val voList = detail.stFoodInfoConstituteList val voList = detail.foodConstituteList if (voList.isNullOrEmpty()) { diff --git a/app/src/main/java/com/shuwei/dish/match/ui/SubmitFoodActivity.kt b/app/src/main/java/com/shuwei/dish/match/ui/SubmitFoodActivity.kt index b1f80c0..93bf3ea 100644 --- a/app/src/main/java/com/shuwei/dish/match/ui/SubmitFoodActivity.kt +++ b/app/src/main/java/com/shuwei/dish/match/ui/SubmitFoodActivity.kt @@ -20,6 +20,7 @@ import com.shuwei.dish.match.dialog.CommonDialog import com.shuwei.dish.match.entity.CookFoodEntity import com.shuwei.dish.match.entity.CookFoodGoodsEntity import com.shuwei.dish.match.entity.FoodRecord +import com.shuwei.dish.match.entity.toDTO import com.shuwei.dish.match.net.UiState import com.shuwei.dish.match.scale.ScaleDeviceConfig import com.shuwei.dish.match.scale.ScaleServiceManager @@ -357,7 +358,8 @@ class SubmitFoodActivity : BaseActivity() { } Log.d(TAG, "submit: json=${cookFoodEntity.toJsonString()}") - netViewModel.submitCookFood(entity = cookFoodEntity) + // 接口提交使用 DTO,与本地 Room 实体解耦 + netViewModel.submitCookFood(entity = cookFoodEntity.toDTO()) } }