diff --git a/.idea/deploymentTargetSelector.xml b/.idea/deploymentTargetSelector.xml
index b268ef3..00284f6 100644
--- a/.idea/deploymentTargetSelector.xml
+++ b/.idea/deploymentTargetSelector.xml
@@ -4,6 +4,14 @@
+
+
+
+
+
+
+
+
diff --git a/.idea/misc.xml b/.idea/misc.xml
index e236b7d..7e8cd7e 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -1,4 +1,3 @@
-
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index ef303cd..fdda7e7 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -95,4 +95,7 @@ dependencies {
// implementation(libs.adapter.coroutines)
implementation("androidx.work:work-runtime-ktx:2.8.1")
+
+ implementation(libs.core)
+ implementation(libs.android.core)
}
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index b1b297d..d9c064b 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -21,11 +21,13 @@
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
- android:icon="@mipmap/ic_launcher512"
+ android:icon="@mipmap/ic_logo512"
android:label="@string/app_name"
- android:roundIcon="@mipmap/ic_launcher512"
+ android:roundIcon="@mipmap/ic_logo512"
android:supportsRtl="true"
android:theme="@style/Theme.SmartPlateCabinet"
+ android:networkSecurityConfig="@xml/network_security_config"
+ android:usesCleartextTraffic="true"
tools:targetApi="31">
+ android:launchMode="singleTask"/>
+
diff --git a/app/src/main/java/com/sw/platecabinet/GlobalData.kt b/app/src/main/java/com/sw/platecabinet/GlobalData.kt
index f26018b..cb1b81f 100644
--- a/app/src/main/java/com/sw/platecabinet/GlobalData.kt
+++ b/app/src/main/java/com/sw/platecabinet/GlobalData.kt
@@ -29,6 +29,17 @@ object GlobalData {
var appId = "Hkz1rBk6PZXbS8KwKr67K2eZtsz8bRoMHLg64bUdgCZj"
var sdkKey = "AabXs3sHM8UhhE7oCGf4LVMLrdkGb1nJNksbjjTdVt7k"
var activeKey = "085F-118G-Q391-53YL"
+
+ /**
+ * 具体业务baseurl
+ */
+ var appBaseUrl: String = ""
+
+ /**
+ * 设备id
+ */
+ var deviceId: String = ""
+ var restId: String = ""
}
/**
@@ -45,6 +56,7 @@ object Constants {
* key
*/
object GlobalKey {
+ const val KEY_EQUIPMENT_INFO = "equipmentInfo"
const val KEY_TOKEN = "tokenKey"
const val KEY_FIRST_RUN = "firstRun"
const val KEY_USER_INFO = "userInfoKey"
diff --git a/app/src/main/java/com/sw/platecabinet/activity/DeviceInitActivity.kt b/app/src/main/java/com/sw/platecabinet/activity/DeviceInitActivity.kt
new file mode 100644
index 0000000..e7e9575
--- /dev/null
+++ b/app/src/main/java/com/sw/platecabinet/activity/DeviceInitActivity.kt
@@ -0,0 +1,72 @@
+package com.sw.platecabinet.activity
+
+import android.content.Intent
+import androidx.activity.viewModels
+import androidx.lifecycle.lifecycleScope
+import com.sw.plate.utils.AppUtil
+import com.sw.platecabinet.GlobalData
+import com.sw.platecabinet.databinding.ActivityDeviceInitBinding
+import com.sw.platecabinet.databinding.ItemTitleTimeBinding
+import com.sw.platecabinet.utils.QRCodeUtil
+import com.sw.platecabinet.viewmodel.DeviceViewModel
+import kotlinx.coroutines.launch
+import timber.log.Timber
+import kotlin.getValue
+
+/**
+ * 设备初始化界面
+ */
+class DeviceInitActivity : BaseActivity() {
+
+ private val deviceViewModel by viewModels()
+
+ override fun inflateViewBinding(): ActivityDeviceInitBinding {
+ return ActivityDeviceInitBinding.inflate(layoutInflater)
+ }
+
+ override fun inflateTitleBinding(): ItemTitleTimeBinding? {
+ return null
+ }
+
+ override fun initialize() {
+ var deviceId = AppUtil.getUDID(this)
+ deviceId = "6ce7cd59-b875-38b2-b73d-88a570be3212"
+ GlobalData.deviceId = deviceId
+ val isSuccess = deviceViewModel.checkEquipmentInfo()
+ if (isSuccess) {
+ goLoginActivity()
+ return
+ }
+ binding.ivQrCode.setImageBitmap(
+ QRCodeUtil.generateQRCode(
+ content = GlobalData.deviceId,
+ size = 200
+ )
+ )
+ binding.btnInit.setOnClickListener {
+ deviceViewModel.getDeviceToken()
+ }
+ }
+
+ override fun registerDataChange() {
+ super.registerDataChange()
+ lifecycleScope.launch {
+ deviceViewModel.deviceInfoResult.collect { it ->
+ if (it == true) {
+ goLoginActivity()
+ }
+ }
+ }
+ }
+
+ private fun goLoginActivity() {
+ val intent = Intent(this, LoginByFaceActivity::class.java)
+ startActivity(intent)
+ finish()
+ }
+
+ override fun onLeftDoubleClick() {
+
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/sw/platecabinet/model/response/ApiResponse.kt b/app/src/main/java/com/sw/platecabinet/model/response/ApiResponse.kt
index 3258796..113835a 100644
--- a/app/src/main/java/com/sw/platecabinet/model/response/ApiResponse.kt
+++ b/app/src/main/java/com/sw/platecabinet/model/response/ApiResponse.kt
@@ -4,7 +4,8 @@ data class ApiResponse(
val code: Int,
val success: Boolean? = false,
val msg: String? = "",
- val data: T? = null
+ val data: T? = null,
+ val result: T? = null,
) {
fun isSuccess(): Boolean = code == 200
}
diff --git a/app/src/main/java/com/sw/platecabinet/model/response/EquipmentInfo.kt b/app/src/main/java/com/sw/platecabinet/model/response/EquipmentInfo.kt
new file mode 100644
index 0000000..4d85533
--- /dev/null
+++ b/app/src/main/java/com/sw/platecabinet/model/response/EquipmentInfo.kt
@@ -0,0 +1,72 @@
+package com.sw.platecabinet.model.response
+
+
+import android.os.Parcelable
+import com.google.gson.annotations.SerializedName
+import kotlinx.parcelize.Parcelize
+
+@Parcelize
+data class EquipmentInfo(
+ @SerializedName("appPackageLocalUrl")
+ val appPackageLocalUrl: String? = "",
+ @SerializedName("appPackageUrl")
+ val appPackageUrl: String? = "",
+ @SerializedName("arcsoftActiveKey")
+ val arcsoftActiveKey: String? = "",
+ @SerializedName("arcsoftAppId")
+ val arcsoftAppId: String? = "",
+ @SerializedName("arcsoftSdkKey")
+ val arcsoftSdkKey: String? = "",
+ @SerializedName("arrayCross")
+ val arrayCross: Int? = 0,
+ @SerializedName("arrayMode")
+ val arrayMode: String? = "",
+ @SerializedName("arrayVertical")
+ val arrayVertical: Int? = 0,
+ @SerializedName("canteenId")
+ val canteenId: String? = "",
+ @SerializedName("canteenName")
+ val canteenName: String? = "",
+ @SerializedName("clientServerIp")
+ val clientServerIp: String? = "",
+ @SerializedName("createBy")
+ val createBy: String? = "",
+ @SerializedName("createTime")
+ val createTime: String? = "",
+ @SerializedName("customerName")
+ val customerName: String? = "",
+ @SerializedName("equipmentCode")
+ val equipmentCode: String? = "",
+ @SerializedName("equipmentName")
+ val equipmentName: String? = "",
+ @SerializedName("equipmentName_dictText")
+ val equipmentNameDictText: String? = "",
+ @SerializedName("id")
+ val id: String? = "",
+ @SerializedName("isSync")
+ val isSync: Int? = 0,
+ @SerializedName("mqName")
+ val mqName: String? = "",
+ @SerializedName("mqPassword")
+ val mqPassword: String? = "",
+ @SerializedName("orgCode")
+ val orgCode: String? = "",
+ @SerializedName("owningTrack")
+ val owningTrack: Int? = 0,
+ @SerializedName("owningTrackOrder")
+ val owningTrackOrder: Int? = 0,
+ @SerializedName("screenHtml")
+ val screenHtml: String? = "",
+ @SerializedName("serviceRequestAddress")
+ val serviceRequestAddress: String? = "",
+ @SerializedName("status")
+ val status: Int? = 0,
+ @SerializedName("sysOrgCode")
+ val sysOrgCode: String? = "",
+ @SerializedName("updateBy")
+ val updateBy: String? = "",
+ @SerializedName("updateTime")
+ val updateTime: String? = "",
+ @SerializedName("zhstServerIp")
+ val zhstServerIp: String? = ""
+) : Parcelable
\ No newline at end of file
diff --git a/app/src/main/java/com/sw/platecabinet/network/ApiClient.kt b/app/src/main/java/com/sw/platecabinet/network/ApiClient.kt
index 9785b37..34dc5e1 100644
--- a/app/src/main/java/com/sw/platecabinet/network/ApiClient.kt
+++ b/app/src/main/java/com/sw/platecabinet/network/ApiClient.kt
@@ -12,6 +12,7 @@ import java.util.concurrent.TimeUnit
object ApiClient {
private const val BASE_URL = "https://vip.shuziweidao.com"
+ private const val DEVICE_BASE_URL = "http://device.shuziweidao.com:8889/"
// private const val BASE_URL = "http://192.168.1.8:9092"
private const val TIME_OUT = 30L // 超时时间(秒)
@@ -33,7 +34,7 @@ object ApiClient {
.build()
private val retrofit = Retrofit.Builder()
- .baseUrl(BASE_URL)
+ .baseUrl(DEVICE_BASE_URL)
.client(okHttpClient)
.addConverterFactory(GsonConverterFactory.create())
// .addCallAdapterFactory(CoroutineCallAdapterFactory()) // 协程适配器
diff --git a/app/src/main/java/com/sw/platecabinet/network/api/ApiService.kt b/app/src/main/java/com/sw/platecabinet/network/api/ApiService.kt
index 37e9beb..bd58353 100644
--- a/app/src/main/java/com/sw/platecabinet/network/api/ApiService.kt
+++ b/app/src/main/java/com/sw/platecabinet/network/api/ApiService.kt
@@ -1,25 +1,48 @@
package com.sw.platecabinet.network.api
+import com.sw.platecabinet.GlobalData
import com.sw.platecabinet.model.request.BindParam
import com.sw.platecabinet.model.request.EquipmentParam
import com.sw.platecabinet.model.request.LoginParam
import com.sw.platecabinet.model.request.SearchParam
import com.sw.platecabinet.model.response.ApiResponse
+import com.sw.platecabinet.model.response.EquipmentInfo
import com.sw.platecabinet.model.response.EquipmentUserInfo
import com.sw.platecabinet.model.response.SearchResult
import com.sw.platecabinet.model.response.UserFaceModel
import retrofit2.http.Body
import retrofit2.http.GET
+import retrofit2.http.Header
import retrofit2.http.POST
import retrofit2.http.Query
+import retrofit2.http.Url
interface ApiService {
+ /**
+ * device获取token
+ */
+ @GET("sys/getEquipmentToken")
+ suspend fun getDeviceToken(
+ @Query("qrcodeId") qrcodeId: String,
+ @Query("appVersion") appVersion: String = GlobalData.appVersion
+ ): ApiResponse
+
+ /**
+ *获取配置信息
+ */
+ @GET("equipment/stEquipment/queryByEquipmentCode")
+ suspend fun getDeviceInfo(
+ @Query("equipmentCode") equipmentCode: String,
+ @Query("appVersion") appVersion: String = GlobalData.appVersion,
+ @Header("X-Access-Token") token: String
+ ): ApiResponse
/**
* 生成token
*/
- @GET("/shuwei-zhct/scales/generateToken")
+ @GET//("/shuwei-zhct/scales/generateToken")
suspend fun generateToken(
+ @Url url: String = "${GlobalData.appBaseUrl}/shuwei-zhct/scales/generateToken",
@Query("deviceId") deviceId: String,
@Query("appVersion") appVersion: String,
@Query("equipmentCode") equipmentCode: String
@@ -28,8 +51,9 @@ interface ApiService {
/**
* 获取人脸数据
*/
- @GET("/shuwei-zhct/scales/getUserFaceCache")
+ @GET//("/shuwei-zhct/scales/getUserFaceCache")
suspend fun getUserFaceCache(
+ @Url url: String = "${GlobalData.appBaseUrl}/shuwei-zhct/scales/getUserFaceCache",
@Query("appVersion") appVersion: String,
@Query("equipmentCode") equipmentCode: String
): ApiResponse>
@@ -37,38 +61,56 @@ interface ApiService {
/**
* 餐盘用户信息获取
*/
- @POST("/shuwei-zhct/swEquipmentRelUser/equipmentBoxLogin")
- suspend fun equipmentBoxLogin(@Body param: LoginParam): ApiResponse
+ @POST//("/shuwei-zhct/swEquipmentRelUser/equipmentBoxLogin")
+ suspend fun equipmentBoxLogin(
+ @Url url: String = "${GlobalData.appBaseUrl}/shuwei-zhct/swEquipmentRelUser/equipmentBoxLogin",
+ @Body param: LoginParam
+ ): ApiResponse
/**
* 餐盘用户信息列表查询
*/
- @POST("/shuwei-zhct/swEquipmentRelUser/list")
- suspend fun getEquipmentList(@Body param: EquipmentParam): ApiResponse>
+ @POST//("/shuwei-zhct/swEquipmentRelUser/list")
+ suspend fun getEquipmentList(
+ @Url url: String = "${GlobalData.appBaseUrl}/shuwei-zhct/swEquipmentRelUser/list",
+ @Body param: EquipmentParam
+ ): ApiResponse>
/**
* 餐盘用户信息绑定解绑
*/
- @POST("/shuwei-zhct/swEquipmentRelUser/addOrEdit")
- suspend fun bindEquipment(@Body param: BindParam): ApiResponse
+ @POST//("/shuwei-zhct/swEquipmentRelUser/addOrEdit")
+ suspend fun bindEquipment(
+ @Url url: String = "${GlobalData.appBaseUrl}/shuwei-zhct/swEquipmentRelUser/addOrEdit",
+ @Body param: BindParam
+ ): ApiResponse
/**
* 用户信息模糊搜索
*/
- @POST("/shuwei-user/swclientUserInfoShop/selectList")
- suspend fun searchUser(@Body param: SearchParam): ApiResponse
+ @POST//("/shuwei-user/swclientUserInfoShop/selectList")
+ suspend fun searchUser(
+ @Url url: String = "${GlobalData.appBaseUrl}/shuwei-user/swclientUserInfoShop/selectList",
+ @Body param: SearchParam
+ ): ApiResponse
/**
* 通过餐盘号获取信息
*/
- @POST("/shuwei-zhct/swEquipmentRelUser/findByPlateNumber")
- suspend fun findByPlateNumber(@Body param: BindParam): ApiResponse
+ @POST//("/shuwei-zhct/swEquipmentRelUser/findByPlateNumber")
+ suspend fun findByPlateNumber(
+ @Url url: String = "${GlobalData.appBaseUrl}/shuwei-zhct/swEquipmentRelUser/findByPlateNumber",
+ @Body param: BindParam
+ ): ApiResponse
/**
* 获取人脸增量数据
*
* @param timeDate 时间戳(毫秒级)
*/
- @GET("/shuwei-zhct/scales/getHeartbeatInterface")
- suspend fun getHeartbeatInterface(@Query("timeDate") timeDate: Long): ApiResponse>
+ @GET//("/shuwei-zhct/scales/getHeartbeatInterface")
+ suspend fun getHeartbeatInterface(
+ @Url url: String = "${GlobalData.appBaseUrl}/shuwei-zhct/scales/getHeartbeatInterface",
+ @Query("timeDate") timeDate: Long
+ ): ApiResponse>
}
\ No newline at end of file
diff --git a/app/src/main/java/com/sw/platecabinet/repository/RemoteRepository.kt b/app/src/main/java/com/sw/platecabinet/repository/RemoteRepository.kt
index b512884..e23addd 100644
--- a/app/src/main/java/com/sw/platecabinet/repository/RemoteRepository.kt
+++ b/app/src/main/java/com/sw/platecabinet/repository/RemoteRepository.kt
@@ -6,6 +6,7 @@ import com.sw.platecabinet.model.request.EquipmentParam
import com.sw.platecabinet.model.request.LoginParam
import com.sw.platecabinet.model.request.SearchParam
import com.sw.platecabinet.model.response.ApiResponse
+import com.sw.platecabinet.model.response.EquipmentInfo
import com.sw.platecabinet.model.response.EquipmentUserInfo
import com.sw.platecabinet.model.response.SearchResult
import com.sw.platecabinet.model.response.UserFaceModel
@@ -17,15 +18,39 @@ import com.sw.platecabinet.network.api.ApiService
class RemoteRepository constructor(
private val apiService: ApiService
) : BaseRepository() {
+
+ /**
+ * 生成token
+ */
+ suspend fun getDeviceToken(qrcodeId: String): ApiResponse {
+ return safeApiCall {
+ apiService.getDeviceToken(
+ qrcodeId
+ )
+ }
+ }
+
+ /**
+ * 获取设备信息
+ */
+ suspend fun getDeviceInfo(equipmentCode: String, token: String): ApiResponse {
+ return safeApiCall {
+ apiService.getDeviceInfo(
+ equipmentCode,
+ token = token
+ )
+ }
+ }
+
/**
* 生成token
*/
suspend fun generateToken(deviceId: String): ApiResponse {
return safeApiCall {
apiService.generateToken(
- deviceId,
- GlobalData.appVersion,
- GlobalData.globalEquipmentCode
+ deviceId = deviceId,
+ appVersion = GlobalData.appVersion,
+ equipmentCode = GlobalData.globalEquipmentCode
)
}
}
@@ -36,8 +61,8 @@ class RemoteRepository constructor(
suspend fun getUserFaceCache(): ApiResponse> {
return safeApiCall {
apiService.getUserFaceCache(
- GlobalData.appVersion,
- GlobalData.globalEquipmentCode
+ appVersion = GlobalData.appVersion,
+ equipmentCode = GlobalData.globalEquipmentCode
)
}
}
@@ -46,35 +71,35 @@ class RemoteRepository constructor(
* 登录
*/
suspend fun equipmentBoxLogin(param: LoginParam): ApiResponse {
- return safeApiCall { apiService.equipmentBoxLogin(param) }
+ return safeApiCall { apiService.equipmentBoxLogin(param = param) }
}
/**
* 获取设备绑定用户列表
*/
suspend fun getEquipmentList(param: EquipmentParam): ApiResponse> {
- return safeApiCall { apiService.getEquipmentList(param) }
+ return safeApiCall { apiService.getEquipmentList(param = param) }
}
/**
* 餐盘用户信息绑定解绑
*/
suspend fun bindEquipment(param: BindParam): ApiResponse {
- return safeApiCall { apiService.bindEquipment(param) }
+ return safeApiCall { apiService.bindEquipment(param = param) }
}
/**
* 用户信息模糊搜索
*/
suspend fun searchUser(param: SearchParam): ApiResponse {
- return safeApiCall { apiService.searchUser(param) }
+ return safeApiCall { apiService.searchUser(param = param) }
}
/**
* 通过餐盘编号获取绑定信息
*/
suspend fun findByPlateNumber(param: BindParam): ApiResponse {
- return safeApiCall { apiService.findByPlateNumber(param) }
+ return safeApiCall { apiService.findByPlateNumber(param = param) }
}
/**
@@ -83,6 +108,6 @@ class RemoteRepository constructor(
* @param timeDate 时间戳(毫秒级)
*/
suspend fun getHeartbeatInterface(timeDate: Long): ApiResponse> {
- return safeApiCall { apiService.getHeartbeatInterface(timeDate) }
+ return safeApiCall { apiService.getHeartbeatInterface(timeDate = timeDate) }
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/sw/platecabinet/utils/QRCodeUtil.kt b/app/src/main/java/com/sw/platecabinet/utils/QRCodeUtil.kt
new file mode 100644
index 0000000..5ddbc01
--- /dev/null
+++ b/app/src/main/java/com/sw/platecabinet/utils/QRCodeUtil.kt
@@ -0,0 +1,103 @@
+package com.sw.platecabinet.utils
+
+import android.graphics.Bitmap
+import android.graphics.Canvas
+import android.graphics.Color
+import com.google.zxing.BarcodeFormat
+import com.google.zxing.EncodeHintType
+import com.google.zxing.WriterException
+import com.google.zxing.common.BitMatrix
+import com.google.zxing.qrcode.QRCodeWriter
+import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel
+import kotlin.apply
+import kotlin.ranges.until
+import kotlin.text.isEmpty
+
+/**
+ * 二维码生成工具类
+ */
+object QRCodeUtil {
+
+ /**
+ * 生成二维码(默认大小)
+ * @param content 二维码内容
+ * @return 生成的二维码Bitmap
+ */
+ @JvmOverloads
+ fun generateQRCode(content: String, size: Int = 500): Bitmap? {
+ return generateQRCode(content, size, Color.BLACK, Color.WHITE)
+ }
+
+ /**
+ * 生成二维码(自定义颜色)
+ * @param content 二维码内容
+ * @param size 二维码边长(像素)
+ * @param colorCode 二维码颜色
+ * @param backgroundColor 背景颜色
+ * @return 生成的二维码Bitmap
+ */
+ fun generateQRCode(
+ content: String,
+ size: Int,
+ colorCode: Int,
+ backgroundColor: Int
+ ): Bitmap? {
+ if (content.isEmpty()) {
+ return null
+ }
+
+ return try {
+ val hints = mutableMapOf().apply {
+ put(EncodeHintType.CHARACTER_SET, "UTF-8")
+ put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H) // 纠错级别
+ put(EncodeHintType.MARGIN, 1) // 边距
+ }
+
+ val bitMatrix = QRCodeWriter().encode(
+ content,
+ BarcodeFormat.QR_CODE,
+ size,
+ size,
+ hints
+ )
+
+ val pixels = IntArray(size * size).apply {
+ for (y in 0 until size) {
+ for (x in 0 until size) {
+ this[y * size + x] = if (bitMatrix.get(x, y)) colorCode else backgroundColor
+ }
+ }
+ }
+
+ Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888).apply {
+ setPixels(pixels, 0, size, 0, 0, size, size)
+ }
+
+ } catch (e: WriterException) {
+ e.printStackTrace()
+ null
+ }
+ }
+
+ /**
+ * 生成带Logo的二维码
+ * @param content 二维码内容
+ * @param size 二维码边长(像素)
+ * @param logo Logo Bitmap
+ * @return 带Logo的二维码Bitmap
+ */
+ fun generateQRCodeWithLogo(content: String, size: Int, logo: Bitmap?): Bitmap? {
+ val qrCode = generateQRCode(content, size) ?: return null
+ logo ?: return qrCode
+
+ val logoSize = size / 5 // Logo大小约为二维码的1/5
+ val scaledLogo = Bitmap.createScaledBitmap(logo, logoSize, logoSize, false)
+
+ val offset = (size - logoSize) / 2
+ return Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888).apply {
+ val canvas = Canvas(this)
+ canvas.drawBitmap(qrCode, 0f, 0f, null)
+ canvas.drawBitmap(scaledLogo, offset.toFloat(), offset.toFloat(), null)
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/sw/platecabinet/viewmodel/BaseViewModel.kt b/app/src/main/java/com/sw/platecabinet/viewmodel/BaseViewModel.kt
index 9051b83..771c484 100644
--- a/app/src/main/java/com/sw/platecabinet/viewmodel/BaseViewModel.kt
+++ b/app/src/main/java/com/sw/platecabinet/viewmodel/BaseViewModel.kt
@@ -3,7 +3,9 @@ package com.sw.platecabinet.viewmodel
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.sw.plate.utils.ToastUtils
+import com.sw.platecabinet.GlobalData
import com.sw.platecabinet.model.response.ApiResponse
+import com.sw.platecabinet.model.response.EquipmentInfo
import com.sw.platecabinet.network.ApiClient
import com.sw.platecabinet.repository.RemoteRepository
import kotlinx.coroutines.flow.MutableStateFlow
@@ -62,4 +64,12 @@ abstract class BaseViewModel() : ViewModel() {
fun handleError(exception: Exception) {
Timber.d("handleError ${exception.message}")
}
+
+ fun parseEquipmentInfo(equipmentInfo: EquipmentInfo) {
+ GlobalData.appBaseUrl = equipmentInfo.appPackageUrl!!
+ GlobalData.sdkKey = equipmentInfo.arcsoftSdkKey!!
+ GlobalData.appId = equipmentInfo.arcsoftAppId!!
+// GlobalData.activeKey = equipmentInfo.arcsoftActiveKey!!
+ GlobalData.restId = equipmentInfo.canteenId!!
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/com/sw/platecabinet/viewmodel/DeviceViewModel.kt b/app/src/main/java/com/sw/platecabinet/viewmodel/DeviceViewModel.kt
new file mode 100644
index 0000000..e31fde6
--- /dev/null
+++ b/app/src/main/java/com/sw/platecabinet/viewmodel/DeviceViewModel.kt
@@ -0,0 +1,68 @@
+package com.sw.platecabinet.viewmodel
+
+import com.sw.inbound.utils.GsonUtils
+import com.sw.inbound.utils.SPUtil
+import com.sw.platecabinet.GlobalData
+import com.sw.platecabinet.GlobalKey
+import com.sw.platecabinet.model.response.EquipmentInfo
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.StateFlow
+import timber.log.Timber
+import kotlin.jvm.java
+
+/**
+ * 初始化的viewmodel
+ */
+class DeviceViewModel : BaseViewModel() {
+ private val _deviceInfoResult = MutableStateFlow(null)
+ val deviceInfoResult: StateFlow = _deviceInfoResult
+
+ /**
+ * 获取token
+ */
+ fun getDeviceToken(deviceId: String = GlobalData.deviceId) {
+ launchWithLoading {
+ val response = repository.getDeviceToken(deviceId)
+ if (parseResponse(response)) {
+ val response1 = repository.getDeviceInfo(deviceId, response.result!!)
+
+ if (parseResponse(response1)) {
+ val equipmentInfo = response1.result
+ if (equipmentInfo == null) return@launchWithLoading
+ try {
+ parseEquipmentInfo(equipmentInfo)
+ SPUtil.getInstance()
+ .put(GlobalKey.KEY_EQUIPMENT_INFO, GsonUtils.toJson(equipmentInfo))
+ _deviceInfoResult.value = true
+ } catch (e: Exception) {
+ Timber.e(e)
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * 检查缓存数据
+ */
+ fun checkEquipmentInfo(): Boolean {
+ val equipmentInfoStr = SPUtil.getInstance().get(GlobalKey.KEY_EQUIPMENT_INFO, "")
+ if (equipmentInfoStr == null) {
+ Timber.e("获取缓存设备信息失败")
+ return false
+ }
+ val equipmentInfo =
+ GsonUtils.fromJson(equipmentInfoStr, EquipmentInfo::class.java)
+ if (equipmentInfo == null) {
+ Timber.e("解析缓存设备信息失败")
+ return false
+ }
+ try {
+ parseEquipmentInfo(equipmentInfo)
+ return true
+ } catch (e: Exception) {
+ Timber.e(e)
+ return false
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/res/drawable/bg_init_button.xml b/app/src/main/res/drawable/bg_init_button.xml
new file mode 100644
index 0000000..71ff7c1
--- /dev/null
+++ b/app/src/main/res/drawable/bg_init_button.xml
@@ -0,0 +1,11 @@
+
+
+ -
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/bg_splash.xml b/app/src/main/res/drawable/bg_splash.xml
new file mode 100644
index 0000000..df638a7
--- /dev/null
+++ b/app/src/main/res/drawable/bg_splash.xml
@@ -0,0 +1,18 @@
+
+
+
+
+ -
+
+
+ -
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/img_init.png b/app/src/main/res/drawable/img_init.png
new file mode 100644
index 0000000..e8d0844
Binary files /dev/null and b/app/src/main/res/drawable/img_init.png differ
diff --git a/app/src/main/res/layout/activity_device_init.xml b/app/src/main/res/layout/activity_device_init.xml
new file mode 100644
index 0000000..940dd59
--- /dev/null
+++ b/app/src/main/res/layout/activity_device_init.xml
@@ -0,0 +1,48 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_title_time.xml b/app/src/main/res/layout/item_title_time.xml
index f77b81c..a67784e 100644
--- a/app/src/main/res/layout/item_title_time.xml
+++ b/app/src/main/res/layout/item_title_time.xml
@@ -3,7 +3,7 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
- android:layout_height="wrap_content"
+ android:layout_height="40dp"
android:paddingHorizontal="24dp">
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher512.png b/app/src/main/res/mipmap-xxxhdpi/ic_logo512.png
similarity index 100%
rename from app/src/main/res/mipmap-xxxhdpi/ic_launcher512.png
rename to app/src/main/res/mipmap-xxxhdpi/ic_logo512.png
diff --git a/app/src/main/res/values-night/themes.xml b/app/src/main/res/values-night/themes.xml
index 2209f65..3877414 100644
--- a/app/src/main/res/values-night/themes.xml
+++ b/app/src/main/res/values-night/themes.xml
@@ -3,5 +3,6 @@
\ No newline at end of file
diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml
index 9b2b5a5..b37dab8 100644
--- a/app/src/main/res/values/themes.xml
+++ b/app/src/main/res/values/themes.xml
@@ -4,6 +4,7 @@
- true
- false
- false
+ - @drawable/bg_splash
diff --git a/app/src/main/res/xml/network_security_config.xml b/app/src/main/res/xml/network_security_config.xml
new file mode 100644
index 0000000..f443c3c
--- /dev/null
+++ b/app/src/main/res/xml/network_security_config.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index 485a7e8..90ead1d 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -23,7 +23,12 @@ timber = "5.0.1"
gson = "2.13.1"
hiltAndroid = "2.56.2"
+core = "3.4.1"
+androidCore = "3.3.0"
+
[libraries]
+android-core = { module = "com.google.zxing:android-core", version.ref = "androidCore" }
+core = { module = "com.google.zxing:core", version.ref = "core" }
androidx-activity-ktx = { module = "androidx.activity:activity-ktx", version.ref = "activityKtx" }
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
androidx-fragment-ktx = { module = "androidx.fragment:fragment-ktx", version.ref = "fragmentKtx" }