接口联调2

This commit is contained in:
2025-08-08 14:54:11 +08:00
parent 65199f4c70
commit 383c354f29
12 changed files with 145 additions and 84 deletions
+4
View File
@@ -69,6 +69,10 @@ dependencies {
implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.4.0") implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.4.0")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.2") implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.2")
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-footer-classics:3.0.0-alpha")
// implementation("io.github.jeremyliao:live-event-bus-x:1.8.0") // implementation("io.github.jeremyliao:live-event-bus-x:1.8.0")
// implementation("com.hoho:android-usb-serial:1.3.0") // implementation("com.hoho:android-usb-serial:1.3.0")
// implementation("io.github.jeadyx:jserialport:1.5") // implementation("io.github.jeadyx:jserialport:1.5")
@@ -8,10 +8,12 @@ import android.app.Application
*/ */
class App : Application() { class App : Application() {
//暂时固定,后续从接口获取 //从接口获取
var accessToken: String = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJjYW50ZWVuSWQiOiIiLCJ0eXBlIjoiNiIsInVzZXJJZCI6IjE2NzgyMjY1NTI5MzE1NDkxODYifQ.CQmbELpqT6QzvVCgCeirwvSvPp8Mhft_h6b1Af574Co" var accessToken: String = ""
//"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJjYW50ZWVuSWQiOiIiLCJ0eXBlIjoiNiIsInVzZXJJZCI6IjE2NzgyMjY1NTI5MzE1NDkxODYifQ.CQmbELpqT6QzvVCgCeirwvSvPp8Mhft_h6b1Af574Co"
var androidId:String = "" var deviceId:String = ""
var canteenId:String = ""
override fun onCreate() { override fun onCreate() {
super.onCreate() super.onCreate()
@@ -21,7 +23,7 @@ class App : Application() {
companion object { companion object {
private lateinit var app: App private lateinit var app: App
fun get(): App { fun getInstance(): App {
return app return app
} }
} }
@@ -8,7 +8,6 @@ import android.os.Looper
import android.provider.Settings import android.provider.Settings
import android.util.Log import android.util.Log
import android.util.SparseArray import android.util.SparseArray
import android.util.SparseIntArray
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.lifecycle.Lifecycle import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
@@ -29,8 +28,6 @@ import com.shuwei.intelligent.shelves.task.TaskManager
import com.shuwei.intelligent.shelves.utils.UIUtils import com.shuwei.intelligent.shelves.utils.UIUtils
import com.shuwei.intelligent.shelves.utils.f2C import com.shuwei.intelligent.shelves.utils.f2C
import com.shuwei.intelligent.shelves.utils.hexToDec import com.shuwei.intelligent.shelves.utils.hexToDec
import kotlinx.coroutines.CoroutineStart
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.Date import java.util.Date
@@ -91,43 +88,40 @@ class HomeActivity : BaseActivity() {
//SerialPortManager.send(DEVICE_INFO_CMD) //SerialPortManager.send(DEVICE_INFO_CMD)
} }
repeatOnLifecycle(Lifecycle.State.CREATED) {
repeatOnLifecycle(Lifecycle.State.STARTED) { launch {
viewModel.getShelfListUiState.collect { state -> viewModel.getAccessTokenUiState.collect { state ->
when (state) { when (state) {
is UiState.Loading -> showProgress() is UiState.Loading -> {}
is UiState.Success<*> -> updateUI(state.data) is UiState.Success<*> -> getTokenSuccess(state.data)
is UiState.Error -> showError(state.msg) is UiState.Error -> UIUtils.toast(state.msg)
else -> {} else -> {}
}
} }
} }
} launch {
repeatOnLifecycle(Lifecycle.State.STARTED) { viewModel.getShelfListUiState.collect { state ->
viewModel.getAccessTokenUiState.collect { state -> when (state) {
when (state) { is UiState.Loading -> showProgress()
is UiState.Loading -> {} is UiState.Success<*> -> updateUI(state.data)
is UiState.Success<*> -> getTokenSuccess(state.data) is UiState.Error -> showError(state.msg)
is UiState.Error -> UIUtils.toast(state.msg) else -> {}
else -> {} }
} }
} }
} }
} }
TaskManager.startTask() TaskManager.startTask()
App.get().androidId = "53babf69-0d2f-3875-a649-f2e12f80ad4c1" val androidId = Settings.Secure.getString(contentResolver, Settings.Secure.ANDROID_ID)
// Settings.Secure.getString(contentResolver, Settings.Secure.ANDROID_ID) Log.d(TAG, "onCreate: androidId=${androidId}")
Log.d(TAG, "onCreate: androidId=${App.get().androidId}") App.getInstance().deviceId = "53babf69-0d2f-3875-a649-f2e12f80ad4c1"
val swDpValue = resources?.configuration?.smallestScreenWidthDp val swDpValue = resources?.configuration?.smallestScreenWidthDp
Log.d(TAG, "onCreate: swDpValue=$swDpValue") Log.d(TAG, "onCreate: swDpValue=$swDpValue")
viewModel.getShelfList(deviceId = App.get().androidId)
viewModel.getAccessToken(App.getInstance().deviceId)
viewModel.getAccessToken(App.get().androidId)
// repeat(100) { // repeat(100) {
// lifecycleScope.launch { // lifecycleScope.launch {
@@ -141,7 +135,9 @@ class HomeActivity : BaseActivity() {
private fun getTokenSuccess(data: RespData<*>) { private fun getTokenSuccess(data: RespData<*>) {
Log.d(TAG, "getTokenSuccess: $data") Log.d(TAG, "getTokenSuccess: $data")
data.result?.let { data.result?.let {
//App.get().accessToken = it.toString() App.getInstance().accessToken = it.toString()
//UIUtils.toast(it.toString())
viewModel.getShelfList(deviceId = App.getInstance().deviceId)
} }
} }
@@ -156,6 +152,7 @@ class HomeActivity : BaseActivity() {
UIUtils.toast("数据错误") UIUtils.toast("数据错误")
return return
} }
App.getInstance().canteenId = data.result.canteenId
val tempList = data.result.containerGoodsList val tempList = data.result.containerGoodsList
if (tempList.isNullOrEmpty()) { if (tempList.isNullOrEmpty()) {
UIUtils.toast("数据为空") UIUtils.toast("数据为空")
@@ -15,6 +15,7 @@ import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle import androidx.lifecycle.repeatOnLifecycle
import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.GridLayoutManager
import com.chad.library.adapter4.util.setOnDebouncedItemClick import com.chad.library.adapter4.util.setOnDebouncedItemClick
import com.scwang.smart.refresh.layout.constant.RefreshState
import com.shuwei.intelligent.shelves.HomeActivity.Companion.DEVICE_INFO_CMD import com.shuwei.intelligent.shelves.HomeActivity.Companion.DEVICE_INFO_CMD
import com.shuwei.intelligent.shelves.adapter.SearchAdapter import com.shuwei.intelligent.shelves.adapter.SearchAdapter
import com.shuwei.intelligent.shelves.base.BaseActivity import com.shuwei.intelligent.shelves.base.BaseActivity
@@ -48,6 +49,7 @@ class ShelfActivity : BaseActivity() {
const val RECEIVER_DEVICE_INFO = "receiverDeviceInfo" const val RECEIVER_DEVICE_INFO = "receiverDeviceInfo"
const val SHELF_WEIGHT = "shelfWeight" const val SHELF_WEIGHT = "shelfWeight"
const val PAGE_SIZE = 50
} }
private lateinit var binding: ActivityShelfBinding private lateinit var binding: ActivityShelfBinding
@@ -57,6 +59,7 @@ class ShelfActivity : BaseActivity() {
private var clickIndex: Int = -1 private var clickIndex: Int = -1
private var realWeight: Int = 0 private var realWeight: Int = 0
private var pageNo: Int = 1
private val viewModel: NetViewModel by viewModels() private val viewModel: NetViewModel by viewModels()
@@ -87,8 +90,7 @@ class ShelfActivity : BaseActivity() {
} }
// loadSearchData() // loadSearchData()
viewModel.getGoodsList( viewModel.getGoodsList(
canteenId = "1599670511042785282", canteenId = "1599670511042785282", goodsName = text.toString().trim()
goodsName = text.toString().trim()
) )
KeyboardUtil.hideKeyboard(context, this) KeyboardUtil.hideKeyboard(context, this)
} }
@@ -119,8 +121,7 @@ class ShelfActivity : BaseActivity() {
val shelfNo = shelfModel?.deviceNo ?: 0 val shelfNo = shelfModel?.deviceNo ?: 0
val hex = shelfNo.toString(16).padStart(2, '0').uppercase() val hex = shelfNo.toString(16).padStart(2, '0').uppercase()
Log.d(TAG, "onCreate: hex=$hex") Log.d(TAG, "onCreate: hex=$hex")
val zeroClearingCmd = val zeroClearingCmd = "${HomeActivity.HEADER}0401${hex}${HomeActivity.FOOTER}"
"${HomeActivity.HEADER}0401${hex}${HomeActivity.FOOTER}"
Log.d(TAG, "onCreate: zeroClearingCmd=$zeroClearingCmd") Log.d(TAG, "onCreate: zeroClearingCmd=$zeroClearingCmd")
SerialPortManager.send(zeroClearingCmd) SerialPortManager.send(zeroClearingCmd)
} }
@@ -144,9 +145,32 @@ class ShelfActivity : BaseActivity() {
registerReceiver(receiver, IntentFilter(RECEIVER_DEVICE_INFO)) registerReceiver(receiver, IntentFilter(RECEIVER_DEVICE_INFO))
binding.refreshLayout.let {
it.setEnableRefresh(true)
it.setEnableLoadMore(false)
it.setOnRefreshListener {
pageNo = 1
getGoodsList()
}
it.setOnLoadMoreListener { getGoodsList() }
}
getGoodsList()
}
private fun finishRefresh() {
binding.refreshLayout.let {
if (it.state == RefreshState.Refreshing) {
it.finishRefresh(500)
} else if (binding.refreshLayout.state == RefreshState.Loading) {
it.finishLoadMore(500)
}
}
}
private fun getGoodsList() {
viewModel.getGoodsList( viewModel.getGoodsList(
canteenId = "1599670511042785282" canteenId = App.getInstance().canteenId, pageNo = pageNo, pageSize = PAGE_SIZE
) )
} }
@@ -156,6 +180,7 @@ class ShelfActivity : BaseActivity() {
@SuppressLint("NotifyDataSetChanged") @SuppressLint("NotifyDataSetChanged")
private fun updateUI(data: RespData<*>) { private fun updateUI(data: RespData<*>) {
finishRefresh()
Loading.dismiss() Loading.dismiss()
Log.d(TAG, "updateUI: ${data.toJsonString()}") Log.d(TAG, "updateUI: ${data.toJsonString()}")
if (data.result !is GoodsRecord) { if (data.result !is GoodsRecord) {
@@ -166,12 +191,21 @@ class ShelfActivity : BaseActivity() {
UIUtils.toast("数据错误") UIUtils.toast("数据错误")
return return
} }
list.clear() if (pageNo == 1) {
list.addAll(data.result.records) list.clear()
}
val records = data.result.records
list.addAll(records)
val enableLoadMore = records.size >= PAGE_SIZE
binding.refreshLayout.setEnableLoadMore(enableLoadMore)
if (enableLoadMore) {
pageNo++
}
searchAdapter.notifyDataSetChanged() searchAdapter.notifyDataSetChanged()
} }
private fun showError(message: String) { private fun showError(message: String) {
finishRefresh()
Loading.dismiss() Loading.dismiss()
UIUtils.toast(message) UIUtils.toast(message)
} }
@@ -6,7 +6,7 @@ data class ShelfModel(
var id: String? = null, var id: String? = null,
var deviceNo: Int = 0, var deviceNo: Int = 0,
var shelfName: String? = null, var shelfName: String? = null,
var goodsId: Int = 0, var goodsId: String = "",
var goodsName: String? = null, var goodsName: String? = null,
var weight: Double? = null, var weight: Double? = null,
var createTime: String? = null var createTime: String? = null
@@ -4,7 +4,6 @@ import com.shuwei.intelligent.shelves.model.GoodsRecord
import com.shuwei.intelligent.shelves.model.ShelfBody import com.shuwei.intelligent.shelves.model.ShelfBody
import com.shuwei.intelligent.shelves.model.ShelfResult import com.shuwei.intelligent.shelves.model.ShelfResult
import retrofit2.http.Body import retrofit2.http.Body
import retrofit2.http.FormUrlEncoded
import retrofit2.http.GET import retrofit2.http.GET
import retrofit2.http.POST import retrofit2.http.POST
import retrofit2.http.Query import retrofit2.http.Query
@@ -21,12 +20,11 @@ interface ApiService {
suspend fun getGoodsList( suspend fun getGoodsList(
@Query("canteenId") canteenId: String = "0", @Query("canteenId") canteenId: String = "0",
@Query("goodsName") goodsName: String? = null, @Query("goodsName") goodsName: String? = null,
@Query("pageNo") pageNo: Int = 1, @Query("pageNo") pageNo: Int = 1,
@Query("pageSize") pageSize: Int = 50, @Query("pageSize") pageSize: Int = 50,
): RespData<GoodsRecord> ): RespData<GoodsRecord>
@FormUrlEncoded
@POST(UrlConfig.SAVE_SHELF_GOODS_LIST) @POST(UrlConfig.SAVE_SHELF_GOODS_LIST)
suspend fun saveShelfGoodsList(@Body body: ShelfBody): RespData<Any?> suspend fun saveShelfGoodsList(@Body body: ShelfBody): RespData<Any?>
@@ -3,10 +3,8 @@ package com.shuwei.intelligent.shelves.net
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.util.Log import android.util.Log
import com.shuwei.intelligent.shelves.App import com.shuwei.intelligent.shelves.App
import okhttp3.Call
import okhttp3.Interceptor import okhttp3.Interceptor
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.Response import okhttp3.Response
import retrofit2.Retrofit import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory import retrofit2.converter.gson.GsonConverterFactory
@@ -36,7 +34,7 @@ class HttpManager private constructor() {
addInterceptor(LoggingInterceptor()) addInterceptor(LoggingInterceptor())
addInterceptor { chain -> addInterceptor { chain ->
val request = chain.request().newBuilder() val request = chain.request().newBuilder()
.header("x-access-token", App.get().accessToken) .header("x-access-token", App.getInstance().accessToken)
.build() .build()
chain.proceed(request) chain.proceed(request)
} }
@@ -4,9 +4,9 @@ import android.content.Context
import android.util.Log import android.util.Log
import androidx.work.CoroutineWorker import androidx.work.CoroutineWorker
import androidx.work.WorkerParameters import androidx.work.WorkerParameters
import com.shuwei.intelligent.shelves.App
import com.shuwei.intelligent.shelves.HomeActivity import com.shuwei.intelligent.shelves.HomeActivity
import com.shuwei.intelligent.shelves.model.ShelfBody import com.shuwei.intelligent.shelves.model.ShelfBody
import com.shuwei.intelligent.shelves.net.HttpManager
import com.shuwei.intelligent.shelves.net.apiService import com.shuwei.intelligent.shelves.net.apiService
import com.shuwei.intelligent.shelves.utils.ext.toJsonString import com.shuwei.intelligent.shelves.utils.ext.toJsonString
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
@@ -39,8 +39,8 @@ class SyncTask(appContext: Context, workerParams: WorkerParameters) :
Log.d(TAG, "performSync: list:${list.toJsonString()}") Log.d(TAG, "performSync: list:${list.toJsonString()}")
val submitList = list.sortedBy { it.deviceNo } val submitList = list.sortedBy { it.deviceNo }
val body = ShelfBody().also { val body = ShelfBody().also {
it.deviceId = "" it.deviceId = App.getInstance().deviceId
it.canteenId = "" it.canteenId = App.getInstance().canteenId
it.goodsList = submitList it.goodsList = submitList
} }
val resp = apiService.saveShelfGoodsList(body) val resp = apiService.saveShelfGoodsList(body)
@@ -15,7 +15,7 @@ object TaskManager {
// .setInitialDelay(10, TimeUnit.SECONDS) // .setInitialDelay(10, TimeUnit.SECONDS)
// .setInputData(inputData) // .setInputData(inputData)
.build() .build()
WorkManager.getInstance(App.get()) WorkManager.getInstance(App.getInstance())
.enqueueUniqueWork(TASK_NAME, ExistingWorkPolicy.REPLACE, nextRequest) .enqueueUniqueWork(TASK_NAME, ExistingWorkPolicy.REPLACE, nextRequest)
// val constraints = Constraints.Builder() // val constraints = Constraints.Builder()
@@ -37,7 +37,7 @@ object TaskManager {
} }
fun cancelTask() { fun cancelTask() {
WorkManager.getInstance(App.get()) WorkManager.getInstance(App.getInstance())
.cancelUniqueWork(TASK_NAME) .cancelUniqueWork(TASK_NAME)
} }
@@ -5,10 +5,10 @@ import com.shuwei.intelligent.shelves.App
//D6DADEDB0302000001000C06 //D6DADEDB0302000001000C06
object UIUtils { object UIUtils {
fun toast(strRes: Int) { fun toast(strRes: Int) {
Toast.makeText(App.get(), strRes, Toast.LENGTH_SHORT).show() Toast.makeText(App.getInstance(), strRes, Toast.LENGTH_SHORT).show()
} }
fun toast(str: String) { fun toast(str: String) {
Toast.makeText(App.get(), str, Toast.LENGTH_SHORT).show() Toast.makeText(App.getInstance(), str, Toast.LENGTH_SHORT).show()
} }
} }
@@ -156,23 +156,37 @@
android:textSize="15sp" android:textSize="15sp"
tools:ignore="Autofill,HardcodedText,TextFields" /> tools:ignore="Autofill,HardcodedText,TextFields" />
</LinearLayout> </LinearLayout>
<com.scwang.smart.refresh.layout.SmartRefreshLayout
<androidx.recyclerview.widget.RecyclerView android:id="@+id/refreshLayout"
android:id="@+id/rvSearch"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="0dp" android:layout_height="0dp"
android:paddingStart="12dp" android:layout_weight="1">
android:paddingBottom="4dp"
android:layout_marginTop="8dp" <com.scwang.smart.refresh.header.ClassicsHeader
android:paddingTop="4dp" android:layout_width="match_parent"
android:paddingEnd="12dp" android:layout_height="wrap_content" />
android:clipToPadding="false"
android:layout_weight="1" <androidx.recyclerview.widget.RecyclerView
android:overScrollMode="never" android:id="@+id/rvSearch"
tools:listitem="@layout/list_item_search" android:layout_width="match_parent"
app:layoutManager="androidx.recyclerview.widget.GridLayoutManager" android:layout_height="match_parent"
app:spanCount="2" android:paddingStart="12dp"
tools:itemCount="10"/> android:paddingBottom="4dp"
android:layout_marginTop="8dp"
android:paddingTop="4dp"
android:paddingEnd="12dp"
android:clipToPadding="false"
android:overScrollMode="never"
tools:listitem="@layout/list_item_search"
app:layoutManager="androidx.recyclerview.widget.GridLayoutManager"
app:spanCount="2"
tools:itemCount="10"/>
<com.scwang.smart.refresh.footer.ClassicsFooter
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</com.scwang.smart.refresh.layout.SmartRefreshLayout>
<!-- android:layout_marginTop="48dp"--> <!-- android:layout_marginTop="48dp"-->
<com.google.android.material.button.MaterialButton <com.google.android.material.button.MaterialButton
@@ -156,23 +156,37 @@
android:textSize="30sp" android:textSize="30sp"
tools:ignore="Autofill,HardcodedText,TextFields" /> tools:ignore="Autofill,HardcodedText,TextFields" />
</LinearLayout> </LinearLayout>
<com.scwang.smart.refresh.layout.SmartRefreshLayout
<androidx.recyclerview.widget.RecyclerView android:id="@+id/refreshLayout"
android:id="@+id/rvSearch"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="0dp" android:layout_height="0dp"
android:paddingStart="36dp" android:layout_weight="1">
android:paddingBottom="12dp"
android:layout_marginTop="24dp" <com.scwang.smart.refresh.header.ClassicsHeader
android:paddingTop="12dp" android:layout_width="match_parent"
android:paddingEnd="36dp" android:layout_height="wrap_content" />
android:clipToPadding="false"
android:layout_weight="1" <androidx.recyclerview.widget.RecyclerView
android:overScrollMode="never" android:id="@+id/rvSearch"
tools:listitem="@layout/list_item_search" android:layout_width="match_parent"
app:layoutManager="androidx.recyclerview.widget.GridLayoutManager" android:layout_height="match_parent"
app:spanCount="2" android:paddingStart="36dp"
tools:itemCount="10"/> android:paddingBottom="12dp"
android:layout_marginTop="24dp"
android:paddingTop="12dp"
android:paddingEnd="36dp"
android:clipToPadding="false"
android:overScrollMode="never"
tools:listitem="@layout/list_item_search"
app:layoutManager="androidx.recyclerview.widget.GridLayoutManager"
app:spanCount="2"
tools:itemCount="10"/>
<com.scwang.smart.refresh.footer.ClassicsFooter
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</com.scwang.smart.refresh.layout.SmartRefreshLayout>
<!-- android:layout_marginTop="48dp"--> <!-- android:layout_marginTop="48dp"-->
<com.google.android.material.button.MaterialButton <com.google.android.material.button.MaterialButton