代码提交

This commit is contained in:
2025-08-11 18:32:04 +08:00
parent 317ac05278
commit 3b4ba599bf
188 changed files with 9770 additions and 34 deletions
+14 -34
View File
@@ -1,35 +1,15 @@
# ---> Android
# Gradle files
.gradle/
build/
# Local configuration file (sdk path, etc)
local.properties
# Log/OS Files
*.log
# Android Studio generated files and folders
captures/
.externalNativeBuild/
.cxx/
*.apk
output.json
# IntelliJ
*.iml
.idea/
misc.xml
deploymentTargetDropDown.xml
render.experimental.xml
# Keystore files
*.jks
*.keystore
# Google Services (e.g. APIs or Firebase)
google-services.json
# Android Profiling
*.hprof
.gradle
/local.properties
/.idea/caches
/.idea/libraries
/.idea/modules.xml
/.idea/workspace.xml
/.idea/navEditor.xml
/.idea/assetWizardSettings.xml
.DS_Store
/build
/captures
.externalNativeBuild
.cxx
local.properties
+3
View File
@@ -0,0 +1,3 @@
# Default ignored files
/shelf/
/workspace.xml
+6
View File
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="AndroidProjectSystem">
<option name="providerId" value="com.android.tools.idea.GradleProjectSystem" />
</component>
</project>
+6
View File
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<bytecodeTargetLevel target="21" />
</component>
</project>
+18
View File
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="deploymentTargetSelector">
<selectionStates>
<SelectionState runConfigName="app">
<option name="selectionMode" value="DROPDOWN" />
<DropdownSelection timestamp="2025-07-21T08:50:38.006773Z">
<Target type="DEFAULT_BOOT">
<handle>
<DeviceId pluginId="LocalEmulator" identifier="path=C:\Users\HUAWEI\.android\avd\Pad_828_1768_New.avd" />
</handle>
</Target>
</DropdownSelection>
<DialogSelection />
</SelectionState>
</selectionStates>
</component>
</project>
+13
View File
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="DeviceTable">
<option name="columnSorters">
<list>
<ColumnSorterState>
<option name="column" value="Name" />
<option name="order" value="ASCENDING" />
</ColumnSorterState>
</list>
</option>
</component>
</project>
+19
View File
@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GradleMigrationSettings" migrationVersion="1" />
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<option name="testRunner" value="CHOOSE_PER_TEST" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="gradleJvm" value="#GRADLE_LOCAL_JAVA_HOME" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />
<option value="$PROJECT_DIR$/app" />
</set>
</option>
</GradleProjectSettings>
</option>
</component>
</project>
+10
View File
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectMigrations">
<option name="MigrateToGradleLocalJavaHome">
<set>
<option value="$PROJECT_DIR$" />
</set>
</option>
</component>
</project>
+9
View File
@@ -0,0 +1,9 @@
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="jbr-21" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">
<option name="id" value="Android" />
</component>
</project>
+17
View File
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RunConfigurationProducerService">
<option name="ignoredProducers">
<set>
<option value="com.intellij.execution.junit.AbstractAllInDirectoryConfigurationProducer" />
<option value="com.intellij.execution.junit.AllInPackageConfigurationProducer" />
<option value="com.intellij.execution.junit.PatternConfigurationProducer" />
<option value="com.intellij.execution.junit.TestInClassConfigurationProducer" />
<option value="com.intellij.execution.junit.UniqueIdConfigurationProducer" />
<option value="com.intellij.execution.junit.testDiscovery.JUnitTestDiscoveryConfigurationProducer" />
<option value="org.jetbrains.kotlin.idea.junit.KotlinJUnitRunConfigurationProducer" />
<option value="org.jetbrains.kotlin.idea.junit.KotlinPatternConfigurationProducer" />
</set>
</option>
</component>
</project>
+1
View File
@@ -0,0 +1 @@
/build
+104
View File
@@ -0,0 +1,104 @@
plugins {
alias(libs.plugins.android.application)
alias(libs.plugins.kotlin.android)
id("com.google.devtools.ksp") version "2.0.21-1.0.27"
}
android {
namespace = "com.shuwei.dish.match"
compileSdk = 36
defaultConfig {
applicationId = "com.shuwei.dish.match"
minSdk = 29
targetSdk = 36
versionCode = 1
versionName = "1.0"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
ndk {
//设置支持的SO库架构
abiFilters.addAll(listOf("armeabi", "armeabi-v7a"))
//, 'x86', 'armeabi-v7a', 'x86_64', 'arm64-v8a'
}
}
signingConfigs {
create("debug_507") {
storeFile = file("../system.keystore")
storePassword = "android"
keyAlias = "wabon"
keyPassword = "android"
}
}
buildTypes {
release {
isMinifyEnabled = false
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
signingConfig = signingConfigs.getByName("debug_507")
}
debug {
//507扫码秤主板在android.buildTypes{}内增加
signingConfig = signingConfigs.getByName("debug_507")
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}
kotlinOptions {
jvmTarget = "11"
}
buildFeatures {
viewBinding = true
}
packagingOptions {
pickFirst("lib/armeabi-v7a/libserial_port.so")
pickFirst("lib/arme64-v8a/libserial_port.so")
}
}
dependencies {
implementation(fileTree("libs") { include("*.jar", "*.aar") })
implementation(libs.androidx.core.ktx)
implementation(libs.androidx.appcompat)
implementation(libs.material)
testImplementation(libs.junit)
androidTestImplementation(libs.androidx.junit)
androidTestImplementation(libs.androidx.espresso.core)
implementation("com.squareup.okhttp3:okhttp:4.9.1")
implementation("com.google.code.gson:gson:2.10.1")
// implementation("com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.30")
implementation("io.github.cymchad:BaseRecyclerViewAdapterHelper4:4.1.2")
implementation("androidx.room:room-runtime:2.5.2")
ksp("androidx.room:room-compiler:2.5.2")
implementation("androidx.room:room-ktx:2.5.2") // Kotlin扩展
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.8.7")
implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.7")
implementation("androidx.activity:activity-ktx:1.8.0")
// implementation("biz.laenger.android:vpbs:0.0.6")
//必须 1.0.0 以上
implementation("io.github.scwang90:refresh-layout-kernel:3.0.0-alpha")
//核心必须依赖
implementation("io.github.scwang90:refresh-header-classics:3.0.0-alpha")
//经典刷新头
implementation("io.github.scwang90:refresh-header-radar:3.0.0-alpha")
//雷达刷新头
implementation("io.github.scwang90:refresh-header-falsify:3.0.0-alpha")
//虚拟刷新头
implementation("io.github.scwang90:refresh-header-material:3.0.0-alpha")
//谷歌刷新头
implementation("io.github.scwang90:refresh-header-two-level:3.0.0-alpha")
//二级刷新头
implementation("io.github.scwang90:refresh-footer-ball:3.0.0-alpha")
//球脉冲加载
implementation("io.github.scwang90:refresh-footer-classics:3.0.0-alpha")
//经典加载
}
Binary file not shown.
Binary file not shown.
+21
View File
@@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
Binary file not shown.
Binary file not shown.
Binary file not shown.
+37
View File
@@ -0,0 +1,37 @@
{
"version": 3,
"artifactType": {
"type": "APK",
"kind": "Directory"
},
"applicationId": "com.shuwei.dish.match",
"variantName": "release",
"elements": [
{
"type": "SINGLE",
"filters": [],
"attributes": [],
"versionCode": 1,
"versionName": "1.0",
"outputFile": "app-release.apk"
}
],
"elementType": "File",
"baselineProfiles": [
{
"minApi": 28,
"maxApi": 30,
"baselineProfiles": [
"baselineProfiles/1/app-release.dm"
]
},
{
"minApi": 31,
"maxApi": 2147483647,
"baselineProfiles": [
"baselineProfiles/0/app-release.dm"
]
}
],
"minSdkVersionForDexing": 29
}
@@ -0,0 +1,24 @@
package com.shuwei.dish.match
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.Assert.*
/**
* Instrumented test, which will execute on an Android device.
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest {
@Test
fun useAppContext() {
// Context of the app under test.
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
assertEquals("com.shuwei.dish.shelves", appContext.packageName)
}
}
+83
View File
@@ -0,0 +1,83 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:sharedUserId="android.uid.system">
<uses-feature android:name="android.hardware.usb.host" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<supports-screens
android:anyDensity="true"
android:largeScreens="true"
android:normalScreens="true"
android:resizeable="true"
android:smallScreens="true" />
<application
android:name=".base.BaseApp"
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:networkSecurityConfig="@xml/network_security_config"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.DishMatch"
android:usesCleartextTraffic="true">
<activity
android:name=".ui.HomeActivity"
android:exported="true"
android:screenOrientation="portrait"
tools:ignore="DiscouragedApi,LockedOrientationActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".ui.SelectDishActivity"
android:launchMode="singleTask"
android:screenOrientation="portrait"
tools:ignore="DiscouragedApi,LockedOrientationActivity" />
<activity
android:name=".ui.PrepareCookActivity"
android:screenOrientation="portrait"
tools:ignore="DiscouragedApi,LockedOrientationActivity" />
<activity
android:name=".ui.DishSamplingActivity"
android:screenOrientation="portrait"
tools:ignore="DiscouragedApi,LockedOrientationActivity" />
<activity
android:name=".ui.SamplingListActivity"
android:launchMode="singleTask"
android:screenOrientation="portrait"
tools:ignore="DiscouragedApi,LockedOrientationActivity" />
<activity
android:name=".ui.SubmitDishActivity"
android:screenOrientation="portrait"
tools:ignore="DiscouragedApi,LockedOrientationActivity" />
<activity
android:name=".ui.DeviceSettingActivity"
android:launchMode="singleTask"
android:screenOrientation="portrait"
tools:ignore="DiscouragedApi,LockedOrientationActivity" />
<activity
android:name=".ui.FoodSearchActivity"
android:screenOrientation="portrait"
tools:ignore="DiscouragedApi,LockedOrientationActivity" />
</application>
</manifest>
Binary file not shown.

After

Width:  |  Height:  |  Size: 110 B

@@ -0,0 +1,54 @@
package com.shuwei.dish.match.adapter
import android.content.Context
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.core.content.ContextCompat
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.ListItemDishCookBinding
import com.shuwei.dish.match.entity.CookFoodGoodsEntity
class DishPartAdapter(list: MutableList<CookFoodGoodsEntity>) :
BaseQuickAdapter<CookFoodGoodsEntity, DishPartAdapter.VH>(list) {
inner class VH(var binding: ListItemDishCookBinding) : QuickViewHolder(binding.root)
override fun onCreateViewHolder(context: Context, parent: ViewGroup, viewType: Int): VH {
val inflater = LayoutInflater.from(context)
val binding = ListItemDishCookBinding.inflate(inflater, parent, false)
return VH(binding)
}
override fun onBindViewHolder(holder: VH, position: Int, item: CookFoodGoodsEntity?) {
holder.binding.run {
tvDishName.text = item!!.goodsName
tvDishType.text = if (item.materialType == 1) "主辅材:主材" else if (item.materialType == 2) "主辅材:辅材" else ""
tvDishWeight.text =
if (item.useWeight == null || item.useWeight == 0) "" else "${item.useWeight}"
tvDishWeight.setTextColor(
ContextCompat.getColor(
context,
if (item.isSamplingPage) R.color.black999 else R.color.dish_green
)
)
ivOperateIcon.setImageResource(
if (item.isSamplingPage)
//采集页面
R.drawable.ic_delete
else
//制作页面
if (item.isSetFinished) R.drawable.ic_dish_selected
else R.drawable.ic_dish_unselected
)
root.run {
setBackgroundResource(
if (item.isItemClicked) R.drawable.shape_item_cook_dish
else R.drawable.shape_white_fb_15_corners
)
}
}
}
}
@@ -0,0 +1,59 @@
package com.shuwei.dish.match.adapter
import android.content.Context
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.core.content.ContextCompat
import com.chad.library.adapter4.BaseQuickAdapter
import com.chad.library.adapter4.viewholder.QuickViewHolder
import com.shuwei.dish.match.R
import com.shuwei.dish.match.entity.FoodRecord
import com.shuwei.dish.match.databinding.ListItemDishBinding
import com.shuwei.dish.match.utils.ext.gone
import com.shuwei.dish.match.utils.ext.visible
class DishShowAdapter(list: MutableList<FoodRecord>) :
BaseQuickAdapter<FoodRecord, DishShowAdapter.VH>(list) {
inner class VH(var binding: ListItemDishBinding) : QuickViewHolder(binding.root)
override fun onCreateViewHolder(context: Context, parent: ViewGroup, viewType: Int): VH {
val inflater = LayoutInflater.from(context)
val binding = ListItemDishBinding.inflate(inflater, parent, false)
return VH(binding)
}
override fun onBindViewHolder(holder: VH, position: Int, item: FoodRecord?) {
holder.binding.run {
val isCooking = item!!.isCooking
val totalWeight = item.totalWeight ?: 0
tvDishName.text = item!!.foodName
if (isCooking) {
tvDishName.setTextColor(
ContextCompat.getColor(holder.itemView.context, R.color.black)
)
clBlock.setBackgroundResource(R.drawable.shape_white_fb_15_corners)
tvDishCount.visible()
tvDishCount.text = "制作统计:-kg"
tvShowState.text = "烹饪中"
} else if (totalWeight > 0) {
tvDishName.setTextColor(
ContextCompat.getColor(holder.itemView.context, R.color.dish_green)
)
clBlock.setBackgroundResource(R.drawable.shape_white_fb_15_corners)
tvDishCount.visible()
tvDishCount.text =
"累计统计:${totalWeight / 1000.0F}kg(${item.count}次)"
tvShowState.text = "${(item.foodWeight ?: 0) / 1000.0F}kg"
} else {
tvDishName.setTextColor(
ContextCompat.getColor(holder.itemView.context, R.color.black999)
)
clBlock.setBackgroundResource(R.drawable.shape_white_dash_15_corners)
tvDishCount.gone()
tvShowState.text = "-"
}
}
}
}
@@ -0,0 +1,33 @@
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.databinding.ListItemDishRecordBinding
import com.shuwei.dish.match.entity.FoodRecord
class FoodRecordAdapter(list: MutableList<FoodRecord>) :
BaseQuickAdapter<FoodRecord, FoodRecordAdapter.VH>(list) {
inner class VH(var binding: ListItemDishRecordBinding) : QuickViewHolder(binding.root)
override fun onBindViewHolder(
holder: VH,
position: Int,
item: FoodRecord?
) {
holder.binding.tvDishInfo.text = item?.foodName
}
override fun onCreateViewHolder(
context: Context,
parent: ViewGroup,
viewType: Int
): VH {
val inflater = LayoutInflater.from(context)
val binding = ListItemDishRecordBinding.inflate(inflater, parent, false)
return VH(binding)
}
}
@@ -0,0 +1,49 @@
package com.shuwei.dish.match.adapter
import android.content.Context
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.core.content.ContextCompat
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.ListItemSearchGoodsInfoBinding
import com.shuwei.dish.match.entity.CookFoodGoodsEntity
class GoodsInfoSearchAdapter(private var list: MutableList<CookFoodGoodsEntity>) :
BaseQuickAdapter<CookFoodGoodsEntity, GoodsInfoSearchAdapter.VH>(list) {
override fun onBindViewHolder(
holder: VH,
position: Int,
item: CookFoodGoodsEntity?
) {
holder.binding.tvGoodsInfo.run {
text = item?.goodsName
setBackgroundResource(
if (item?.isClicked == true) R.drawable.shape_green_stroke
else R.drawable.shape_white_12_corners
)
setTextColor(
ContextCompat.getColor(
context,
if (item?.isClicked == true) R.color.dish_green
else R.color.black666
)
)
}
}
override fun onCreateViewHolder(
context: Context,
parent: ViewGroup,
viewType: Int
): VH {
val binding =
ListItemSearchGoodsInfoBinding.inflate(LayoutInflater.from(context), parent, false)
return VH(binding)
}
inner class VH(var binding: ListItemSearchGoodsInfoBinding) : QuickViewHolder(binding.root)
}
@@ -0,0 +1,46 @@
package com.shuwei.dish.match.adapter
import android.content.Context
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.core.content.ContextCompat
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.ListItemHomeModeBinding
import com.shuwei.dish.match.entity.HomeModeBean
import com.shuwei.dish.match.utils.ext.gone
import com.shuwei.dish.match.utils.ext.visible
class HomeModeAdapter(list: MutableList<HomeModeBean>) : BaseQuickAdapter<HomeModeBean, HomeModeAdapter.VH>(list) {
inner class VH(var binding: ListItemHomeModeBinding) : QuickViewHolder(binding.root)
override fun onCreateViewHolder(context: Context, parent: ViewGroup, viewType: Int): VH {
val binding = ListItemHomeModeBinding.inflate(LayoutInflater.from(context), parent, false)
return VH(binding)
}
override fun onBindViewHolder(holder: VH, position: Int, item: HomeModeBean?) {
holder.binding.run {
tvModeName.text = item!!.modeName
tvModeDesc.text = item.modeDesc
ivModeIcon.setImageResource(item.modeIconId)
tvLockRemind.run {
if (item.isLocked) visible() else gone()
}
var modeNameColor = R.color.mode_name
var modeDescColor = R.color.mode_desc
var rightIconId = R.drawable.ic_arrow_right
if (item.isLocked) {
modeNameColor = R.color.mode_name
modeDescColor = R.color.mode_desc
rightIconId = R.drawable.ic_lock
}
this.ivRightIcon.setImageResource(rightIconId)
tvModeName.setTextColor(ContextCompat.getColor(root.context, modeNameColor))
tvModeDesc.setTextColor(ContextCompat.getColor(root.context, modeDescColor))
}
}
}
@@ -0,0 +1,52 @@
package com.shuwei.dish.match.adapter
import android.content.Context
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.core.content.ContextCompat
import com.chad.library.adapter4.BaseQuickAdapter
import com.chad.library.adapter4.viewholder.QuickViewHolder
import com.shuwei.dish.match.R
import com.shuwei.dish.match.entity.FoodRecord
import com.shuwei.dish.match.databinding.ListItemDishBinding
import com.shuwei.dish.match.utils.ext.gone
import com.shuwei.dish.match.utils.ext.visible
class SamplingAdapter(list: MutableList<FoodRecord>) :
BaseQuickAdapter<FoodRecord, SamplingAdapter.VH>(list) {
inner class VH(var binding: ListItemDishBinding) : QuickViewHolder(binding.root)
override fun onCreateViewHolder(context: Context, parent: ViewGroup, viewType: Int): VH {
val inflater = LayoutInflater.from(context)
val binding = ListItemDishBinding.inflate(inflater, parent, false)
return VH(binding)
}
override fun onBindViewHolder(holder: VH, position: Int, item: FoodRecord?) {
holder.binding.run {
val isCooking = item!!.isCooking
clBlock.setBackgroundResource(R.drawable.shape_white_fb_15_corners)
val totalWeight = item!!.totalWeight ?: 0
tvDishName.run {
text = item!!.foodName
setTextColor(
ContextCompat.getColor(
holder.itemView.context,
if (isCooking) R.color.black else R.color.dish_green
)
)
}
tvDishCount.visible()
if (isCooking) {
tvDishCount.text = "制作统计:-kg"
tvShowState.text = "烹饪中"
} else {
val useWeight = if (totalWeight > 0) totalWeight else (item.foodWeight ?: 0)
tvDishCount.text = "累计统计:${useWeight / 1000.0F}kg(${item.count}次)"
tvShowState.text = "${(item.foodWeight ?: 0) / 1000.0F}kg"
}
}
}
}
@@ -0,0 +1,132 @@
package com.shuwei.dish.match.adapter
import android.annotation.SuppressLint
import android.widget.TextView
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.shuwei.dish.match.base.BaseActivity
import com.shuwei.dish.match.dialog.BottomDialog2
import com.shuwei.dish.match.entity.SeasoningEntity
import com.shuwei.dish.match.ui.DeviceSettingActivity
import com.shuwei.dish.match.ui.SubmitDishActivity
import com.shuwei.dish.match.utils.DataUtil
object SeasoningCellTool {
private val TAG = "SeasoningCellTool"
private val list = mutableListOf<SeasoningEntity>()
private lateinit var activity: BaseActivity
private var pageType: Int = 0
@SuppressLint("StaticFieldLeak")
private lateinit var cellAdapter: TextCellAdapter
@SuppressLint("NotifyDataSetChanged")
fun loadData(
activity: BaseActivity,
initList: MutableList<SeasoningEntity>? = null,
recyclerView: RecyclerView,
tvCell: TextView,
pageType: Int = 0
) {
this.activity = activity
this.pageType = pageType
list.clear()
val tempList = buildData(initList, pageType)
list.addAll(tempList)
recyclerView.run {
if (adapter == null) {
layoutManager = GridLayoutManager(
activity,
3,
GridLayoutManager.VERTICAL,
false
)
cellAdapter = TextCellAdapter(list).apply {
onCellClick = { position ->
val currentAddress = DataUtil.getWeighAddressArray().get(position)
BottomDialog2(
weighIndex = position,
weighAddress = currentAddress,
clickName = list[position].goodsName
).show(activity) { item ->
list[position].let { current ->
syncItem(current, item)
//3-调料
current.materialType = 3
current.sort = position
}
notifyItemChanged(position)
if (position == 14) {
syncItem(list[10], list[14])
syncItem(list[11], list[14])
syncItem(list[13], list[14])
TextCellAdapter.loadCell(tvCell, list[14])
notifyItemChanged(10)
notifyItemChanged(11)
notifyItemChanged(13)
notifyItemChanged(14)
}
if (activity is DeviceSettingActivity) {
//activity.list = list
activity.saveSeasoning(list[position])
}
}
}
}
adapter = cellAdapter
} else {
cellAdapter.notifyDataSetChanged()
}
if (activity is SubmitDishActivity) {
activity.updateSeasoningList(list)
}
}
if (pageType == 1) {
tvCell.setOnClickListener {
cellAdapter.onCellClick?.invoke(14)
}
}
TextCellAdapter.loadCell(tvCell, list[list.size - 1])
}
private fun buildData(
initList: MutableList<SeasoningEntity>?,
pageType: Int = 0
): MutableList<SeasoningEntity> {
val list = mutableListOf<SeasoningEntity>()
repeat(15) {
list.add(SeasoningEntity().apply { this.pageType = pageType })
}
if (initList.isNullOrEmpty().not()) {
initList.forEach {
list[it.sort] = it.apply { this.pageType = pageType }
}
var lastItem = initList.firstOrNull { it.sort == 14 }
lastItem = lastItem ?: list[list.size - 1]
list[10] = lastItem
list[11] = lastItem
list[13] = lastItem
}
return list
}
private fun syncItem(item: SeasoningEntity, newItem: SeasoningEntity) {
item.run {
goodsId = newItem.goodsId
goodsName = newItem.goodsName
goodsOrRelationCode = newItem.goodsOrRelationCode
relateionType = newItem.relateionType
materialType = newItem.materialType
allEdible = newItem.allEdible
useWeight = newItem.useWeight
popularName = newItem.popularName
canteenId = newItem.canteenId
relateionType_dictText = newItem.relateionType_dictText
foodId = newItem.foodId
sort = newItem.sort
}
}
}
@@ -0,0 +1,49 @@
package com.shuwei.dish.match.adapter
import android.content.Context
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.core.content.ContextCompat
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.ListItemSearchGoodsInfoBinding
import com.shuwei.dish.match.entity.SeasoningEntity
class SeasoningSearchAdapter(private var list: MutableList<SeasoningEntity>) :
BaseQuickAdapter<SeasoningEntity, SeasoningSearchAdapter.VH>(list) {
override fun onBindViewHolder(
holder: VH,
position: Int,
item: SeasoningEntity?
) {
holder.binding.tvGoodsInfo.run {
text = item?.goodsName
setBackgroundResource(
if (item?.isClicked == true) R.drawable.shape_green_stroke
else R.drawable.shape_white_12_corners
)
setTextColor(
ContextCompat.getColor(
context,
if (item?.isClicked == true) R.color.dish_green
else R.color.black666
)
)
}
}
override fun onCreateViewHolder(
context: Context,
parent: ViewGroup,
viewType: Int
): VH {
val binding =
ListItemSearchGoodsInfoBinding.inflate(LayoutInflater.from(context), parent, false)
return VH(binding)
}
inner class VH(var binding: ListItemSearchGoodsInfoBinding) : QuickViewHolder(binding.root)
}
@@ -0,0 +1,117 @@
package com.shuwei.dish.match.adapter
import android.graphics.Typeface
import android.text.SpannableStringBuilder
import android.text.style.AbsoluteSizeSpan
import android.text.style.ForegroundColorSpan
import android.text.style.LineHeightSpan
import android.text.style.StyleSpan
import android.view.LayoutInflater
import android.view.ViewGroup
import android.widget.TextView
import androidx.core.content.ContextCompat
import androidx.core.graphics.toColorInt
import androidx.recyclerview.widget.RecyclerView
import com.chad.library.adapter4.viewholder.QuickViewHolder
import com.shuwei.dish.match.R
import com.shuwei.dish.match.databinding.ListItemCellBinding
import com.shuwei.dish.match.entity.SeasoningEntity
import com.shuwei.dish.match.utils.ext.appendText
import com.shuwei.dish.match.utils.ext.buildSpannableString
import com.shuwei.dish.match.utils.ext.clickWithDebounce
import com.shuwei.dish.match.utils.ext.dp
import com.shuwei.dish.match.utils.ext.invisible
import com.shuwei.dish.match.utils.ext.visible
class TextCellAdapter(var list: MutableList<SeasoningEntity>) :
RecyclerView.Adapter<TextCellAdapter.VH>() {
inner class VH(var binding: ListItemCellBinding) : QuickViewHolder(binding.root)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): VH {
val inflater = LayoutInflater.from(parent.context)
val binding = ListItemCellBinding.inflate(inflater, parent, false)
return VH(binding)
}
override fun onBindViewHolder(holder: VH, position: Int) {
val item = list[position]
holder.binding.run {
if (position == 10 || position == 11 || position == 13 || position == 14) {
root.invisible()
} else {
root.visible()
}
loadCell(tvCell, item)
//root.setBackgroundResource(R.color.dish_green)
(root.layoutParams as RecyclerView.LayoutParams).let {
// it.bottomMargin = 15.dp
it.width = 226.dp
it.height = 120.dp
// it.rightMargin = 0
// it.leftMargin = if (position % 3 == 0) 0 else 15.dp
it.leftMargin = 7.dp
it.rightMargin = 8.dp
it.topMargin = 7.dp
it.bottomMargin = 8.dp
}
if (item.pageType == 1) {
root.clickWithDebounce { onCellClick?.invoke(position) }
}
}
}
override fun getItemCount() = list.size
var onCellClick: ((positon: Int) -> Unit)? = null
companion object {
fun loadCell(tvCell: TextView, item: SeasoningEntity) {
if (item.goodsName.isNullOrBlank()) {
tvCell.run {
text = "未配置"
setTextColor(ContextCompat.getColor(context, R.color.black999))
}
} else {
// if (item.pageType == 1) {
// tvCell.run {
// text = item.goodsName
// setTextColor(ContextCompat.getColor(context, R.color.black))
// }
// } else {
tvCell.text = getTextSpan(item)
// }
}
}
fun getTextSpan(item: SeasoningEntity): SpannableStringBuilder {
val endIndex = if (item.sort == 14) 10 else 6
var name = item.goodsName!!
if (name.length > endIndex) {
name = "${name.substring(0, endIndex)}"
}
return buildSpannableString {
appendText(
name,
ForegroundColorSpan("#000000".toColorInt()),
StyleSpan(Typeface.BOLD),
AbsoluteSizeSpan(28, true),
LineHeightSpan { text, start, end, spanstartv, v, fm ->
fm.descent += 10.dp // 增加行间距
}
)
append("\n")
val weight = item.useWeight ?: 0
val weightColor = if (weight == 0) "#999999" else "#00BC71"
appendText(
"${weight}g",
ForegroundColorSpan(weightColor.toColorInt()),
AbsoluteSizeSpan(30, true)
)
}
}
}
}
@@ -0,0 +1,163 @@
package com.shuwei.dish.match.base
import android.content.Intent
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.util.Log
import android.view.View
import android.widget.FrameLayout
import android.widget.ImageView
import android.widget.TextView
import androidx.activity.enableEdgeToEdge
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import com.shuwei.dish.match.R
import com.shuwei.dish.match.databinding.ActivityBaseBinding
import com.shuwei.dish.match.dialog.Loading
import com.shuwei.dish.match.http.HttpUtil
import com.shuwei.dish.match.http.UrlConfig
import com.shuwei.dish.match.ui.HomeActivity.Companion.TAG
import com.shuwei.dish.match.utils.ActivityManager
import com.shuwei.dish.match.utils.ext.gone
import com.shuwei.dish.match.utils.ext.put
import com.shuwei.dish.match.utils.ext.toast
import java.time.LocalDateTime
import java.time.ZoneId
import java.time.format.DateTimeFormatter
import java.util.Locale
@Suppress("DEPRECATION")
open class BaseActivity : AppCompatActivity() {
private lateinit var binding: ActivityBaseBinding
private var launcher: ActivityResultLauncher<Intent>? = null
private var launchCallback: ((Intent?) -> Unit)? = null
public fun launch(cls: Class<*>, launchCallback: (Intent?) -> Unit) {
this.launchCallback = launchCallback
launcher?.launch(Intent(this, cls))
}
public fun launch(intent: Intent, launchCallback: (Intent?) -> Unit) {
this.launchCallback = launchCallback
launcher?.launch(intent)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
ActivityManager.addActivity(this)
binding = ActivityBaseBinding.inflate(layoutInflater)
setContentView(binding.root)
statusBarDarkFont(enable = false)
launcher =
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
if (result.resultCode == RESULT_OK) {
launchCallback?.invoke(result.data)
}
}
// window.setDecorFitsSystemWindows(false) // 启用 Edge-to-Edge
// window.insetsController?.apply {
// hide(WindowInsets.Type.statusBars()) // 隐藏状态栏
// systemBarsBehavior =
// WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE // 滑动时临时显示
// }
binding.llTitleBar.gone()
binding.ivBack.setOnClickListener { finish() }
}
override fun onDestroy() {
dismissLoading()
super.onDestroy()
ActivityManager.removeActivity(this)
}
fun hideStatusBar() {
enableEdgeToEdge()
// val uiOptions = (View.SYSTEM_UI_FLAG_FULLSCREEN // 隐藏状态栏
// or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) // 隐藏导航栏(可选)
window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_FULLSCREEN
}
fun statusBarDarkFont(enable: Boolean) {
//window.decorView.systemUiVisibility = if (enable) View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR else 0
val color = ContextCompat.getColor(this,
if (enable) R.color.black else R.color.white
)
binding.tvLeftTime.setTextColor(color)
binding.tvRightTime.setTextColor(color)
}
fun setTitleBar(
titleBarAction: ((FrameLayout) -> Unit)? = null,
backAction: ((ImageView) -> Unit)? = null,
titleAction: ((TextView) -> Unit)? = null,
rightIconActon: ((ImageView) -> Unit)? = null
) {
titleBarAction?.invoke(binding.llTitleBar)
backAction?.invoke(binding.ivBack)
titleAction?.invoke(binding.tvTitle)
rightIconActon?.invoke(binding.ivRightIcon)
}
public fun setHeaderBackground(isHomePage: Boolean = false) {
binding.ivHeaderBg.setImageResource(
if (isHomePage) R.drawable.bg_home_page else R.drawable.bg_other_page
)
}
override fun setContentView(view: View?) {
if (view == binding.root) {
super.setContentView(view)
} else {
binding.flContainer.addView(view)
}
}
private fun updateDateTime() {
val formatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日 EEEE***HH:mm:ss", Locale.CHINA)
val dateTime = formatter.format(LocalDateTime.now(ZoneId.of("Asia/Shanghai")))
val arr = dateTime.split("***")
binding.tvRightTime.text = arr[0]
binding.tvLeftTime.text = arr[1]
}
private val handler = Handler(Looper.getMainLooper())
private val updateTask = object : Runnable {
override fun run() {
updateDateTime()
handler.postDelayed(this, 1000)
}
}
override fun onResume() {
super.onResume()
hideStatusBar()
handler.post(updateTask)
}
override fun onPause() {
super.onPause()
handler.removeCallbacks(updateTask)
}
fun showLoading() {
Loading.show(this)
}
fun dismissLoading() {
Loading.dismiss()
}
fun delayDismissLoading() {
window.decorView.postDelayed({
Loading.dismiss()
},500)
}
}
@@ -0,0 +1,36 @@
package com.shuwei.dish.match.base
import android.app.Application
import android.content.Context
import android.content.SharedPreferences
import com.shuwei.dish.match.R
import com.shuwei.dish.match.db.DatabaseProvider
class BaseApp : Application() {
val database by lazy { DatabaseProvider(this).instance }
var token: String? = null
var androidId: String? = null
override fun onCreate() {
super.onCreate()
instance = this
}
companion object {
@Volatile
private var sharedPref: SharedPreferences? = null
public var instance: BaseApp? = null
fun getSharedPref(): SharedPreferences? {
if (sharedPref != null) {
return sharedPref
}
val saveName = instance?.getString(R.string.sp_save_name)
sharedPref = instance?.getSharedPreferences(saveName, Context.MODE_PRIVATE)
return sharedPref
}
}
}
@@ -0,0 +1,9 @@
package com.shuwei.dish.match.base
import androidx.fragment.app.Fragment
open class BaseFragment : Fragment() {
}
@@ -0,0 +1,10 @@
package com.shuwei.dish.match.base
class BaseReq<T> {
var code: Int? = null
var success: Boolean? = null
var data: T? = null
var message: String? = null
var result: T? = null
var msg: String? = null
}
@@ -0,0 +1,174 @@
package com.shuwei.dish.match.db
import android.content.Context
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
import androidx.room.migration.Migration
import androidx.sqlite.db.SupportSQLiteDatabase
import com.shuwei.dish.match.db.dao.AppDao
import com.shuwei.dish.match.entity.CookFoodEntity
import com.shuwei.dish.match.entity.CookFoodGoodsEntity
import com.shuwei.dish.match.entity.SeasoningEntity
// 步骤1:更新版本号
@Database(
// 添加所有实体类
entities = [
SeasoningEntity::class,
CookFoodEntity::class,
CookFoodGoodsEntity::class,
],
version = 6,
exportSchema = true
)
abstract class AppDatabase : RoomDatabase() {
// abstract fun seasoningDao(): SeasoningDao
// abstract fun cookFoodDao(): CookFoodDao
// abstract fun cookFoodGoodsDao(): CookFoodGoodsDao
abstract fun appDao(): AppDao
}
// 步骤2:创建Migration对象
val MIGRATION_1_2 = MigrationImpl(1, 2) { db ->
// 获取SQLite版本
runCatching {
// 使用兼容方案
db.beginTransaction()
db.execSQL(
"""
CREATE TABLE `dm_seasoning_new` (
`id` INTEGER NOT NULL,
`name` TEXT,
`weight` INTEGER,
`sort` INTEGER NOT NULL,
`isDel` INTEGER NOT NULL,
`createTime` INTEGER NOT NULL,
PRIMARY KEY(`id`)
)
"""
)
db.execSQL(
"""
INSERT INTO dm_seasoning_new
SELECT id, name, weight, sort, isDel, create_time
FROM dm_seasoning
"""
)
db.execSQL("DROP TABLE dm_seasoning")
db.execSQL("ALTER TABLE dm_seasoning_new RENAME TO dm_seasoning")
// 执行上述临时表方案
db.setTransactionSuccessful()
}.onFailure {
it.printStackTrace()
}
db.endTransaction()
}
val MIGRATION_3_4 = MigrationImpl(3, 4) { db ->
db.execSQL(
"""
CREATE TABLE IF NOT EXISTS `dm_cook_food` (
`foodId` INTEGER PRIMARY KEY NOT NULL,
`foodName` TEXT,
`canteenId` INTEGER,
`cookedFoodWeight` INTEGER NOT NULL,
`isDel` INTEGER NOT NULL,
`createTime` TEXT NOT NULL
)
"""
)
db.execSQL(
"""
CREATE TABLE IF NOT EXISTS `dm_cook_food_goods` (
`goodsId` INTEGER PRIMARY KEY NOT NULL,
`goodsName` TEXT,
`foodId` INTEGER NOT NULL,
`relateionType` INTEGER NOT NULL,
`allEdible` INTEGER NOT NULL,
`useWeight` INTEGER NOT NULL,
`isDel` INTEGER NOT NULL,
`createTime` TEXT NOT NULL
)
"""
)
}
val MIGRATION_4_5 = MigrationImpl(4, 5) { db ->
db.execSQL("ALTER TABLE dm_cook_food_goods ADD sort INTEGER DEFAULT (0) NOT NULL")
}
val MIGRATION_5_6 = MigrationImpl(5, 6) { db ->
runCatching {
db.beginTransaction()
db.execSQL(
"""
CREATE TABLE IF NOT EXISTS `dm_cook_food_goods_new` (
`id` INTEGER PRIMARY KEY NOT NULL,
`goodsId` INTEGER NOT NULL,
`goodsName` TEXT,
`foodId` INTEGER NOT NULL,
`relateionType` INTEGER NOT NULL,
`allEdible` INTEGER NOT NULL,
`useWeight` INTEGER NOT NULL,
`sort` INTEGER NOT NULL DEFAULT 0,
`isDel` INTEGER NOT NULL,
`createTime` TEXT NOT NULL
)
"""
)
db.execSQL(
"""
INSERT INTO dm_cook_food_goods_new
SELECT NULL, goodsId, goodsName, foodId, relateionType, allEdible, useWeight, sort, isDel, createTime
FROM dm_cook_food_goods
"""
)
db.execSQL("DROP TABLE dm_cook_food_goods")
db.execSQL("ALTER TABLE dm_cook_food_goods_new RENAME TO dm_cook_food_goods")
// 执行上述临时表方案
db.setTransactionSuccessful()
}.onFailure {
it.printStackTrace()
}
db.endTransaction()
}
class DatabaseProvider(private val context: Context) {
// 单例模式确保全局唯一实例‌
val instance: AppDatabase by lazy {
Room.databaseBuilder(
context.applicationContext,
AppDatabase::class.java,
"app_dish_match.db"
)
.addCallback(object : RoomDatabase.Callback() {
override fun onCreate(db: SupportSQLiteDatabase) {
// 数据库首次创建时初始化数据
}
})
// .addMigrations(MIGRATION_1_2)
// .addMigrations(MIGRATION_3_4)
// .addMigrations(MIGRATION_4_5)
// .addMigrations(MIGRATION_5_6)
.build()
}
}
class MigrationImpl(
startVersion: Int,
endVersion: Int,
private val block: (db: SupportSQLiteDatabase) -> Unit
) : Migration(startVersion, endVersion) {
override fun migrate(database: SupportSQLiteDatabase) {
block(database)
}
}
@@ -0,0 +1,34 @@
package com.shuwei.dish.match.db
import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Update
// 1. 定义基础实体接口
interface BaseEntity {
}
//定义回调接口
interface OnCompleteListener {
fun onComplete()
}
// 2. 封装通用DAO操作
@Dao
interface BaseDao<T : BaseEntity> {
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insert(item: T): Long
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertAll(items: MutableList<T>): Array<Long>
@Update
suspend fun update(item: T)
@Delete
suspend fun delete(item: T)
}
@@ -0,0 +1,141 @@
package com.shuwei.dish.match.db
import com.shuwei.dish.match.db.dao.AppDao
import com.shuwei.dish.match.entity.CookFoodEntity
import com.shuwei.dish.match.entity.CookFoodGoodsEntity
import com.shuwei.dish.match.entity.SeasoningEntity
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
class AppRepository(val appDao: AppDao) {
suspend fun insertCookFood(item: CookFoodEntity) = withContext(Dispatchers.IO) {
appDao.insertCookFood(item)
}
suspend fun updateCookFood(item: CookFoodEntity) = withContext(Dispatchers.IO) {
appDao.updateCookFood(item)
}
suspend fun getCookFoodById(foodId: String, cookMode: Int) = withContext(Dispatchers.IO) {
appDao.getCookFoodById(foodId, cookMode)
}
suspend fun getCookFoodList(cookMode: Int) = withContext(Dispatchers.IO) {
appDao.getCookFoodList(cookMode)
}
suspend fun countCookFood(cookMode: Int) = withContext(Dispatchers.IO) {
appDao.countCookFood(cookMode)
}
suspend fun deleteCookFood(foodId: String, cookMode: Int) = withContext(Dispatchers.IO) {
appDao.deleteCookFood(foodId, cookMode)
}
suspend fun deleteCookFoodGoodsList(foodId: String) = withContext(Dispatchers.IO) {
appDao.deleteCookFoodGoodsList(foodId)
}
//--------------------------------------------------------------------------------------------
suspend fun insertGoods(item: CookFoodGoodsEntity) = withContext(Dispatchers.IO) {
appDao.insertGoods(item)
}
suspend fun insertGoodsList(items: MutableList<CookFoodGoodsEntity>) =
withContext(Dispatchers.IO) {
appDao.insertGoodsList(items)
}
suspend fun updateGoods(item: CookFoodGoodsEntity) = withContext(Dispatchers.IO) {
appDao.updateGoods(item)
}
suspend fun getCookFoodGoodsList(foodId: String) = withContext(Dispatchers.IO) {
appDao.getCookFoodGoodsList(foodId)
}
suspend fun getCookFoodGoodsListByType(
foodId: String,
materialType: Int
) = withContext(Dispatchers.IO) {
appDao.getCookFoodGoodsListByType(foodId, materialType)
}
//--------------------------------------------------------------------------------------------
suspend fun getSeasoningById(id: Long) = withContext(Dispatchers.IO) {
appDao.getSeasoningById(id)
}
suspend fun getSeasoningBySort(sort:Int) = withContext(Dispatchers.IO) {
appDao.getSeasoningBySort(sort)
}
suspend fun getSeasoningByGoodsId(goodsId: Int) = withContext(Dispatchers.IO) {
appDao.getSeasoningByGoodsId(goodsId)
}
suspend fun getAllStream() = withContext(Dispatchers.IO) {
appDao.getAllStream()
}
suspend fun search(query: String) = withContext(Dispatchers.IO) {
appDao.search(query)
}
suspend fun deleteBatch() = withContext(Dispatchers.IO) {
appDao.deleteBatch()
}
suspend fun deleteEmptySeasoning() = withContext(Dispatchers.IO) {
appDao.deleteEmptySeasoning()
}
suspend fun insertSeasoningList(items: MutableList<SeasoningEntity>) =
withContext(Dispatchers.IO) {
appDao.insertSeasoningList(items)
}
suspend fun updateSeasoning(item: SeasoningEntity) = withContext(Dispatchers.IO) {
appDao.updateSeasoning(item)
}
suspend fun insertSeasoning(item: SeasoningEntity) = withContext(Dispatchers.IO) {
appDao.insertSeasoning(item)
}
}
//
//class SeasoningRepository(val seasoningDao: SeasoningDao) {
// val seasoningList: Flow<List<SeasoningEntity>> = seasoningDao.getAllStream()
//
// fun addSeasoning(item: SeasoningEntity) = withContext(Dispatchers.IO) {
// seasoningDao.insert(item)
// }
//
// fun searchSeasoning(query: String) = withContext(Dispatchers.IO) {
// seasoningDao.search(query)
// }
//}
//
//class CookFoodRepository(val cookFoodDao: CookFoodDao) {
// fun getCookFood(foodId: String, cookMode:Int = 0) = withContext(Dispatchers.IO) {
// cookFoodDao.getCookFoodById(foodId, cookMode)
// }
//
// fun getCookFoodByList(cookMode:Int = 0) = withContext(Dispatchers.IO) {
// cookFoodDao.getCookFoodList(cookMode)
// }
//
// fun countCookFood(cookMode:Int = 0)= withContext(Dispatchers.IO) {
// cookFoodDao.countCookFood(cookMode)
// }
//}
//
//class CookFoodGoodsRepository(val cookFoodGoodsDao: CookFoodGoodsDao) {
// fun getFoodGoodsList(foodId: String) = withContext(Dispatchers.IO) {
// cookFoodGoodsDao.getCookFoodGoodsList(foodId)
// }
//
//}
@@ -0,0 +1,90 @@
package com.shuwei.dish.match.db.dao
import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import androidx.room.Update
import com.shuwei.dish.match.entity.CookFoodEntity
import com.shuwei.dish.match.entity.CookFoodGoodsEntity
import com.shuwei.dish.match.entity.SeasoningEntity
import kotlinx.coroutines.flow.Flow
@Dao
interface AppDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertCookFood(item: CookFoodEntity): Long
@Update
suspend fun updateCookFood(item: CookFoodEntity)
@Query("SELECT * FROM dm_cook_food WHERE isDel = 0 AND foodId = :foodId AND cookMode = :cookMode")
suspend fun getCookFoodById(foodId: String, cookMode: Int): CookFoodEntity?
@Query("SELECT * FROM dm_cook_food WHERE isDel = 0 AND cookMode = :cookMode ORDER BY createTime DESC")
suspend fun getCookFoodList(cookMode: Int): MutableList<CookFoodEntity>?
@Query("SELECT count(1) FROM dm_cook_food WHERE isDel = 0 AND cookMode = :cookMode")
suspend fun countCookFood(cookMode: Int): Int
@Query("DELETE FROM dm_cook_food WHERE foodId = :foodId AND cookMode = :cookMode")
suspend fun deleteCookFood(foodId: String, cookMode: Int)
//--------------------------------------------------------------------------------------------
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertGoods(item: CookFoodGoodsEntity): Long
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertGoodsList(items: MutableList<CookFoodGoodsEntity>): Array<Long>
@Update
suspend fun updateGoods(item: CookFoodGoodsEntity)
@Query("SELECT * FROM dm_cook_food_goods WHERE isDel = 0 AND foodId = :foodId")
suspend fun getCookFoodGoodsList(foodId: String): MutableList<CookFoodGoodsEntity>
@Query("SELECT * FROM dm_cook_food_goods WHERE isDel = 0 AND foodId = :foodId AND materialType = :materialType")
suspend fun getCookFoodGoodsListByType(
foodId: String,
materialType: Int
): MutableList<CookFoodGoodsEntity>
@Query("DELETE FROM dm_cook_food_goods WHERE foodId = :foodId")
suspend fun deleteCookFoodGoodsList(foodId: String)
//--------------------------------------------------------------------------------------------
@Query("SELECT * FROM dm_seasoning WHERE isDel = 0 AND id = :id")
suspend fun getSeasoningById(id: Long): SeasoningEntity?
@Query("SELECT * FROM dm_seasoning WHERE isDel = 0 AND sort = :sort")
suspend fun getSeasoningBySort(sort: Int): SeasoningEntity?
@Query("SELECT * FROM dm_seasoning WHERE isDel = 0 AND goodsId = :goodsId")
suspend fun getSeasoningByGoodsId(goodsId: Int): SeasoningEntity?
@Query("SELECT * FROM dm_seasoning WHERE isDel = 0 AND goodsId != -1 AND goodsName != '' ORDER BY sort ASC")
fun getAllStream(): Flow<MutableList<SeasoningEntity>>
@Query("SELECT * FROM dm_seasoning WHERE isDel = 0 AND goodsName LIKE '%' || :query || '%'")
suspend fun search(query: String): MutableList<SeasoningEntity>
@Query("DELETE FROM dm_seasoning WHERE isDel = 0 AND goodsId = -1 AND goodsName = ''")
suspend fun deleteEmptySeasoning(): Int
@Query("DELETE FROM dm_seasoning WHERE isDel = 0")
suspend fun deleteBatch(): Int
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertSeasoningList(items: MutableList<SeasoningEntity>): Array<Long>
@Update
suspend fun updateSeasoning(item: SeasoningEntity)
@Insert
suspend fun insertSeasoning(item: SeasoningEntity): Long
//--------------------------------------------------------------------------------------------
}
@@ -0,0 +1,20 @@
//package com.shuwei.dish.match.db.dao
//
//import androidx.room.Dao
//import androidx.room.Query
//import com.shuwei.dish.match.db.BaseDao
//import com.shuwei.dish.match.entity.CookFoodEntity
//
//@Dao
//interface CookFoodDao : BaseDao<CookFoodEntity> {
//
// @Query("SELECT * FROM dm_cook_food WHERE isDel = 0 AND foodId = :foodId AND cookMode = :cookMode")
// suspend fun getCookFoodById(foodId: String, cookMode:Int): CookFoodEntity?
//
// @Query("SELECT * FROM dm_cook_food WHERE isDel = 0 AND cookMode = :cookMode")
// suspend fun getCookFoodList(cookMode:Int): MutableList<CookFoodEntity>?
//
// @Query("SELECT count(1) FROM dm_cook_food WHERE isDel = 0 AND cookMode = :cookMode")
// suspend fun countCookFood(cookMode:Int): Int
//
//}
@@ -0,0 +1,29 @@
//package com.shuwei.dish.match.db.dao
//
//import androidx.room.Dao
//import androidx.room.Query
//import com.shuwei.dish.match.db.BaseDao
//import com.shuwei.dish.match.entity.CookFoodGoodsEntity
//
//@Dao
//interface CookFoodGoodsDao : BaseDao<CookFoodGoodsEntity> {
//
// @Query("SELECT * FROM dm_cook_food_goods WHERE isDel = 0 AND foodId = :foodId")
// suspend fun getCookFoodGoodsList(foodId: String): MutableList<CookFoodGoodsEntity>
//
// @Query("SELECT * FROM dm_cook_food_goods WHERE isDel = 0 AND foodId = :foodId AND materialType = :materialType")
// suspend fun getCookFoodGoodsListByType(foodId: String, materialType:Int): MutableList<CookFoodGoodsEntity>
//
//// @Query(
//// """
//// UPDATE dm_cook_food_goods
//// SET goodsName=:entity.goodsName, foodId=:entity.foodId, relateionType=:entity.relateionType, sort=:entity.sort
//// allEdible=:entity.allEdible, useWeight=:entity.useWeight, isDel=:entity.isDel, createTime=:entity.createTime
//// WHERE isDel = 0
//// AND foodId=:entity.foodId
//// AND goodsId=:goodsId
//// """
//// )
//// fun updateByGoodsId(entity: CookFoodGoodsEntity)
//
//}
@@ -0,0 +1,25 @@
//package com.shuwei.dish.match.db.dao
//
//import androidx.room.Dao
//import androidx.room.Query
//import com.shuwei.dish.match.db.BaseDao
//import com.shuwei.dish.match.entity.SeasoningEntity
//import kotlinx.coroutines.flow.Flow
//
//@Dao
//interface SeasoningDao : BaseDao<SeasoningEntity> {
//
//// @Query("SELECT * FROM dm_seasoning WHERE isDel = 0 AND id = :id")
//// suspend fun getSeasoningById(id: Long): SeasoningEntity?
////
//// @Query("SELECT * FROM dm_seasoning WHERE isDel = 0 ORDER BY sort ASC")
//// fun getAllStream(): Flow<MutableList<SeasoningEntity>>
////
//// @Query("SELECT * FROM dm_seasoning WHERE isDel = 0 AND name LIKE '%' || :query || '%'")
//// suspend fun search(query: String): MutableList<SeasoningEntity>
////
//// @Query("DELETE FROM dm_seasoning WHERE rowid IN " +
//// "(SELECT rowid FROM dm_seasoning LIMIT 1000)")
//// suspend fun deleteBatch(): Int
//
//}
@@ -0,0 +1,191 @@
package com.shuwei.dish.match.dialog
import android.annotation.SuppressLint
import android.os.Handler
import android.os.Looper
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import androidx.core.view.isEmpty
import androidx.core.widget.addTextChangedListener
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.shuwei.dish.match.R
import com.shuwei.dish.match.adapter.GoodsInfoSearchAdapter
import com.shuwei.dish.match.base.BaseActivity
import com.shuwei.dish.match.databinding.DialogBottomSheetBinding
import com.shuwei.dish.match.entity.CookFoodGoodsEntity
import com.shuwei.dish.match.entity.GoodsRecordBean
import com.shuwei.dish.match.http.HttpUtil
import com.shuwei.dish.match.http.UrlConfig
import com.shuwei.dish.match.utils.KeyboardUtil
import com.shuwei.dish.match.utils.ext.addOnActionSearchListener
import com.shuwei.dish.match.utils.ext.toJsonString
import com.shuwei.dish.match.utils.ext.toObject
import com.shuwei.dish.match.utils.ext.toast
/**
* @param goodsType 1-调料,0-食材
*/
class BottomDialog(
private var goodsType: Int = 1
) {
companion object {
const val TAG = "BottomDialog"
}
private var list = mutableListOf<CookFoodGoodsEntity>()
private lateinit var binding: DialogBottomSheetBinding
private lateinit var goodsInfoSearchAdapter: GoodsInfoSearchAdapter
private var goodsName: String? = null
private var activity: BaseActivity? = null
fun show(activity: BaseActivity, callback: (item: CookFoodGoodsEntity) -> Unit) {
this.activity = activity
//直接使用BottomSheetDialog
var dialog: BottomSheetDialog? = null
val inflater = LayoutInflater.from(activity)
binding = DialogBottomSheetBinding.inflate(inflater)
binding.tvSheetName.text = if (goodsType == 1) "调料检索" else "食材检索"
binding.etSheetInput.hint = if (goodsType == 1) "输入调料名称" else "输入食材名称或速记码"
goodsInfoSearchAdapter = GoodsInfoSearchAdapter(list).apply {
setOnItemClickListener { _, _, position ->
list[position].isClicked = true
notifyItemChanged(position)
Handler(Looper.getMainLooper()).postDelayed({
callback(list[position])
dialog?.dismiss()
}, 300)
}
}
binding.recyclerView.run {
layoutManager = GridLayoutManager(activity, 2, GridLayoutManager.VERTICAL, false)
adapter = goodsInfoSearchAdapter
addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrollStateChanged(rv: RecyclerView, newState: Int) {
super.onScrollStateChanged(rv, newState);
}
override fun onScrolled(rv: RecyclerView, dx: Int, dy: Int) {
//解决RecyclerView和smartRefreshLayout滑动冲突问题
super.onScrolled(rv, dx, dy)
val topRowVerticalPosition = if (rv.isEmpty()) 0 else rv.getChildAt(0).top
binding.refreshLayout.setNestedScrollingEnabled(topRowVerticalPosition >= 0)
}
})
}
dialog = BottomSheetDialog(activity, R.style.BottomSheet).apply {
setContentView(binding.root)
setCancelable(true)
behavior.skipCollapsed = false // 跳过折叠状态
// behavior.peekHeight = 880.dp
// window?.setLayout(-1, 880.dp)
show()
setOnDismissListener {
activity.hideStatusBar()
}
}
binding.refreshLayout.setOnRefreshListener {
pageNo = 1
getGoodsList()
}
binding.refreshLayout.setOnLoadMoreListener {
getGoodsList()
}
binding.etSheetInput.addTextChangedListener(
onTextChanged = { text, start, before, count ->
goodsName = text.toString()
})
binding.ivSearch.setOnClickListener { v ->
searchGoods(v)
}
binding.root.setOnClickListener { v ->
KeyboardUtil.hideKeyboard(v.context, v)
}
binding.etSheetInput.let { v ->
v.addOnActionSearchListener {
searchGoods(v)
}
}
binding.refreshLayout.setEnableRefresh(false)
}
private fun searchGoods(v: View) {
if (goodsName.isNullOrBlank()) {
activity?.toast("${binding.etSheetInput.hint}")
return
}
pageNo = 1
getGoodsList()
KeyboardUtil.hideKeyboard(v.context, v)
}
private var pageNo = 1
private val pageSize = 120
/**
*/
@SuppressLint("NotifyDataSetChanged")
private fun getGoodsList() {
// val pathSegmentList = UrlConfig.QUERY_GOODS_LIST.split(delimiters = arrayOf("/"), limit = 1)
val queryParams = mutableMapOf(
"goodsType" to "$goodsType",
"canteenId" to "0",
"pageNo" to "$pageNo",
"pageSize" to "$pageSize"
)
if (goodsName.isNullOrBlank().not()) {
queryParams.put("name", goodsName!!)
}
val sb = StringBuilder().apply {
append(UrlConfig.QUERY_GOODS_LIST)
append("?")
queryParams.forEach { (key, value) ->
append("$key=$value&")
}
}
sb.deleteCharAt(sb.length - 1)
Log.d(TAG, "getGoodsList: url = $sb")
HttpUtil.get(
url = sb.toString(),
doSuccess = {
val json = it.toJsonString()
Log.d(TAG, "getGoodsList: json=$json")
val recordBean: GoodsRecordBean? = json.toObject<GoodsRecordBean>()
if (recordBean == null || recordBean.records.isNullOrEmpty()) {
activity?.toast(if (goodsType == 1) "暂未搜索到调料信息" else "暂未搜索到食材信息")
return@get
}
val records = recordBean.records
if (pageNo == 1) {
list.clear()
}
list.addAll(records!!)
goodsInfoSearchAdapter.notifyDataSetChanged()
if (pageNo == 1) {
binding.refreshLayout.finishRefresh(1200)
} else {
binding.refreshLayout.finishLoadMore(1200)
}
val isLoadMoreEnable = records.size >= pageSize
binding.refreshLayout.setEnableLoadMore(isLoadMoreEnable)
if (isLoadMoreEnable) {
pageNo++
}
}, doFailure = { code, msg ->
activity?.toast(msg)
if (pageNo == 1) {
binding.refreshLayout.finishRefresh(1200)
} else {
binding.refreshLayout.finishLoadMore(1200)
}
})
}
}
@@ -0,0 +1,249 @@
package com.shuwei.dish.match.dialog
import android.annotation.SuppressLint
import android.graphics.Typeface
import android.os.Handler
import android.os.Looper
import android.text.SpannableStringBuilder
import android.text.style.AbsoluteSizeSpan
import android.text.style.ForegroundColorSpan
import android.text.style.LineHeightSpan
import android.text.style.StyleSpan
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import androidx.core.graphics.toColorInt
import androidx.core.view.isEmpty
import androidx.core.widget.addTextChangedListener
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.aithings.Weigher
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.shuwei.dish.match.R
import com.shuwei.dish.match.adapter.SeasoningSearchAdapter
import com.shuwei.dish.match.base.BaseActivity
import com.shuwei.dish.match.databinding.DialogBottomSheet2Binding
import com.shuwei.dish.match.entity.SeasoningEntity
import com.shuwei.dish.match.entity.SeasoningRecordBean
import com.shuwei.dish.match.http.HttpUtil
import com.shuwei.dish.match.http.UrlConfig
import com.shuwei.dish.match.utils.KeyboardUtil
import com.shuwei.dish.match.utils.WeightUtil
import com.shuwei.dish.match.utils.ext.addOnActionSearchListener
import com.shuwei.dish.match.utils.ext.appendText
import com.shuwei.dish.match.utils.ext.buildSpannableString
import com.shuwei.dish.match.utils.ext.dp
import com.shuwei.dish.match.utils.ext.toJsonString
import com.shuwei.dish.match.utils.ext.toObject
import com.shuwei.dish.match.utils.ext.toast
/**
* @param goodsType 1-调料,0-食材
*/
class BottomDialog2(
private var weighIndex: Int,
private var weighAddress: Int,
private var clickName: String? = null
) {
companion object {
const val TAG = "BottomDialog"
}
private val goodsType: Int = 1
private var list = mutableListOf<SeasoningEntity>()
private lateinit var binding: DialogBottomSheet2Binding
private lateinit var searchAdapter: SeasoningSearchAdapter
private var goodsName: String? = null
private var activity: BaseActivity? = null
fun show(activity: BaseActivity, callback: (item: SeasoningEntity) -> Unit) {
this.activity = activity
//直接使用BottomSheetDialog
var dialog: BottomSheetDialog? = null
val inflater = LayoutInflater.from(activity)
binding = DialogBottomSheet2Binding.inflate(inflater)
//binding.tvSheetName.text = if (goodsType == 1) "调料检索" else "食材检索"
binding.etSheetInput.hint = if (goodsType == 1) "输入调料名称" else "输入食材名称或速记码"
searchAdapter = SeasoningSearchAdapter(list).apply {
setOnItemClickListener { _, _, position ->
list[position].isClicked = true
notifyItemChanged(position)
Handler(Looper.getMainLooper()).postDelayed({
callback(list[position].also { it.useWeight = currentWeight })
dialog?.dismiss()
}, 300)
}
}
binding.recyclerView.run {
layoutManager = GridLayoutManager(activity, 2, GridLayoutManager.VERTICAL, false)
adapter = searchAdapter
addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrollStateChanged(rv: RecyclerView, newState: Int) {
super.onScrollStateChanged(rv, newState);
}
override fun onScrolled(rv: RecyclerView, dx: Int, dy: Int) {
//解决RecyclerView和smartRefreshLayout滑动冲突问题
super.onScrolled(rv, dx, dy)
val topRowVerticalPosition = if (rv.isEmpty()) 0 else rv.getChildAt(0).top
binding.refreshLayout.setNestedScrollingEnabled(topRowVerticalPosition >= 0)
}
})
}
dialog = BottomSheetDialog(activity, R.style.BottomSheet).apply {
setContentView(binding.root)
setCancelable(true)
behavior.skipCollapsed = false // 跳过折叠状态
// behavior.peekHeight = 880.dp
// window?.setLayout(-1, 880.dp)
show()
setOnDismissListener {
activity.hideStatusBar()
}
}
binding.refreshLayout.setOnRefreshListener {
pageNo = 1
getGoodsList()
}
binding.refreshLayout.setOnLoadMoreListener {
getGoodsList()
}
binding.etSheetInput.addTextChangedListener(
onTextChanged = { text, start, before, count ->
goodsName = text.toString()
})
binding.ivSearch.setOnClickListener { v ->
searchGoods(v)
}
binding.root.setOnClickListener { v ->
KeyboardUtil.hideKeyboard(v.context, v)
}
binding.etSheetInput.let { v ->
v.addOnActionSearchListener {
searchGoods(v)
}
}
binding.refreshLayout.setEnableRefresh(false)
binding.tvClear.setOnClickListener {
Weigher.tareTwo(weighAddress)
}
WeightUtil.addWeightListener { address, state, weight ->
if (weighAddress == address) {
this.currentWeight = weight
binding.tvWeight.text = getTextSpan(weight)
}
}
binding.tvWeight.text = getTextSpan(0)
if (clickName.isNullOrBlank().not()) {
binding.etSheetInput.setText(clickName!!.trim())
pageNo = 1
getGoodsList()
}
}
private fun searchGoods(v: View) {
if (goodsName.isNullOrBlank()) {
activity?.toast("${binding.etSheetInput.hint}")
return
}
pageNo = 1
getGoodsList()
KeyboardUtil.hideKeyboard(v.context, v)
}
private var currentWeight = 0
private var pageNo = 1
private val pageSize = 120
/**
*/
@SuppressLint("NotifyDataSetChanged")
private fun getGoodsList() {
val queryParams = mutableMapOf(
"goodsType" to "$goodsType",
"canteenId" to "0",
"pageNo" to "$pageNo",
"pageSize" to "$pageSize"
)
if (goodsName.isNullOrBlank().not()) {
queryParams.put("name", goodsName!!)
}
val sb = StringBuilder().apply {
append(UrlConfig.QUERY_GOODS_LIST)
append("?")
queryParams.forEach { (key, value) ->
append("$key=$value&")
}
}
sb.deleteCharAt(sb.length - 1)
Log.d(TAG, "getGoodsList: url = $sb")
HttpUtil.get(
url = sb.toString(),
doSuccess = {
val json = it.toJsonString()
Log.d(TAG, "getGoodsList: json=$json")
val recordBean: SeasoningRecordBean? = json.toObject<SeasoningRecordBean>()
if (recordBean == null || recordBean.records.isNullOrEmpty()) {
activity?.toast(if (goodsType == 1) "暂未搜索到调料信息" else "暂未搜索到食材信息")
return@get
}
val records = recordBean.records
if (pageNo == 1) {
list.clear()
}
list.addAll(records!!)
searchAdapter.notifyDataSetChanged()
if (pageNo == 1) {
binding.refreshLayout.finishRefresh(1200)
} else {
binding.refreshLayout.finishLoadMore(1200)
}
val isLoadMoreEnable = records.size >= pageSize
binding.refreshLayout.setEnableLoadMore(isLoadMoreEnable)
if (isLoadMoreEnable) {
pageNo++
}
}, doFailure = { code, msg ->
activity?.toast(msg)
if (pageNo == 1) {
binding.refreshLayout.finishRefresh(1200)
} else {
binding.refreshLayout.finishLoadMore(1200)
}
})
}
fun getTextSpan(weight: Int): SpannableStringBuilder {
var topWeight = "$weight"
var bottomUnit = ""
if (weight >= 1000) {
topWeight = "${weight / 1000F}"
bottomUnit = "千克"
}
return buildSpannableString {
appendText(
topWeight,
ForegroundColorSpan("#000000".toColorInt()),
StyleSpan(Typeface.BOLD),
AbsoluteSizeSpan(72, true),
LineHeightSpan { text, start, end, spanstartv, v, fm ->
fm.descent += 10.dp // 增加行间距
}
)
append("\n")
appendText(
bottomUnit,
ForegroundColorSpan("#999999".toColorInt()),
AbsoluteSizeSpan(30, true)
)
}
}
}
@@ -0,0 +1,80 @@
package com.shuwei.dish.match.dialog
import android.app.Activity
import android.app.Dialog
import android.graphics.drawable.ColorDrawable
import android.os.Bundle
import android.view.View
import android.view.Window
import android.view.WindowManager
import androidx.annotation.StyleRes
import androidx.fragment.app.FragmentActivity
import com.shuwei.dish.match.databinding.DialogCommonBinding
import com.shuwei.dish.match.utils.ext.dp
import java.lang.ref.WeakReference
open class CommonDialog(
private var activity: FragmentActivity
) : Dialog(activity) {
private lateinit var binding: DialogCommonBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
requestWindowFeature(Window.FEATURE_NO_TITLE)
binding = DialogCommonBinding.inflate(layoutInflater)
setContentView(binding.root)
window?.run {
// decorView.setPadding(0.dp, 0, 0.dp, 0)
attributes = attributes.apply {
width = 708.dp
}
setBackgroundDrawable(ColorDrawable())
setCancelable(false)
// setFlags(
// WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
// WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
// )
}
binding.llContent.run {
removeAllViews()
addView(messageView)
}
addListener()
}
private fun addListener() {
binding.btnLeft.setOnClickListener { onLeftClick?.invoke() }
binding.btnRight.setOnClickListener { onRightClick?.invoke() }
setOnDismissListener { onDismiss?.invoke() }
}
override fun show() {
super.show()
binding.btnLeft.text = leftText
binding.btnRight.text = rightText
}
var messageView: View? = null
var onLeftClick: (() -> Unit)? = null
var onRightClick: (() -> Unit)? = null
var leftText = ""
var rightText = ""
var onDismiss: (() -> Unit)? = null
}
open class SafeDialog(activity: Activity, @StyleRes themeResId: Int) :
Dialog(activity, themeResId) {
private val weakContext = WeakReference(activity)
override fun show() {
weakContext.get()?.let {
if (!it.isFinishing && !it.isDestroyed) super.show()
}
}
}
@@ -0,0 +1,136 @@
//package com.shuwei.dish.match.dialog
//
//import android.app.Activity
//import android.graphics.Color
//import android.os.Bundle
//import android.util.TypedValue
//import android.view.Gravity
//import android.view.WindowManager
//import android.widget.TextView
//import androidx.core.graphics.drawable.toDrawable
//import com.shuwei.dish.match.R
//
//class CustomToast(
// private val activity: Activity,
// private val message: String?,
// private val duration: Int = 2000
//) :
// SafeDialog(
// activity = activity,
// themeResId = R.style.ToastDialogTheme,
// ) {
//
// override fun onCreate(savedInstanceState: Bundle?) {
// super.onCreate(savedInstanceState)
// setContentView(R.layout.custom_toast)
// findViewById<TextView>(R.id.tvMessage)?.text = message
// setCancelable(true)
// if (message.isNullOrBlank() ||
// duration <= 0 ||
// activity.isDestroyed ||
// activity.isFinishing
// ) {
// return
// }
// window?.run {
// setBackgroundDrawable(Color.TRANSPARENT.toDrawable())
// setDimAmount(0f)
// setGravity(Gravity.BOTTOM)
// val metrics = activity.resources.displayMetrics
// val marginPx = TypedValue.applyDimension(
// TypedValue.COMPLEX_UNIT_DIP,
// 120f,
// metrics
// )
// attributes = attributes?.apply {
// y = marginPx.toInt() // 直接设置像素值
// }
// setFlags(
// WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
// WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
// )
// }
// }
//
// override fun show() {
// runCatching {
// super.show()
// window?.decorView?.postDelayed({
// if (message.isNullOrBlank() || activity.isDestroyed || activity.isFinishing) {
// return@postDelayed
// }
// super.dismiss()
// }, duration.toLong())
// }.onFailure {
// it.printStackTrace()
// }
// }
//
// override fun dismiss() {
// runCatching {
// super.dismiss()
// }.onFailure {
// it.printStackTrace()
// }
// }
//
//}
//
////class CustomToast2(
//// private val activity: Activity,
//// private val message: String?,
//// private val duration: Int = 2000
////) :
//// DialogFragment() {
////
//// override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
//// return SafeDialog(
//// activity = activity,
//// themeResId = R.style.ToastDialogTheme,
//// ).apply {
//// setContentView(R.layout.custom_toast)
//// findViewById<TextView>(R.id.tvMessage)?.text = message
//// setCancelable(true)
//// if (message.isNullOrBlank() ||
//// duration <= 0 ||
//// activity.isDestroyed ||
//// activity.isFinishing
//// ) {
//// return@apply
//// }
//// window?.run {
//// setBackgroundDrawable(Color.TRANSPARENT.toDrawable())
//// setDimAmount(0f)
//// setGravity(Gravity.BOTTOM)
//// val metrics = activity.resources.displayMetrics
//// val marginPx = TypedValue.applyDimension(
//// TypedValue.COMPLEX_UNIT_DIP,
//// 120f,
//// metrics
//// )
//// attributes = attributes?.apply {
//// y = marginPx.toInt() // 直接设置像素值
//// }
//// setFlags(
//// WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
//// WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
//// )
//// }
//// }
//// }
////
//// override fun show(manager: FragmentManager, tag: String?) {
//// runCatching {
//// super.show(manager, tag)
//// Handler(Looper.getMainLooper()).postDelayed({
//// if (message.isNullOrBlank() || activity.isDestroyed || activity.isFinishing) {
//// return@postDelayed
//// }
//// dismiss()
//// }, duration.toLong())
//// }.onFailure {
//// it.printStackTrace()
//// }
//// }
////
////}
@@ -0,0 +1,26 @@
//package com.shuwei.dish.match.dialog
//
//import android.content.Context
//import android.view.LayoutInflater
//import androidx.fragment.app.FragmentActivity
//import com.shuwei.dish.match.databinding.LayoutFoodRemindBinding
//
//object DialogTool {
//
// fun load(activity: FragmentActivity, leftText:) {
// val layoutInflater = LayoutInflater.from(activity)
// val remindBinding = LayoutFoodRemindBinding.inflate(layoutInflater)
// CommonDialog(activity).apply {
// messageView = remindBinding.root
// leftText = "返回调整"
// rightText = "确认无误"
// onLeftClick = { dismiss() }
// onRightClick = {
// goToSubmit()
// dismiss()
// }
// onDismiss = { hideStatusBar() }
// }.show()
// }
//
//}
@@ -0,0 +1,140 @@
package com.shuwei.dish.match.dialog
import android.app.Dialog
import android.content.Context
import android.graphics.Color
import android.view.LayoutInflater
import android.view.WindowManager
import androidx.core.graphics.drawable.toDrawable
import com.shuwei.dish.match.R
import com.shuwei.dish.match.databinding.DialogLoadingBinding
object Loading {
private var dialog: LoadingDialog? = null
fun show(context: Context) {
if (dialog?.isShowing == true) {
dialog?.dismiss()
}
if (dialog == null) {
dialog = LoadingDialog(context)
}
dialog?.show()
}
fun dismiss() {
dialog?.let {
if (it.isShowing) {
it.dismiss()
}
}
dialog = null
}
}
class LoadingDialog(
context: Context,
message: String = "加载中……",
private var onDismiss: () -> Unit = {}
) : Dialog(context, R.style.LoadingDialog) {
init {
val binding = DialogLoadingBinding.inflate(LayoutInflater.from(context))
binding.tvMessage.text = message
setContentView(binding.root)
setCancelable(true)
window?.run {
setBackgroundDrawable(Color.TRANSPARENT.toDrawable())
setFlags(
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
);
}
setOnDismissListener {
onDismiss()
}
}
}
//class LoadingDialog3(
// private val activity: Activity,
// private val message: String = "加载中……",
// private val onDismiss: () -> Unit = {}
//) : DialogFragment() {
//
// override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
// return SafeDialog(
// activity = activity,
// themeResId = R.style.ToastDialogTheme,
// ).apply {
// val binding = DialogLoadingBinding.inflate(LayoutInflater.from(context))
// binding.tvMessage.text = message
// setContentView(binding.root)
// setCancelable(true)
// window?.run {
// setBackgroundDrawable(Color.TRANSPARENT.toDrawable())
// setFlags(
// WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
// WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
// );
// }
// setOnDismissListener {
// onDismiss()
// }
// }
// }
//
// override fun dismiss() {
// super.dismiss()
// }
//
// override fun show(manager: FragmentManager, tag: String?) {
// runCatching {
// super.show(manager, tag)
// Handler(Looper.getMainLooper()).postDelayed({
// super.dismiss()
// }, 800)
// }.onFailure {
// it.printStackTrace()
// }
// }
//
//}
//class LoadingDialog(
// private val activity: Activity,
// private val message: String = "加载中……",
// private val onDismiss: () -> Unit = {}
//) : SafeDialog(
// activity = activity,
// themeResId = R.style.ToastDialogTheme,
//) {
//
// override fun onCreate(savedInstanceState: Bundle?) {
// super.onCreate(savedInstanceState)
// val binding = DialogLoadingBinding.inflate(LayoutInflater.from(context))
// binding.tvMessage.text = message
// setContentView(binding.root)
// setCancelable(true)
// window?.run {
// setBackgroundDrawable(Color.TRANSPARENT.toDrawable())
// setFlags(
// WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
// WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
// );
// }
// setOnDismissListener {
// onDismiss()
// }
// }
//
// fun show(manager: FragmentManager, tag: String?) {
// show()
// Handler(Looper.getMainLooper()).postDelayed({
// super.dismiss()
// }, 800)
// }
//
//}
@@ -0,0 +1,26 @@
package com.shuwei.dish.match.entity
import androidx.room.Entity
import androidx.room.Ignore
import androidx.room.PrimaryKey
import com.shuwei.dish.match.db.BaseEntity
import com.shuwei.dish.match.utils.DateTimeUtil
import java.time.LocalDateTime
@Entity(tableName = "dm_cook_food")
data class CookFoodEntity(
@PrimaryKey
var foodId: String,
var foodName: String? = null,
var canteenId: Int? = null,
var foodWeight: Int = 0,
//0-制作模式,1-采样模式,2-品控模式
var cookMode:Int = 0,
var isDel: Int = 0,
var createTime: String = DateTimeUtil.formatDateTime(LocalDateTime.now()),
) : BaseEntity {
@Ignore
var stFoodInfoConstituteList: MutableList<CookFoodGoodsEntity>? = null
constructor() : this(foodId = "") // 必需的空构造
}
@@ -0,0 +1,76 @@
package com.shuwei.dish.match.entity
import androidx.room.Entity
import androidx.room.Ignore
import androidx.room.PrimaryKey
import com.shuwei.dish.match.db.BaseEntity
import com.shuwei.dish.match.utils.DateTimeUtil
import java.io.Serializable
import java.time.LocalDateTime
@Entity(tableName = "dm_cook_food_goods")
class CookFoodGoodsEntity(
@PrimaryKey(autoGenerate = true)
var id: Long = 0,
/**
* 物品id
*/
var goodsId: Int,
/**
* 物品名称
*/
var goodsName: String? = null,
/**
* 菜品id
*/
var foodId: String? = "",
var goodsOrRelationCode: String? = "",
/**
* 调料数据顺序
*/
var sort: Int = 0,
/**
* 食材原材料:1,预制品:2
*/
var relateionType: Int = 0,
/**
* 物品类型:1主料2辅料3调料
*/
var materialType: Int = 0,
/**
* 物品 是否全部可食:1-全部可食,0-部分可食,默认全部
*/
var allEdible: Int = 1,
/**
* 物品 用料重量
*/
var useWeight: Int? = 0,
var popularName: String? = "",
var canteenId: String? = "",
var relateionType_dictText: String? = "",
var isDel: Int = 0,
var createTime: String = DateTimeUtil.formatDateTime(LocalDateTime.now())
) : BaseEntity, Serializable {
constructor() : this(goodsId = -1) // 必需的空构造,
@Ignore
var isSetFinished: Boolean = false
@Ignore
var isItemClicked: Boolean = false
@Ignore
var isSamplingPage: Boolean = false
@Ignore
var isNewDishType: Boolean = false
@Ignore
var isClicked: Boolean = false
}
@@ -0,0 +1,58 @@
package com.shuwei.dish.match.entity
data class HomeModeBean(
var modeName: String = "",
var modeDesc: String = "",
var modeIconId: Int = 0,
var isLocked: Boolean = false,
var onClick: (() -> Unit)? = null
)
data class FoodRecordBean(
var records: MutableList<FoodRecord>? = null,
var total: Int,
var size: Int,
var current: Int,
var page: Int
)
data class GoodsRecordBean(
var records: MutableList<CookFoodGoodsEntity>? = null,
var total: Int,
var size: Int,
var current: Int,
var page: Int
)
data class SeasoningRecordBean(
var records: MutableList<SeasoningEntity>? = null,
var total: Int,
var size: Int,
var current: Int,
var page: Int
)
//data class DishDetailEntity(
// var foodId: String? = null,
// var foodWeight: Double? = null,
// var foodRealWeight: Double? = null,
// var voList: List<DishPartEntity>? = null
//)
//data class DishPartEntity(
// var foodId: String? = null,
// var foodName: String? = null,
// var foodWeight: Int? = null,
// var useWeight: Int? = null,
// var useRealWeight: Int? = null,
// var goodsId: Int? = null,
// var goodsName: String? = null,
// var materialType: Int? = null,
// var isSetFinished: Boolean = false,
// var isItemClicked: Boolean = false,
// var isSamplingPage: Boolean = false
//)
@@ -0,0 +1,25 @@
package com.shuwei.dish.match.entity
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
import com.shuwei.dish.match.db.BaseEntity
//@Entity(tableName = "dm_dish")
//data class DishEntity (
// /**
// * 菜品id
// */
// @PrimaryKey var id: Long,
// /**
// * 菜品名称
// */
// var name: String? = "",
// /**
// * 菜品重量
// */
// var weight: Int? = 0,
//
// var sort: Int = 0,
// @ColumnInfo(name = "create_time") val createTime: Long = System.currentTimeMillis()
//): BaseEntity
@@ -0,0 +1,17 @@
package com.shuwei.dish.match.entity
import java.io.Serializable
data class FoodRecord(
var foodId: String? = null,
var foodName: String? = null,
var foodWeight: Int? = null,
var totalWeight: Int? = null,
var count: Int? = null,
var isCooking: Boolean = false,
//0-制作模式,1-采样模式,2-品控模式
var cookMode: Int = 0,
var sort: Int = 0
) : Serializable
@@ -0,0 +1,38 @@
//package com.shuwei.dish.match.entity
//
//import androidx.room.Ignore
//import androidx.room.PrimaryKey
//import com.shuwei.dish.match.db.BaseEntity
//
//data class GoodsInfoEntity(
// @PrimaryKey(autoGenerate = true) var id: Long = 0,
// var goodsId: Int,
// var goodsName: String? = "",
// var popularName: String? = "",
// var canteenId: String? = "",
// var goodsOrRelationCode: String? = "",
// var relateionType: Int? = -1,
// var relateionType_dictText: String? = "",
//
// var sort: Int = 0,
//
// var swMaterBaseMaterial: String? = "",
// var preMaterClass: String? = "",
// var preUseWeight: Int? = 0,
// var preWeight: Int? = 0,
// var oil: String? = "",
// var sugar: String? = "",
// /**
// * isDel表示数据是否已删除,1-已删除,为无效数据,0-正常使用,有效数据
// */
// var isDel: Int = 0,
// val createTime: Long = System.currentTimeMillis()
//) : BaseEntity {
// @Ignore
// var pageType: Int = 0
//
// @Ignore
// var isClicked: Boolean = false
//
// constructor() : this(id = -1, goodsId = -1) // 必需的空构造
//}
@@ -0,0 +1,69 @@
package com.shuwei.dish.match.entity
import androidx.room.Entity
import androidx.room.Ignore
import androidx.room.PrimaryKey
import com.shuwei.dish.match.db.BaseEntity
import com.shuwei.dish.match.utils.DateTimeUtil
import java.time.LocalDateTime
@Entity(tableName = "dm_seasoning")
data class SeasoningEntity(
@PrimaryKey(autoGenerate = true)
var id: Long = 0,
/**
* 物品id
*/
var goodsId: Int,
/**
* 物品名称
*/
var goodsName: String? = null,
/**
* 菜品id
*/
var foodId: String? = "",
var goodsOrRelationCode: String? = "",
/**
* 食材原材料:1,预制品:2
*/
var relateionType: Int = 0,
/**
* 物品类型:1主料2辅料3调料
*/
var materialType: Int = 3,
/**
* 物品 是否全部可食:1-全部可食,0-部分可食,默认全部
*/
var allEdible: Int = 1,
/**
* 物品 用料重量
*/
var useWeight: Int? = 0,
var popularName: String? = "",
var canteenId: String? = "",
var relateionType_dictText: String? = "",
var sort: Int = 9999,
/**
* isDel表示数据是否已删除,1-已删除,为无效数据,0-正常使用,有效数据
*/
var isDel: Int = 0,
var createTime: String = DateTimeUtil.formatDateTime(LocalDateTime.now())
) : BaseEntity {
@Ignore
var pageType: Int = 0
@Ignore
var isClicked: Boolean = false
constructor() : this(goodsId = -1) // 必需的空构造
}
@@ -0,0 +1,70 @@
package com.shuwei.dish.match.http
import android.annotation.SuppressLint
import android.util.Log
import okhttp3.Call
import okhttp3.Interceptor
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.Response
import java.util.concurrent.TimeUnit
import javax.net.ssl.*
import java.security.SecureRandom
import java.security.cert.X509Certificate
class HttpClient private constructor() {
private val client: OkHttpClient by lazy {
OkHttpClient.Builder()
.apply {
connectTimeout(15, TimeUnit.SECONDS)
readTimeout(30, TimeUnit.SECONDS)
writeTimeout(15, TimeUnit.SECONDS)
sslSocketFactory(createSSLSocketFactory(), TrustAllCerts())
hostnameVerifier { _, _ -> true }
//if (BuildConfig.Debug) {
addInterceptor(LoggingInterceptor())
// }
}
.build()
}
companion object {
val instance by lazy { HttpClient() }
}
fun newCall(request: Request): Call = client.newCall(request)
inner class LoggingInterceptor : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
val request = chain.request()
// 打印请求日志
Log.d("OkHttp", "--> ${request.method} ${request.url}")
val response = chain.proceed(request)
// 打印响应日志
Log.d("OkHttp", "<-- ${response.code} ${response.request.url}")
return response
}
}
// 信任所有证书的TrustManager实现
@SuppressLint("CustomX509TrustManager")
class TrustAllCerts : X509TrustManager {
@SuppressLint("TrustAllX509TrustManager")
override fun checkClientTrusted(chain: Array<X509Certificate>, authType: String) {}
@SuppressLint("TrustAllX509TrustManager")
override fun checkServerTrusted(chain: Array<X509Certificate>, authType: String) {}
override fun getAcceptedIssuers(): Array<X509Certificate> = arrayOf()
}
// 创建信任所有证书的SSLSocketFactory
fun createSSLSocketFactory(): SSLSocketFactory {
val sslContext = SSLContext.getInstance("TLS").apply {
init(null, arrayOf(TrustAllCerts()), SecureRandom())
}
return sslContext.socketFactory
}
}
@@ -0,0 +1,166 @@
package com.shuwei.dish.match.http
import android.os.Handler
import android.os.Looper
import android.util.Log
import com.google.gson.reflect.TypeToken
import com.shuwei.dish.match.base.BaseApp
import com.shuwei.dish.match.base.BaseReq
import com.shuwei.dish.match.http.HttpUtil.runMainThread
import com.shuwei.dish.match.utils.ext.put
import com.shuwei.dish.match.utils.ext.toType
import com.shuwei.dish.match.utils.ext.toast
import okhttp3.Call
import okhttp3.Callback
import okhttp3.HttpUrl
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.Request
import okhttp3.RequestBody.Companion.toRequestBody
import okhttp3.Response
import java.io.IOException
object HttpUtil {
fun runMainThread(action: () -> Unit) {
Handler(Looper.getMainLooper()).post {
action()
}
}
// GET请求(HTTPS
fun get(
url: String,
doSuccess: (data: Any) -> Unit,
doFailure: (code: Int?, msg: String?) -> Unit
) {
val token = getToken()
val request = Request.Builder()
.url(url)
.apply {
if (token.isNotBlank()) {
addHeader("X-Access-Token", token)
}
}
.get()
.build()
HttpClient.instance.newCall(request).enqueue(CallbackImpl(doSuccess, doFailure))
}
fun get(
isHttps: Boolean = false,
host: String = "vip.shuziweidao.com",
pathSegmentList: List<String>,
queryParams: Map<String, String>,
doSuccess: (data: Any) -> Unit,
doFailure: (code: Int?, msg: String?) -> Unit
) {
val token = getToken()
val url = HttpUrl.Builder()
.scheme(if (isHttps) "https" else "http")
.host(host)
.apply {
pathSegmentList.forEach { addPathSegment(it) }
queryParams.forEach { (key, value) -> addQueryParameter(key, value) }
}
.build()
val request = Request.Builder()
.url(url)
.apply {
if (token.isNotBlank()) {
addHeader("Authorization", token)
}
}
.get()
.build()
HttpClient.instance.newCall(request).enqueue(CallbackImpl(doSuccess, doFailure))
}
// POST表单(HTTPS
// fun postForm(url: String, params: Map<String, String>, callback: Callback) {
// val formBody = FormBody.Builder().apply {
// params.forEach { (k, v) -> add(k, v) }
// }.build()
//
// Request.Builder()
// .url(url)
// .post(formBody)
// .build().let { HttpClient.instance.newCall(it).enqueue(callback) }
// }
// POST JSONHTTPS
fun postJson(
url: String,
json: String,
doSuccess: (data: Any) -> Unit,
doFailure: (code: Int?, msg: String?) -> Unit
) {
val body = json
.toRequestBody("application/json; charset=utf-8".toMediaTypeOrNull())
val token = getToken()
Request.Builder()
.url(url)
.apply {
if (token.isNotBlank()) {
addHeader("X-Access-Token", token)
}
}
.post(body)
.build()
.let { HttpClient.instance.newCall(it).enqueue(CallbackImpl(doSuccess, doFailure)) }
}
}
class CallbackImpl(
private val doSuccess: (data: Any) -> Unit,
private val doFailure: (code: Int?, msg: String?) -> Unit
) :
Callback {
override fun onFailure(call: Call, e: IOException) {
runMainThread {
e.printStackTrace()
doFailure(-1, "服务异常,${e.message}")
}
}
override fun onResponse(call: Call, response: Response) {
val respData = response.body?.string()
runMainThread {
Log.d("HttpUtil", respData ?: "")
runCatching {
val typeToken = object : TypeToken<BaseReq<Any>>() {}
val baseReq = respData?.toType<BaseReq<Any>>(typeToken = typeToken)
if (baseReq == null) {
doFailure(-1, "查询数据失败")
return@runCatching
}
if (baseReq.code != 200) {
doFailure(baseReq.code, baseReq.message)
if (baseReq.code == 500 || baseReq.code == 401) {
getAppToken()
}
return@runCatching
}
doSuccess(baseReq.result ?: "")
}.onFailure {
it.printStackTrace()
doFailure(-1, "解析异常")
}
}
}
}
private fun getToken() = BaseApp.instance?.token ?:""
//BaseApp.getSharedPref()?.getString("token", "") ?: ""
private fun getAppToken() {
val url = "${UrlConfig.GET_TOKEN}?qrcodeId=${BaseApp.instance?.androidId}"
// Log.d(TAG, "getToken: url = $url")
HttpUtil.get(url = url, doSuccess = {
BaseApp.getSharedPref()?.put("token" to it)
BaseApp.instance?.token = it.toString()
}) { code, msg ->
//toast(msg)
}
}
@@ -0,0 +1,23 @@
package com.shuwei.dish.match.http
object UrlConfig {
// const val BASE_URL = "http://vip.shuziweidao.com/shuwei-zhct"
// const val DISH_DETAIL = "$BASE_URL/scales/goodsUseList?foodId={foodId}&foodWeight={foodWeight}"
// const val DISH_LIST = "$BASE_URL/scales/getRestInfoFoods?eaId=99&type=0&foodName"
const val BASE_URL = "http://192.168.1.207:9102"
// const val DISH_LIST = "$BASE_URL/scales/getRestInfoFoods?eaId=99&type=0&foodName"
const val DISH_DETAIL = "$BASE_URL/food/stFoodInfoMatching/queryById"
// "$BASE_URL/scales/generateToken?deviceId=1111111111111111111111111111"
const val GET_TOKEN = "$BASE_URL/restaurant/equipment/stEquipment/getEquipmentToken"
const val SUBMIT_DISH = "$BASE_URL/food/stFoodInfoMatching/saveoredit"
const val QUERY_GOODS_LIST = "$BASE_URL/food/stFoodInfoMatching/queryGoodsInfoList"
const val QUERY_FOOD_LIST = "$BASE_URL/food/stFoodInfoMatching/list"
const val SAMPLING_LIST = "$BASE_URL/food/stFoodInfoMatching/queryHistorical/goodsInfoList"
}
@@ -0,0 +1,265 @@
package com.shuwei.dish.match.ui
import android.graphics.Typeface
import android.os.Bundle
import android.text.SpannableStringBuilder
import android.text.style.AbsoluteSizeSpan
import android.text.style.ForegroundColorSpan
import android.text.style.LineHeightSpan
import android.text.style.StyleSpan
import android.util.Log
import androidx.core.graphics.toColorInt
import androidx.lifecycle.ViewModelProvider
import com.shuwei.dish.match.R
import com.shuwei.dish.match.adapter.SeasoningCellTool
import com.shuwei.dish.match.adapter.TextCellAdapter
import com.shuwei.dish.match.base.BaseActivity
import com.shuwei.dish.match.base.BaseApp
import com.shuwei.dish.match.databinding.ActivityDeviceSettingBinding
import com.shuwei.dish.match.db.AppRepository
import com.shuwei.dish.match.entity.SeasoningEntity
import com.shuwei.dish.match.utils.ext.appendText
import com.shuwei.dish.match.utils.ext.buildSpannableString
import com.shuwei.dish.match.utils.ext.dp
import com.shuwei.dish.match.utils.ext.startActivity
import com.shuwei.dish.match.utils.ext.toJsonString
import com.shuwei.dish.match.utils.ext.toast
import com.shuwei.dish.match.utils.ext.visible
import com.shuwei.dish.match.viewmodel.AppViewModel
import com.shuwei.dish.match.viewmodel.factory.AppFactory
class DeviceSettingActivity : BaseActivity() {
companion object {
const val TAG = "DeviceSettingActivity"
const val COOK_MODE = "cookMode"
val modeList = listOf<ModeBean>(
ModeBean("制作模式", "菜品快速制作,记录熟重"),
ModeBean("采样模式", "菜品快速制作,记录熟重"),
ModeBean("品控模式", "菜品快速制作,记录熟重")
)
}
data class ModeBean(
var modeName: String,
var modeDesc: String
)
private lateinit var binding: ActivityDeviceSettingBinding
private lateinit var appViewModel: AppViewModel
// public lateinit var list: MutableList<SeasoningEntity>
private var cookMode: Int = 0
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityDeviceSettingBinding.inflate(layoutInflater)
setContentView(binding.root)
cookMode = intent.getIntExtra(COOK_MODE, 0)
initViewModel()
setHeaderBackground()
setTitleBar(titleBarAction = {
it.visible()
}, titleAction = {
it.text = "设备配置"
})
addListener()
loadQualitySpan(isEnable = false)
when (cookMode) {
1 -> {
binding.rbModeCook.isChecked = true
binding.rbModeSampling.isChecked = false
loadCookSpan(isClicked = true)
loadSamplingSpan()
}
2 -> {
binding.rbModeCook.isChecked = false
binding.rbModeSampling.isChecked = true
loadCookSpan()
loadSamplingSpan(isClicked = true)
}
else -> 0
}
binding.rbModeCook.setOnClickListener {
binding.rbModeCook.isChecked = true
binding.rbModeSampling.isChecked = false
loadCookSpan(isClicked = true)
loadSamplingSpan()
startActivity<SelectDishActivity> { }
finish()
}
binding.rbModeSampling.setOnClickListener {
binding.rbModeCook.isChecked = false
binding.rbModeSampling.isChecked = true
loadCookSpan()
loadSamplingSpan(isClicked = true)
startActivity<SamplingListActivity> { }
finish()
}
}
private fun initViewModel() {
val db = BaseApp.instance!!.database
val factory =
AppFactory(AppRepository(db.appDao()))
appViewModel =
ViewModelProvider(this, factory)[AppViewModel::class.java]
}
override fun onResume() {
super.onResume()
appViewModel.loadSeasoning { it ->
SeasoningCellTool.loadData(
activity = this,
initList = it,
recyclerView = binding.rvSeasoning,
tvCell = binding.tvRightBottomCell,
pageType = 1
)
// (binding.rvSeasoning.adapter as TextCellAdapter).let { adapter ->
// list = adapter.list
// }
}
}
// private var isCookMode: Boolean = true
private fun addListener() {
// binding.modeRadioGroup.setOnCheckedChangeListener { _, checkedId ->
// when (checkedId) {
// R.id.rbModeCook -> {
// isCookMode = true
// loadCookSpan(isClicked = true)
// loadSamplingSpan()
// loadQualitySpan(isEnable = false)
// }
//
// R.id.rbModeSampling -> {
// isCookMode = false
// loadCookSpan()
// loadSamplingSpan(isClicked = true)
// loadQualitySpan(isEnable = false)
// }
//
// R.id.rbModeQuality -> {
// loadCookSpan()
// loadSamplingSpan()
// loadQualitySpan(isEnable = false)
// }
// }
// }
// binding.btnCancel.setOnClickListener { finish() }
// binding.btnConfirm.setOnClickListener { confirmSetting() }
}
private fun confirmSetting() {
// runCatching {
// showLoading()
//// list.forEachIndexed { index, entity ->
//// entity.sort = index
//// }
//// val list2 = mutableListOf<SeasoningEntity>()
//// list2.addAll(list)
//// val array = arrayOf(10, 11, 13)
//// list.forEachIndexed { index, entity ->
//// if (entity.sort == 14 && array.contains(index)) {
//// list2.remove(entity)
//// }
//// }
// Log.d(TAG, "addListener->Click: ${list.toJsonString()}")
//
// appViewModel.addSeasoning(list) {
// dismissLoading()
// if (isCookMode) {
// startActivity<SelectDishActivity> { }
// } else {
// startActivity<SamplingListActivity> { }
// }
//// val activityStack = ActivityManager.getActivityStack()
//// activityStack.forEach {
//// if (it !is SelectDishActivity && it !is SamplingListActivity) {
//// it.finish()
//// }
//// }
// }
// }.onFailure {
// it.printStackTrace()
// toast("数据提交失败")
// }
}
private fun loadQualitySpan(isClicked: Boolean = false, isEnable: Boolean = true) {
binding.rbModeQuality.text =
getModeTextSpan(
topText = modeList[2].modeName,
bottomText = modeList[2].modeDesc,
topColor = if (isEnable) if (isClicked) "#00BC71" else "#000000" else "#B4B4B4",
bottomColor = if (isEnable) "#8B8B8B" else "#B4B4B4"
)
}
private fun loadSamplingSpan(isClicked: Boolean = false, isEnable: Boolean = true) {
binding.rbModeSampling.text =
getModeTextSpan(
topText = modeList[1].modeName,
bottomText = modeList[1].modeDesc,
topColor = if (isEnable) if (isClicked) "#00BC71" else "#000000" else "#B4B4B4",
bottomColor = if (isEnable) "#8B8B8B" else "#B4B4B4"
)
}
private fun loadCookSpan(isClicked: Boolean = false, isEnable: Boolean = true) {
binding.rbModeCook.text =
getModeTextSpan(
topText = modeList[0].modeName,
bottomText = modeList[0].modeDesc,
topColor = if (isEnable) if (isClicked) "#00BC71" else "#000000" else "#B4B4B4",
bottomColor = if (isEnable) "#8B8B8B" else "#B4B4B4"
)
}
private fun getModeTextSpan(
topText: String,
topColor: String,
bottomText: String,
bottomColor: String
): SpannableStringBuilder {
return buildSpannableString {
appendText(
topText,
ForegroundColorSpan(topColor.toColorInt()),
StyleSpan(Typeface.BOLD),
AbsoluteSizeSpan(36, true),
LineHeightSpan { text, start, end, spanstartv, v, fm ->
fm.descent += 10.dp // 增加行间距
}
)
append("\n")
appendText(
bottomText,
ForegroundColorSpan(bottomColor.toColorInt()),
AbsoluteSizeSpan(26, true)
)
}
}
fun saveSeasoning(entity: SeasoningEntity) {
appViewModel.saveSeasoning(entity){
toast("保存成功")
}
}
}
@@ -0,0 +1,131 @@
package com.shuwei.dish.match.ui
import android.annotation.SuppressLint
import android.os.Bundle
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import com.shuwei.dish.match.R
import com.shuwei.dish.match.base.BaseActivity
import com.shuwei.dish.match.base.BaseApp
import com.shuwei.dish.match.databinding.ActivitySamplingBinding
import com.shuwei.dish.match.databinding.LayoutFoodRemindBinding
import com.shuwei.dish.match.db.AppRepository
import com.shuwei.dish.match.dialog.CommonDialog
import com.shuwei.dish.match.entity.CookFoodEntity
import com.shuwei.dish.match.ui.fragment.DishSamplingFragment
import com.shuwei.dish.match.utils.ext.gone
import com.shuwei.dish.match.utils.ext.startActivity
import com.shuwei.dish.match.utils.ext.visible
import com.shuwei.dish.match.viewmodel.AppViewModel
import com.shuwei.dish.match.viewmodel.factory.AppFactory
class DishSamplingActivity : BaseActivity() {
private lateinit var binding: ActivitySamplingBinding
var foodName: String? = null
companion object {
public const val FOOD_NAME = "foodName"
public const val PAGE_FROM = "pageFrom"
public const val HOME = "home"
}
private var pageFrom: String? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivitySamplingBinding.inflate(layoutInflater)
setContentView(binding.root)
pageFrom = intent.getStringExtra(PAGE_FROM)
setTitleBar()
setHeaderBackground()
initViewModel()
loadDishSamplingPage()
foodName = intent.getStringExtra(FOOD_NAME)
}
private fun setTitleBar() {
setTitleBar(titleBarAction = {
it.visible()
}, titleAction = {
it.text = "菜品采集"
}, rightIconActon = {
it.gone()
it.setImageResource(R.drawable.ic_setting)
it.setOnClickListener {
//startActivity<DeviceSettingActivity>()
}
}, backAction = {
it.visible()
it.setOnClickListener {
onBackPressed()
}
})
}
private var dishSamplingFragment: DishSamplingFragment? = null
private fun loadDishSamplingPage() {
if (dishSamplingFragment == null) {
dishSamplingFragment = DishSamplingFragment()
}
dishSamplingFragment?.let {
loadFragment(it)
}
}
private fun loadFragment(fragment: Fragment) {
supportFragmentManager.beginTransaction().apply {
replace(R.id.flContainer, fragment)
commit()
}
}
private lateinit var appViewModel: AppViewModel
private fun initViewModel() {
val db = BaseApp.instance!!.database
val factory =
AppFactory(AppRepository(db.appDao()))
appViewModel =
ViewModelProvider(this, factory)[AppViewModel::class.java]
}
fun getCookFoodList(action: (MutableList<CookFoodEntity>?) -> Unit) {
appViewModel.getCookFoodList(cookMode = 1) { action(it) }
}
@Suppress("DEPRECATION")
@SuppressLint("GestureBackNavigation")
@Deprecated("Deprecated in Java")
override fun onBackPressed() {
val list = dishSamplingFragment?.list
if (list.isNullOrEmpty().not()) {
//说明有新增的食材
saveDataRemindDialog()
return
}
if (pageFrom == HOME) {
startActivity<SamplingListActivity>()
}
super.onBackPressed()
}
private fun saveDataRemindDialog() {
val remindBinding = LayoutFoodRemindBinding.inflate(layoutInflater)
remindBinding.tvDialogTitle.text = "温馨提示"
remindBinding.tvDialogContent.text = "您好,当前页面存在未保存的数据,确认返回吗?"
CommonDialog(this).apply {
messageView = remindBinding.root
leftText = "取消"
rightText = "确认"
onLeftClick = { dismiss() }
onRightClick = {
dismiss()
finish()
}
onDismiss = { hideStatusBar() }
}.show()
}
}
@@ -0,0 +1,215 @@
package com.shuwei.dish.match.ui
import android.annotation.SuppressLint
import android.content.Intent
import android.os.Bundle
import android.view.LayoutInflater
import androidx.recyclerview.widget.LinearLayoutManager
import com.shuwei.dish.match.R
import com.shuwei.dish.match.adapter.FoodRecordAdapter
import com.shuwei.dish.match.base.BaseActivity
import com.shuwei.dish.match.databinding.ActivityFoodSearchBinding
import com.shuwei.dish.match.databinding.LayoutEmptyViewBinding
import com.shuwei.dish.match.entity.FoodRecord
import com.shuwei.dish.match.entity.FoodRecordBean
import com.shuwei.dish.match.http.HttpUtil
import com.shuwei.dish.match.http.UrlConfig
import com.shuwei.dish.match.utils.KeyboardUtil
import com.shuwei.dish.match.utils.ext.addOnActionSearchListener
import com.shuwei.dish.match.utils.ext.gone
import com.shuwei.dish.match.utils.ext.startActivity
import com.shuwei.dish.match.utils.ext.toJsonString
import com.shuwei.dish.match.utils.ext.toObject
import com.shuwei.dish.match.utils.ext.toast
import com.shuwei.dish.match.utils.ext.visible
import java.io.Serializable
class FoodSearchActivity : BaseActivity() {
companion object {
private const val TAG = "FoodSearchActivity"
const val PAGE_TYPE = "pageType"
const val FOOD_ID = "foodId"
const val FOOD_NAME = "foodName"
}
private lateinit var binding: ActivityFoodSearchBinding
private var list: MutableList<FoodRecord> = mutableListOf()
private var pageType = 0
private val recordAdapter by lazy {
FoodRecordAdapter(list).apply {
isStateViewEnable = true
setOnItemClickListener { adapter, view, position ->
if (pageType == 1) {
startActivity<PrepareCookActivity> {
putExtra(PrepareCookActivity.FOOD_ITEM, list[position] as Serializable)
}
return@setOnItemClickListener
}
setResult(RESULT_OK, Intent().apply {
putExtra(FOOD_ID, list[position].foodId)
putExtra(FOOD_NAME, list[position].foodName)
})
finish()
}
}
}
private var foodName: String? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityFoodSearchBinding.inflate(layoutInflater)
setContentView(binding.root)
pageType = intent.getIntExtra(PAGE_TYPE, 0)
setHeaderBackground()
foodName = intent.getStringExtra(FOOD_NAME)
binding.etInputDish.setText(foodName)
setTitleBar(titleBarAction = {
it.visible()
}, titleAction = {
it.text = "菜品搜索"
}, rightIconActon = {
it.gone()
it.setImageResource(R.drawable.ic_setting)
it.setOnClickListener {
//startActivity<DeviceSettingActivity>()
}
})
binding.rvDishSearchList.run {
layoutManager =
LinearLayoutManager(this@FoodSearchActivity, LinearLayoutManager.VERTICAL, false)
adapter = recordAdapter
}
addViewListener()
}
private fun addViewListener() {
binding.ivDishSearch.setOnClickListener { v ->
pageNo = 1
getInputAndSearch()
KeyboardUtil.hideKeyboard(v.context, v)
}
binding.refreshLayout.setEnableRefresh(true)
binding.refreshLayout.setEnableLoadMore(false)
binding.refreshLayout.setOnRefreshListener {
pageNo = 1
getInputAndSearch()
}
binding.refreshLayout.setOnLoadMoreListener {
getInputAndSearch()
}
if (foodName.isNullOrBlank().not()) {
pageNo = 1
queryListInfo(foodName!!)
}
binding.root.setOnClickListener { v ->
KeyboardUtil.hideKeyboard(v.context, v)
}
binding.etInputDish.let { v ->
v.addOnActionSearchListener {
pageNo = 1
getInputAndSearch()
KeyboardUtil.hideKeyboard(v.context, v)
}
}
}
private fun getInputAndSearch() {
val input = binding.etInputDish.text.toString().trim()
if (input.isBlank()) {
toast("请输入菜品名称")
binding.refreshLayout.finishRefresh()
return
}
queryListInfo(input)
}
private var pageNo = 1
private var pageSize = 100
@SuppressLint("NotifyDataSetChanged")
private fun queryListInfo(input: String) {
showLoading()
val map = mapOf(
"foodName" to input.trim(),
"pageNo" to "$pageNo",
"pageSize" to "$pageSize",
"canteenId" to "0"
)
val sb = StringBuilder(UrlConfig.QUERY_FOOD_LIST).apply {
append("?")
map.forEach { (key, value) -> append("$key=$value&") }
}
sb.deleteCharAt(sb.length - 1)
HttpUtil.get(
url = sb.toString(),
doSuccess = {
delayDismissLoading()
finishRefresh()
binding.refreshLayout.run {
setEnableRefresh(true)
}
val json = it.toJsonString()
val recordBean: FoodRecordBean? = json.toObject<FoodRecordBean>()
if (recordBean == null || recordBean.records.isNullOrEmpty()) {
// toast("暂未搜索到相关菜品信息")
if (pageNo == 1) {
loadEmptyView()
}
return@get
}
val records = recordBean.records
if (pageNo == 1) {
list.clear()
}
list.addAll(records!!)
recordAdapter.notifyDataSetChanged()
val isLoadMoreEnable = records.size >= pageSize
binding.refreshLayout.setEnableLoadMore(isLoadMoreEnable)
if (isLoadMoreEnable) {
pageNo++
}
},
doFailure = { code, msg ->
binding.refreshLayout.run {
setEnableRefresh(true)
}
toast(msg)
delayDismissLoading()
finishRefresh()
if (pageNo == 1) {
loadEmptyView()
}
}
)
}
private fun finishRefresh() {
if (pageNo == 1) {
binding.refreshLayout.finishRefresh(1200)
} else {
binding.refreshLayout.finishLoadMore(1200)
}
}
private var emptyViewBinding: LayoutEmptyViewBinding? = null
@SuppressLint("NotifyDataSetChanged")
private fun loadEmptyView() {
list.clear()
recordAdapter.notifyDataSetChanged()
if (emptyViewBinding == null) {
emptyViewBinding = LayoutEmptyViewBinding.inflate(LayoutInflater.from(this), binding.rvDishSearchList, false)
}
emptyViewBinding!!.tvContent.text = "暂无数据"
emptyViewBinding!!.tvSubContent.text = "可以尝试换个名称重新搜索"
recordAdapter.stateView = emptyViewBinding!!.root
binding.refreshLayout.run {
setEnableRefresh(false)
setEnableLoadMore(false)
}
}
}
@@ -0,0 +1,156 @@
package com.shuwei.dish.match.ui
import android.annotation.SuppressLint
import android.os.Bundle
import android.provider.Settings
import android.util.Log
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.LinearLayoutManager
import com.aithings.Weigher
import com.shuwei.dish.match.R
import com.shuwei.dish.match.adapter.HomeModeAdapter
import com.shuwei.dish.match.base.BaseActivity
import com.shuwei.dish.match.base.BaseApp
import com.shuwei.dish.match.databinding.ActivityHomeBinding
import com.shuwei.dish.match.db.AppRepository
import com.shuwei.dish.match.entity.HomeModeBean
import com.shuwei.dish.match.http.HttpUtil
import com.shuwei.dish.match.http.UrlConfig
import com.shuwei.dish.match.utils.WeightUtil
import com.shuwei.dish.match.utils.ext.put
import com.shuwei.dish.match.utils.ext.startActivity
import com.shuwei.dish.match.utils.ext.toast
import com.shuwei.dish.match.viewmodel.AppViewModel
import com.shuwei.dish.match.viewmodel.factory.AppFactory
class HomeActivity : BaseActivity() {
companion object {
const val TAG = "HomeActivity"
}
private lateinit var binding: ActivityHomeBinding
private var connect: Boolean = false
@SuppressLint("HardwareIds")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
statusBarDarkFont(enable = true)
initViewModel()
// 获取 ANDROID_ID
BaseApp.instance?.androidId =
Settings.Secure.getString(contentResolver, Settings.Secure.ANDROID_ID)
binding = ActivityHomeBinding.inflate(layoutInflater)
setContentView(binding.root)
setHeaderBackground(isHomePage = true)
initRecyclerView()
getAppToken()
WeightUtil.connect { connect ->
this.connect = connect
}
Weigher.init()
Weigher.getWeight()
Weigher.startContinuousRead()
// binding.tvTopText.setOnClickListener {
// startActivity<SamplingListActivity>()
// }
// appViewModel.deleteEmptySeasoning()
// appViewModel.deleteCookFoodAndGoods(0,"") {}
// appViewModel.getCookFoodGoodsList("") {goodsList->
// goodsList.forEach {
// it.foodId = "1594990392084779010"
// appViewModel.updateGoods(it)
// }
// }
// appViewModel.deleteAll()
}
private fun initRecyclerView() {
initModeList()
binding.rvModeList.run {
layoutManager =
LinearLayoutManager(this@HomeActivity, LinearLayoutManager.VERTICAL, false)
adapter = modeAdapter
}
}
private val modeList = mutableListOf<HomeModeBean>()
private val modeAdapter by lazy {
HomeModeAdapter(modeList).apply {
addOnItemChildClickListener(R.id.layoutCard) { adapter, view, position ->
modeList[position].onClick?.invoke()
}
}
}
private fun initModeList() {
modeList.add(
HomeModeBean(
modeName = "制作模式",
modeDesc = "菜品快速制作,记录熟重",
modeIconId = R.drawable.ic_mode_cook,
onClick = {
startActivity<SelectDishActivity>()
finish()
})
)
modeList.add(
HomeModeBean(
modeName = "采样模式",
modeDesc = "菜品快速制作,记录熟重",
modeIconId = R.drawable.ic_mode_sampling,
onClick = {
goSampling()
})
)
modeList.add(
HomeModeBean(
modeName = "品控模式",
modeDesc = "菜品快速制作,记录熟重",
modeIconId = R.drawable.ic_mode_quality,
isLocked = true,
onClick = {
toast("即将解锁")
})
)
}
private lateinit var appViewModel: AppViewModel
private fun initViewModel() {
val db = BaseApp.instance!!.database
val factory = AppFactory(AppRepository(db.appDao()))
appViewModel = ViewModelProvider(this, factory)[AppViewModel::class.java]
}
private fun goSampling() {
appViewModel.countCookFood(cookMode = 1) {
if (it > 0) {
startActivity<SamplingListActivity>()
finish()
return@countCookFood
}
startActivity<DishSamplingActivity> {
putExtra(DishSamplingActivity.PAGE_FROM, DishSamplingActivity.HOME)
}
finish()
}
}
private fun getAppToken() {
val url = "${UrlConfig.GET_TOKEN}?qrcodeId=${BaseApp.instance?.androidId}"
// Log.d(TAG, "getToken: url = $url")
HttpUtil.get(url = url, doSuccess = {
BaseApp.getSharedPref()?.put("token" to it)
BaseApp.instance?.token = it.toString()
}) { code, msg ->
toast(msg)
}
}
}
@@ -0,0 +1,316 @@
package com.shuwei.dish.match.ui
import android.annotation.SuppressLint
import android.content.Intent
import android.graphics.Typeface
import android.os.Bundle
import android.util.Log
import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.LinearLayoutManager
import com.aithings.Weigher
import com.shuwei.dish.match.R
import com.shuwei.dish.match.adapter.DishPartAdapter
import com.shuwei.dish.match.base.BaseActivity
import com.shuwei.dish.match.databinding.ActivityPrepareCookBinding
import com.shuwei.dish.match.databinding.LayoutFoodRemindBinding
import com.shuwei.dish.match.dialog.BottomDialog
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.http.HttpUtil
import com.shuwei.dish.match.http.UrlConfig
import com.shuwei.dish.match.utils.SwipeCallback
import com.shuwei.dish.match.utils.WeightUtil
import com.shuwei.dish.match.utils.ext.clickWithDebounce
import com.shuwei.dish.match.utils.ext.gone
import com.shuwei.dish.match.utils.ext.toJsonString
import com.shuwei.dish.match.utils.ext.toObject
import com.shuwei.dish.match.utils.ext.toast
import com.shuwei.dish.match.utils.ext.visible
import java.io.Serializable
@SuppressLint("NotifyDataSetChanged")
class PrepareCookActivity : BaseActivity() {
companion object {
const val TAG = "CookActivity"
const val FOOD_ITEM = "foodItem"
}
private lateinit var binding: ActivityPrepareCookBinding
private var food: FoodRecord? = null
private var goodsList: MutableList<CookFoodGoodsEntity>? = null
@Suppress("DEPRECATION")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityPrepareCookBinding.inflate(layoutInflater)
setContentView(binding.root)
setHeaderBackground()
setTitleBar(titleBarAction = {
it.visible()
}, titleAction = {
it.text = "菜品制作"
}, rightIconActon = {
it.gone()
it.setImageResource(R.drawable.ic_setting)
it.setOnClickListener {
//startActivity<DeviceSettingActivity>()
}
}, backAction = {
it.setOnClickListener {
onBackPressed()
}
})
food = intent.extras?.getSerializable(FOOD_ITEM) as FoodRecord?
binding.tvDishName.text = food?.foodName ?: ""
addViewClickListener()
getDishDetail()
}
private fun addViewClickListener() {
binding.ivWeightClear.setOnClickListener {
Weigher.tareTwo(2)
}
WeightUtil.addWeightListener(getWeight = { address, state, weight ->
Log.d(TAG, "addViewClickListener: address=$address,state=$state,weight=$weight")
if (address == 2) {
binding.tvDishPartWeight.text = "${weight}"
}
})
binding.ivWeightAdd.setOnClickListener {
if (clickIndex == -1) {
toast("请选择菜品构成")
return@setOnClickListener
}
val clickItem = list[clickIndex]
clickItem.run {
if (isNewDishType && materialType != 1 && materialType != 2) {
toast("请选择主辅材类型")
return@setOnClickListener
}
}
val weight = binding.tvDishPartWeight.text.toString().toInt()
if (weight <= 0) {
toast("食材用量需要大于0")
return@setOnClickListener
}
Log.d(TAG, "addViewClickListener->useRealWeight=$weight")
clickItem.run {
useWeight = weight
isSetFinished = true
dishPartAdapter.notifyItemChanged(clickIndex)
}
}
binding.tvAddFood.clickWithDebounce {
BottomDialog(goodsType = 0).show(this) { item ->
val filterResult = list.firstOrNull { it.goodsId == item.goodsId }
if (filterResult != null) {
toast("不允许重复添加同一食材")
return@show
}
list.add(CookFoodGoodsEntity().apply {
goodsId = item.goodsId
goodsName = item.goodsName
// materialType =
isNewDishType = true
})
onItemClick(list.size - 1)
}
}
binding.btnCook.clickWithDebounce {
val count = list.count { it.isSetFinished.not() }
if (count > 0) {
showRemindDialog()
return@clickWithDebounce
}
goToSubmit()
}
binding.rgCook.setOnCheckedChangeListener { group, checkedId ->
val tempType =
if (checkedId == R.id.rbDishTypeFirst) 1 else if (checkedId == R.id.rbDishTypeSecond) 2 else -1
list[clickIndex].materialType = tempType
dishPartAdapter.notifyItemChanged(clickIndex)
binding.tvDishType.text =
if (tempType == 1) "主材" else if (tempType == 2) "辅材" else ""
}
}
private fun goToSubmit() {
getGoodsList()
if (goodsList.isNullOrEmpty()) {
toast("菜品构成信息未设置")
return
}
Log.d(TAG, "goToSubmit: goodsList:${goodsList?.toJsonString()}")
startActivity(
Intent(this, SubmitDishActivity::class.java)
.putExtra(SubmitDishActivity.GOODS_LIST, goodsList as Serializable)
.putExtra(SubmitDishActivity.FOOD_ITEM, food as Serializable)
)
}
private fun getGoodsList() {
if (goodsList == null) {
goodsList = mutableListOf()
}
list.forEach {
if (it.isSetFinished) {
goodsList?.add(CookFoodGoodsEntity().apply {
foodId = food!!.foodId
goodsId = it.goodsId
relateionType = it.relateionType
allEdible = it.allEdible
goodsName = it.goodsName
materialType = it.materialType
useWeight = it.useWeight ?: 0
goodsOrRelationCode = it.goodsOrRelationCode
})
}
}
}
private fun showRemindDialog() {
val remindBinding = LayoutFoodRemindBinding.inflate(layoutInflater)
CommonDialog(this).apply {
messageView = remindBinding.root
leftText = "返回调整"
rightText = "确认无误"
onLeftClick = { dismiss() }
onRightClick = {
goToSubmit()
dismiss()
}
onDismiss = { hideStatusBar() }
}.show()
}
private fun getDishDetail() {
//649
val url = "${UrlConfig.DISH_DETAIL}?foodId=${food?.foodId}"
HttpUtil.get(
url = url,
doSuccess = {
val json = it.toJsonString()
Log.d(TAG, "getDishDetail: json:$json")
val detail: CookFoodEntity? = json.toObject<CookFoodEntity>()
if (detail == null) {
toast("查询菜品信息为空")
return@get
}
loadDishDetail(detail)
}) { code, msg ->
toast(msg)
}
}
private fun loadDishDetail(detail: CookFoodEntity) {
val voList = detail.stFoodInfoConstituteList
if (voList.isNullOrEmpty()) {
return
}
//筛选出主材和辅材
val tempDate = voList.filter { it.materialType == 1 || it.materialType == 2 }
.apply {
forEach { it.useWeight = 0 }
}
list.clear()
list.addAll(tempDate)
firstReqSize = list.size
initRecyclerView()
}
private var firstReqSize = 0
private val list = mutableListOf<CookFoodGoodsEntity>()
private val dishPartAdapter by lazy {
DishPartAdapter(list).apply {
setOnItemClickListener { _, _, positon ->
onItemClick(positon)
}
}
}
private fun onItemClick(positon: Int) {
this@PrepareCookActivity.clickIndex = positon
list[clickIndex].let { it ->
binding.tvDishShowName.run {
text = it.goodsName
setTypeface(typeface, Typeface.BOLD)
}
binding.tvDishType.text =
if (it.materialType == 1) "主材" else if (it.materialType == 2) "辅材" else ""
list.forEach { bean -> bean.isItemClicked = false }
it.isItemClicked = true
dishPartAdapter.notifyDataSetChanged()
if (it.isNewDishType) {
binding.dividerDishType.visible()
binding.llDishType.visible()
} else {
binding.dividerDishType.gone()
binding.llDishType.gone()
}
}
}
private var clickIndex = -1
private fun initRecyclerView() {
binding.rvDishPartList.run {
layoutManager =
LinearLayoutManager(this@PrepareCookActivity, LinearLayoutManager.VERTICAL, false)
adapter = dishPartAdapter
val itemTouchHelper = ItemTouchHelper(SwipeCallback(dishPartAdapter) { position ->
if (list[position].isNewDishType.not()) {
toast("只能删除刚添加的食材")
dishPartAdapter.notifyItemChanged(position)
return@SwipeCallback
}
dishPartAdapter.removeAt(position)
toast("已删除")
})
itemTouchHelper.attachToRecyclerView(this)
}
}
@Suppress("DEPRECATION")
@SuppressLint("GestureBackNavigation")
@Deprecated("Deprecated in Java")
override fun onBackPressed() {
if (list.size > firstReqSize) {
//说明有新增的食材
saveDataRemindDialog()
return
}
val filterResult = list.firstOrNull { (it.useWeight ?: 0) > 0 }
if (filterResult != null) {
//说明有称重的数据
saveDataRemindDialog()
return
}
super.onBackPressed()
}
private fun saveDataRemindDialog() {
val remindBinding = LayoutFoodRemindBinding.inflate(layoutInflater)
remindBinding.tvDialogTitle.text = "温馨提示"
remindBinding.tvDialogContent.text = "您好,当前页面存在尚未保存的数据,确认返回上页吗?"
CommonDialog(this).apply {
messageView = remindBinding.root
leftText = "取消"
rightText = "确认"
onLeftClick = { dismiss() }
onRightClick = {
dismiss()
finish()
}
onDismiss = { hideStatusBar() }
}.show()
}
}
@@ -0,0 +1,111 @@
package com.shuwei.dish.match.ui
import android.annotation.SuppressLint
import android.app.Dialog
import android.content.Intent
import android.os.Bundle
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import com.shuwei.dish.match.R
import com.shuwei.dish.match.base.BaseActivity
import com.shuwei.dish.match.base.BaseApp
import com.shuwei.dish.match.databinding.ActivitySamplingBinding
import com.shuwei.dish.match.db.AppRepository
import com.shuwei.dish.match.entity.CookFoodEntity
import com.shuwei.dish.match.ui.fragment.SamplingListFragment
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
import com.shuwei.dish.match.viewmodel.AppViewModel
import com.shuwei.dish.match.viewmodel.factory.AppFactory
class SamplingListActivity : BaseActivity() {
private lateinit var binding: ActivitySamplingBinding
companion object {
const val IS_COOKING = "isCooking"
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivitySamplingBinding.inflate(layoutInflater)
setContentView(binding.root)
setTitleBar()
setHeaderBackground()
initViewModel()
loadSamplingListPage()
}
private fun setTitleBar() {
setTitleBar(titleBarAction = {
it.visible()
}, titleAction = {
it.text = "采样历史"
}, rightIconActon = {
it.visible()
it.setImageResource(R.drawable.ic_setting)
it.setOnClickListener {
startActivity<DeviceSettingActivity> {
putExtra(DeviceSettingActivity.COOK_MODE, 2)
}
}
}, backAction = {
it.gone()
})
}
private var samplingListFragment: SamplingListFragment? = null
private fun loadSamplingListPage() {
if (samplingListFragment == null) {
samplingListFragment = SamplingListFragment()
}
samplingListFragment?.let {
loadFragment(it)
}
}
private fun loadFragment(fragment: Fragment) {
supportFragmentManager.beginTransaction().apply {
replace(R.id.flContainer, fragment)
commit()
}
}
private lateinit var appViewModel: AppViewModel
private fun initViewModel() {
val db = BaseApp.instance!!.database
val factory =
AppFactory(AppRepository(db.appDao()))
appViewModel =
ViewModelProvider(this, factory)[AppViewModel::class.java]
}
fun getCookFoodList(action: (MutableList<CookFoodEntity>?) -> Unit) {
appViewModel.getCookFoodList(cookMode = 1) { action(it) }
}
fun deleteCookFoodAndGoods(foodId: String, action: () -> Unit) {
appViewModel.deleteCookFoodAndGoods(cookMode = 1, foodId = foodId, onFinish = action)
}
override fun onNewIntent(intent: Intent?) {
super.onNewIntent(intent)
val isCooking = intent?.getBooleanExtra(IS_COOKING, false) ?: false
samplingListFragment?.refreshPage(isCooking)
}
@Deprecated("Deprecated in Java")
@SuppressLint("GestureBackNavigation", "MissingSuperCall")
override fun onBackPressed() {
//super.onBackPressed()
//当前页面不允许返回
//dialog = toast("不允许返回操作")
}
}
@@ -0,0 +1,138 @@
package com.shuwei.dish.match.ui
import android.annotation.SuppressLint
import android.app.Dialog
import android.content.Intent
import android.os.Bundle
import androidx.lifecycle.ViewModelProvider
import com.shuwei.dish.match.R
import com.shuwei.dish.match.base.BaseActivity
import com.shuwei.dish.match.base.BaseApp
import com.shuwei.dish.match.databinding.ActivitySelectDishBinding
import com.shuwei.dish.match.db.AppRepository
import com.shuwei.dish.match.entity.CookFoodEntity
import com.shuwei.dish.match.ui.fragment.DishListFragment
import com.shuwei.dish.match.utils.KeyboardUtil
import com.shuwei.dish.match.utils.ext.addOnActionSearchListener
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
import com.shuwei.dish.match.viewmodel.AppViewModel
import com.shuwei.dish.match.viewmodel.factory.AppFactory
class SelectDishActivity : BaseActivity() {
companion object {
const val IS_COOKING = "isCooking"
}
private lateinit var binding: ActivitySelectDishBinding
private var dishListFragment: DishListFragment? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivitySelectDishBinding.inflate(layoutInflater)
setContentView(binding.root)
setHeaderBackground()
setTitleBar(titleBarAction = {
it.visible()
}, titleAction = {
it.text = "选择菜品"
}, rightIconActon = {
it.visible()
it.setImageResource(R.drawable.ic_setting)
it.setOnClickListener {
startActivity<DeviceSettingActivity> {
putExtra(DeviceSettingActivity.COOK_MODE, 1)
}
}
}, backAction = {
it.gone()
})
initViewModel()
addViewListener()
loadFragment()
}
private lateinit var appViewModel: AppViewModel
var dinnerType: String = "早餐"
private fun initViewModel() {
val db = BaseApp.instance!!.database
val factory =
AppFactory(AppRepository(db.appDao()))
appViewModel =
ViewModelProvider(this, factory)[AppViewModel::class.java]
}
fun getCookFoodList(action: (MutableList<CookFoodEntity>?) -> Unit) {
appViewModel.getCookFoodList(cookMode = 0) { action(it) }
}
fun addViewListener() {
binding.dishRadioGroup.setOnCheckedChangeListener { _, checkedId ->
dinnerType = when (checkedId) {
R.id.rbBreakfast -> "早餐"
R.id.rbLunch -> "午餐"
R.id.rbDinner -> "晚餐"
else -> ""
}
dishListFragment?.getDishList(1, false)
}
// binding.llSearchBar.setOnClickListener {
// startActivity<FoodSearchActivity> {
// putExtra(FoodSearchActivity.PAGE_TYPE, 1)
// }
// }
binding.etInputDish.addOnActionSearchListener {
jumpSearch()
}
binding.ivDishSearch.setOnClickListener {
jumpSearch()
}
}
private fun jumpSearch() {
val searchText = binding.etInputDish.text.toString().trim()
if (searchText.isBlank()) {
toast(binding.etInputDish.hint.toString())
return
}
startActivity<FoodSearchActivity> {
putExtra(FoodSearchActivity.PAGE_TYPE, 1)
putExtra(FoodSearchActivity.FOOD_NAME, searchText)
}
KeyboardUtil.hideKeyboard(this, binding.etInputDish)
}
private fun loadFragment() {
DishListFragment.instance().let {
dishListFragment = it
supportFragmentManager.beginTransaction().apply {
replace(R.id.flSubPage, it)
commit()
}
}
}
fun deleteCookFoodAndGoods(foodId: String, action: () -> Unit) {
appViewModel.deleteCookFoodAndGoods(cookMode = 0, foodId = foodId, onFinish = action)
}
override fun onNewIntent(intent: Intent?) {
super.onNewIntent(intent)
val isCooking = intent?.getBooleanExtra(IS_COOKING, false) ?: false
dishListFragment?.getDishList(1, isCooking)
}
@Deprecated("Deprecated in Java")
@SuppressLint("GestureBackNavigation", "MissingSuperCall")
override fun onBackPressed() {
//super.onBackPressed()
//当前页面不允许返回
// dialog = toast("不允许返回操作")
}
}
@@ -0,0 +1,393 @@
package com.shuwei.dish.match.ui
import android.annotation.SuppressLint
import android.os.Bundle
import android.util.Log
import android.util.SparseArray
import android.util.SparseIntArray
import androidx.core.util.forEach
import androidx.lifecycle.ViewModelProvider
import com.aithings.Weigher
import com.google.gson.reflect.TypeToken
import com.shuwei.dish.match.R
import com.shuwei.dish.match.adapter.SeasoningCellTool
import com.shuwei.dish.match.adapter.TextCellAdapter
import com.shuwei.dish.match.base.BaseActivity
import com.shuwei.dish.match.base.BaseApp
import com.shuwei.dish.match.databinding.ActivitySubmitDishBinding
import com.shuwei.dish.match.db.AppRepository
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.SeasoningEntity
import com.shuwei.dish.match.http.HttpUtil
import com.shuwei.dish.match.http.UrlConfig
import com.shuwei.dish.match.utils.DataUtil
import com.shuwei.dish.match.utils.WeightUtil
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.toJsonString
import com.shuwei.dish.match.utils.ext.toType
import com.shuwei.dish.match.utils.ext.toast
import com.shuwei.dish.match.utils.ext.visible
import com.shuwei.dish.match.viewmodel.AppViewModel
import com.shuwei.dish.match.viewmodel.factory.AppFactory
@SuppressLint("UseSparseArrays")
class SubmitDishActivity : BaseActivity() {
companion object {
const val TAG = "SubmitDishActivity"
const val FOOD_ITEM = "foodItem"
const val GOODS_LIST = "goodsList"
}
private lateinit var binding: ActivitySubmitDishBinding
private var food: FoodRecord? = null
private var goodsList: MutableList<CookFoodGoodsEntity>? = null
private var isCooking = false
private val cookFoodEntity by lazy {
CookFoodEntity().apply {
food?.let {
foodId = it.foodId ?: ""
foodName = it.foodName
cookMode = it.cookMode
}
canteenId = 0
}
}
@Suppress("unchecked_cast", "DEPRECATION")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivitySubmitDishBinding.inflate(layoutInflater)
setContentView(binding.root)
initViewModel()
setHeaderBackground()
intent.extras?.apply {
food = getSerializable(FOOD_ITEM) as FoodRecord?
Log.d(TAG, "onCreate: cookMode=${food?.cookMode}")
isCooking = food?.isCooking ?: false
if (isCooking) {
//烹饪中,从本地查询数据
loadSeasoningFromLocal()
} else {
//非烹饪中,从菜品主辅材配置页面带入数据
goodsList = getSerializable(GOODS_LIST) as MutableList<CookFoodGoodsEntity>?
}
}
setTitleBar(titleBarAction = {
it.visible()
}, titleAction = {
it.text = food?.foodName
}, rightIconActon = {
it.gone()
it.setImageResource(R.drawable.ic_setting)
it.setOnClickListener {
//startActivity<DeviceSettingActivity>()
}
})
addViewListener()
}
private fun loadSeasoningFromLocal() {
appViewModel.getCookFoodGoodsList(food?.foodId!!) { it ->
goodsList = mutableListOf()
//设置主辅材数据
goodsList?.addAll(it.filter { goods -> goods.materialType != 3 })
//获取调料数据并展示
val filterList: List<SeasoningEntity>? = it.filter { goods -> goods.materialType == 3 }
.map { entity ->
SeasoningEntity().also { se ->
se.goodsId = entity.goodsId
se.goodsName = entity.goodsName
se.goodsOrRelationCode = entity.goodsOrRelationCode
se.relateionType = entity.relateionType
se.materialType = entity.materialType
se.allEdible = entity.allEdible
se.useWeight = entity.useWeight
se.popularName = entity.popularName
se.canteenId = entity.canteenId
se.relateionType_dictText = entity.relateionType_dictText
se.foodId = entity.foodId
se.sort = entity.sort
se.pageType = 0
}
}
filterList?.toMutableList()?.let { cellData ->
loadTextCell(cellData)
}
}
}
private lateinit var seasoningList: List<SeasoningEntity>
private var isFirstSave = true
fun updateSeasoningList(list: MutableList<SeasoningEntity>) {
if (isFirstSave) {
val json = list.toJsonString()
val typeToken = object : TypeToken<List<SeasoningEntity>>() {}
seasoningList = json.toType(typeToken = typeToken)
isFirstSave = false
}
}
private val seasoningArray by lazy {
SparseArray<Int>()
}
private val firstGoodsArray by lazy {
SparseArray<Int>()
}
private fun addViewListener() {
addWeightListener()
binding.btnWeightClear.setOnClickListener { Weigher.tareTwo(1) }
binding.btnCook.clickWithDebounce {
cook()
}
binding.btnSubmit.clickWithDebounce {
if (cookFoodEntity.foodWeight <= 0) {
toast("未识别到菜品熟重")
return@clickWithDebounce
}
submit()
}
}
private fun addWeightListener() {
WeightUtil.addWeightListener(getWeight = { address, state, weight ->
if (address == 1) {
cookFoodEntity.foodWeight = weight
binding.tvTotalWeight.text = "${weight / 1000f}"
}
// if (state != SensorScale.STATE_STABLE) {
// return@addWeightListener
// }
val firstWeight = firstGoodsArray.get(address, null)
if (firstWeight != weight) {
Log.d(
TAG,
"addViewListener: state=$state,address=$address,weight=$weight,firstWeight=$firstWeight"
)
}
if (firstWeight == null) {
//未设置数据
firstGoodsArray.put(address, weight)
return@addWeightListener
}
// val cookingWeight =
// if (isCooking && seasoningList.isNullOrEmpty().not())
// seasoningList?.get(weightRelateArray2.get(address))?.weight ?: 0
// else 0
// var realUseWeight = firstWeight - weight + cookingWeight
var realUseWeight = firstWeight - weight
realUseWeight = if (realUseWeight > 0) realUseWeight else 0
// Log.d(
// TAG,
// "addViewListener: state=$state,address=$address,总共使用重量:$realUseWeight"
// )
seasoningArray.put(address, realUseWeight)
refreshSeasoningWeight()
})
}
@SuppressLint("NotifyDataSetChanged")
private fun refreshSeasoningWeight() {
binding.rvSeasoning.adapter?.let { adapter ->
if (adapter is TextCellAdapter) {
adapter.list.let { items ->
weightRelateArray.forEach { key, value ->
items[key].useWeight =
(seasoningArray.get(value) ?: 0) + getCookingSeasoning(value)
}
}
adapter.notifyDataSetChanged()
TextCellAdapter.loadCell(binding.tvRightBottomCell, adapter.list[14])
}
}
}
private fun getCookingSeasoning(address: Int): Int {
if (isCooking.not()) return 0
if (seasoningList.isEmpty()) return 0
val weight = seasoningList[weightRelateArray2.get(address)].useWeight ?: 0
//Log.i(TAG, "getCookingSeasoning: weight[${address}]=$weight,seasoningList=${seasoningList.toJsonString()}")
return weight
}
private val weightRelateArray2 by lazy {
SparseIntArray().apply {
weightRelateArray.forEach { key, value ->
if (value == 3) {
put(3, 14)
} else {
put(value, key)
}
}
}
}
private val weightRelateArray by lazy {
DataUtil.getWeighAddressArray()
}
// private fun prepareData(acton: () -> Unit) {
//
// //只有制作和采样列表页面才能进入设置页面,提交页面无法进行设置,不存在调料数据被修改的问题
// val seasoningJson = realSeasoningData.toJsonString()
// val typeToken = object : TypeToken<List<CookFoodGoodsEntity>>() {}
// val tempSeasoningList = seasoningJson.toType(typeToken = typeToken)
// goodsList?.addAll(tempSeasoningList)
// acton()
//
// }
private fun cook() {
if (food == null || goodsList.isNullOrEmpty()) {
toast("未获取到菜品或构成信息")
return
}
val realSeasoningData = (binding.rvSeasoning.adapter as TextCellAdapter).list
if (realSeasoningData.isEmpty() && !isCooking) {
toast("未获取到调料信息")
return
}
showLoading()
//只有制作和采样列表页面才能进入设置页面,提交页面无法进行设置,不存在调料数据被修改的问题
val seasoningJson = realSeasoningData.toJsonString()
val typeToken = object : TypeToken<List<CookFoodGoodsEntity>>() {}
val tempSeasoningList = seasoningJson.toType(typeToken = typeToken)
goodsList?.addAll(tempSeasoningList)
val isSamplingData = food!!.cookMode == 1
if (isSamplingData) {
//生成临时foodId,解决采样模式没有foodId,无法关联数据的问题
val tempFoodId = cookFoodEntity.foodId.ifBlank { "${System.currentTimeMillis()}" }
cookFoodEntity.foodId = tempFoodId
}
//全部设置同一foodId
goodsList?.forEach {
it.foodId = cookFoodEntity.foodId
}
//保存菜品-保存主辅料调料
appViewModel.saveCookFoodAndGoods(
cookMode = food!!.cookMode,
entity = cookFoodEntity,
list = goodsList,
onFinish = {
runOnUiThread {
dismissLoading()
jumpPage(isSamplingData, true)
}
})
}
private fun submit() {
if (food == null || goodsList.isNullOrEmpty()) {
toast("未获取到菜品或构成信息")
return
}
val realSeasoningData = (binding.rvSeasoning.adapter as TextCellAdapter).list
if (realSeasoningData.isEmpty() && !isCooking) {
toast("未获取到调料信息")
return
}
showLoading()
//只有制作和采样列表页面才能进入设置页面,提交页面无法进行设置,不存在调料数据被修改的问题
val seasoningJson = realSeasoningData.toJsonString()
val typeToken = object : TypeToken<List<CookFoodGoodsEntity>>() {}
val tempSeasoningList = seasoningJson.toType(typeToken = typeToken)
tempSeasoningList.forEach { entity ->
val realWeight = entity.useWeight ?: 0
val filterData = goodsList?.firstOrNull { it.goodsId == entity.goodsId }
//确保重量大于0,且无重复数据
if (realWeight > 0 && filterData == null) {
goodsList?.add(entity)
}
}
cookFoodEntity.stFoodInfoConstituteList = this@SubmitDishActivity.goodsList
val isSamplingData = food!!.cookMode == 1
if (isSamplingData) {
//采样模式没有foodId
cookFoodEntity.foodId = ""
goodsList?.forEach { it.foodId = "" }
}
val json = cookFoodEntity.toJsonString()
Log.d(TAG, "submit: json=$json")
HttpUtil.postJson(
url = UrlConfig.SUBMIT_DISH,
json = json,
doSuccess = {
Log.d(TAG, "submit: postJson=$it")
//删除本地数据
appViewModel.deleteCookFoodAndGoods(
cookMode = food!!.cookMode,
foodId = food!!.foodId!!
) {
dismissLoading()
jumpPage(isSamplingData, false)
}
}, doFailure = { code, msg ->
Log.d(TAG, "submit: postJson:code=$code,msg=$msg")
toast(msg)
dismissLoading()
})
}
private fun jumpPage(isSampling: Boolean, isCooking: Boolean) {
if (isSampling) {
startActivity<SamplingListActivity> {
putExtra(SelectDishActivity.IS_COOKING, isCooking)
}
return
}
startActivity<SelectDishActivity> {
putExtra(SelectDishActivity.IS_COOKING, isCooking)
}
}
private lateinit var appViewModel: AppViewModel
private fun initViewModel() {
val db = BaseApp.instance!!.database
val factory =
AppFactory(AppRepository(db.appDao()))
appViewModel =
ViewModelProvider(this, factory)[AppViewModel::class.java]
}
override fun onResume() {
super.onResume()
binding.tvRightBottomCell.visible()
if (isCooking.not()) {
//烹饪中使用本地数据,未烹饪则使用默认的调料配置数据
appViewModel.loadSeasoning {
Log.d(TAG, "onResume: loadSeasoning:${it.toJsonString()}")
loadTextCell(it)
}
}
}
private fun loadTextCell(list: MutableList<SeasoningEntity>) {
SeasoningCellTool.loadData(
activity = this,
initList = list,
recyclerView = binding.rvSeasoning,
tvCell = binding.tvRightBottomCell
)
}
}
@@ -0,0 +1,243 @@
package com.shuwei.dish.match.ui.fragment
import android.annotation.SuppressLint
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.LinearLayoutManager
import com.shuwei.dish.match.adapter.DishShowAdapter
import com.shuwei.dish.match.databinding.FragmentDishListBinding
import com.shuwei.dish.match.databinding.LayoutEmptyViewBinding
import com.shuwei.dish.match.entity.FoodRecord
import com.shuwei.dish.match.entity.FoodRecordBean
import com.shuwei.dish.match.http.HttpUtil
import com.shuwei.dish.match.http.UrlConfig
import com.shuwei.dish.match.ui.PrepareCookActivity
import com.shuwei.dish.match.ui.SelectDishActivity
import com.shuwei.dish.match.ui.SubmitDishActivity
import com.shuwei.dish.match.utils.SwipeCallback
import com.shuwei.dish.match.utils.ext.startActivity
import com.shuwei.dish.match.utils.ext.toJsonString
import com.shuwei.dish.match.utils.ext.toObject
import com.shuwei.dish.match.utils.ext.toast
import java.io.Serializable
class DishListFragment : Fragment() {
companion object {
private const val TAG = "DishListFragment"
// const val DINNER_TYPE = "dinnerType"
public fun instance(): DishListFragment {
return DishListFragment().apply {
// arguments = Bundle().apply {
// putInt(DINNER_TYPE, type)
// }
}
}
}
// private var dinnerType = ""
private var pageNo = 1
private val pageSize = 30
private lateinit var activity: SelectDishActivity
private var list: MutableList<FoodRecord> = mutableListOf()
private val dishAdapter by lazy {
DishShowAdapter(list = list).apply {
isStateViewEnable = true
setOnItemClickListener { adapter, view, position ->
val item = list[position]
if (item.isCooking) {
//烹饪中,跳到称熟重页面
context.startActivity<SubmitDishActivity> {
putExtra(
SubmitDishActivity.FOOD_ITEM,
item as Serializable
)
}
return@setOnItemClickListener
}
context.startActivity<PrepareCookActivity> {
putExtra(
SubmitDishActivity.FOOD_ITEM,
item as Serializable
)
}
}
}
}
private lateinit var binding: FragmentDishListBinding
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = FragmentDishListBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
activity = requireActivity() as SelectDishActivity
//toast("type=$type")
binding.rvDishList.run {
layoutManager =
LinearLayoutManager(requireContext(), LinearLayoutManager.VERTICAL, false)
adapter = dishAdapter
val itemTouchHelper = ItemTouchHelper(SwipeCallback(dishAdapter) { position ->
if (list[position].isCooking.not()) {
activity.toast("只能删除烹饪中的菜品")
dishAdapter.notifyItemChanged(position)
return@SwipeCallback
}
activity.deleteCookFoodAndGoods(foodId = list[position].foodId ?: "") {
dishAdapter.removeAt(position)
activity.toast("已删除")
}
})
itemTouchHelper.attachToRecyclerView(this)
}
addViewListener()
pageNo = 1
activity.showLoading()
getDishList()
}
private fun addViewListener() {
binding.refreshLayout.run {
setEnableRefresh(true)
setEnableLoadMore(false)
setOnRefreshListener {
pageNo = 1
getDishList()
}
setOnLoadMoreListener {
getDishList()
}
}
}
fun getDishList(pageNo: Int, isCooking: Boolean) {
this.pageNo = pageNo
getDishList()
}
@SuppressLint("NotifyDataSetChanged")
@Suppress("unchecked_cast")
fun getDishList() {
activity.showLoading()
val map = mapOf(
// "foodName" to input,
"dinnerType" to activity.dinnerType,
"pageNo" to "$pageNo",
"pageSize" to "$pageSize",
"canteenId" to "0"
)
val sb = StringBuilder(UrlConfig.QUERY_FOOD_LIST).apply {
append("?")
map.forEach { (key, value) -> append("$key=$value&") }
}
sb.deleteCharAt(sb.length - 1)
HttpUtil.get(
url = sb.toString(),
doSuccess = {
binding.refreshLayout.run {
setEnableRefresh(true)
}
activity.delayDismissLoading()
finishRefresh()
val json = it.toJsonString()
val recordBean: FoodRecordBean? = json.toObject<FoodRecordBean>()
if (recordBean == null || recordBean.records.isNullOrEmpty()) {
//toast("暂未搜索到相关菜品信息")
if (pageNo == 1) {
loadEmptyView()
}
return@get
}
val records = recordBean.records
if (pageNo == 1) {
list.clear()
}
list.addAll(records!!)
dishAdapter.notifyDataSetChanged()
val isLoadMoreEnable = records.size >= pageSize
binding.refreshLayout.setEnableLoadMore(isLoadMoreEnable)
if (isLoadMoreEnable) {
pageNo++
}
refreshLocalData(list)
}, doFailure = { code, msg ->
binding.refreshLayout.run {
setEnableRefresh(true)
}
toast(msg)
finishRefresh()
if (pageNo == 1) {
loadEmptyView()
}
activity.delayDismissLoading()
})
}
private var emptyViewBinding: LayoutEmptyViewBinding? = null
@SuppressLint("NotifyDataSetChanged")
private fun loadEmptyView() {
list.clear()
dishAdapter.notifyDataSetChanged()
if (emptyViewBinding == null) {
emptyViewBinding = LayoutEmptyViewBinding.inflate(
LayoutInflater.from(requireContext()),
binding.rvDishList,
false
)
}
emptyViewBinding!!.tvContent.text = "暂无数据"
emptyViewBinding!!.tvSubContent.text = "获取菜品数据失败,请检查网络设置或稍后重试"
dishAdapter.stateView = emptyViewBinding!!.root
//dishAdapter.setStateViewLayout(requireContext(), R.layout.layout_empty_view)
}
private fun finishRefresh() {
if (pageNo == 1) {
binding.refreshLayout.finishRefresh(1200)
} else {
binding.refreshLayout.finishLoadMore(1200)
}
}
@SuppressLint("NotifyDataSetChanged")
private fun refreshLocalData(list: MutableList<FoodRecord>) {
activity.getCookFoodList { cookFoodEntities ->
if (cookFoodEntities.isNullOrEmpty()) {
return@getCookFoodList
}
val tempList = mutableListOf<FoodRecord>()
cookFoodEntities.forEachIndexed { index, entity ->
val food = list.firstOrNull { it.foodId == entity.foodId }
if (food != null) {
food.isCooking = true
food.sort = index
tempList.add(food)
}
}
list.removeAll(tempList)
list.addAll(0, tempList)
dishAdapter.notifyDataSetChanged()
}
}
}
@@ -0,0 +1,187 @@
package com.shuwei.dish.match.ui.fragment
import android.annotation.SuppressLint
import android.content.Intent
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.LinearLayoutManager
import com.aithings.Weigher
import com.shuwei.dish.match.R
import com.shuwei.dish.match.adapter.DishPartAdapter
import com.shuwei.dish.match.databinding.FragmentDishSamplingBinding
import com.shuwei.dish.match.dialog.BottomDialog
import com.shuwei.dish.match.entity.CookFoodGoodsEntity
import com.shuwei.dish.match.entity.FoodRecord
import com.shuwei.dish.match.ui.FoodSearchActivity
import com.shuwei.dish.match.ui.DishSamplingActivity
import com.shuwei.dish.match.ui.SubmitDishActivity
import com.shuwei.dish.match.utils.KeyboardUtil
import com.shuwei.dish.match.utils.WeightUtil
import com.shuwei.dish.match.utils.ext.addOnActionSearchListener
import com.shuwei.dish.match.utils.ext.clickWithDebounce
import com.shuwei.dish.match.utils.ext.startActivity
import com.shuwei.dish.match.utils.ext.toJsonString
import com.shuwei.dish.match.utils.ext.toast
import java.io.Serializable
class DishSamplingFragment : Fragment() {
private val TAG = "DishSamplingFragment"
private lateinit var activity: DishSamplingActivity
private lateinit var binding: FragmentDishSamplingBinding
val list: MutableList<CookFoodGoodsEntity> = mutableListOf()
private var tempDishEntity: CookFoodGoodsEntity? = null
private var dishMaterialType = 1
private val dishAdapter by lazy {
DishPartAdapter(list).apply {
addOnItemChildClickListener(R.id.ivOperateIcon) { _, _, positon ->
//删除操作
removeAt(positon)
}
}
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
): View {
binding = FragmentDishSamplingBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
activity = requireActivity() as DishSamplingActivity
addViewClickListener()
foodName = activity.foodName
binding.etInputDish.setText(foodName)
}
@SuppressLint("NotifyDataSetChanged")
private fun addViewClickListener() {
binding.rvDishPartList.run {
layoutManager = LinearLayoutManager(activity, LinearLayoutManager.VERTICAL, false)
adapter = dishAdapter
}
binding.tvInputDishType.run {
clickWithDebounce {
BottomDialog(goodsType = 0).show(activity) { item ->
val filterResult = list.firstOrNull { it.goodsName == item.goodsName }
if (filterResult != null) {
toast("不允许重复添加同一食材")
return@show
}
text = item.goodsName
tempDishEntity = CookFoodGoodsEntity().apply {
goodsId = item.goodsId
goodsName = item.goodsName
relateionType = item.relateionType?:0
goodsOrRelationCode = item.goodsOrRelationCode
// TODO: 待定
//allEdible = item.allEdible
}
}
}
}
binding.ivWeightClear.setOnClickListener {
Weigher.tareTwo(2)
}
WeightUtil.addWeightListener(getWeight = { address, state, weight ->
Log.d(TAG, "addViewClickListener: address=$address,state=$state,weight=$weight")
if (address == 2) {
tempDishEntity?.useWeight = weight
binding.tvDishPartWeight.text = "${weight}"
}
})
binding.ivWeightAdd.setOnClickListener {
if (tempDishEntity == null) {
activity.toast("请输入食材名称")
return@setOnClickListener
}
if (binding.rgSampling.checkedRadioButtonId == -1) {
activity.toast("请选择主辅材类型")
return@setOnClickListener
}
if (tempDishEntity!!.useWeight == null) {
activity.toast("请将食材放在称上称重")
return@setOnClickListener
}
tempDishEntity!!.apply {
isSamplingPage = true
materialType = dishMaterialType
}
val result = list.firstOrNull { it.goodsId == tempDishEntity!!.goodsId }
if (result != null) {
activity.toast("${result.goodsName}食材已添加,请勿重复操作")
return@setOnClickListener
}
list.add(tempDishEntity!!)
dishAdapter.notifyDataSetChanged()
tempDishEntity = null
binding.tvInputDishType.text = ""
binding.rgSampling.clearCheck()
}
binding.rgSampling.setOnCheckedChangeListener { group, checkedId ->
dishMaterialType = if (checkedId == R.id.rbDishTypeFirst) 1 else 2
}
binding.ivDishSearch.setOnClickListener { v ->
jumpSearch(v)
}
binding.btnCook.clickWithDebounce {
val showFoodName = binding.etInputDish.text.toString().trim()
if (showFoodName.isBlank()) {
toast("菜品名称为空")
return@clickWithDebounce
}
if (list.isEmpty()) {
toast("菜品构成信息未设置")
return@clickWithDebounce
}
val food = FoodRecord()
food.foodId = foodId
food.foodName = showFoodName
food.cookMode = 1
Log.d(TAG, "goToSubmit: goodsList:${list.toJsonString()}")
activity.startActivity<SubmitDishActivity> {
putExtra(SubmitDishActivity.GOODS_LIST, list as Serializable)
putExtra(SubmitDishActivity.FOOD_ITEM, food as Serializable)
}
}
binding.etInputDish.let { v ->
v.addOnActionSearchListener {
jumpSearch(v)
}
}
}
private fun jumpSearch(v: View) {
activity.launch(Intent(activity, FoodSearchActivity::class.java).apply {
putExtra(FoodSearchActivity.FOOD_NAME, binding.etInputDish.text.toString().trim() )
}) { intent ->
intent?.let {
foodId = it.getStringExtra(FoodSearchActivity.FOOD_ID)
foodName = it.getStringExtra(FoodSearchActivity.FOOD_NAME)
binding.etInputDish.run {
setText(foodName)
setSelection(text.length)
}
}
}
KeyboardUtil.hideKeyboard(v.context, v)
}
private var foodId: String? = null
private var foodName: String? = null
}
@@ -0,0 +1,254 @@
package com.shuwei.dish.match.ui.fragment
import android.annotation.SuppressLint
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.LinearLayoutManager
import com.shuwei.dish.match.R
import com.shuwei.dish.match.adapter.SamplingAdapter
import com.shuwei.dish.match.databinding.FragmentSamplingListBinding
import com.shuwei.dish.match.databinding.LayoutEmptyViewBinding
import com.shuwei.dish.match.entity.FoodRecord
import com.shuwei.dish.match.entity.FoodRecordBean
import com.shuwei.dish.match.http.HttpUtil
import com.shuwei.dish.match.http.UrlConfig
import com.shuwei.dish.match.ui.DishSamplingActivity
import com.shuwei.dish.match.ui.SamplingListActivity
import com.shuwei.dish.match.ui.SubmitDishActivity
import com.shuwei.dish.match.utils.DateTimeUtil
import com.shuwei.dish.match.utils.SwipeCallback
import com.shuwei.dish.match.utils.ext.startActivity
import com.shuwei.dish.match.utils.ext.toJsonString
import com.shuwei.dish.match.utils.ext.toObject
import com.shuwei.dish.match.utils.ext.toast
import java.io.Serializable
class SamplingListFragment : Fragment() {
companion object {
private const val TAG = "SamplingListFragment"
}
private lateinit var activity: SamplingListActivity
private lateinit var binding: FragmentSamplingListBinding
private var list: MutableList<FoodRecord> = mutableListOf()
private val dishAdapter by lazy {
SamplingAdapter(list = list).apply {
isStateViewEnable = true
setOnItemClickListener { adapter, view, position ->
val item = list[position]
if (item.isCooking) {
//烹饪中,跳到称熟重页面
context.startActivity<SubmitDishActivity> {
putExtra(
SubmitDishActivity.FOOD_ITEM,
item as Serializable
)
}
return@setOnItemClickListener
}
context.startActivity<DishSamplingActivity> {
putExtra(DishSamplingActivity.FOOD_NAME, item.foodName)
}
}
}
}
@SuppressLint("NotifyDataSetChanged")
private fun initRecyclerView() {
binding.rvSamplingList.run {
layoutManager =
LinearLayoutManager(requireContext(), LinearLayoutManager.VERTICAL, false)
adapter = dishAdapter
val itemTouchHelper = ItemTouchHelper(SwipeCallback(dishAdapter) { position ->
if (list[position].isCooking.not()) {
activity.toast("只能删除烹饪中的菜品")
dishAdapter.notifyItemChanged(position)
return@SwipeCallback
}
activity.deleteCookFoodAndGoods(foodId = list[position].foodId?:"") {
if (list.size > 1) {
dishAdapter.removeAt(position)
} else {
loadEmptyView()
}
activity.toast("已删除")
}
})
itemTouchHelper.attachToRecyclerView(this)
}
}
private fun addViewListener() {
binding.btnAddSampling.setOnClickListener {
activity.startActivity<DishSamplingActivity>()
}
binding.refreshLayout.setOnRefreshListener {
pageNo = 1
getSamplingList()
}
binding.refreshLayout.setOnLoadMoreListener {
getSamplingList()
}
binding.dishRadioGroup.setOnCheckedChangeListener { group, checkedId ->
if (checkedId == R.id.rbCooking) {
refreshLocalData()
} else {
pageNo = 1
getSamplingList()
}
}
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
binding = FragmentSamplingListBinding.inflate(inflater, container, false)
return binding.root
}
@SuppressLint("NotifyDataSetChanged")
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
activity = requireActivity() as SamplingListActivity
initRecyclerView()
addViewListener()
refreshLocalData()
}
var pageNo = 1
private val pageSize = 30
@SuppressLint("NotifyDataSetChanged")
fun getSamplingList() {
activity.showLoading()
val map = mapOf(
// "foodName" to input,
"pageNo" to "$pageNo",
"pageSize" to "$pageSize",
"canteenId" to "0"
)
val sb = StringBuilder(UrlConfig.SAMPLING_LIST).apply {
append("?")
map.forEach { (key, value) -> append("$key=$value&") }
}
sb.deleteCharAt(sb.length - 1)
HttpUtil.get(
url = sb.toString(),
doSuccess = {
binding.refreshLayout.run {
setEnableRefresh(true)
}
activity.delayDismissLoading()
finishRefresh()
val json = it.toJsonString()
val recordBean: FoodRecordBean? = json.toObject<FoodRecordBean>()
if (recordBean == null || recordBean.records.isNullOrEmpty()) {
//toast("暂未搜索到相关菜品信息")
if (pageNo == 1) {
loadEmptyView()
}
return@get
}
val records = recordBean.records
if (pageNo == 1) {
list.clear()
}
list.addAll(records!!)
dishAdapter.notifyDataSetChanged()
val isLoadMoreEnable = records.size >= pageSize
binding.refreshLayout.setEnableLoadMore(isLoadMoreEnable)
binding.refreshLayout.setEnableRefresh(true)
if (isLoadMoreEnable) {
pageNo++
}
}, doFailure = { code, msg ->
binding.refreshLayout.run {
setEnableRefresh(true)
}
toast(msg)
finishRefresh()
binding.refreshLayout.setEnableRefresh(true)
activity.delayDismissLoading()
if (pageNo == 1) {
loadEmptyView()
}
})
}
private fun finishRefresh() {
if (pageNo == 1) {
binding.refreshLayout.finishRefresh(1200)
} else {
binding.refreshLayout.finishLoadMore(1200)
}
}
private var emptyViewBinding:LayoutEmptyViewBinding?=null
@SuppressLint("NotifyDataSetChanged")
private fun loadEmptyView() {
list.clear()
dishAdapter.notifyDataSetChanged()
if (emptyViewBinding == null) {
emptyViewBinding = LayoutEmptyViewBinding.inflate(LayoutInflater.from(requireContext()), binding.rvSamplingList, false)
}
emptyViewBinding!!.tvContent.text = "暂无数据"
emptyViewBinding!!.tvSubContent.text = "今日暂无采样数据,点击下方按钮新增采样"
dishAdapter.stateView = emptyViewBinding!!.root
//dishAdapter.setStateViewLayout(requireContext(), R.layout.layout_empty_view)
binding.refreshLayout.run {
setEnableRefresh(false)
setEnableLoadMore(false)
}
}
fun refreshPage(isCooking: Boolean) {
binding.dishRadioGroup.check(
if (isCooking) R.id.rbCooking else R.id.rbFinished
)
}
@SuppressLint("NotifyDataSetChanged")
fun refreshLocalData() {
activity.showLoading()
//查询本地数据
activity.getCookFoodList { cookFoodEntities ->
activity.delayDismissLoading()
if (cookFoodEntities.isNullOrEmpty()) {
loadEmptyView()
return@getCookFoodList
}
val tempList = mutableListOf<FoodRecord>()
cookFoodEntities
.sortedByDescending { DateTimeUtil.convert(dateStr = it.createTime) }
.forEach { entity ->
tempList.add(FoodRecord().apply {
foodId = entity.foodId
foodName = entity.foodName
cookMode = 1
isCooking = true
})
}
list.clear()
list.addAll(tempList)
dishAdapter.notifyDataSetChanged()
binding.refreshLayout.run {
setEnableRefresh(false)
setEnableLoadMore(false)
}
}
}
}
@@ -0,0 +1,52 @@
package com.shuwei.dish.match.utils
import android.app.Activity
import java.util.Stack
object ActivityManager {
private val activityStack = Stack<Activity>()
// 添加Activity到栈
fun addActivity(activity: Activity) {
activityStack.add(activity)
}
// 移除指定Activity
fun removeActivity(activity: Activity) {
activityStack.remove(activity)
}
// 获取当前Activity
fun currentActivity(): Activity? {
return if (activityStack.isEmpty()) null else activityStack.lastElement()
}
// 结束指定Activity
fun finishActivity(activity: Activity) {
if (!activity.isFinishing) {
activity.finish()
}
}
// 结束所有Activity
fun finishAllActivity() {
activityStack.forEach {
if (!it.isFinishing) {
it.finish()
}
}
activityStack.clear()
}
// 退出应用程序
fun exitApp() {
finishAllActivity()
android.os.Process.killProcess(android.os.Process.myPid())
}
fun getActivityStack(): Stack<Activity>{
return activityStack
}
}
@@ -0,0 +1,28 @@
package com.shuwei.dish.match.utils
import android.util.SparseIntArray
object DataUtil {
fun getWeighAddressArray(): SparseIntArray {
return SparseIntArray().apply {
put(0, 12)
put(1, 13)
put(2, 14)
put(3, 9)
put(4, 10)
put(5, 11)
put(6, 6)
put(7, 7)
put(8, 8)
put(9, 5)
put(12, 4)
put(10, 3)
put(11, 3)
put(13, 3)
put(14, 3)
}
}
}
@@ -0,0 +1,32 @@
package com.shuwei.dish.match.utils
import java.time.LocalDateTime
import java.time.ZoneId
import java.time.format.DateTimeFormatter
import java.util.Date
object DateTimeUtil {
const val YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss"
fun formatDateTime(dateTime: LocalDateTime, pattern: String = YYYY_MM_DD_HH_MM_SS): String {
val formatter = DateTimeFormatter.ofPattern(pattern)
return dateTime.format(formatter)
}
fun convert(dateStr: String, pattern: String = YYYY_MM_DD_HH_MM_SS): Date {
val formatter = DateTimeFormatter.ofPattern(pattern)
val ldt = LocalDateTime.parse(dateStr, formatter)
val zdt = ldt.atZone(ZoneId.systemDefault())
return Date.from(zdt.toInstant())
}
fun main() {
val now = LocalDateTime.now()
println("默认格式: ${formatDateTime(now)}")
println("自定义格式: ${formatDateTime(now, "yyyy年MM月dd日 HH时mm分ss秒")}")
}
}
@@ -0,0 +1,26 @@
package com.shuwei.dish.match.utils
import com.google.gson.TypeAdapter
import com.google.gson.stream.JsonReader
import com.google.gson.stream.JsonToken
import com.google.gson.stream.JsonWriter
class DecimalAdapter : TypeAdapter<Number>() {
override fun write(out: JsonWriter, value: Number) {
// out.value(value.toString()) // 强制以字符串形式写入
out.value("$value") // 强制以字符串形式写入
}
override fun read(reader: JsonReader): Number {
return when (reader.peek()) {
JsonToken.NUMBER -> reader.nextDouble()
JsonToken.STRING -> reader.nextString().toDouble()
else -> 0.0
}
}
}
// 使用方式
//val gson = GsonBuilder()
// .registerTypeAdapter(Double::class.java, DecimalAdapter())
// .create()
@@ -0,0 +1,17 @@
package com.shuwei.dish.match.utils
import android.content.Context
import android.view.View
import android.view.inputmethod.InputMethodManager
object KeyboardUtil {
fun hideKeyboard(context: Context, view: View) {
val imm = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
imm.hideSoftInputFromWindow(view.windowToken, 0)
view.clearFocus() // 清除焦点避免键盘再次弹出
}
}
@@ -0,0 +1,11 @@
package com.shuwei.dish.match.utils
import android.util.Log
//object LogUtil {
//
// fun d(tag: String, msg: String) {
// Log.d(tag, msg)
// }
//
//}
@@ -0,0 +1,62 @@
package com.shuwei.dish.match.utils
import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.RecyclerView
import com.chad.library.adapter4.BaseQuickAdapter
import com.chad.library.adapter4.viewholder.QuickViewHolder
import com.shuwei.dish.match.adapter.DishPartAdapter
import com.shuwei.dish.match.adapter.DishShowAdapter
import com.shuwei.dish.match.adapter.SamplingAdapter
class SwipeCallback(
private val adapter: BaseQuickAdapter<*,*>,
private val callback: (position: Int) -> Unit = {}
) :
ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT) {
override fun onMove(
recyclerView: RecyclerView,
viewHolder: RecyclerView.ViewHolder,
target: RecyclerView.ViewHolder
): Boolean {
return false // 不允许拖动,只允许滑动删除
}
override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
val position = viewHolder.getBindingAdapterPosition()
callback(position)
}
override fun getMovementFlags(
recyclerView: RecyclerView,
viewHolder: RecyclerView.ViewHolder
): Int {
val position = viewHolder.getBindingAdapterPosition()
// 默认的拖动和滑动方向
val dragFlags = 0
// ItemTouchHelper.UP or ItemTouchHelper.DOWN
var swipeFlags = ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT
if (adapter is SamplingAdapter) {
if (!adapter.items[position].isCooking) {
swipeFlags = 0
}
} else if (adapter is DishShowAdapter) {
if (!adapter.items[position].isCooking) {
swipeFlags = 0
}
} else if (adapter is DishPartAdapter) {
if (!adapter.items[position].isNewDishType) {
swipeFlags = 0
}
}
// 根据viewHolder的逻辑判断是否允许滑动
val count = recyclerView.adapter?.itemCount ?:0
//BaseQuickAdapter中空布局使用的ViewHolder是这个import com.chad.library.adapter4.viewholder.StateLayoutVH
if (count == 1 && viewHolder !is QuickViewHolder) {
swipeFlags = 0 // 不允许滑动
}
return makeMovementFlags(dragFlags, swipeFlags)
}
}
@@ -0,0 +1,28 @@
package com.shuwei.dish.match.utils
import android.content.Context
import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import android.widget.TextView
import android.widget.Toast
import com.shuwei.dish.match.R
object ToastUtil {
fun show(context: Context, message: String, duration:Int = Toast.LENGTH_SHORT) {
val inflater = LayoutInflater.from(context)
val layout: View = inflater.inflate(R.layout.custom_toast, null)
val textView = layout.findViewById<TextView>(R.id.tvMessage)
textView.text = message
val toast = Toast(context)
toast.view = layout // 设置自定义视图
toast.setGravity(Gravity.CENTER, 0, 0) // 调整位置居中显示
toast.setDuration(duration)
toast.show()
}
}
@@ -0,0 +1,148 @@
package com.shuwei.dish.match.utils
import android.os.Build
import android.os.Handler
import android.os.Looper
import android.util.Log
import com.aithings.Weigher
import com.shuwei.dish.match.base.BaseApp
import com.shuwei.dish.match.utils.ext.toast
import com.wabon.wbintelligenthardwaresdk.api.SensorScale
object WeightUtil {
fun connect(initCallback: (connect: Boolean) -> Unit) {
Weigher.setListener(object : WeightListenerImpl() {
override fun onInit(connect: Boolean) {
initCallback(connect)
Log.d("WeightUtil", "connect=$connect")
}
override fun onZero() {
Log.d("WeightUtil", "zero ok")
}
override fun onTare() {
Log.d("WeightUtil", "去皮置零操作成功")
}
override fun onSetIdentify() {
Log.d("WeightUtil", "鉴别率设置操作成功")
}
override fun onGetWeight(address: Int, state: Int, weight: Int) {
runOnUiThread {
val stateStr = when (state) {
SensorScale.STATE_STABLE -> "稳定"
SensorScale.STATE_UNSTABLE -> "不稳定"
SensorScale.STATE_OVER_WEIGHT -> "量程溢出"
else -> ""
}
val result1 = String.format("$stateStr 重量:%s kg", weight / 1000f)
Log.d("WeightUtil", "ttlReturn, address:$address,$result1")
}
}
override fun onReadIdentify(rate: Int) {
Log.d("WeightUtil", "读取鉴别率成功:rate=$rate")
}
override fun onFail(errCode: Int) {
val str = when (errCode) {
Weigher.ERR_001 -> "电子称未初始化"
Weigher.ERR_002 -> "开机零位异常"
Weigher.ERR_003 -> "传感器故障"
Weigher.ERR_004 -> "鉴别率超出范围"
Weigher.ERR_PCB_NOT_SUPPORT -> "主板不支持, " + Build.MODEL
else -> ""
}
Log.d("WeightUtil", str)
}
override fun onFastFilter() {
Log.d("WeightUtil", "快速滤波设置成功")
}
override fun onReadParam() {
Log.d("WeightUtil", "prepare ok")
}
override fun onRangCal() {
Log.d("WeightUtil", "rang cal ok")
}
override fun onSetParam() {
Log.d("WeightUtil", "onSetParam")
}
})
}
private fun runOnUiThread(action: () -> Unit) {
Handler(Looper.getMainLooper()).post {
action()
}
}
fun addWeightListener(
zero: (() -> Unit) = {},
getWeight: ((address: Int, state: Int, weight: Int) -> Unit) = { _, _, _ -> }
) {
Weigher.setListener(object : WeightListenerImpl() {
override fun onZero() {
zero()
}
override fun onGetWeight(address: Int, state: Int, weight: Int) {
getWeight(address, state, weight)
}
})
}
}
open class WeightListenerImpl : Weigher.Listener {
override fun onInit(connect: Boolean) {
}
override fun onZero() {
}
override fun onTare() {
}
override fun onSetIdentify() {
}
override fun onGetWeight(address: Int, state: Int, weight: Int) {
}
override fun onReadIdentify(rate: Int) {
}
override fun onFail(errCode: Int) {
}
override fun onFastFilter() {
}
override fun onReadParam() {
}
override fun onRangCal() {
}
override fun onSetParam() {
}
}
@@ -0,0 +1,175 @@
package com.shuwei.dish.match.utils.ext
import android.annotation.SuppressLint
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.content.SharedPreferences
import android.content.res.Resources
import android.os.Bundle
import android.util.TypedValue
import android.view.View
import android.view.inputmethod.EditorInfo
import android.widget.EditText
import android.widget.Toast
import androidx.core.app.ActivityOptionsCompat
import androidx.fragment.app.Fragment
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import com.shuwei.dish.match.utils.ToastUtil
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
fun Context.toast(
message: String?,
duration: Int = Toast.LENGTH_SHORT,
) {
if (message.isNullOrBlank()) {
return
}
//Toast.makeText(this, message, duration).show()
ToastUtil.show(this, message, duration)
}
fun Fragment.toast(
message: String?,
duration: Int = 2000
) {
activity?.toast(message, duration)
}
//fun Fragment.toast(
// message: String?,
// duration: Int = 2000
//) {
// if (isAdded.not()) {
// return
// }
// CustomToast(
// activity = requireActivity(),
// message = message,
// duration = duration
// ).show()
//}
//
//public fun BaseActivity.toast(message: String?, duration: Int = 2000) {
// CustomToast(
// activity = this,
// message = message,
// duration = duration
// ).show()
//}
fun View.visible() {
visibility = View.VISIBLE
}
fun View.invisible() {
visibility = View.INVISIBLE
}
fun View.gone() {
visibility = View.GONE
}
inline fun <reified T : Activity> Context.startActivity(
bundle: Bundle? = null,
options: ActivityOptionsCompat? = null
) {
Intent(this, T::class.java).apply {
bundle?.let { putExtras(it) }
if (options != null && this@startActivity is Activity) {
startActivity(this, options.toBundle())
} else {
startActivity(this)
}
}
}
inline fun <reified T> Context.startActivity(
block: Intent.() -> Unit = {}
) {
Intent(this, T::class.java).apply {
block()
startActivity(this)
}
}
//inline fun <reified T : Activity> Context.startActivity(action:(bundle: Bundle)-> Unit) {
// Intent(this, T::class.java).apply {
// action(Bundle())
// startActivity(this)
// }
//}
inline fun <reified T> String.toType(gson: Gson? = null, typeToken: TypeToken<T>): T {
return (gson ?: Gson()).fromJson(this, typeToken.type)
}
inline fun <reified T> String.toObject(gson: Gson? = null): T {
return (gson ?: Gson()).fromJson(this, T::class.java)
}
fun Any?.toJsonString(gson: Gson? = null): String {
return (gson ?: Gson()).toJson(this) ?: ""
}
@SuppressLint("ApplySharedPref")
inline fun SharedPreferences.edit(
commit: Boolean = false,
action: SharedPreferences.Editor.() -> Unit
) {
val editor = edit()
action(editor)
if (commit) editor.commit() else editor.apply()
}
fun SharedPreferences.put(vararg pairs: Pair<String, Any>) {
edit {
pairs.forEach { (key, value) ->
when (value) {
is Int -> putInt(key, value)
is String -> putString(key, value)
is Boolean -> putBoolean(key, value)
is Float -> putFloat(key, value)
is Long -> putLong(key, value)
}
}
}
}
val Float.dp: Float
get() = TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
this,
Resources.getSystem().displayMetrics
)
val Int.dp: Int
get() = this.toFloat().dp.toInt()
fun EditText.addOnActionSearchListener(searchCallback: () -> Unit) {
setOnEditorActionListener { v, actionId, event ->
if (actionId == EditorInfo.IME_ACTION_SEARCH) {
// 处理搜索逻辑
searchCallback()
return@setOnEditorActionListener true // 阻止事件继续传递
}
return@setOnEditorActionListener false
}
}
fun View.clickWithDebounce(delay: Long = 500, action: () -> Unit) {
var job: Job? = null
setOnClickListener {
job?.cancel()
job = CoroutineScope(Dispatchers.Main).launch {
delay(delay)
action()
}
}
}
@@ -0,0 +1,25 @@
package com.shuwei.dish.match.utils.ext
import android.text.SpannableString
import android.text.SpannableStringBuilder
import android.text.Spanned
inline fun buildSpannableString(builderAction: SpannableStringBuilder.() -> Unit): SpannableStringBuilder {
return SpannableStringBuilder().apply(builderAction)
}
fun SpannableStringBuilder.appendText(text: String, vararg spans: Any): SpannableStringBuilder {
val start = length
append(text)
spans.forEach { span ->
setSpan(span, start, length, Spanned.SPAN_INCLUSIVE_EXCLUSIVE)
}
return this
}
fun SpannableStringBuilder.withSpan(span: Any, block: SpannableStringBuilder.() -> Unit) {
val start = length
block()
setSpan(span, start, length, Spanned.SPAN_INCLUSIVE_EXCLUSIVE)
}
@@ -0,0 +1,183 @@
package com.shuwei.dish.match.viewmodel
import android.util.Log
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.shuwei.dish.match.base.BaseApp
import com.shuwei.dish.match.db.AppRepository
import com.shuwei.dish.match.entity.CookFoodEntity
import com.shuwei.dish.match.entity.CookFoodGoodsEntity
import com.shuwei.dish.match.entity.SeasoningEntity
import com.shuwei.dish.match.utils.ext.toast
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlin.collections.forEach
class AppViewModel(private val rep: AppRepository) : ViewModel() {
fun updateCookFood(entity: CookFoodEntity) {
viewModelScope.launch {
rep.updateCookFood(entity)
}
}
fun getCookFoodById(foodId: String, cookMode: Int, action: (CookFoodEntity?) -> Unit) {
viewModelScope.launch {
val data = rep.getCookFoodById(foodId, cookMode)
action(data)
}
}
fun getCookFoodList(cookMode: Int, action: (MutableList<CookFoodEntity>?) -> Unit) {
viewModelScope.launch {
val data = rep.getCookFoodList(cookMode)
action(data)
}
}
fun countCookFood(cookMode: Int, action: (Int) -> Unit) {
viewModelScope.launch {
val count = rep.countCookFood(cookMode)
action(count)
}
}
fun saveCookFood(cookMode: Int, entity: CookFoodEntity) {
viewModelScope.launch {
val data = rep.getCookFoodById(entity.foodId, cookMode)
if (data == null) {
rep.insertCookFood(entity)
return@launch
}
rep.updateCookFood(entity)
}
}
fun saveCookFoodAndGoods(
cookMode: Int,
entity: CookFoodEntity,
list: MutableList<CookFoodGoodsEntity>?,
onFinish: () -> Unit
) {
viewModelScope.launch {
val data = rep.getCookFoodById(entity.foodId, cookMode)
if (data != null) {
//存在数据删除
rep.deleteCookFood(entity.foodId, cookMode)
rep.deleteCookFoodGoodsList(entity.foodId)
}
//重新保存数据
rep.insertCookFood(entity)
list?.let { rep.insertGoodsList(it) }
onFinish()
}
}
fun deleteCookFoodAndGoods(
cookMode: Int,
foodId: String,
onFinish: () -> Unit
) {
viewModelScope.launch {
rep.deleteCookFood(foodId = foodId, cookMode = cookMode)
rep.deleteCookFoodGoodsList(foodId)
onFinish()
}
}
//--------------------------------------------------------------------------------------------------------
fun getCookFoodGoodsList(
foodId: String,
action: (list: MutableList<CookFoodGoodsEntity>) -> Unit
) {
viewModelScope.launch {
val list = rep.getCookFoodGoodsList(foodId)
action(list)
}
}
fun updateGoods(entity: CookFoodGoodsEntity) {
viewModelScope.launch {
rep.updateGoods(entity)
}
}
fun saveCookFoodGoods(list: MutableList<CookFoodGoodsEntity>) {
viewModelScope.launch {
val foodId = list[0].foodId
val data: MutableList<CookFoodGoodsEntity>? =
rep.getCookFoodGoodsList(foodId!!)
if (data.isNullOrEmpty()) {
rep.insertGoodsList(list)
return@launch
}
val localDbSeasoningList = rep.getCookFoodGoodsListByType(foodId, 3)
localDbSeasoningList.forEach {
it.isDel = 1
//更新本地调料数据为已删除的状态
rep.updateGoods(it)
}
//筛选出调料数据保存,主辅材不会变更不需要再次处理
val saveSeasoningList = list.filter { it.materialType == 3 }
rep.insertGoodsList(saveSeasoningList.toMutableList())
}
}
//--------------------------------------------------------------------------------------------------------
fun addSeasoning(list: MutableList<SeasoningEntity>, callback: () -> Unit) {
viewModelScope.launch {
rep.deleteBatch()
rep.insertSeasoningList(items = list)
callback()
}
}
private var isProcessing = false
fun loadSeasoning(action: (list: MutableList<SeasoningEntity>) -> Unit) {
viewModelScope.launch {
if (isProcessing) return@launch
isProcessing = true
rep.getAllStream().collect { list ->
action(list)
isProcessing = false
}
}
}
fun deleteEmptySeasoning() {
viewModelScope.launch {
rep.deleteEmptySeasoning()
}
}
fun deleteAll() {
viewModelScope.launch {
rep.deleteBatch()
}
}
fun updateAll(list: MutableList<SeasoningEntity>) {
viewModelScope.launch {
list.forEach {
rep.updateSeasoning(it)
}
}
}
fun saveSeasoning(entity: SeasoningEntity, block:()-> Unit) {
viewModelScope.launch {
val seasoning = rep.getSeasoningBySort(entity.sort)
if (seasoning == null) {
rep.insertSeasoning(entity)
block()
return@launch
}
rep.updateSeasoning(entity.also { it.id = seasoning.id })
block()
}
}
//--------------------------------------------------------------------------------------------------------
}
@@ -0,0 +1,42 @@
//package com.shuwei.dish.match.viewmodel
//
//import androidx.lifecycle.ViewModel
//import androidx.lifecycle.viewModelScope
//import com.shuwei.dish.match.db.CookFoodGoodsRepository
//import com.shuwei.dish.match.entity.CookFoodGoodsEntity
//import kotlinx.coroutines.launch
//
//class CookFoodGoodsViewModel(private val rep: CookFoodGoodsRepository) : ViewModel() {
//
// fun getCookFoodGoodsList(
// foodId: String,
// action: (list: MutableList<CookFoodGoodsEntity>) -> Unit
// ) {
// viewModelScope.launch {
// val list = rep.cookFoodGoodsDao.getCookFoodGoodsList(foodId)
// action(list)
// }
// }
//
// fun saveCookFoodGoods(list: MutableList<CookFoodGoodsEntity>) {
// viewModelScope.launch {
// val foodId = list[0].foodId
// val data: MutableList<CookFoodGoodsEntity>? =
// rep.cookFoodGoodsDao.getCookFoodGoodsList(foodId!!)
// if (data.isNullOrEmpty()) {
// rep.cookFoodGoodsDao.insertAll(list)
// return@launch
// }
// val localDbSeasoningList = rep.cookFoodGoodsDao.getCookFoodGoodsListByType(foodId, 3)
// localDbSeasoningList.forEach {
// it.isDel = 1
// //更新本地调料数据为已删除的状态
// rep.cookFoodGoodsDao.update(it)
// }
// //筛选出调料数据保存,主辅材不会变更不需要再次处理
// val saveSeasoningList = list.filter { it.materialType == 3 }
// rep.cookFoodGoodsDao.insertAll(saveSeasoningList.toMutableList())
// }
// }
//
//}
@@ -0,0 +1,44 @@
//package com.shuwei.dish.match.viewmodel
//
//import androidx.lifecycle.ViewModel
//import androidx.lifecycle.viewModelScope
//import com.shuwei.dish.match.db.CookFoodRepository
//import com.shuwei.dish.match.entity.CookFoodEntity
//import kotlinx.coroutines.launch
//
//class CookFoodViewModel(private val rep: CookFoodRepository) : ViewModel() {
//
// fun getCookFoodById(foodId: String, cookMode: Int, action: (CookFoodEntity?) -> Unit) {
// viewModelScope.launch {
// val data = rep.cookFoodDao.getCookFoodById(foodId, cookMode)
// action(data)
// }
// }
//
// fun getCookFoodList(cookMode: Int, action: (MutableList<CookFoodEntity>?) -> Unit) {
// viewModelScope.launch {
// val data = rep.cookFoodDao.getCookFoodList(cookMode)
// action(data)
// }
// }
//
// fun countCookFood(cookMode: Int, action: (Int) -> Unit) {
// viewModelScope.launch {
// val count = rep.cookFoodDao.countCookFood(cookMode)
// action(count)
// }
// }
//
// fun saveCookFood(cookMode: Int, entity: CookFoodEntity) {
// viewModelScope.launch {
// val data = rep.cookFoodDao.getCookFoodById(entity.foodId, cookMode)
// if (data == null) {
// rep.cookFoodDao.insert(entity)
// return@launch
// }
// rep.cookFoodDao.update(entity)
//
// }
// }
//
//}
@@ -0,0 +1,47 @@
//package com.shuwei.dish.match.viewmodel
//
//import androidx.lifecycle.ViewModel
//import androidx.lifecycle.viewModelScope
//import com.shuwei.dish.match.db.SeasoningRepository
//import com.shuwei.dish.match.entity.SeasoningEntity
//import kotlinx.coroutines.delay
//import kotlinx.coroutines.launch
//
//class DeviceSettingViewModel(private val rep: SeasoningRepository) : ViewModel() {
// fun addSeasoning(list: MutableList<SeasoningEntity>, callback:()-> Unit) {
// viewModelScope.launch {
// rep.seasoningDao.deleteBatch()
// delay(500)
// val rows: Array<Long>? = rep.seasoningDao.insertAll(items = list)
// if (rows.isNullOrEmpty().not()) {
// callback()
// }
// }
// }
//
// private var isProcessing = false
// fun loadSeasoning(action: (list: MutableList<SeasoningEntity>) -> Unit) {
// viewModelScope.launch {
// if (isProcessing) return@launch
// isProcessing = true
// rep.seasoningDao.getAllStream().collect { list ->
// action(list)
// isProcessing = false
// }
// }
// }
//
// fun deleteAll() {
// viewModelScope.launch {
// rep.seasoningDao.deleteBatch()
// }
// }
//
// fun updateAll(list: MutableList<SeasoningEntity>) {
// viewModelScope.launch {
// list.forEach {
// rep.seasoningDao.update(it)
// }
// }
// }
//}
@@ -0,0 +1,24 @@
//package com.shuwei.dish.match.viewmodel
//
//import androidx.lifecycle.ViewModel
//import androidx.lifecycle.viewModelScope
//import com.shuwei.dish.match.db.SeasoningRepository
//import com.shuwei.dish.match.entity.CookFoodEntity
//import com.shuwei.dish.match.entity.SeasoningEntity
//import kotlinx.coroutines.launch
//
//class SubmitDishViewModel(private val rep: SeasoningRepository) : ViewModel() {
//
// private var isProcessing = false
// fun loadSeasoning(action: (list: MutableList<SeasoningEntity>) -> Unit) {
// viewModelScope.launch {
// if (isProcessing) return@launch
// isProcessing = true
// rep.seasoningDao.getAllStream().collect { list ->
// action(list)
// isProcessing = false
// }
// }
// }
//
//}
@@ -0,0 +1,43 @@
package com.shuwei.dish.match.viewmodel.factory
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import com.shuwei.dish.match.db.AppRepository
import com.shuwei.dish.match.viewmodel.AppViewModel
@Suppress("UNCHECKED_CAST")
class AppFactory(private val repo: AppRepository) : ViewModelProvider.Factory {
override fun <T : ViewModel> create(modelClass: Class<T>): T {
return AppViewModel(repo) as T
}
}
//
//@Suppress("UNCHECKED_CAST")
//class DeviceSettingFactory(private val repo: SeasoningRepository) : ViewModelProvider.Factory {
// override fun <T : ViewModel> create(modelClass: Class<T>): T {
// return DeviceSettingViewModel(repo) as T
// }
//}
//
////@Suppress("UNCHECKED_CAST")
////class SubmitDishFactory(private val repo: SeasoningRepository) : ViewModelProvider.Factory {
//// override fun <T : ViewModel> create(modelClass: Class<T>): T {
//// return SubmitDishViewModel(repo) as T
//// }
////}
//
//@Suppress("UNCHECKED_CAST")
//class CookFoodFactory(private val repo: CookFoodRepository) : ViewModelProvider.Factory {
// override fun <T : ViewModel> create(modelClass: Class<T>): T {
// return CookFoodViewModel(repo) as T
// }
//}
//
//@Suppress("UNCHECKED_CAST")
//class CookFoodGoodsFactory(private val repo: CookFoodGoodsRepository) : ViewModelProvider.Factory {
// override fun <T : ViewModel> create(modelClass: Class<T>): T {
// return CookFoodGoodsViewModel(repo) as T
// }
//}
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@color/black" android:state_checked="true" />
<item android:color="@color/black666" android:state_checked="false" />
</selector>
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@color/dish_green" android:state_checked="true" />
<item android:color="@color/black" android:state_checked="false" />
</selector>
Binary file not shown.

After

Width:  |  Height:  |  Size: 501 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 149 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Some files were not shown because too many files have changed in this diff Show More