refactor(sdk): 重构项目并添加 native 代码支持
- 移除了不必要的日志库 LogUtil - 添加了高德地图服务并配置了相关权限 - 更新了 API 接口定义,统一添加了前缀 -重构了 AppConfig 类,使用 native代码获取配置信息 - 更新了项目构建配置,支持 native 代码编译 - 优化了部分代码结构,提高了代码的可维护性
This commit is contained in:
@ -1,7 +1,9 @@
|
||||
import com.android.build.gradle.LibraryExtension
|
||||
|
||||
plugins {
|
||||
alias(libs.plugins.android.library)
|
||||
alias(libs.plugins.jetbrains.kotlin.android)
|
||||
id 'com.google.devtools.ksp'
|
||||
alias(libs.plugins.jetbrains.kotlin.android)
|
||||
id 'maven-publish'
|
||||
// kotlin 序列化注解
|
||||
id 'kotlin-parcelize'
|
||||
@ -19,6 +21,12 @@ android {
|
||||
vectorDrawables {
|
||||
useSupportLibrary true
|
||||
}
|
||||
|
||||
ndk {
|
||||
abiFilters 'armeabi-v7a', 'arm64-v8a'
|
||||
}
|
||||
|
||||
multiDexEnabled true
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
@ -31,7 +39,6 @@ android {
|
||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
|
||||
// publishNonDefault true
|
||||
}
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_11
|
||||
@ -48,9 +55,17 @@ android {
|
||||
composeOptions {
|
||||
kotlinCompilerExtensionVersion '1.5.15'
|
||||
}
|
||||
packaging {
|
||||
resources {
|
||||
excludes += '/META-INF/{AL2.0,LGPL2.1}'
|
||||
if (project.extensions.getByName("android") is LibraryExtension) {
|
||||
// AGP 7.0+
|
||||
packaging {
|
||||
resources {
|
||||
excludes += "META-INF/LICENSE"
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// AGP 6.x
|
||||
packagingOptions {
|
||||
exclude("META-INF/LICENSE")
|
||||
}
|
||||
}
|
||||
publishing {
|
||||
@ -64,7 +79,7 @@ publishing {
|
||||
release(MavenPublication) {
|
||||
groupId = 'io.github.szl9'
|
||||
artifactId = 'zd_servicing'
|
||||
version = "1.0.1.9.9.138"
|
||||
version = "1.0.3"
|
||||
|
||||
pom {
|
||||
packaging = "aar"
|
||||
@ -135,81 +150,87 @@ tasks.register('generateRepo', Zip) {
|
||||
into 'zd_servicing'
|
||||
archiveFileName.set('zd_servicing.zip')
|
||||
}
|
||||
|
||||
|
||||
dependencies {
|
||||
api libs.androidx.core.ktx
|
||||
api libs.androidx.appcompat
|
||||
api libs.material
|
||||
api libs.androidx.lifecycle.viewmodel.compose
|
||||
api libs.androidx.lifecycle.runtime.ktx
|
||||
api libs.androidx.activity.compose
|
||||
api platform(libs.androidx.compose.bom)
|
||||
api libs.androidx.ui
|
||||
api libs.androidx.ui.graphics
|
||||
api libs.androidx.ui.tooling.preview
|
||||
api libs.androidx.material3
|
||||
api libs.androidx.work.runtime.ktx
|
||||
api libs.androidx.exifinterface
|
||||
api "androidx.core:core-ktx:1.15.0" // coreKtx = "1.15.0"
|
||||
api "androidx.appcompat:appcompat:1.7.0" // appcompat = "1.7.0"
|
||||
api "com.google.android.material:material:1.12.0" // material = "1.12.0"
|
||||
api "androidx.lifecycle:lifecycle-viewmodel-compose:2.8.7" // lifecycleRuntimeKtx = "2.8.7"
|
||||
api "androidx.lifecycle:lifecycle-runtime-ktx:2.8.7" // lifecycleRuntimeKtx = "2.8.7"
|
||||
api "androidx.activity:activity-compose:1.10.0" // activityCompose = "1.10.0"
|
||||
api platform("androidx.compose:compose-bom:2025.01.01") // composeBom = "2025.01.01"
|
||||
api "androidx.compose.ui:ui:1.7.7" // uiVersion = "1.7.7"
|
||||
api "androidx.compose.ui:ui-graphics:1.7.7" // uiGraphics = "1.7.7"
|
||||
api "androidx.compose.ui:ui-tooling-preview:1.7.7" // uiToolingPreview = "1.7.7"
|
||||
api "androidx.compose.material3:material3:1.3.1" // material3="1.3.1"
|
||||
api "androidx.work:work-runtime-ktx:2.10.0" // workRuntimeKtx = "2.10.0"
|
||||
api "androidx.exifinterface:exifinterface:1.3.7" // exifinterface = "1.3.7"
|
||||
|
||||
testApi libs.junit
|
||||
androidTestApi libs.androidx.junit
|
||||
androidTestApi libs.androidx.espresso.core
|
||||
androidTestApi platform(libs.androidx.compose.bom)
|
||||
androidTestApi libs.androidx.ui.test.junit4
|
||||
debugApi libs.androidx.ui.test.manifest
|
||||
debugApi libs.ui.tooling
|
||||
testApi "junit:junit:4.13.2" // junit = "4.13.2"
|
||||
androidTestApi "androidx.test.ext:junit:1.2.1" // junitVersion = "1.2.1"
|
||||
androidTestApi "androidx.test.espresso:espresso-core:3.6.1" // espressoCore = "3.6.1"
|
||||
androidTestApi platform("androidx.compose:compose-bom:2025.01.01") // composeBom = "2025.01.01"
|
||||
androidTestApi "androidx.compose.ui:ui-test-junit4:1.7.7" // uiGraphics = "1.7.7"
|
||||
debugApi "androidx.compose.ui:ui-test-manifest:1.7.7" // uiGraphics = "1.7.7"
|
||||
debugApi "androidx.compose.ui:ui-tooling:1.4.0"
|
||||
// From [libraries] ui-tooling, version.ref = "uiToolingVersion", and [versions] uiToolingVersion = "1.4.0"
|
||||
|
||||
api libs.coil.compose
|
||||
api libs.coil.gif
|
||||
api "io.coil-kt:coil-compose:2.6.0" // coilCompose = "2.6.0"
|
||||
api "io.coil-kt:coil-gif:2.6.0" // coilCompose = "2.6.0"
|
||||
|
||||
api libs.permissionx
|
||||
api libs.utilcodex
|
||||
api "com.guolindev.permissionx:permissionx:1.8.0" // permissionx = "1.8.0"
|
||||
api "com.blankj:utilcodex:1.31.1" // utilcodex = "1.31.1"
|
||||
|
||||
api libs.crashreport
|
||||
api "com.tencent.bugly:crashreport:4.0.4" // crashreport = "4.0.4"
|
||||
|
||||
// 高德地图
|
||||
api libs.xdmap
|
||||
api libs.location
|
||||
api libs.search
|
||||
api "com.amap.api:3dmap:8.1.0" // xdmap = "8.1.0"
|
||||
api "com.amap.api:location:5.6.1" // location = "5.6.1"
|
||||
api "com.amap.api:search:7.3.0" // search = "7.3.0"
|
||||
|
||||
// // JPush
|
||||
api libs.jpush
|
||||
api libs.gson
|
||||
// JPush
|
||||
api "cn.jiguang.sdk:jpush:5.6.0" // jpush = "5.6.0"
|
||||
api "com.google.code.gson:gson:2.11.0" // gson = "2.11.0"
|
||||
|
||||
// 网络
|
||||
api libs.retrofit
|
||||
api libs.converter.gson
|
||||
api libs.adapter.rxjava3
|
||||
api libs.rxjava
|
||||
api libs.rxandroid
|
||||
api libs.logging.interceptor
|
||||
api libs.fastjson
|
||||
api "com.squareup.retrofit2:retrofit:2.9.0" // retrofit = "2.9.0"
|
||||
api "com.squareup.retrofit2:converter-gson:2.9.0" // converterGson = "2.9.0"
|
||||
api "com.squareup.retrofit2:adapter-rxjava3:2.9.0"
|
||||
// From [libraries] adapter-rxjava3, version.ref = "converterGson"
|
||||
api "io.reactivex.rxjava3:rxjava:3.1.7" // rxjava = "3.1.7"
|
||||
api "io.reactivex.rxjava3:rxandroid:3.0.2" // rxandroid = "3.0.2"
|
||||
api "com.squareup.okhttp3:logging-interceptor:4.11.0" // loggingInterceptor = "4.11.0"
|
||||
api "com.alibaba:fastjson:1.2.69" // fastjson = "1.2.69"
|
||||
|
||||
// 本地数据
|
||||
api libs.room.runtime
|
||||
annotationProcessor libs.room.compiler
|
||||
ksp libs.room.compiler
|
||||
api libs.mmkv
|
||||
api "androidx.room:room-runtime:2.6.1" // roomRuntimeVersion = "2.6.1"
|
||||
annotationProcessor "androidx.room:room-compiler:2.6.1" // roomCompilerVersion = "2.6.1"
|
||||
ksp "androidx.room:room-compiler:2.6.1" // roomCompilerVersion = "2.6.1"
|
||||
api "com.tencent:mmkv:1.3.11" // mmkv = "1.3.11"
|
||||
|
||||
// 7z
|
||||
api libs.xz
|
||||
api libs.commons.compress
|
||||
api "org.tukaani:xz:1.9" // xz = "1.9"
|
||||
api "org.apache.commons:commons-compress:1.23.0" // commonsCompress = "1.23.0"
|
||||
|
||||
api libs.core
|
||||
api libs.tbssdk
|
||||
api "com.google.zxing:core:3.5.3" // core = "3.5.3"
|
||||
api "com.tencent.tbs:tbssdk:44286" // tbssdk = "44286"
|
||||
|
||||
// CameraX
|
||||
api libs.androidx.camera.core
|
||||
api libs.androidx.camera.camera2
|
||||
api libs.androidx.camera.lifecycle
|
||||
api libs.androidx.camera.view
|
||||
api libs.androidx.camera.extensions
|
||||
// CameraX - Assuming all camera dependencies use 'cameraCore' version
|
||||
api "androidx.camera:camera-core:1.4.1" // cameraCore = "1.4.1"
|
||||
api "androidx.camera:camera-camera2:1.4.1" // cameraCore = "1.4.1"
|
||||
api "androidx.camera:camera-lifecycle:1.4.1" // cameraCore = "1.4.1"
|
||||
api "androidx.camera:camera-view:1.4.1" // cameraCore = "1.4.1"
|
||||
api "androidx.camera:camera-extensions:1.4.1" // cameraCore = "1.4.1"
|
||||
|
||||
api libs.glide
|
||||
annotationProcessor libs.compiler
|
||||
api "com.github.bumptech.glide:glide:4.16.0" // glide = "4.16.0"
|
||||
annotationProcessor "com.github.bumptech.glide:compiler:4.14.2" // compiler = "4.14.2"
|
||||
|
||||
api libs.org.eclipse.paho.client.mqttv3
|
||||
api libs.org.eclipse.paho.android.service
|
||||
api "org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.2.5"
|
||||
// orgEclipsePahoClientMqttv3 = "1.2.5"
|
||||
api "org.eclipse.paho:org.eclipse.paho.android.service:1.1.1"
|
||||
// orgEclipsePahoAndroidService = "1.1.1"
|
||||
|
||||
api libs.face.detection
|
||||
api "com.google.mlkit:face-detection:16.1.7" // faceDetection = "16.1.7"
|
||||
}
|
||||
|
||||
|
6
servicing/proguard-rules.pro
vendored
6
servicing/proguard-rules.pro
vendored
@ -1,5 +1,11 @@
|
||||
-dontwarn java.lang.invoke.StringConcatFactory
|
||||
|
||||
# 设置混淆的压缩比率 0 ~ 7
|
||||
-optimizationpasses 5
|
||||
|
||||
# 混淆采用的算法
|
||||
-optimizations !code/simplification/cast,!field/*,!class/merging/*
|
||||
|
||||
# 保留行号用于调试
|
||||
-keepattributes SourceFile,LineNumberTable
|
||||
-renamesourcefileattribute SourceFile
|
||||
|
@ -226,6 +226,12 @@
|
||||
android:screenOrientation="portrait"
|
||||
android:theme="@style/Theme.Dealer" />
|
||||
|
||||
<service
|
||||
android:name="com.amap.api.location.APSService"
|
||||
android:exported="false"
|
||||
android:foregroundServiceType="location"
|
||||
android:process=":aps" />
|
||||
|
||||
<receiver
|
||||
android:name="com.za.service.ZdPushServiceReceive"
|
||||
android:exported="false">
|
||||
|
@ -3,7 +3,7 @@ package com.za.base
|
||||
import com.za.common.GlobalData
|
||||
import com.za.net.RetrofitHelper
|
||||
|
||||
object AppConfig {
|
||||
internal object AppConfig {
|
||||
var isRelease = false
|
||||
|
||||
// API 相关地址
|
||||
@ -52,14 +52,14 @@ object AppConfig {
|
||||
fun release() {
|
||||
isRelease = true // API 配置
|
||||
GlobalData.networkEnv = Const.NetEnv.Main
|
||||
BASE_URL = "https://api.sinoassist.com"
|
||||
IMG_BASE_URL = "https://api.sinoassist.com"
|
||||
Resource_URL = "https://www.sinoassist.com/res"
|
||||
BASE_URL = getReleaseBaseUrl()
|
||||
IMG_BASE_URL = getReleaseImgBaseUrl()
|
||||
Resource_URL = getReleaseResourceUrl()
|
||||
|
||||
// H5 配置
|
||||
trainUrl = "https://www.sinoassist.com/h5/supplier/dispatch/diverTrainDocment"
|
||||
documentUrl = "https://www.sinoassist.com/h5/supplier/dispatch/docmentList"
|
||||
newDriverTrainUrl = "https://www.sinoassist.com/h5/supplier/dispatch/driverTrainingList";
|
||||
trainUrl = getReleaseTrainUrl()
|
||||
documentUrl = getReleaseDocumentUrl()
|
||||
newDriverTrainUrl = getReleaseNewDriverTrainUrl()
|
||||
}
|
||||
|
||||
|
||||
@ -71,13 +71,12 @@ object AppConfig {
|
||||
GlobalData.networkEnv = Const.NetEnv.Review
|
||||
|
||||
// API 配置
|
||||
BASE_URL = "http://interface.review.sino-assist.com"
|
||||
IMG_BASE_URL = "http://interface.review.sino-assist.com"
|
||||
Resource_URL = "https://www.sinoassist.com/res"
|
||||
documentUrl = "http://interface.review.sino-assist.com/h5/supplier/dispatch/docmentList"
|
||||
trainUrl = "http://interface.review.sino-assist.com/h5/supplier/dispatch/diverTrainDocment"
|
||||
newDriverTrainUrl =
|
||||
"http://interface.review.sino-assist.com/h5/supplier/dispatch/driverTrainingList"
|
||||
BASE_URL = getReviewBaseUrl()
|
||||
IMG_BASE_URL = getReviewImgBaseUrl()
|
||||
Resource_URL = getReviewResourceUrl()
|
||||
documentUrl = getReviewDocumentUrl()
|
||||
trainUrl = getReviewTrainUrl()
|
||||
newDriverTrainUrl = getReviewNewDriverTrainUrl()
|
||||
}
|
||||
|
||||
/**
|
||||
@ -88,13 +87,13 @@ object AppConfig {
|
||||
GlobalData.networkEnv = Const.NetEnv.CRM1
|
||||
|
||||
// API 配置
|
||||
BASE_URL = "https://api1.sino-assist.com"
|
||||
IMG_BASE_URL = "https://api1.sino-assist.com"
|
||||
Resource_URL = "https://crm1.sino-assist.com/res"
|
||||
BASE_URL = getCrm1BaseUrl()
|
||||
IMG_BASE_URL = getCrm1ImgBaseUrl()
|
||||
Resource_URL = getCrm1ResourceUrl()
|
||||
|
||||
documentUrl = "https://crm1.sino-assist.com/h5/supplier/dispatch/docmentList";
|
||||
trainUrl = "https://crm1.sino-assist.com/h5/supplier/dispatch/diverTrainDocment";
|
||||
newDriverTrainUrl = "https://crm1.sino-assist.com/h5/supplier/dispatch/driverTrainingList";
|
||||
documentUrl = getCrm1DocumentUrl()
|
||||
trainUrl = getCrm1TrainUrl()
|
||||
newDriverTrainUrl = getCrm1NewDriverTrainUrl()
|
||||
}
|
||||
|
||||
/**
|
||||
@ -105,9 +104,9 @@ object AppConfig {
|
||||
GlobalData.networkEnv = Const.NetEnv.CRM2
|
||||
|
||||
// API 配置
|
||||
BASE_URL = "https://api2.sino-assist.com"
|
||||
IMG_BASE_URL = "https://api2.sino-assist.com"
|
||||
Resource_URL = "https://crm2.sino-assist.com/res"
|
||||
BASE_URL = getCrm2BaseUrl()
|
||||
IMG_BASE_URL = getCrm2ImgBaseUrl()
|
||||
Resource_URL = getCrm2ResourceUrl()
|
||||
}
|
||||
|
||||
|
||||
@ -115,15 +114,12 @@ object AppConfig {
|
||||
isRelease = false
|
||||
GlobalData.networkEnv = Const.NetEnv.UAT
|
||||
|
||||
BASE_URL = "https://api-uat.sino-assist.com" //crm2
|
||||
IMG_BASE_URL = "https://api-uat.sino-assist.com"
|
||||
Resource_URL = "https://uat.sino-assist.com/res"
|
||||
documentUrl = "https://uat.sino-assist.com/h5/supplier/dispatch/docmentList"
|
||||
trainUrl = "https://uat.sino-assist.com/h5/supplier/dispatch/diverTrainDocment"
|
||||
newDriverTrainUrl = "https://uat.sino-assist.com/h5/supplier/dispatch/driverTrainingList"
|
||||
documentUrl = "https://uat.sino-assist.com/h5/supplier/dispatch/docmentList";
|
||||
trainUrl = "https://uat.sino-assist.com/h5/supplier/dispatch/diverTrainDocment";
|
||||
newDriverTrainUrl = "https://uat.sino-assist.com/h5/supplier/dispatch/driverTrainingList";
|
||||
BASE_URL = getUatBaseUrl()
|
||||
IMG_BASE_URL = getUatImgBaseUrl()
|
||||
Resource_URL = getUatResourceUrl()
|
||||
documentUrl = getUatDocumentUrl()
|
||||
trainUrl = getUatTrainUrl()
|
||||
newDriverTrainUrl = getUatNewDriverTrainUrl()
|
||||
}
|
||||
|
||||
/**
|
||||
@ -151,4 +147,42 @@ object AppConfig {
|
||||
}
|
||||
return documentUrl + "?token=${GlobalData.token}&driverId=${GlobalData.driverInfoBean?.userId}&keyword=$keyWord"
|
||||
}
|
||||
|
||||
private external fun getReleaseBaseUrl() : String
|
||||
private external fun getReleaseImgBaseUrl() : String
|
||||
private external fun getReleaseResourceUrl() : String
|
||||
private external fun getReleaseTrainUrl() : String
|
||||
private external fun getReleaseDocumentUrl() : String
|
||||
private external fun getReleaseNewDriverTrainUrl() : String
|
||||
|
||||
private external fun getReviewBaseUrl() : String
|
||||
private external fun getReviewImgBaseUrl() : String
|
||||
private external fun getReviewResourceUrl() : String
|
||||
private external fun getReviewTrainUrl() : String
|
||||
private external fun getReviewDocumentUrl() : String
|
||||
private external fun getReviewNewDriverTrainUrl() : String
|
||||
|
||||
|
||||
private external fun getCrm1BaseUrl() : String
|
||||
private external fun getCrm1ImgBaseUrl() : String
|
||||
private external fun getCrm1ResourceUrl() : String
|
||||
private external fun getCrm1TrainUrl() : String
|
||||
private external fun getCrm1DocumentUrl() : String
|
||||
private external fun getCrm1NewDriverTrainUrl() : String
|
||||
|
||||
private external fun getCrm2BaseUrl() : String
|
||||
private external fun getCrm2ImgBaseUrl() : String
|
||||
private external fun getCrm2ResourceUrl() : String
|
||||
private external fun getCrm2TrainUrl() : String
|
||||
private external fun getCrm2DocumentUrl() : String
|
||||
private external fun getCrm2NewDriverTrainUrl() : String
|
||||
|
||||
private external fun getUatBaseUrl() : String
|
||||
private external fun getUatImgBaseUrl() : String
|
||||
private external fun getUatResourceUrl() : String
|
||||
private external fun getUatTrainUrl() : String
|
||||
private external fun getUatDocumentUrl() : String
|
||||
private external fun getUatNewDriverTrainUrl() : String
|
||||
|
||||
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
package com.za.base
|
||||
|
||||
interface AppForegroundListener {
|
||||
internal interface AppForegroundListener {
|
||||
|
||||
/**
|
||||
* APP处于 前台
|
||||
|
@ -9,7 +9,7 @@ import com.za.common.GlobalData
|
||||
import com.za.common.log.LogUtil
|
||||
import java.util.concurrent.atomic.AtomicBoolean
|
||||
|
||||
open class BaseActivityLifecycleCallbacks : ActivityLifecycleCallbacks {
|
||||
internal class BaseActivityLifecycleCallbacks : ActivityLifecycleCallbacks {
|
||||
|
||||
|
||||
override fun onActivityCreated(activity : Activity, savedInstanceState : Bundle?) {
|
||||
|
@ -5,7 +5,7 @@ import androidx.lifecycle.ViewModel
|
||||
|
||||
val showTipDialog = mutableStateOf<String?>(null) //提示框
|
||||
|
||||
abstract class BaseVm<T, U> : ViewModel() {
|
||||
internal abstract class BaseVm<T, U> : ViewModel() {
|
||||
val tag : String = javaClass.simpleName
|
||||
abstract fun updateState(uiState : U)
|
||||
abstract fun dispatch(action : T)
|
||||
|
@ -1,6 +1,6 @@
|
||||
package com.za.base
|
||||
|
||||
object Const {
|
||||
internal object Const {
|
||||
const val Image_Max_length = 1024 * 400L
|
||||
const val faceFileName = "zd_com.dear"
|
||||
const val NetWorkException = 999
|
||||
|
@ -12,7 +12,7 @@ import com.za.offline.OfflineManager
|
||||
import com.za.offline.OfflineUpdateTaskBean
|
||||
import com.za.room.RoomHelper
|
||||
|
||||
abstract class IServicingVm<T, U> : BaseVm<T, U>() {
|
||||
internal abstract class IServicingVm<T, U> : BaseVm<T, U>() {
|
||||
|
||||
fun getCurrentOrder() : OrderInfo? =
|
||||
GlobalData.currentOrder ?: RoomHelper.db?.orderDao()?.getCurrentOrder()
|
||||
|
@ -106,7 +106,7 @@ enum class DetectionStatus {
|
||||
ABNORMAL // 异常
|
||||
}
|
||||
|
||||
class NetworkRouteSelectionActivity : BaseActivity() {
|
||||
internal class NetworkRouteSelectionActivity : BaseActivity() {
|
||||
@Composable
|
||||
override fun ContentView() {
|
||||
NetworkRouteScreen(telephonyManager = getSystemService(TELEPHONY_SERVICE) as TelephonyManager,
|
||||
|
@ -7,7 +7,6 @@ import androidx.appcompat.app.AlertDialog
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.google.gson.Gson
|
||||
import com.za.bean.JpushBean
|
||||
import com.za.common.GlobalData
|
||||
import com.za.common.log.LogUtil
|
||||
import com.za.service.PushListener
|
||||
import com.za.service.ServiceManager
|
||||
@ -82,7 +81,7 @@ open class PushMessageActivity : AppCompatActivity() {
|
||||
currentDialog?.dismiss()
|
||||
currentDialog = null
|
||||
} catch (e : Exception) {
|
||||
LogUtil.print("PushActivityLifecycleCallbacks", "关闭对话框失败: ${e.message}")
|
||||
LogUtil.print("PushMessageActivity", "关闭对话框失败: ${e.message}")
|
||||
}
|
||||
}
|
||||
|
||||
@ -91,10 +90,11 @@ open class PushMessageActivity : AppCompatActivity() {
|
||||
internal const val DIALOG_TAG_GIVE_UP = "giveUp"
|
||||
|
||||
private fun sendMessageToMainProcess(context : Context, type : String, message : String) {
|
||||
|
||||
// 使用广播将消息发送到主进程
|
||||
val intent = Intent(Const.PushMessageType.ACTION_MAIN.takeIf { GlobalData.isMaster }
|
||||
?: Const.PushMessageType.ACTION_SDK)
|
||||
val intent = if (context.packageName == "com.za.rescue.dealer") {
|
||||
Intent(Const.PushMessageType.ACTION_MAIN)
|
||||
} else {
|
||||
Intent(Const.PushMessageType.ACTION_SDK)
|
||||
}
|
||||
intent.setPackage(context.packageName)
|
||||
intent.putExtra("type", type)
|
||||
intent.putExtra("message", message)
|
||||
|
@ -19,72 +19,48 @@ import coil.compose.AsyncImage
|
||||
import com.za.servicing.R
|
||||
|
||||
@Composable
|
||||
fun EmptyView(
|
||||
modifier: Modifier = Modifier,
|
||||
message: String = "暂无数据",
|
||||
imageSize: Pair<Int, Int> = Pair(118, 143),
|
||||
imageRes: Int = R.drawable.sv_emty_data
|
||||
) {
|
||||
Column(
|
||||
modifier = modifier.fillMaxSize(),
|
||||
verticalArrangement = Arrangement.Center,
|
||||
horizontalAlignment = Alignment.CenterHorizontally
|
||||
) {
|
||||
AsyncImage(
|
||||
model = imageRes,
|
||||
contentDescription = message,
|
||||
modifier = Modifier.size(imageSize.first.dp, imageSize.second.dp)
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.height(12.dp))
|
||||
|
||||
Text(
|
||||
text = message,
|
||||
color = Color.Gray,
|
||||
fontSize = 14.sp,
|
||||
textAlign = TextAlign.Center
|
||||
)
|
||||
}
|
||||
fun EmptyView(modifier : Modifier = Modifier,
|
||||
message : String = "暂无数据",
|
||||
imageSize : Pair<Int, Int> = Pair(118, 143),
|
||||
imageRes : Int = R.drawable.sv_emty_data) {
|
||||
Column(modifier = modifier.fillMaxSize(),
|
||||
verticalArrangement = Arrangement.Center,
|
||||
horizontalAlignment = Alignment.CenterHorizontally) {
|
||||
AsyncImage(model = imageRes,
|
||||
contentDescription = message,
|
||||
modifier = Modifier.size(imageSize.first.dp, imageSize.second.dp))
|
||||
|
||||
Spacer(modifier = Modifier.height(12.dp))
|
||||
|
||||
Text(text = message, color = Color.Gray, fontSize = 14.sp, textAlign = TextAlign.Center)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun LoadError(
|
||||
modifier: Modifier = Modifier,
|
||||
message: String = "加载出错",
|
||||
imageSize: Pair<Int, Int> = Pair(118, 143),
|
||||
onRetry: (() -> Unit)? = null
|
||||
) {
|
||||
Column(
|
||||
modifier = modifier.fillMaxSize(),
|
||||
verticalArrangement = Arrangement.Center,
|
||||
horizontalAlignment = Alignment.CenterHorizontally
|
||||
) {
|
||||
AsyncImage(
|
||||
model = R.drawable.sv_load_error,
|
||||
contentDescription = message,
|
||||
modifier = Modifier.size(imageSize.first.dp, imageSize.second.dp)
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.height(12.dp))
|
||||
|
||||
Text(
|
||||
text = message,
|
||||
color = Color.Gray,
|
||||
fontSize = 14.sp,
|
||||
textAlign = TextAlign.Center
|
||||
)
|
||||
|
||||
if (onRetry != null) {
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
|
||||
Text(
|
||||
text = "点击重试",
|
||||
color = Color(0xFF1BA8F7),
|
||||
fontSize = 14.sp,
|
||||
modifier = Modifier
|
||||
fun LoadError(modifier : Modifier = Modifier,
|
||||
message : String = "加载出错",
|
||||
imageSize : Pair<Int, Int> = Pair(118, 143),
|
||||
onRetry : (() -> Unit)? = null) {
|
||||
Column(modifier = modifier.fillMaxSize(),
|
||||
verticalArrangement = Arrangement.Center,
|
||||
horizontalAlignment = Alignment.CenterHorizontally) {
|
||||
AsyncImage(model = R.drawable.sv_load_error,
|
||||
contentDescription = message,
|
||||
modifier = Modifier.size(imageSize.first.dp, imageSize.second.dp))
|
||||
|
||||
Spacer(modifier = Modifier.height(12.dp))
|
||||
|
||||
Text(text = message, color = Color.Gray, fontSize = 14.sp, textAlign = TextAlign.Center)
|
||||
|
||||
if (onRetry != null) {
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
|
||||
Text(text = "点击重试",
|
||||
color = Color(0xFF1BA8F7),
|
||||
fontSize = 14.sp,
|
||||
modifier = Modifier
|
||||
.align(Alignment.CenterHorizontally)
|
||||
.clickable { onRetry() }
|
||||
)
|
||||
}
|
||||
}
|
||||
.clickable { onRetry() })
|
||||
}
|
||||
}
|
||||
}
|
@ -15,7 +15,7 @@ import com.za.net.RetrofitHelper
|
||||
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.rxjava3.schedulers.Schedulers
|
||||
|
||||
object CallLogManager {
|
||||
internal object CallLogManager {
|
||||
private const val TAG = "CallLogManager"
|
||||
private var lastUploadTime : Long? = null
|
||||
set(value) {
|
||||
|
@ -12,7 +12,7 @@ import com.za.room.RoomHelper
|
||||
import com.za.room.db.user.DriverInfoBean
|
||||
import com.za.service.location.ZdLocationManager
|
||||
|
||||
object GlobalData : GlobalLocalData() {
|
||||
internal object GlobalData : GlobalLocalData() {
|
||||
lateinit var application : Application
|
||||
private val mmkv : MMKV by lazy { MMKV.defaultMMKV() }
|
||||
var activityCount : Int = 0
|
||||
|
@ -11,6 +11,7 @@ import com.za.service.location.ZdLocationManager
|
||||
|
||||
object ZDManager {
|
||||
lateinit var application : Application
|
||||
|
||||
fun init(application : Application, isRelease : Boolean = false) {
|
||||
this.application = application
|
||||
thirdSdkInit(isRelease)
|
||||
@ -20,10 +21,17 @@ object ZDManager {
|
||||
GlobalData.application = application
|
||||
MMKV.initialize(application)
|
||||
AppConfig.init(isRelease)
|
||||
Bugly.init(application, "6972a6b56d", true)
|
||||
Bugly.init(application, getBuglyAppId(), true)
|
||||
LogUtil.init(application)
|
||||
RoomHelper.init(application)
|
||||
ZdLocationManager.init(application)
|
||||
SpeechManager.init(application)
|
||||
}
|
||||
|
||||
|
||||
init {
|
||||
System.loadLibrary("config")
|
||||
}
|
||||
|
||||
private external fun getBuglyAppId() : String
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ import java.io.UnsupportedEncodingException
|
||||
import java.net.URLDecoder
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
object LogRetrofitHelper {
|
||||
internal object LogRetrofitHelper {
|
||||
private var retrofit: Retrofit? = null
|
||||
private var apiService: LogService? = null
|
||||
private val loggerInterceptor = HttpLoggingInterceptor {
|
||||
|
@ -7,7 +7,7 @@ import retrofit2.http.POST
|
||||
import retrofit2.http.Part
|
||||
import retrofit2.http.Query
|
||||
|
||||
interface LogService {
|
||||
internal interface LogService {
|
||||
//日志上传
|
||||
@Multipart
|
||||
@POST("/oss/minio/upload")
|
||||
|
@ -32,7 +32,7 @@ import java.util.concurrent.ExecutorService
|
||||
import java.util.concurrent.Executors
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
object LogUtil {
|
||||
internal object LogUtil {
|
||||
private var context : Application? = null
|
||||
private var executors : ExecutorService? = null
|
||||
private var normalLogDirPath : String? = null
|
||||
@ -113,6 +113,7 @@ object LogUtil {
|
||||
}
|
||||
LogUtils.getConfig().setFilePrefix(this.vehicleName)
|
||||
LogUtils.e("$tag---$content")
|
||||
|
||||
} catch (e : Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
@ -1,122 +0,0 @@
|
||||
package com.za.common.speech
|
||||
|
||||
import android.media.MediaPlayer
|
||||
import com.google.gson.Gson
|
||||
import com.google.gson.JsonObject
|
||||
import com.za.common.log.LogUtil
|
||||
import okhttp3.OkHttpClient
|
||||
import okhttp3.ResponseBody
|
||||
import okhttp3.logging.HttpLoggingInterceptor
|
||||
import retrofit2.Call
|
||||
import retrofit2.Retrofit
|
||||
import retrofit2.adapter.rxjava3.RxJava3CallAdapterFactory
|
||||
import retrofit2.converter.gson.GsonConverterFactory
|
||||
import retrofit2.http.Body
|
||||
import retrofit2.http.POST
|
||||
import java.io.File
|
||||
import java.io.FileOutputStream
|
||||
import java.io.IOException
|
||||
|
||||
interface SpeechApiService {
|
||||
@POST("v1/audio/speech")
|
||||
fun textToSpeech(@Body request: JsonObject): Call<ResponseBody>
|
||||
}
|
||||
|
||||
object CustomerSpeechManager {
|
||||
|
||||
private const val BASE_URL = "http://192.168.3.129:8880/"
|
||||
|
||||
private val gson: Gson by lazy {
|
||||
Gson().newBuilder()
|
||||
.setLenient()
|
||||
.create()
|
||||
}
|
||||
|
||||
private val retrofit: Retrofit by lazy {
|
||||
val loggingInterceptor = HttpLoggingInterceptor().apply {
|
||||
level = HttpLoggingInterceptor.Level.BODY
|
||||
}
|
||||
|
||||
val client = OkHttpClient.Builder()
|
||||
.addInterceptor(loggingInterceptor)
|
||||
.build()
|
||||
|
||||
Retrofit.Builder()
|
||||
.baseUrl(BASE_URL)
|
||||
.client(client)
|
||||
.addConverterFactory(GsonConverterFactory.create(gson))
|
||||
.addCallAdapterFactory(RxJava3CallAdapterFactory.create())
|
||||
.build()
|
||||
}
|
||||
|
||||
private val speechApiService: SpeechApiService by lazy {
|
||||
retrofit.create(SpeechApiService::class.java)
|
||||
}
|
||||
|
||||
fun textToSpeech(input: String, destinationFile: File): Boolean {
|
||||
val requestBody = JsonObject().apply {
|
||||
addProperty("input", input)
|
||||
addProperty("voice", "zf_xiaoxiao")
|
||||
addProperty("response_format", "mp3")
|
||||
addProperty("stream", true)
|
||||
addProperty("speed", 1)
|
||||
addProperty("return_download_link", false) // Set to false to get the stream directly
|
||||
addProperty("lang_code", "z")
|
||||
}
|
||||
|
||||
val call = speechApiService.textToSpeech(requestBody)
|
||||
try {
|
||||
val response = call.execute()
|
||||
LogUtil.print("CustomerSpeechManager", "response: $response")
|
||||
if (response.isSuccessful) {
|
||||
val responseBody = response.body()
|
||||
if (responseBody != null) {
|
||||
saveToFile(responseBody, destinationFile)
|
||||
playAudio(destinationFile)
|
||||
return true
|
||||
}
|
||||
} else {
|
||||
LogUtil.print("CustomerSpeechManager", "Request failed: ${response.code()}")
|
||||
}
|
||||
} catch (e: IOException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
private fun saveToFile(body: ResponseBody, destinationFile: File) {
|
||||
body.byteStream().use {
|
||||
FileOutputStream(destinationFile).buffered().use { outputStream ->
|
||||
val buffer = ByteArray(4096)
|
||||
var bytesRead: Int
|
||||
while (it.read(buffer).also { bytesRead = it } != -1) {
|
||||
outputStream.write(buffer, 0, bytesRead)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun playAudio(file: File) {
|
||||
val mediaPlayer = MediaPlayer().apply {
|
||||
try {
|
||||
setDataSource(file.absolutePath)
|
||||
prepare()
|
||||
start()
|
||||
} catch (e: IOException) {
|
||||
e.printStackTrace()
|
||||
release()
|
||||
}
|
||||
}
|
||||
|
||||
mediaPlayer.setOnCompletionListener {
|
||||
it.release()
|
||||
}
|
||||
|
||||
mediaPlayer.setOnErrorListener { mp, what, extra ->
|
||||
mp.release()
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -21,7 +21,7 @@ import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
object SpeechManager {
|
||||
internal object SpeechManager {
|
||||
private var mContext : Application? = null
|
||||
|
||||
|
||||
|
@ -12,7 +12,7 @@ import java.util.Locale
|
||||
|
||||
|
||||
@SuppressLint("StaticFieldLeak")
|
||||
object TTSManager {
|
||||
internal object TTSManager {
|
||||
private var tts : TextToSpeech? = null
|
||||
private var context : Context? = null
|
||||
private var listener : OnTTSListener? = null
|
||||
|
@ -95,7 +95,7 @@ import retrofit2.http.Multipart
|
||||
import retrofit2.http.POST
|
||||
import retrofit2.http.Part
|
||||
|
||||
interface ApiService {
|
||||
internal interface ApiService {
|
||||
|
||||
//获取车辆列表
|
||||
@POST("/driverApp/supplier/listVehicleNew")
|
||||
@ -236,35 +236,35 @@ interface ApiService {
|
||||
@POST("/driverApp/task/getTaskSettlementAndTrace")
|
||||
fun getTaskSettlementAndTrace(@Body info : HistoryDetailRequest) : Observable<BaseResponse<TaskSettlementAndTraceBean>>
|
||||
|
||||
@POST("driverApp/task/updateSettleInfo")
|
||||
@POST("/driverApp/task/updateSettleInfo")
|
||||
fun updateSettleInfo(@Body settleInfoRequest : SettleInfoRequest) : Observable<BaseResponse<String>>
|
||||
|
||||
|
||||
//人脸比对
|
||||
@POST("driverApp/supplier/driverFaceCompare")
|
||||
@POST("/driverApp/supplier/driverFaceCompare")
|
||||
fun driverFaceCompare(@Body driverFaceCompareRequest : DriverFaceCompareRequest) : Observable<BaseResponse<DriverFaceCompareBean>>
|
||||
|
||||
@POST("driverApp/supplier/driverIdentityAuthWeb")
|
||||
@POST("/driverApp/supplier/driverIdentityAuthWeb")
|
||||
fun driverIdentityAuthWeb(@Body request : DriverIdentityAuthWebRequest) : Observable<BaseResponse<DriverIdentityAuthWebBean>>
|
||||
|
||||
//今日保养
|
||||
@POST("driverApp/supplier/getTodayMaintain")
|
||||
@POST("/driverApp/supplier/getTodayMaintain")
|
||||
fun getTodayMaintain(@Body info : TodayMaintainRequest) : Observable<BaseResponse<List<TodayMaintainbean>>>
|
||||
|
||||
//今日保养
|
||||
@POST("driverApp/supplier/uploadTodayMaintain")
|
||||
@POST("/driverApp/supplier/uploadTodayMaintain")
|
||||
fun uploadTodayMaintain(@Body params : TodayMaintainUploadRequest) : Observable<BaseResponse<String>>
|
||||
|
||||
//加油小票识别
|
||||
@POST("driverApp/supplier/recognizeRefuelTicket")
|
||||
@POST("/driverApp/supplier/recognizeRefuelTicket")
|
||||
fun recognizeRefuelTicket(@Body bean : RecognizeRefuelOcrRequestBean?) : Observable<BaseResponse<RecognizeRefuelTicketBean>>
|
||||
|
||||
//提交加油记录
|
||||
@POST("driverApp/supplier/vehicleRefuelSubmit")
|
||||
@POST("/driverApp/supplier/vehicleRefuelSubmit")
|
||||
fun vehicleRefuelSubmit(@Body info : RecognizeRefuelTicketRequestBean?) : Observable<BaseResponse<String>>
|
||||
|
||||
//获取车辆维保记录
|
||||
@POST("driverApp/supplier/v2/getVehicleMaintenanceSubmit")
|
||||
@POST("/driverApp/supplier/v2/getVehicleMaintenanceSubmit")
|
||||
fun getVehicleMaintenanceSubmit(@Body info : FetchVehicleMaintenanceSubmitHistoryRequestBean) : Observable<BaseResponse<VehicleRepairBean>>
|
||||
|
||||
//获取车辆维保详细信息
|
||||
@ -272,31 +272,29 @@ interface ApiService {
|
||||
fun getVehicleRepairDetail(@Body info : FetchVehicleMaintenanceSubmitHistoryRequestBean) : Observable<BaseResponse<VehicleRepairBean>>
|
||||
|
||||
//维修地点匹配
|
||||
@POST("driverApp/supplier/v2/vehicleRepairPointMatcherList")
|
||||
@POST("/driverApp/supplier/v2/vehicleRepairPointMatcherList")
|
||||
fun vehicleRepairPointMatcherList(@Body info : VehicleRepairPointMatcherListRequest) : Observable<BaseResponse<List<VehicleRepairPointMatcherItem>>>
|
||||
|
||||
//提交维保记录
|
||||
@POST("driverApp/supplier/v2/vehicleMaintenanceSubmit")
|
||||
@POST("/driverApp/supplier/v2/vehicleMaintenanceSubmit")
|
||||
fun vehicleMaintenanceSubmit(@Body info : VehicleMaintenanceSubmitRequest) : Observable<BaseResponse<String>>
|
||||
|
||||
//获取车辆维修历史
|
||||
@POST("/driverApp/supplier/v2/vehicleMaintenanceList")
|
||||
fun vehicleMaintenanceList(@Body info : FetchVehicleMaintenanceSubmitHistoryRequestBean) : Observable<BaseResponse<List<VehicleMaintenanceHistoryBean>>>
|
||||
|
||||
@POST("driverApp/base/getVoiceUrl")
|
||||
@POST("/driverApp/base/getVoiceUrl")
|
||||
fun getVoiceUrl(@Body info : AppNewOrderVoiceRequest) : Observable<BaseResponse<String>>
|
||||
|
||||
@POST("driverApp/supplier/iaiCompareFace")
|
||||
@POST("/driverApp/supplier/iaiCompareFace")
|
||||
fun iaiCompareFace(@Body info : DriverFaceCompareRequest) : Observable<BaseResponse<IaiCompareFaceBean>>
|
||||
|
||||
@POST("driverApp/task/getTaskNotes")
|
||||
@POST("/driverApp/task/getTaskNotes")
|
||||
fun getTaskNotes(@Body request : TaskNotesRequest) : Observable<BaseResponse<TaskNotesBean>>
|
||||
|
||||
@POST("driverApp/supplier/unifiedOCRWithCompress")
|
||||
@POST("/driverApp/supplier/unifiedOCRWithCompress")
|
||||
fun unifiedOCRWithCompress(@Body request : UnifiedOCRWithCompressRequest) : Observable<BaseResponse<String>>
|
||||
|
||||
@POST("driverApp/v2/user/saveSignature")
|
||||
@POST("/driverApp/v2/user/saveSignature")
|
||||
fun saveSignature(@Body request : SaveSignatureRequest) : Observable<BaseResponse<String>>
|
||||
|
||||
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ import javax.net.ssl.SSLHandshakeException
|
||||
/**
|
||||
* Created by DoggieX on 2017/7/26.
|
||||
*/
|
||||
abstract class BaseObserver<T> : Observer<BaseResponse<T>> {
|
||||
internal abstract class BaseObserver<T> : Observer<BaseResponse<T>> {
|
||||
override fun onSubscribe(d : Disposable) { // if (!NetworkUtils.isAvailable()) {
|
||||
// doFailure(999, "网络无法使用")
|
||||
// d.dispose()
|
||||
|
@ -39,7 +39,7 @@ import okhttp3.MultipartBody
|
||||
import okhttp3.RequestBody.Companion.asRequestBody
|
||||
import java.io.File
|
||||
|
||||
object CommonMethod {
|
||||
internal object CommonMethod {
|
||||
fun uploadGps(uploadGpsRequest : UploadGpsRequest,
|
||||
success : () -> Unit = {},
|
||||
failed : (String?) -> Unit = {}) {
|
||||
|
@ -6,7 +6,7 @@ import com.za.bean.db.order.PhotoTemplateInfo
|
||||
import com.za.common.log.LogUtil
|
||||
import com.za.servicing.R
|
||||
|
||||
object LocalPhotoTemplateControl {
|
||||
internal object LocalPhotoTemplateControl {
|
||||
|
||||
fun buildPhotoTemplate(orderInfo : OrderInfo?) : List<PhotoTemplateInfo> {
|
||||
if (orderInfo == null) {
|
||||
|
@ -26,12 +26,14 @@ import okio.Buffer;
|
||||
*/
|
||||
public class RequestEncryptInterceptor implements Interceptor {
|
||||
|
||||
static final String PUBLIC_KEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA7UM6zdWdBuO0DZZVkxVfJioawUe6qH1p5Uz/qR9zbawl2oWyxxcBfxQyPS+HxOej/ZnyS4bu7qhh99alDqkJzk6g9oGZWs+jEF5GRWt9nChlfUsjvHQwuF2TSQMTdPtDPCByF/QgMFCAfbCqTrNmOETrZ/2GFy1Re0BTlhh6X/XzpzqtK+enikEMlQ5fIM5ljdXgyCnvDou9ptWqzw8Zmsat6LeA0UKz+bgpJAbw6KfK+8lPMqUpNFfkmJuEd5+JQOG9McH7j9pBagohkC6k3Cn92dAf9iD6NSDKSNgt1vxXhaNnfAbYJ5pqeSGy6QMSVO0TXYj4asln5OutD/284QIDAQAB";
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Response intercept(@NonNull Chain chain) throws IOException {
|
||||
Request request = chain.request();
|
||||
return chain.proceed(invoke(chain.request()));
|
||||
}
|
||||
|
||||
private Request invoke(Request req) throws IOException {
|
||||
Request request = req;
|
||||
String method = request.method().toLowerCase().trim();
|
||||
HttpUrl url = request.url();
|
||||
boolean skipEncrypt = url.encodedPath().endsWith("appVersion")
|
||||
@ -87,7 +89,7 @@ public class RequestEncryptInterceptor implements Interceptor {
|
||||
|| url.encodedPath().endsWith("fastLogin")
|
||||
|| url.encodedPath().endsWith("loginWithTask")) {
|
||||
|
||||
byte[] bytes = RSAUtils.encryptByPublicKey(aesKey.getBytes(StandardCharsets.UTF_8), PUBLIC_KEY);
|
||||
byte[] bytes = RSAUtils.encryptByPublicKey(aesKey.getBytes(StandardCharsets.UTF_8), getPublicKey());
|
||||
String tokenSecret = Base64.encodeToString(bytes, Base64.NO_WRAP);
|
||||
requestBuilder.addHeader("secret", tokenSecret);
|
||||
} else {
|
||||
@ -104,6 +106,10 @@ public class RequestEncryptInterceptor implements Interceptor {
|
||||
}
|
||||
}
|
||||
}
|
||||
return chain.proceed(request);
|
||||
|
||||
return request;
|
||||
}
|
||||
}
|
||||
|
||||
private native String getPublicKey();
|
||||
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
package com.za.net
|
||||
|
||||
import com.za.base.AppConfig
|
||||
import com.za.common.GlobalData
|
||||
import com.za.common.log.LogUtil
|
||||
import okhttp3.OkHttpClient
|
||||
import okhttp3.logging.HttpLoggingInterceptor
|
||||
@ -11,7 +12,7 @@ import java.io.UnsupportedEncodingException
|
||||
import java.net.URLDecoder
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
object RetrofitHelper {
|
||||
internal object RetrofitHelper {
|
||||
private var retrofit : Retrofit? = null
|
||||
private var apiService : ApiService? = null
|
||||
private val loggerInterceptor = HttpLoggingInterceptor {
|
||||
@ -29,8 +30,9 @@ object RetrofitHelper {
|
||||
if (it.contains("name=\"file\"; filename")) {
|
||||
return@HttpLoggingInterceptor
|
||||
}
|
||||
LogUtil.print("--network--",
|
||||
URLDecoder.decode(it.replace(Regex("%(?![0-9a-fA-F]{2})"), ""), "utf-8"))
|
||||
|
||||
// LogUtil.print("--network--",
|
||||
// URLDecoder.decode(it.replace(Regex("%(?![0-9a-fA-F]{2})"), ""), "utf-8"))
|
||||
} catch (e : UnsupportedEncodingException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ import com.za.base.Const
|
||||
import com.za.room.db.GlobalRoom
|
||||
|
||||
@SuppressLint("StaticFieldLeak")
|
||||
object RoomHelper {
|
||||
internal object RoomHelper {
|
||||
const val VERSION: Int = 43
|
||||
private lateinit var mContext: Context
|
||||
var db: GlobalRoom? = null
|
||||
|
@ -26,7 +26,7 @@ import com.za.room.db.water_marker.WaterMarkerDao
|
||||
@Database(entities = [EleWorkOrderBean::class, EleCarDamagePhotoBean::class, LocalResourceBean::class, WaterMarkerTemplateBean::class, WaterMarkerItemBean::class, ChangeBatteryPhoto::class, NewPhotoTemplateBean::class, OrderInfo::class, OfflineUpdateTaskBean::class, PhotoTemplateInfo::class],
|
||||
version = RoomHelper.VERSION,
|
||||
exportSchema = false)
|
||||
abstract class GlobalRoom : RoomDatabase() {
|
||||
internal abstract class GlobalRoom : RoomDatabase() {
|
||||
abstract fun eleWorkOrderDao() : EleWorkOrderDao
|
||||
|
||||
abstract fun eleCarDamagePhotoDao() : EleCarDamagePhotoDao
|
||||
|
@ -9,7 +9,7 @@ import androidx.room.Update
|
||||
import com.za.bean.db.ele.EleCarDamagePhotoBean
|
||||
|
||||
@Dao
|
||||
interface EleCarDamagePhotoDao {
|
||||
internal interface EleCarDamagePhotoDao {
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE, entity = EleCarDamagePhotoBean::class)
|
||||
fun insert(eleCarDamagePhotoBean: EleCarDamagePhotoBean)
|
||||
|
||||
|
@ -8,7 +8,7 @@ import androidx.room.Update
|
||||
import com.za.bean.db.ele.EleWorkOrderBean
|
||||
|
||||
@Dao
|
||||
interface EleWorkOrderDao {
|
||||
internal interface EleWorkOrderDao {
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE, entity = EleWorkOrderBean::class)
|
||||
fun insertEleWorkOrder(eleWorkOrderBean: EleWorkOrderBean)
|
||||
|
||||
|
@ -9,7 +9,7 @@ import com.za.base.Const
|
||||
import com.za.bean.db.order.PhotoTemplateInfo
|
||||
|
||||
@Dao
|
||||
interface ChangeBatteryDao {
|
||||
internal interface ChangeBatteryDao {
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE, entity = PhotoTemplateInfo::class)
|
||||
fun insert(photoTemplateInfo: PhotoTemplateInfo)
|
||||
|
@ -8,7 +8,7 @@ import androidx.room.Update
|
||||
import com.za.bean.db.order.OrderInfo
|
||||
|
||||
@Dao
|
||||
interface OrderDao {
|
||||
internal interface OrderDao {
|
||||
//更换电瓶照片
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
fun insertOrder(orderInfo: OrderInfo)
|
||||
|
@ -9,7 +9,7 @@ import com.za.base.Const
|
||||
import com.za.bean.db.order.PhotoTemplateInfo
|
||||
|
||||
@Dao
|
||||
interface PhotoTemplateDao {
|
||||
internal interface PhotoTemplateDao {
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE, entity = PhotoTemplateInfo::class)
|
||||
fun insert(photoTemplateInfo: PhotoTemplateInfo)
|
||||
|
@ -35,7 +35,7 @@ interface PushListener {
|
||||
|
||||
data class LastJPushBean(val msg : String, val time : Long = System.currentTimeMillis())
|
||||
|
||||
object ServiceManager {
|
||||
internal object ServiceManager {
|
||||
@Volatile
|
||||
private var pushListener : PushListener? = null
|
||||
private var lastJPushBean : LastJPushBean? = null
|
||||
|
@ -43,7 +43,7 @@ class ZdPushServiceReceive : BroadcastReceiver() {
|
||||
if (ActivityUtils.getTopActivity() == null) {
|
||||
AppUtils.launchApp(GlobalData.application.packageName)
|
||||
}
|
||||
LogUtil.print("PushActivityLifecycleCallbacks", "收到来自远程进程的消息: $type")
|
||||
LogUtil.print("ZdPushServiceReceive", "收到来自远程进程的消息: $type")
|
||||
when (type) {
|
||||
Const.PushMessageType.BROADCAST -> handleBroadcast("broadcast:$message")
|
||||
|
||||
@ -56,7 +56,7 @@ class ZdPushServiceReceive : BroadcastReceiver() {
|
||||
handleGiveUpOrder(activity, jpushBean)
|
||||
}
|
||||
} catch (e : Exception) {
|
||||
LogUtil.print("PushActivityLifecycleCallbacks",
|
||||
LogUtil.print("ZdPushServiceReceive",
|
||||
"处理订单放弃消息失败: ${e.message}")
|
||||
}
|
||||
}
|
||||
@ -70,7 +70,7 @@ class ZdPushServiceReceive : BroadcastReceiver() {
|
||||
handleImportantTip(activity, jpushBean)
|
||||
}
|
||||
} catch (e : Exception) {
|
||||
LogUtil.print("PushActivityLifecycleCallbacks",
|
||||
LogUtil.print("ZdPushServiceReceive",
|
||||
"处理重要提示消息失败: ${e.message}")
|
||||
}
|
||||
}
|
||||
@ -84,7 +84,7 @@ class ZdPushServiceReceive : BroadcastReceiver() {
|
||||
handleReDispatchOrder(activity, jpushBean)
|
||||
}
|
||||
} catch (e : Exception) {
|
||||
LogUtil.print("PushActivityLifecycleCallbacks",
|
||||
LogUtil.print("ZdPushServiceReceive",
|
||||
"处理订单重新派发消息失败: ${e.message}")
|
||||
}
|
||||
}
|
||||
@ -97,7 +97,7 @@ class ZdPushServiceReceive : BroadcastReceiver() {
|
||||
handlerModifyOrder()
|
||||
}
|
||||
} catch (e : Exception) {
|
||||
LogUtil.print("PushActivityLifecycleCallbacks",
|
||||
LogUtil.print("ZdPushServiceReceive",
|
||||
"处理重要提示消息失败: ${e.message}")
|
||||
}
|
||||
}
|
||||
@ -110,7 +110,7 @@ class ZdPushServiceReceive : BroadcastReceiver() {
|
||||
handleRevokeOrder(activity)
|
||||
}
|
||||
} catch (e : Exception) {
|
||||
LogUtil.print("PushActivityLifecycleCallbacks",
|
||||
LogUtil.print("ZdPushServiceReceive",
|
||||
"处理订单撤回消息失败: ${e.message}")
|
||||
}
|
||||
}
|
||||
@ -124,7 +124,7 @@ class ZdPushServiceReceive : BroadcastReceiver() {
|
||||
handeReportMessage(jpushBean = jpushBean)
|
||||
}
|
||||
} catch (e : Exception) {
|
||||
LogUtil.print("PushActivityLifecycleCallbacks",
|
||||
LogUtil.print("ZdPushServiceReceive",
|
||||
"处理重要提示消息失败: ${e.message}")
|
||||
}
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ import kotlin.math.sin
|
||||
import kotlin.math.sqrt
|
||||
|
||||
@SuppressLint("StaticFieldLeak")
|
||||
object ZdLocationManager : AMapLocationListener {
|
||||
internal object ZdLocationManager : AMapLocationListener {
|
||||
private const val TAG = "ZdLocationManager"
|
||||
private var aMapLocationClient : AMapLocationClient? = null
|
||||
private var context : Context? = null
|
||||
|
@ -1,11 +1,18 @@
|
||||
package com.za.service.mqtt
|
||||
|
||||
object MqttConfig {
|
||||
const val INSTANCE_ID = "mqtt-cn-oew23jbkb1f"
|
||||
const val END_POINT = "mqtt-cn-oew23jbkb1f.mqtt.aliyuncs.com"
|
||||
const val ACCESS_KEY = "LTAI5tKgZ9ACKorXzzWLxgg7"
|
||||
const val SECRET_KEY = "D04F0UH2GzrDsYaJ9GTfULGPjcsvvz"
|
||||
const val GROUP_ID = "GID_ZDJY"
|
||||
const val TOPIC_PREFIX = "pushBaseTopic/p2p"
|
||||
const val QOS_LEVEL = 0
|
||||
}
|
||||
val INSTANCE_ID = getMqttInstanceId()
|
||||
val END_POINT = getMqttEndpoint()
|
||||
val ACCESS_KEY = getMqttAccessKey()
|
||||
val SECRET_KEY = getMqttSecretKey()
|
||||
val GROUP_ID = getMqttGroupId()
|
||||
val TOPIC_PREFIX = getMqttTopicPrefix()
|
||||
const val QOS_LEVEL = 0
|
||||
|
||||
external fun getMqttInstanceId() : String
|
||||
external fun getMqttEndpoint() : String
|
||||
external fun getMqttAccessKey() : String
|
||||
external fun getMqttSecretKey() : String
|
||||
external fun getMqttGroupId() : String
|
||||
external fun getMqttTopicPrefix() : String
|
||||
}
|
@ -1,16 +1,16 @@
|
||||
package com.za.service.mqtt
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import com.za.common.GlobalData
|
||||
import com.za.common.log.LogUtil
|
||||
import com.za.common.util.DeviceUtil
|
||||
import com.za.common.util.Tools.macSignature
|
||||
import com.za.service.ServiceManager
|
||||
import org.eclipse.paho.android.service.MqttAndroidClient
|
||||
import org.eclipse.paho.client.mqttv3.IMqttActionListener
|
||||
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken
|
||||
import org.eclipse.paho.client.mqttv3.IMqttToken
|
||||
import org.eclipse.paho.client.mqttv3.MqttCallback
|
||||
import org.eclipse.paho.client.mqttv3.MqttCallbackExtended
|
||||
import org.eclipse.paho.client.mqttv3.MqttClient
|
||||
import org.eclipse.paho.client.mqttv3.MqttConnectOptions
|
||||
import org.eclipse.paho.client.mqttv3.MqttException
|
||||
import org.eclipse.paho.client.mqttv3.MqttMessage
|
||||
@ -23,35 +23,45 @@ object MyMqttClient {
|
||||
private lateinit var topic : String
|
||||
|
||||
@SuppressLint("StaticFieldLeak")
|
||||
private var mqttClient : MqttAndroidClient? = null
|
||||
private var mqttClient : MqttClient? = null
|
||||
|
||||
fun initialize(deviceId : String?) {
|
||||
clientId = "${MqttConfig.GROUP_ID}@@@$deviceId"
|
||||
topic = "${MqttConfig.TOPIC_PREFIX}/$clientId"
|
||||
mqttClient = MqttAndroidClient(GlobalData.application,
|
||||
"tcp://${MqttConfig.END_POINT}:1883",
|
||||
clientId,
|
||||
MemoryPersistence())
|
||||
mqttClient = MqttClient("tcp://${MqttConfig.END_POINT}:1883", clientId, MemoryPersistence())
|
||||
setupMqttCallbacks()
|
||||
connect()
|
||||
LogUtil.print("MyMqttClient ", "initialize success")
|
||||
}
|
||||
|
||||
private fun setupMqttCallbacks() {
|
||||
mqttClient?.setCallback(object : MqttCallback {
|
||||
|
||||
override fun connectionLost(throwable : Throwable) {
|
||||
LogUtil.print("MyMqttClient ",
|
||||
"Connection lost: ${throwable.message}") // connect()
|
||||
mqttClient?.setCallback(object : MqttCallbackExtended {
|
||||
override fun connectComplete(reconnect : Boolean, serverURI : String?) {
|
||||
Handler(Looper.getMainLooper()).post {
|
||||
isConnecting = false
|
||||
LogUtil.print("MyMqttClient ", "connect success==")
|
||||
subscribeTopic()
|
||||
}
|
||||
}
|
||||
|
||||
override fun messageArrived(topic : String, mqttMessage : MqttMessage) {
|
||||
val message = String(mqttMessage.payload)
|
||||
LogUtil.print("MyMqttClient ", "Message arrived: $message")
|
||||
ServiceManager.handlerPushMsg(message)
|
||||
override fun connectionLost(cause : Throwable?) {
|
||||
isConnecting = false
|
||||
LogUtil.print("MyMqttClient ", "Connection lost: ${cause?.message}")
|
||||
}
|
||||
|
||||
override fun deliveryComplete(token : IMqttDeliveryToken) {
|
||||
override fun messageArrived(topic : String?, message : MqttMessage?) {
|
||||
if (message == null) {
|
||||
LogUtil.print("MyMqttClient ", "Message arrived: null")
|
||||
return
|
||||
}
|
||||
Handler(Looper.getMainLooper()).post {
|
||||
val message = String(message.payload)
|
||||
LogUtil.print("MyMqttClient ", "Message arrived: $message")
|
||||
ServiceManager.handlerPushMsg(message)
|
||||
}
|
||||
}
|
||||
|
||||
override fun deliveryComplete(token : IMqttDeliveryToken?) {
|
||||
LogUtil.print("MyMqttClient ", "Message delivery complete")
|
||||
}
|
||||
})
|
||||
@ -78,19 +88,7 @@ object MyMqttClient {
|
||||
mqttConnectOption.maxReconnectDelay = 30 * 1000
|
||||
mqttConnectOption.mqttVersion = MqttConnectOptions.MQTT_VERSION_3_1_1
|
||||
mqttConnectOption.connectionTimeout = 30
|
||||
|
||||
mqttClient?.connect(mqttConnectOption, null, object : IMqttActionListener {
|
||||
override fun onSuccess(asyncActionToken : IMqttToken?) {
|
||||
isConnecting = false
|
||||
LogUtil.print("MyMqttClient ", "connect success==")
|
||||
subscribeTopic()
|
||||
}
|
||||
|
||||
override fun onFailure(asyncActionToken : IMqttToken?, exception : Throwable?) {
|
||||
isConnecting = false
|
||||
LogUtil.print("MyMqttClient ", "connect failed== ${exception?.message}")
|
||||
}
|
||||
})
|
||||
mqttClient?.connect(mqttConnectOption)
|
||||
} catch (e : MqttException) {
|
||||
LogUtil.print("MyMqttClient ", "Connection failed2: ${e.message}")
|
||||
}
|
||||
@ -99,7 +97,6 @@ object MyMqttClient {
|
||||
|
||||
//检测mqtt连接状态
|
||||
fun publishMessage() {
|
||||
|
||||
if (mqttClient == null) {
|
||||
initialize(deviceId = DeviceUtil.getAndroidId(GlobalData.application))
|
||||
return
|
||||
@ -117,19 +114,8 @@ object MyMqttClient {
|
||||
private fun subscribeTopic() {
|
||||
try {
|
||||
if (mqttClient?.isConnected == true) {
|
||||
mqttClient?.subscribe(topic,
|
||||
MqttConfig.QOS_LEVEL,
|
||||
null,
|
||||
object : IMqttActionListener {
|
||||
override fun onSuccess(asyncActionToken : IMqttToken?) {
|
||||
LogUtil.print("MyMqttClient ", "Subscribed to topic: $topic")
|
||||
}
|
||||
|
||||
override fun onFailure(asyncActionToken : IMqttToken?,
|
||||
exception : Throwable) {
|
||||
LogUtil.print("MyMqttClient ", "Subscribe failed: ${exception.message}")
|
||||
}
|
||||
})
|
||||
mqttClient?.subscribe(topic, MqttConfig.QOS_LEVEL)
|
||||
LogUtil.print("MyMqttClient ", "mqtt subscribe $topic ")
|
||||
} else {
|
||||
LogUtil.print("MyMqttClient ", "Cannot subscribe: MQTT client is not connected")
|
||||
}
|
||||
@ -141,15 +127,7 @@ object MyMqttClient {
|
||||
fun disconnect() {
|
||||
try {
|
||||
if (mqttClient?.isConnected == true) {
|
||||
mqttClient?.disconnect(null, object : IMqttActionListener {
|
||||
override fun onSuccess(asyncActionToken : IMqttToken?) {
|
||||
LogUtil.print("MyMqttClient ", "Disconnected")
|
||||
}
|
||||
|
||||
override fun onFailure(asyncActionToken : IMqttToken?, exception : Throwable) {
|
||||
LogUtil.print("MyMqttClient ", "Disconnect failed")
|
||||
}
|
||||
})
|
||||
mqttClient?.disconnect()
|
||||
}
|
||||
} catch (e : MqttException) {
|
||||
LogUtil.print("MyMqttClient ", "Disconnect failed: ${e.message}")
|
||||
|
@ -41,7 +41,7 @@ import com.za.common.log.LogUtil
|
||||
import com.za.ext.finish
|
||||
import com.za.servicing.R
|
||||
|
||||
class CommonH5Activity : BaseActivity() {
|
||||
internal class CommonH5Activity : BaseActivity() {
|
||||
private var webView : WebView? = null
|
||||
private var isDestroyed = false
|
||||
|
||||
|
@ -136,11 +136,12 @@ class ServicingMainActivity : BaseActivity() {
|
||||
})
|
||||
}
|
||||
|
||||
fun sendMessageToMainProcess(context : Context,
|
||||
type : String,
|
||||
message : String) { // 使用广播将消息发送到主进程
|
||||
val intent = Intent(Const.PushMessageType.ACTION_MAIN.takeIf { GlobalData.isMaster }
|
||||
?: Const.PushMessageType.ACTION_SDK)
|
||||
fun sendMessageToMainProcess(context : Context, type : String, message : String) {
|
||||
val intent = if (context.packageName == "com.za.rescue.dealer") {
|
||||
Intent(Const.PushMessageType.ACTION_MAIN)
|
||||
} else {
|
||||
Intent(Const.PushMessageType.ACTION_SDK)
|
||||
}
|
||||
intent.setPackage(context.packageName)
|
||||
intent.putExtra("type", type)
|
||||
intent.putExtra("message", message)
|
||||
|
@ -15,7 +15,7 @@ import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.rxjava3.schedulers.Schedulers
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
|
||||
class ServicingMainVm : BaseVm<ServicingMainVm.Action, ServicingMainVm.UiState>() {
|
||||
internal class ServicingMainVm : BaseVm<ServicingMainVm.Action, ServicingMainVm.UiState>() {
|
||||
|
||||
private val _uiState = MutableStateFlow(UiState())
|
||||
val uiState get() = _uiState
|
||||
@ -87,6 +87,9 @@ class ServicingMainVm : BaseVm<ServicingMainVm.Action, ServicingMainVm.UiState>(
|
||||
return
|
||||
}
|
||||
GlobalData.token = it.token
|
||||
GlobalData.driverId = it.userId
|
||||
GlobalData.vehicleId = it.vehicleId
|
||||
GlobalData.deviceId = deviceId
|
||||
CommonMethod.getGenerateInfo(success = { success() },
|
||||
failed = { failure(it ?: "") })
|
||||
}
|
||||
|
@ -68,277 +68,252 @@ import kotlin.coroutines.resume
|
||||
import kotlin.coroutines.suspendCoroutine
|
||||
|
||||
class MapSearchActivity : BaseActivity() {
|
||||
@SuppressLint("MissingPermission")
|
||||
@Composable
|
||||
override fun ContentView() {
|
||||
MapSearchScreen(onLocationSelected = ::onLocationSelected)
|
||||
}
|
||||
@SuppressLint("MissingPermission")
|
||||
@Composable
|
||||
override fun ContentView() {
|
||||
MapSearchScreen(onLocationSelected = ::onLocationSelected)
|
||||
}
|
||||
|
||||
private fun onLocationSelected(poiData: PoiData) {
|
||||
val intent = Intent()
|
||||
intent.putExtra("poiData", poiData)
|
||||
setResult(RESULT_OK, intent)
|
||||
finish()
|
||||
}
|
||||
private fun onLocationSelected(poiData : PoiData) {
|
||||
val intent = Intent()
|
||||
intent.putExtra("poiData", poiData)
|
||||
setResult(RESULT_OK, intent)
|
||||
finish()
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("MissingPermission")
|
||||
@Composable
|
||||
fun MapSearchScreen(onLocationSelected: (PoiData) -> Unit) {
|
||||
val context = LocalContext.current
|
||||
val scope = rememberCoroutineScope()
|
||||
var searchText by remember { mutableStateOf("") }
|
||||
var selectLatLng by remember { mutableStateOf(LatLonPoint(0.0, 0.0)) }
|
||||
var mapInitialized by remember { mutableStateOf(false) }
|
||||
val mapView = remember { MapView(context) } // Remember the MapView instance
|
||||
var locationClient: AMapLocationClient? by remember { mutableStateOf(null) }
|
||||
var isLoading by remember { mutableStateOf(false) }
|
||||
var errorMessage by remember { mutableStateOf<String?>(null) }
|
||||
var searchResults by remember { mutableStateOf<List<PoiItem>>(emptyList()) }
|
||||
fun MapSearchScreen(onLocationSelected : (PoiData) -> Unit) {
|
||||
val context = LocalContext.current
|
||||
val scope = rememberCoroutineScope()
|
||||
var searchText by remember { mutableStateOf("") }
|
||||
var selectLatLng by remember { mutableStateOf(LatLonPoint(0.0, 0.0)) }
|
||||
var mapInitialized by remember { mutableStateOf(false) }
|
||||
val mapView = remember { MapView(context) } // Remember the MapView instance
|
||||
var locationClient : AMapLocationClient? by remember { mutableStateOf(null) }
|
||||
var isLoading by remember { mutableStateOf(false) }
|
||||
var errorMessage by remember { mutableStateOf<String?>(null) }
|
||||
var searchResults by remember { mutableStateOf<List<PoiItem>>(emptyList()) }
|
||||
|
||||
// Permission handling
|
||||
val locationPermissionGranted = remember { mutableStateOf(false) }
|
||||
val locationPermissionLauncher = rememberLauncherForActivityResult(
|
||||
ActivityResultContracts.RequestPermission()
|
||||
) { isGranted: Boolean ->
|
||||
locationPermissionGranted.value = isGranted
|
||||
}
|
||||
// Permission handling
|
||||
val locationPermissionGranted = remember { mutableStateOf(false) }
|
||||
val locationPermissionLauncher =
|
||||
rememberLauncherForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted : Boolean ->
|
||||
locationPermissionGranted.value = isGranted
|
||||
}
|
||||
|
||||
// Check if location permission is granted
|
||||
val checkPermission = {
|
||||
if (ContextCompat.checkSelfPermission(
|
||||
context,
|
||||
Manifest.permission.ACCESS_FINE_LOCATION
|
||||
) == PackageManager.PERMISSION_GRANTED
|
||||
) {
|
||||
locationPermissionGranted.value = true
|
||||
} else {
|
||||
locationPermissionLauncher.launch(Manifest.permission.ACCESS_FINE_LOCATION)
|
||||
}
|
||||
}
|
||||
// Check if location permission is granted
|
||||
val checkPermission = {
|
||||
if (ContextCompat.checkSelfPermission(context,
|
||||
Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
|
||||
) {
|
||||
locationPermissionGranted.value = true
|
||||
} else {
|
||||
locationPermissionLauncher.launch(Manifest.permission.ACCESS_FINE_LOCATION)
|
||||
}
|
||||
}
|
||||
|
||||
errorMessage?.let { message ->
|
||||
Snackbar(
|
||||
action = {
|
||||
Button(onClick = { errorMessage = null }) {
|
||||
Text("关闭")
|
||||
}
|
||||
},
|
||||
modifier = Modifier.padding(8.dp)
|
||||
) {
|
||||
Text(message)
|
||||
}
|
||||
}
|
||||
errorMessage?.let { message ->
|
||||
Snackbar(action = {
|
||||
Button(onClick = { errorMessage = null }) {
|
||||
Text("关闭")
|
||||
}
|
||||
}, modifier = Modifier.padding(8.dp)) {
|
||||
Text(message)
|
||||
}
|
||||
}
|
||||
|
||||
LaunchedEffect(key1 = Unit) {
|
||||
checkPermission()
|
||||
}
|
||||
LaunchedEffect(key1 = Unit) {
|
||||
checkPermission()
|
||||
}
|
||||
|
||||
LaunchedEffect(key1 = locationPermissionGranted.value) {
|
||||
if (locationPermissionGranted.value) {
|
||||
locationClient = AMapLocationClient(context).apply {
|
||||
setLocationOption(AMapLocationClientOption().apply {
|
||||
isOnceLocation = true // Only need the location once
|
||||
isNeedAddress = true
|
||||
})
|
||||
setLocationListener { location ->
|
||||
if (location != null) {
|
||||
val latLng = LatLng(location.latitude, location.longitude)
|
||||
selectLatLng = LatLonPoint(location.latitude, location.longitude)
|
||||
scope.launch {
|
||||
val address = reverseGeocode(context, selectLatLng)
|
||||
searchText = address
|
||||
}
|
||||
mapView.map.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, 15f))
|
||||
} else {
|
||||
Log.e("MapSearchScreen", "Location failed")
|
||||
errorMessage = "位置获取失败"
|
||||
}
|
||||
locationClient?.apply {
|
||||
stopLocation() // 停止位置更新
|
||||
onDestroy() // 销毁位置客户端
|
||||
}
|
||||
locationClient = null
|
||||
}
|
||||
startLocation()
|
||||
}
|
||||
} else {
|
||||
Log.e("MapSearchScreen", "Location permission not granted")
|
||||
errorMessage = "位置权限未授予"
|
||||
}
|
||||
}
|
||||
LaunchedEffect(key1 = locationPermissionGranted.value) {
|
||||
if (locationPermissionGranted.value) {
|
||||
locationClient = AMapLocationClient(context).apply {
|
||||
setLocationOption(AMapLocationClientOption().apply {
|
||||
isOnceLocation = true // Only need the location once
|
||||
isNeedAddress = true
|
||||
})
|
||||
setLocationListener { location ->
|
||||
if (location != null) {
|
||||
val latLng = LatLng(location.latitude, location.longitude)
|
||||
selectLatLng = LatLonPoint(location.latitude, location.longitude)
|
||||
scope.launch {
|
||||
val address = reverseGeocode(context, selectLatLng)
|
||||
searchText = address
|
||||
}
|
||||
mapView.map.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, 15f))
|
||||
} else {
|
||||
Log.e("MapSearchScreen", "Location failed")
|
||||
errorMessage = "位置获取失败"
|
||||
}
|
||||
locationClient?.apply {
|
||||
stopLocation() // 停止位置更新
|
||||
onDestroy() // 销毁位置客户端
|
||||
}
|
||||
locationClient = null
|
||||
}
|
||||
startLocation()
|
||||
}
|
||||
} else {
|
||||
Log.e("MapSearchScreen", "Location permission not granted")
|
||||
errorMessage = "位置权限未授予"
|
||||
}
|
||||
}
|
||||
|
||||
DisposableEffect(key1 = mapView) {
|
||||
onDispose {
|
||||
locationClient?.onDestroy()
|
||||
mapView.onDestroy()
|
||||
}
|
||||
}
|
||||
DisposableEffect(key1 = mapView) {
|
||||
onDispose {
|
||||
locationClient?.onDestroy()
|
||||
mapView.onDestroy()
|
||||
}
|
||||
}
|
||||
|
||||
Scaffold(
|
||||
topBar = {
|
||||
HeadView(title = "地图选点", onBack = { context.finish() })
|
||||
}
|
||||
) { paddingValues ->
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.padding(paddingValues)
|
||||
.padding(16.dp)
|
||||
.verticalScroll(state = rememberScrollState())
|
||||
) {
|
||||
Card(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(bottom = 16.dp)
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier.padding(16.dp)
|
||||
) {
|
||||
TextField(
|
||||
value = searchText,
|
||||
onValueChange = { searchText = it },
|
||||
label = { Text("搜索地址") },
|
||||
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Search),
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
Button(
|
||||
onClick = {
|
||||
if (searchText.isNotBlank()) {
|
||||
isLoading = true
|
||||
errorMessage = null
|
||||
searchResults = emptyList() // Clear previous results
|
||||
scope.launch {
|
||||
val results = searchPoi(context, searchText)
|
||||
searchResults = results
|
||||
isLoading = false
|
||||
}
|
||||
} else {
|
||||
errorMessage = "请输入地址"
|
||||
}
|
||||
},
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
) {
|
||||
Text("搜索")
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isLoading) {
|
||||
CircularProgressIndicator(
|
||||
modifier = Modifier.align(Alignment.CenterHorizontally)
|
||||
)
|
||||
}
|
||||
if (searchResults.isNotEmpty()) {
|
||||
LazyColumn(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.height(180.dp)
|
||||
.padding(bottom = 16.dp)
|
||||
) {
|
||||
items(items = searchResults) {
|
||||
Box(modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.clickable {
|
||||
selectLatLng = it.latLonPoint
|
||||
searchText = it.title
|
||||
}
|
||||
.padding(5.dp)) {
|
||||
Text(it.title, color = Color.Black)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Wrap MapView with AndroidView
|
||||
AndroidView(
|
||||
factory = {
|
||||
mapView.apply {
|
||||
onCreate(null)
|
||||
onResume()
|
||||
}
|
||||
},
|
||||
update = {
|
||||
it.map.setOnMapClickListener { latLng ->
|
||||
selectLatLng = LatLonPoint(latLng.latitude, latLng.longitude)
|
||||
scope.launch {
|
||||
val address = reverseGeocode(context, selectLatLng)
|
||||
searchText = address
|
||||
}
|
||||
}
|
||||
if (!mapInitialized) {
|
||||
mapInitialized = true
|
||||
}
|
||||
},
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.height(300.dp)
|
||||
)
|
||||
Scaffold(topBar = {
|
||||
HeadView(title = "地图选点", onBack = { context.finish() })
|
||||
}) { paddingValues ->
|
||||
Column(modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.padding(paddingValues)
|
||||
.padding(16.dp)
|
||||
.verticalScroll(state = rememberScrollState())) {
|
||||
Card(modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(bottom = 16.dp)) {
|
||||
Column(modifier = Modifier.padding(16.dp)) {
|
||||
TextField(value = searchText,
|
||||
onValueChange = { searchText = it },
|
||||
label = { Text("搜索地址") },
|
||||
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Search),
|
||||
modifier = Modifier.fillMaxWidth())
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
Button(onClick = {
|
||||
if (searchText.isNotBlank()) {
|
||||
isLoading = true
|
||||
errorMessage = null
|
||||
searchResults = emptyList() // Clear previous results
|
||||
scope.launch {
|
||||
val results = searchPoi(context, searchText)
|
||||
searchResults = results
|
||||
isLoading = false
|
||||
}
|
||||
} else {
|
||||
errorMessage = "请输入地址"
|
||||
}
|
||||
}, modifier = Modifier.fillMaxWidth()) {
|
||||
Text("搜索")
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isLoading) {
|
||||
CircularProgressIndicator(modifier = Modifier.align(Alignment.CenterHorizontally))
|
||||
}
|
||||
if (searchResults.isNotEmpty()) {
|
||||
LazyColumn(modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.height(180.dp)
|
||||
.padding(bottom = 16.dp)) {
|
||||
items(items = searchResults) {
|
||||
Box(modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.clickable {
|
||||
selectLatLng = it.latLonPoint
|
||||
searchText = it.title
|
||||
}
|
||||
.padding(5.dp)) {
|
||||
Text(it.title, color = Color.Black)
|
||||
}
|
||||
}
|
||||
}
|
||||
} // Wrap MapView with AndroidView
|
||||
AndroidView(factory = {
|
||||
mapView.apply {
|
||||
onCreate(null)
|
||||
onResume()
|
||||
}
|
||||
}, update = {
|
||||
it.map.setOnMapClickListener { latLng ->
|
||||
selectLatLng = LatLonPoint(latLng.latitude, latLng.longitude)
|
||||
scope.launch {
|
||||
val address = reverseGeocode(context, selectLatLng)
|
||||
searchText = address
|
||||
}
|
||||
}
|
||||
if (! mapInitialized) {
|
||||
mapInitialized = true
|
||||
}
|
||||
}, modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.height(300.dp))
|
||||
|
||||
Spacer(modifier = Modifier.height(20.dp))
|
||||
Spacer(modifier = Modifier.height(20.dp))
|
||||
|
||||
CommonButton(text = "确定") {
|
||||
onLocationSelected(PoiData(name = searchText, lat = selectLatLng.latitude, lng = selectLatLng.longitude))
|
||||
}
|
||||
}
|
||||
}
|
||||
CommonButton(text = "确定") {
|
||||
onLocationSelected(PoiData(name = searchText,
|
||||
lat = selectLatLng.latitude,
|
||||
lng = selectLatLng.longitude))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun searchPoi(context: Context, query: String): List<PoiItem> {
|
||||
return suspendCoroutine { continuation ->
|
||||
val poiSearchQuery = PoiSearch.Query(query, "", "") // 第二个参数是城市代码,留空表示全国搜索
|
||||
poiSearchQuery.pageNum = 0
|
||||
poiSearchQuery.pageSize = 10
|
||||
val poiSearch = PoiSearch(context, poiSearchQuery)
|
||||
private suspend fun searchPoi(context : Context, query : String) : List<PoiItem> {
|
||||
return suspendCoroutine { continuation ->
|
||||
val poiSearchQuery = PoiSearch.Query(query, "", "") // 第二个参数是城市代码,留空表示全国搜索
|
||||
poiSearchQuery.pageNum = 0
|
||||
poiSearchQuery.pageSize = 10
|
||||
val poiSearch = PoiSearch(context, poiSearchQuery)
|
||||
|
||||
poiSearch.setOnPoiSearchListener(object : PoiSearch.OnPoiSearchListener {
|
||||
override fun onPoiSearched(result: PoiResult?, rCode: Int) {
|
||||
if (rCode == AMapException.CODE_AMAP_SUCCESS) {
|
||||
val pois = result?.pois ?: emptyList()
|
||||
continuation.resume(pois)
|
||||
} else {
|
||||
Log.e("MapSearchScreen", "POI 搜索失败:$rCode")
|
||||
continuation.resume(emptyList())
|
||||
}
|
||||
}
|
||||
poiSearch.setOnPoiSearchListener(object : PoiSearch.OnPoiSearchListener {
|
||||
override fun onPoiSearched(result : PoiResult?, rCode : Int) {
|
||||
if (rCode == AMapException.CODE_AMAP_SUCCESS) {
|
||||
val pois = result?.pois ?: emptyList()
|
||||
continuation.resume(pois)
|
||||
} else {
|
||||
Log.e("MapSearchScreen", "POI 搜索失败:$rCode")
|
||||
continuation.resume(emptyList())
|
||||
}
|
||||
}
|
||||
|
||||
override fun onPoiItemSearched(poiItem: PoiItem?, rCode: Int) {
|
||||
// Not used in this case
|
||||
}
|
||||
})
|
||||
override fun onPoiItemSearched(poiItem : PoiItem?,
|
||||
rCode : Int) { // Not used in this case
|
||||
}
|
||||
})
|
||||
|
||||
poiSearch.searchPOIAsyn()
|
||||
}
|
||||
poiSearch.searchPOIAsyn()
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun reverseGeocode(context: Context, latLng: LatLonPoint): String {
|
||||
return suspendCoroutine { continuation ->
|
||||
val geocodeSearch = GeocodeSearch(context)
|
||||
geocodeSearch.setOnGeocodeSearchListener(object : GeocodeSearch.OnGeocodeSearchListener {
|
||||
override fun onRegeocodeSearched(result: RegeocodeResult?, rCode: Int) {
|
||||
if (rCode == AMapException.CODE_AMAP_SUCCESS) {
|
||||
val address = result?.regeocodeAddress?.formatAddress
|
||||
continuation.resume(address ?: "")
|
||||
} else {
|
||||
Log.e("MapSearchScreen", "Reverse Geocode failed: $rCode")
|
||||
continuation.resume("")
|
||||
}
|
||||
}
|
||||
private suspend fun reverseGeocode(context : Context, latLng : LatLonPoint) : String {
|
||||
return suspendCoroutine { continuation ->
|
||||
val geocodeSearch = GeocodeSearch(context)
|
||||
geocodeSearch.setOnGeocodeSearchListener(object : GeocodeSearch.OnGeocodeSearchListener {
|
||||
override fun onRegeocodeSearched(result : RegeocodeResult?, rCode : Int) {
|
||||
if (rCode == AMapException.CODE_AMAP_SUCCESS) {
|
||||
val address = result?.regeocodeAddress?.formatAddress
|
||||
continuation.resume(address ?: "")
|
||||
} else {
|
||||
Log.e("MapSearchScreen", "Reverse Geocode failed: $rCode")
|
||||
continuation.resume("")
|
||||
}
|
||||
}
|
||||
|
||||
override fun onGeocodeSearched(result: GeocodeResult?, rCode: Int) {
|
||||
// Not used in reverse geocoding
|
||||
}
|
||||
})
|
||||
override fun onGeocodeSearched(result : GeocodeResult?,
|
||||
rCode : Int) { // Not used in reverse geocoding
|
||||
}
|
||||
})
|
||||
|
||||
// Perform Reverse Geocoding (LatLng -> address)
|
||||
val query = com.amap.api.services.geocoder.RegeocodeQuery(latLng, 200f, GeocodeSearch.AMAP)
|
||||
geocodeSearch.getFromLocationAsyn(query) // Use the async version
|
||||
}
|
||||
// Perform Reverse Geocoding (LatLng -> address)
|
||||
val query = com.amap.api.services.geocoder.RegeocodeQuery(latLng, 200f, GeocodeSearch.AMAP)
|
||||
geocodeSearch.getFromLocationAsyn(query) // Use the async version
|
||||
}
|
||||
}
|
||||
|
||||
data class PoiData(val name: String? = null, val lat: Double? = null, val lng: Double? = null) : Serializable
|
||||
data class PoiData(val name : String? = null, val lat : Double? = null, val lng : Double? = null) :
|
||||
Serializable
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
fun PreviewMapSearchScreen() {
|
||||
MapSearchScreen(onLocationSelected = {})
|
||||
MapSearchScreen(onLocationSelected = {})
|
||||
}
|
@ -74,7 +74,7 @@ import com.za.ext.finish
|
||||
import com.za.servicing.R
|
||||
import com.za.ui.servicing.in_servicing_setting.OrderTaskNotesDialog
|
||||
|
||||
class NewOrderActivity : BaseActivity() {
|
||||
internal class NewOrderActivity : BaseActivity() {
|
||||
|
||||
@Composable
|
||||
override fun ContentView() {
|
||||
|
@ -89,7 +89,7 @@ data class NewOrderItemUIBean(
|
||||
|
||||
// 1 服务中 2 历史订单
|
||||
@Composable
|
||||
fun NewOrderItem(uiBean : NewOrderItemUIBean?,
|
||||
internal fun NewOrderItem(uiBean : NewOrderItemUIBean?,
|
||||
goInServicing : () -> Unit = {},
|
||||
goHistory : () -> Unit = {},
|
||||
goDetail : () -> Unit = {},
|
||||
|
@ -34,7 +34,7 @@ import java.text.SimpleDateFormat
|
||||
import java.util.Date
|
||||
import java.util.Locale
|
||||
|
||||
class NewOrderVm : BaseVm<NewOrderVm.Action, NewOrderVm.UiState>() {
|
||||
internal class NewOrderVm : BaseVm<NewOrderVm.Action, NewOrderVm.UiState>() {
|
||||
private val _uiState = MutableStateFlow(UiState())
|
||||
val uiState get() = _uiState
|
||||
|
||||
|
@ -42,7 +42,7 @@ import com.za.base.view.EmptyView
|
||||
import com.za.base.view.HeadView
|
||||
import com.za.ext.finish
|
||||
|
||||
class HistoryReportActivity : BaseActivity() {
|
||||
internal class HistoryReportActivity : BaseActivity() {
|
||||
@Composable
|
||||
override fun ContentView() {
|
||||
HistoryReportScreen()
|
||||
@ -50,7 +50,7 @@ class HistoryReportActivity : BaseActivity() {
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun HistoryReportScreen(vm : HistoryReportVm = viewModel()) {
|
||||
internal fun HistoryReportScreen(vm : HistoryReportVm = viewModel()) {
|
||||
val uiState by vm.uiState.collectAsStateWithLifecycle()
|
||||
val context = LocalContext.current
|
||||
val lifecycleOwner = LocalLifecycleOwner.current
|
||||
|
@ -13,42 +13,41 @@ import io.reactivex.rxjava3.schedulers.Schedulers
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
|
||||
class HistoryReportVm : BaseVm<HistoryReportVm.Action, HistoryReportVm.UiState>() {
|
||||
private val _uiState = MutableStateFlow(UiState())
|
||||
val uiState get() = _uiState.asStateFlow()
|
||||
internal class HistoryReportVm : BaseVm<HistoryReportVm.Action, HistoryReportVm.UiState>() {
|
||||
private val _uiState = MutableStateFlow(UiState())
|
||||
val uiState get() = _uiState.asStateFlow()
|
||||
|
||||
override fun updateState(uiState: UiState) {
|
||||
_uiState.value = uiState
|
||||
}
|
||||
override fun updateState(uiState : UiState) {
|
||||
_uiState.value = uiState
|
||||
}
|
||||
|
||||
override fun dispatch(action: Action) {
|
||||
when (action) {
|
||||
Action.Init -> init()
|
||||
}
|
||||
}
|
||||
override fun dispatch(action : Action) {
|
||||
when (action) {
|
||||
Action.Init -> init()
|
||||
}
|
||||
}
|
||||
|
||||
private fun init() {
|
||||
LoadingManager.showLoading()
|
||||
val request = ReportHistoryRequest(taskId = "${GlobalData.currentOrder?.taskId}")
|
||||
RetrofitHelper.getDefaultService().getReportHistory(request)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(object : BaseObserver<List<ReportHistoryBean>>() {
|
||||
override fun doSuccess(it: List<ReportHistoryBean>?) {
|
||||
LoadingManager.hideLoading()
|
||||
updateState(uiState.value.copy(historyReportList = it))
|
||||
}
|
||||
private fun init() {
|
||||
LoadingManager.showLoading()
|
||||
val request = ReportHistoryRequest(taskId = "${GlobalData.currentOrder?.taskId}")
|
||||
RetrofitHelper.getDefaultService().getReportHistory(request).subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(object : BaseObserver<List<ReportHistoryBean>>() {
|
||||
override fun doSuccess(it : List<ReportHistoryBean>?) {
|
||||
LoadingManager.hideLoading()
|
||||
updateState(uiState.value.copy(historyReportList = it))
|
||||
}
|
||||
|
||||
override fun doFailure(code: Int, msg: String?) {
|
||||
LoadingManager.hideLoading()
|
||||
ToastUtils.showLong(msg)
|
||||
}
|
||||
})
|
||||
}
|
||||
override fun doFailure(code : Int, msg : String?) {
|
||||
LoadingManager.hideLoading()
|
||||
ToastUtils.showLong(msg)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
data class UiState(val historyReportList: List<ReportHistoryBean>? = null)
|
||||
data class UiState(val historyReportList : List<ReportHistoryBean>? = null)
|
||||
|
||||
sealed class Action {
|
||||
data object Init : Action()
|
||||
}
|
||||
sealed class Action {
|
||||
data object Init : Action()
|
||||
}
|
||||
}
|
@ -44,7 +44,6 @@ import androidx.compose.ui.platform.LocalSoftwareKeyboardController
|
||||
import androidx.compose.ui.res.vectorResource
|
||||
import androidx.compose.ui.text.TextStyle
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
@ -61,7 +60,7 @@ import com.za.ui.map_search.MapSearchActivity
|
||||
import com.za.ui.map_search.PoiData
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
class OrderReportActivity : BaseActivity() {
|
||||
internal class OrderReportActivity : BaseActivity() {
|
||||
@Composable
|
||||
override fun ContentView() {
|
||||
OrderReportScreen()
|
||||
@ -73,7 +72,7 @@ private val TextGrey = Color(0xFF5F6368)
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun OrderReportScreen(vm: OrderReportVm = viewModel()) {
|
||||
internal fun OrderReportScreen(vm: OrderReportVm = viewModel()) {
|
||||
val uiState by vm.uiState.collectAsStateWithLifecycle()
|
||||
val scaffoldState = rememberBottomSheetScaffoldState()
|
||||
val scope = rememberCoroutineScope()
|
||||
@ -202,9 +201,3 @@ fun OrderReportScreen(vm: OrderReportVm = viewModel()) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
fun OrderReportPreview(modifier: Modifier = Modifier) {
|
||||
OrderReportScreen()
|
||||
}
|
@ -14,7 +14,7 @@ import io.reactivex.rxjava3.schedulers.Schedulers
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
|
||||
class OrderReportVm : BaseVm<OrderReportVm.Action, OrderReportVm.UiState>() {
|
||||
internal class OrderReportVm : BaseVm<OrderReportVm.Action, OrderReportVm.UiState>() {
|
||||
private val _uiState = MutableStateFlow(UiState())
|
||||
val uiState get() = _uiState.asStateFlow()
|
||||
|
||||
|
@ -38,7 +38,7 @@ import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlin.math.abs
|
||||
|
||||
class ReportFloatingManager : Service() {
|
||||
internal class ReportFloatingManager : Service() {
|
||||
private var windowManager : WindowManager? = null
|
||||
private var floatingView : View? = null
|
||||
private var touchJob : Job? = null
|
||||
|
@ -359,7 +359,7 @@ private fun ocrRecognition(photoTemplateInfo : PhotoTemplateInfo,
|
||||
|
||||
|
||||
@Composable
|
||||
fun InServicingPhotoView(modifier : Modifier = Modifier,
|
||||
internal fun InServicingPhotoView(modifier : Modifier = Modifier,
|
||||
photoTemplateInfo : PhotoTemplateInfo,
|
||||
index : Int? = null,
|
||||
success : (PhotoTemplateInfo) -> Unit) {
|
||||
@ -445,7 +445,7 @@ fun InServicingPhotoView(modifier : Modifier = Modifier,
|
||||
|
||||
|
||||
@Composable
|
||||
fun InServicingPhotoViewIsCanClick(modifier : Modifier = Modifier,
|
||||
internal fun InServicingPhotoViewIsCanClick(modifier : Modifier = Modifier,
|
||||
photoTemplateInfo : PhotoTemplateInfo,
|
||||
index : Int? = null,
|
||||
isCanClick : Boolean = true,
|
||||
@ -534,7 +534,7 @@ fun InServicingPhotoViewIsCanClick(modifier : Modifier = Modifier,
|
||||
|
||||
|
||||
@Composable
|
||||
fun InServicingPhotoWithoutTitleView(modifier : Modifier = Modifier,
|
||||
internal fun InServicingPhotoWithoutTitleView(modifier : Modifier = Modifier,
|
||||
photoTemplateInfo : PhotoTemplateInfo,
|
||||
index : Int? = null,
|
||||
success : (PhotoTemplateInfo) -> Unit) {
|
||||
@ -591,7 +591,7 @@ fun InServicingPhotoWithoutTitleView(modifier : Modifier = Modifier,
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun InServicingPhotoItemView(modifier : Modifier = Modifier,
|
||||
internal fun InServicingPhotoItemView(modifier : Modifier = Modifier,
|
||||
photoTemplateInfo : PhotoTemplateInfo,
|
||||
isCanClick : Boolean = true,
|
||||
success : (PhotoTemplateInfo) -> Unit) {
|
||||
|
@ -24,7 +24,7 @@ import com.za.ext.goNextPage
|
||||
import com.za.ui.servicing.InServicingPhotoView
|
||||
import com.za.ui.servicing.view.InServicingHeadView
|
||||
|
||||
class CheckVehicleActivity : BaseActivity() {
|
||||
internal class CheckVehicleActivity : BaseActivity() {
|
||||
@Composable
|
||||
override fun ContentView() {
|
||||
CheckVehicleScreen()
|
||||
@ -32,7 +32,7 @@ class CheckVehicleActivity : BaseActivity() {
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun CheckVehicleScreen(vm: CheckVehicleVm = viewModel()) {
|
||||
internal fun CheckVehicleScreen(vm: CheckVehicleVm = viewModel()) {
|
||||
val uiState = vm.uiState.collectAsStateWithLifecycle()
|
||||
val context = LocalContext.current
|
||||
|
||||
|
@ -19,7 +19,7 @@ import com.za.offline.OfflineUpdateTaskBean
|
||||
import com.za.service.location.ZdLocationManager
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
|
||||
class CheckVehicleVm : IServicingVm<CheckVehicleVm.Action, CheckVehicleVm.UiState>() {
|
||||
internal class CheckVehicleVm : IServicingVm<CheckVehicleVm.Action, CheckVehicleVm.UiState>() {
|
||||
private val _uiState = MutableStateFlow(UiState())
|
||||
val uiState get() = _uiState
|
||||
override fun updateState(uiState : UiState) {
|
||||
|
@ -24,7 +24,7 @@ import com.za.ext.goNextPage
|
||||
import com.za.ui.servicing.InServicingPhotoView
|
||||
import com.za.ui.servicing.view.InServicingHeadView
|
||||
|
||||
class DeparturePhotoActivity : BaseActivity() {
|
||||
internal class DeparturePhotoActivity : BaseActivity() {
|
||||
@Composable
|
||||
override fun ContentView() {
|
||||
DeparturePhotoScreen()
|
||||
@ -32,7 +32,7 @@ class DeparturePhotoActivity : BaseActivity() {
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun DeparturePhotoScreen(vm : DeparturePhotoVm = viewModel()) {
|
||||
internal fun DeparturePhotoScreen(vm : DeparturePhotoVm = viewModel()) {
|
||||
val uiState = vm.uiState.collectAsStateWithLifecycle()
|
||||
val context = LocalContext.current
|
||||
|
||||
|
@ -15,7 +15,7 @@ import com.za.net.CommonMethod
|
||||
import com.za.service.location.ZdLocationManager
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
|
||||
class DeparturePhotoVm : IServicingVm<DeparturePhotoVm.Action, DeparturePhotoVm.UiState>() {
|
||||
internal class DeparturePhotoVm : IServicingVm<DeparturePhotoVm.Action, DeparturePhotoVm.UiState>() {
|
||||
private val _uiState = MutableStateFlow(UiState())
|
||||
val uiState get() = _uiState
|
||||
|
||||
|
@ -24,7 +24,7 @@ import com.za.ext.goNextPage
|
||||
import com.za.ui.servicing.InServicingPhotoView
|
||||
import com.za.ui.servicing.view.InServicingHeadView
|
||||
|
||||
class DestinationPhotoActivity : BaseActivity() {
|
||||
internal class DestinationPhotoActivity : BaseActivity() {
|
||||
@Composable
|
||||
override fun ContentView() {
|
||||
DestinationPhotoScreen()
|
||||
@ -32,7 +32,7 @@ class DestinationPhotoActivity : BaseActivity() {
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun DestinationPhotoScreen(vm: DestinationPhotoVm = viewModel()) {
|
||||
internal fun DestinationPhotoScreen(vm: DestinationPhotoVm = viewModel()) {
|
||||
val uiState = vm.uiState.collectAsStateWithLifecycle()
|
||||
val context = LocalContext.current
|
||||
|
||||
|
@ -19,7 +19,7 @@ import com.za.offline.OfflineUpdateTaskBean
|
||||
import com.za.service.location.ZdLocationManager
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
|
||||
class DestinationPhotoVm : IServicingVm<DestinationPhotoVm.Action, DestinationPhotoVm.UiState>() {
|
||||
internal class DestinationPhotoVm : IServicingVm<DestinationPhotoVm.Action, DestinationPhotoVm.UiState>() {
|
||||
private val _uiState = MutableStateFlow(UiState())
|
||||
val uiState get() = _uiState
|
||||
override fun updateState(uiState : UiState) {
|
||||
|
@ -61,7 +61,7 @@ import com.za.ui.camera.ZdCameraXActivity
|
||||
import com.za.ui.servicing.view.InServicingHeadView
|
||||
|
||||
@Composable
|
||||
fun EleSignCheckScreen(vm: EleSignCheckVm = viewModel()) {
|
||||
internal fun EleSignCheckScreen(vm: EleSignCheckVm = viewModel()) {
|
||||
val context = LocalContext.current
|
||||
val uiState = vm.uiState.collectAsStateWithLifecycle()
|
||||
LaunchedEffect(key1 = Unit) {
|
||||
@ -163,8 +163,8 @@ private fun EleSignCheckContent(eleWorkOrderBean: EleWorkOrderBean?,
|
||||
.background(color = Color.White, shape = RoundedCornerShape(4.dp))) {
|
||||
Column(modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.background(brush = Brush.verticalGradient(arrayListOf(Color(0xFF97A0BA), Color(0xFFE1E8F3))),
|
||||
shape = RoundedCornerShape(topStart = 4.dp, topEnd = 4.dp))
|
||||
.background(brush = Brush.verticalGradient(arrayListOf(Color(0xFF97A0BA),
|
||||
Color(0xFFE1E8F3))), shape = RoundedCornerShape(topStart = 4.dp, topEnd = 4.dp))
|
||||
.padding(10.dp)) {
|
||||
Text(text = "验车拍照", color = Color(0xFF213B54), fontWeight = FontWeight.Bold, fontSize = 16.sp)
|
||||
Row(modifier = Modifier
|
||||
|
@ -24,7 +24,7 @@ import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import java.io.File
|
||||
import java.util.Date
|
||||
|
||||
class EleSignCheckVm : IServicingVm<EleSignCheckVm.Action, EleSignCheckVm.UiState>() {
|
||||
internal class EleSignCheckVm : IServicingVm<EleSignCheckVm.Action, EleSignCheckVm.UiState>() {
|
||||
private val _uiState = MutableStateFlow(UiState())
|
||||
val uiState get() = _uiState
|
||||
override fun updateState(uiState: UiState) {
|
||||
|
@ -49,7 +49,7 @@ import com.za.ui.view.SignatureView
|
||||
import kotlin.math.ceil
|
||||
|
||||
@Composable
|
||||
fun EleSignScreen(vm : EleSignVm = viewModel()) {
|
||||
internal fun EleSignScreen(vm : EleSignVm = viewModel()) {
|
||||
val context = LocalContext.current
|
||||
val uiState = vm.uiState.collectAsStateWithLifecycle()
|
||||
LaunchedEffect(key1 = Unit) {
|
||||
|
@ -26,7 +26,7 @@ import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.io.File
|
||||
|
||||
class EleSignVm : IServicingVm<EleSignVm.Action, EleSignVm.UiState>() {
|
||||
internal class EleSignVm : IServicingVm<EleSignVm.Action, EleSignVm.UiState>() {
|
||||
private val _uiState = MutableStateFlow(UiState())
|
||||
val uiState get() = _uiState
|
||||
override fun updateState(uiState : UiState) {
|
||||
|
@ -52,7 +52,7 @@ import com.za.ui.new_order.NewOrderUiType
|
||||
import com.za.ui.servicing.view.InServicingHeadView
|
||||
import com.za.ui.servicing.view.ServiceOperation
|
||||
|
||||
class GoAccidentSiteActivity : BaseActivity() {
|
||||
internal class GoAccidentSiteActivity : BaseActivity() {
|
||||
@Composable
|
||||
override fun ContentView() {
|
||||
GoAccidentSiteScreen()
|
||||
@ -61,7 +61,7 @@ class GoAccidentSiteActivity : BaseActivity() {
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun GoAccidentSiteScreen(vm : GoAccidentSiteVm = viewModel()) {
|
||||
internal fun GoAccidentSiteScreen(vm : GoAccidentSiteVm = viewModel()) {
|
||||
val uiState = vm.uiState.collectAsStateWithLifecycle()
|
||||
val context = LocalContext.current
|
||||
val lifecycleOwner = LocalLifecycleOwner.current
|
||||
@ -121,16 +121,13 @@ fun GoAccidentSiteScreen(vm : GoAccidentSiteVm = viewModel()) {
|
||||
title = "任务提交失败,是否离线提交?",
|
||||
cancelEnable = true,
|
||||
cancel = {
|
||||
vm.dispatch(GoAccidentSiteVm.Action.UpdateState(uiState.value.copy(
|
||||
showOfflineDialog = false)))
|
||||
vm.dispatch(GoAccidentSiteVm.Action.UpdateState(uiState.value.copy(showOfflineDialog = false)))
|
||||
},
|
||||
dismiss = {
|
||||
vm.dispatch(GoAccidentSiteVm.Action.UpdateState(uiState.value.copy(
|
||||
showOfflineDialog = false)))
|
||||
vm.dispatch(GoAccidentSiteVm.Action.UpdateState(uiState.value.copy(showOfflineDialog = false)))
|
||||
},
|
||||
confirm = {
|
||||
vm.dispatch(GoAccidentSiteVm.Action.UpdateState(uiState.value.copy(
|
||||
showOfflineDialog = false)))
|
||||
vm.dispatch(GoAccidentSiteVm.Action.UpdateState(uiState.value.copy(showOfflineDialog = false)))
|
||||
vm.dispatch(GoAccidentSiteVm.Action.UpdateOffline)
|
||||
})
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ import java.util.Calendar
|
||||
import java.util.Date
|
||||
import java.util.Locale
|
||||
|
||||
class GoAccidentSiteVm : IServicingVm<GoAccidentSiteVm.Action, GoAccidentSiteVm.UiState>() {
|
||||
internal class GoAccidentSiteVm : IServicingVm<GoAccidentSiteVm.Action, GoAccidentSiteVm.UiState>() {
|
||||
private val _uiState = MutableStateFlow(UiState())
|
||||
val uiState get() = _uiState
|
||||
override fun updateState(uiState : UiState) {
|
||||
|
@ -52,7 +52,7 @@ import com.za.ui.new_order.NewOrderUiType
|
||||
import com.za.ui.servicing.view.InServicingHeadView
|
||||
import com.za.ui.servicing.view.ServiceOperation
|
||||
|
||||
class GoToDestinationActivity : BaseActivity() {
|
||||
internal class GoToDestinationActivity : BaseActivity() {
|
||||
@Composable
|
||||
override fun ContentView() {
|
||||
GoToDestinationScreen()
|
||||
@ -61,7 +61,7 @@ class GoToDestinationActivity : BaseActivity() {
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun GoToDestinationScreen(vm : GoToDestinationVm = viewModel()) {
|
||||
internal fun GoToDestinationScreen(vm : GoToDestinationVm = viewModel()) {
|
||||
val uiState = vm.uiState.collectAsStateWithLifecycle()
|
||||
val context = LocalContext.current
|
||||
val lifecycleOwner = LocalLifecycleOwner.current
|
||||
|
@ -39,7 +39,7 @@ import java.util.Calendar
|
||||
import java.util.Date
|
||||
import java.util.Locale
|
||||
|
||||
class GoToDestinationVm : IServicingVm<GoToDestinationVm.Action, GoToDestinationVm.UiState>() {
|
||||
internal class GoToDestinationVm : IServicingVm<GoToDestinationVm.Action, GoToDestinationVm.UiState>() {
|
||||
private val _uiState = MutableStateFlow(UiState())
|
||||
val uiState get() = _uiState
|
||||
override fun updateState(uiState : UiState) {
|
||||
|
@ -47,7 +47,7 @@ import com.za.ext.copy
|
||||
import com.za.servicing.R
|
||||
|
||||
@Composable
|
||||
fun OrderDetailItemScreen(orderInfo : OrderInfo?) {
|
||||
internal fun OrderDetailItemScreen(orderInfo : OrderInfo?) {
|
||||
Column(modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.verticalScroll(state = rememberScrollState())
|
||||
@ -433,7 +433,7 @@ private fun OrderDetailServiceInformationView(orderInfo : OrderInfo?) {
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun OrderDetailTime(orderInfo : OrderInfo?) {
|
||||
internal fun OrderDetailTime(orderInfo : OrderInfo?) {
|
||||
val titleSize = 12.sp
|
||||
val titleColor = Color(0xFF7A7A7A)
|
||||
val contentColor = Color.Black
|
||||
|
@ -44,7 +44,7 @@ import com.za.ui.servicing.order_give_up.OrderGiveUpActivity
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@Composable
|
||||
fun OrderDetailScreen(orderInfo : OrderInfo?) {
|
||||
internal fun OrderDetailScreen(orderInfo : OrderInfo?) {
|
||||
val context = LocalContext.current
|
||||
val titleList = listOf("订单详情", "案件要求")
|
||||
val pagerState = rememberPagerState(initialPage = 0, pageCount = { titleList.size })
|
||||
|
@ -9,9 +9,9 @@ import androidx.compose.ui.graphics.Color
|
||||
import com.za.bean.db.order.OrderInfo
|
||||
|
||||
@Composable
|
||||
fun OrderEleScreen(orderInfo: OrderInfo?) {
|
||||
Box(modifier = Modifier.fillMaxSize()) {
|
||||
Text(text = "电子工单", color = Color.Black)
|
||||
}
|
||||
internal fun OrderEleScreen(orderInfo : OrderInfo?) {
|
||||
Box(modifier = Modifier.fillMaxSize()) {
|
||||
Text(text = "电子工单", color = Color.Black)
|
||||
}
|
||||
|
||||
}
|
@ -28,7 +28,7 @@ import com.za.bean.db.order.OrderInfo
|
||||
import com.za.ext.finish
|
||||
|
||||
@Composable
|
||||
fun OrderOnSitePhotoScreen(orderInfo: OrderInfo?) {
|
||||
internal fun OrderOnSitePhotoScreen(orderInfo: OrderInfo?) {
|
||||
val context = LocalContext.current
|
||||
val showPreviewPhotoDialog = remember { mutableStateOf<String?>("") }
|
||||
if (!showPreviewPhotoDialog.value.isNullOrBlank()) {
|
||||
|
@ -9,7 +9,7 @@ import androidx.compose.ui.graphics.Color
|
||||
import com.za.bean.db.order.OrderInfo
|
||||
|
||||
@Composable
|
||||
fun OrderPhotoScreen(orderInfo: OrderInfo?) {
|
||||
internal fun OrderPhotoScreen(orderInfo: OrderInfo?) {
|
||||
Box(modifier = Modifier.fillMaxSize()) {
|
||||
Text(text = "案件照片", color = Color.Black)
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ import com.za.base.BaseActivity
|
||||
import com.za.base.Const
|
||||
import com.za.bean.db.order.OrderInfo
|
||||
|
||||
class OrderRequirementsActivity : BaseActivity() {
|
||||
internal class OrderRequirementsActivity : BaseActivity() {
|
||||
@Composable
|
||||
override fun ContentView() {
|
||||
val orderInfo = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
|
@ -44,7 +44,7 @@ import com.za.servicing.R
|
||||
import com.za.ui.h5.CommonH5Activity
|
||||
|
||||
@Composable
|
||||
fun OrderRequirementsScreen(orderInfo : OrderInfo?) {
|
||||
internal fun OrderRequirementsScreen(orderInfo : OrderInfo?) {
|
||||
Scaffold {
|
||||
Column(modifier = Modifier
|
||||
.fillMaxSize()
|
||||
@ -63,7 +63,7 @@ fun OrderRequirementsScreen(orderInfo : OrderInfo?) {
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun OrderRequirementsItemView(title : String?, content : String?) {
|
||||
internal fun OrderRequirementsItemView(title : String?, content : String?) {
|
||||
Column(modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(vertical = 5.dp)) {
|
||||
|
@ -9,7 +9,7 @@ import androidx.compose.ui.graphics.Color
|
||||
import com.za.bean.db.order.OrderInfo
|
||||
|
||||
@Composable
|
||||
fun OrderSettleScreen(orderInfo: OrderInfo?) {
|
||||
internal fun OrderSettleScreen(orderInfo: OrderInfo?) {
|
||||
Box(modifier = Modifier.fillMaxSize()) {
|
||||
Text(text = "结算单", color = Color.Black)
|
||||
}
|
||||
|
@ -9,8 +9,8 @@ import androidx.compose.ui.graphics.Color
|
||||
import com.za.bean.db.order.OrderInfo
|
||||
|
||||
@Composable
|
||||
fun OrderTriceScreen(orderInfo: OrderInfo?) {
|
||||
Box(modifier = Modifier.fillMaxSize()) {
|
||||
Text(text = "订单轨迹", color = Color.Black)
|
||||
}
|
||||
internal fun OrderTriceScreen(orderInfo : OrderInfo?) {
|
||||
Box(modifier = Modifier.fillMaxSize()) {
|
||||
Text(text = "订单轨迹", color = Color.Black)
|
||||
}
|
||||
}
|
@ -4,7 +4,7 @@ import androidx.compose.runtime.Composable
|
||||
import com.za.base.BaseActivity
|
||||
|
||||
|
||||
class ServicePeopleConfirmActivity : BaseActivity() {
|
||||
internal class ServicePeopleConfirmActivity : BaseActivity() {
|
||||
|
||||
@Composable
|
||||
override fun ContentView() {
|
||||
|
@ -23,7 +23,7 @@ import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import java.io.File
|
||||
|
||||
class InServicePeopleConfirmVm : IServicingVm<Action, UiState>() {
|
||||
internal class InServicePeopleConfirmVm : IServicingVm<Action, UiState>() {
|
||||
private val _uiState = MutableStateFlow(UiState())
|
||||
val uiState get() = _uiState as StateFlow<UiState>
|
||||
override fun updateState(uiState : UiState) {
|
||||
|
@ -43,7 +43,7 @@ import com.za.servicing.R
|
||||
import com.za.ui.camera.ServicePeopleRealActivity
|
||||
|
||||
@Composable
|
||||
fun ServicePeopleConfirmScreen(vm : InServicePeopleConfirmVm = viewModel(),
|
||||
internal fun ServicePeopleConfirmScreen(vm : InServicePeopleConfirmVm = viewModel(),
|
||||
success : () -> Unit = {},
|
||||
onBack : () -> Unit) {
|
||||
val context = LocalContext.current
|
||||
|
@ -7,7 +7,7 @@ import com.za.ext.getEleState
|
||||
import com.za.ui.servicing.ele_check.EleSignCheckScreen
|
||||
import com.za.ui.servicing.ele_sign.EleSignScreen
|
||||
|
||||
class InOperationActivity : BaseActivity() {
|
||||
internal class InOperationActivity : BaseActivity() {
|
||||
|
||||
@Composable
|
||||
override fun ContentView() {
|
||||
|
@ -24,7 +24,7 @@ import com.za.ui.servicing.InServicingPhotoView
|
||||
import com.za.ui.servicing.view.InServicingHeadView
|
||||
|
||||
@Composable
|
||||
fun InOperationScreen(vm: InOperationVm = viewModel()) {
|
||||
internal fun InOperationScreen(vm: InOperationVm = viewModel()) {
|
||||
val uiState = vm.uiState.collectAsStateWithLifecycle()
|
||||
val context = LocalContext.current
|
||||
|
||||
|
@ -19,7 +19,7 @@ import com.za.offline.OfflineUpdateTaskBean
|
||||
import com.za.service.location.ZdLocationManager
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
|
||||
class InOperationVm : IServicingVm<InOperationVm.Action, InOperationVm.UiState>() {
|
||||
internal class InOperationVm : IServicingVm<InOperationVm.Action, InOperationVm.UiState>() {
|
||||
private val _uiState = MutableStateFlow(UiState())
|
||||
val uiState get() = _uiState
|
||||
override fun updateState(uiState : UiState) {
|
||||
|
@ -33,7 +33,7 @@ import com.za.ext.goStatusPage
|
||||
import com.za.ui.servicing.InServicingPhotoView
|
||||
|
||||
@Composable
|
||||
fun ChangeBatteryScreen(vm : ChangeBatteryVm = viewModel()) {
|
||||
internal fun ChangeBatteryScreen(vm : ChangeBatteryVm = viewModel()) {
|
||||
val uiState = vm.uiState.collectAsStateWithLifecycle()
|
||||
val context = LocalContext.current
|
||||
LaunchedEffect(key1 = Unit) {
|
||||
|
@ -23,7 +23,7 @@ import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.rxjava3.schedulers.Schedulers
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
|
||||
class ChangeBatteryVm : BaseVm<ChangeBatteryVm.Action, ChangeBatteryVm.UiState>() {
|
||||
internal class ChangeBatteryVm : BaseVm<ChangeBatteryVm.Action, ChangeBatteryVm.UiState>() {
|
||||
private val _uiState = MutableStateFlow(UiState())
|
||||
val uiState get() = _uiState
|
||||
|
||||
|
@ -73,7 +73,7 @@ import kotlin.math.ceil
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
fun ConfirmEleScreen(vm : ConfirmEleVm = viewModel()) {
|
||||
internal fun ConfirmEleScreen(vm : ConfirmEleVm = viewModel()) {
|
||||
val context = LocalContext.current
|
||||
val uiState = vm.uiState.collectAsStateWithLifecycle()
|
||||
LaunchedEffect(key1 = Unit) {
|
||||
@ -414,7 +414,8 @@ fun ConfirmEleScreen(vm : ConfirmEleVm = viewModel()) {
|
||||
vm.dispatch(ConfirmEleVm.Action.UploadServiceSignature(it))
|
||||
},
|
||||
serverPath = uiState.value.eleWorkOrderBean?.localServicePeopleSignPath
|
||||
?: uiState.value.eleWorkOrderBean?.serverServicePeopleSignPath)
|
||||
?: uiState.value.eleWorkOrderBean?.serverServicePeopleSignPath
|
||||
?: GlobalData.driverInfoBean?.signatureUrl)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.io.File
|
||||
|
||||
class ConfirmEleVm : IServicingVm<ConfirmEleVm.Action, ConfirmEleVm.UiState>() {
|
||||
internal class ConfirmEleVm : IServicingVm<ConfirmEleVm.Action, ConfirmEleVm.UiState>() {
|
||||
private val _uiState = MutableStateFlow(UiState())
|
||||
val uiState get() = _uiState
|
||||
|
||||
@ -283,7 +283,8 @@ class ConfirmEleVm : IServicingVm<ConfirmEleVm.Action, ConfirmEleVm.UiState>() {
|
||||
} else null,
|
||||
hasSuccess = eleWorkOrderBean.isSuccess,
|
||||
recipientSignPath = eleWorkOrderBean.serverAcceptCarSignPath,
|
||||
waitstaffSignPath = eleWorkOrderBean.serverServicePeopleSignPath)
|
||||
waitstaffSignPath = eleWorkOrderBean.serverServicePeopleSignPath
|
||||
?: GlobalData.driverInfoBean?.signatureUrl)
|
||||
LoadingManager.showLoading()
|
||||
RetrofitHelper.getDefaultService().saveElectronOrder(saveEleOrderRequest)
|
||||
.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
|
||||
|
@ -55,7 +55,7 @@ import com.za.signature.GridPaintActivity
|
||||
import com.za.signature.config.PenConfig
|
||||
|
||||
@Composable
|
||||
fun ConfirmH5SuccessScreen(vm : ConfirmH5SuccessVm = viewModel()) {
|
||||
internal fun ConfirmH5SuccessScreen(vm : ConfirmH5SuccessVm = viewModel()) {
|
||||
val uiState = vm.uiState.collectAsStateWithLifecycle()
|
||||
val context = LocalContext.current
|
||||
val webView = WebView(context)
|
||||
|
@ -26,7 +26,7 @@ import io.reactivex.rxjava3.schedulers.Schedulers
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import java.io.File
|
||||
|
||||
class ConfirmH5SuccessVm : IServicingVm<ConfirmH5SuccessVm.Action, ConfirmH5SuccessVm.UiState>() {
|
||||
internal class ConfirmH5SuccessVm : IServicingVm<ConfirmH5SuccessVm.Action, ConfirmH5SuccessVm.UiState>() {
|
||||
private val _uiState = MutableStateFlow(UiState())
|
||||
val uiState get() = _uiState
|
||||
override fun updateState(uiState : UiState) {
|
||||
|
@ -1,9 +0,0 @@
|
||||
package com.za.ui.servicing.order_confirm
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
|
||||
@Composable
|
||||
fun EleSuccessScreen(modifier: Modifier = Modifier) {
|
||||
|
||||
}
|
@ -17,7 +17,7 @@ import com.za.ui.servicing.order_confirm.input_money.InputMoneyActivity
|
||||
import com.za.ui.servicing.order_confirm.real_order_confirm.RealOrderConfirmActivity
|
||||
import com.za.ui.servicing.order_confirm.receive_money.ReceiveMoneyActivity
|
||||
|
||||
class OrderConfirmActivity : BaseActivity() {
|
||||
internal class OrderConfirmActivity : BaseActivity() {
|
||||
|
||||
@Composable
|
||||
override fun ContentView() {
|
||||
@ -26,7 +26,7 @@ class OrderConfirmActivity : BaseActivity() {
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun OrderConfirmInitScreen(vm : OrderConfirmInitVm = viewModel()) {
|
||||
internal fun OrderConfirmInitScreen(vm : OrderConfirmInitVm = viewModel()) {
|
||||
val uiState = vm.uiState.collectAsStateWithLifecycle()
|
||||
val context = LocalContext.current
|
||||
LaunchedEffect(key1 = Unit) {
|
||||
|
@ -16,7 +16,7 @@ import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.rxjava3.schedulers.Schedulers
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
|
||||
class OrderConfirmInitVm : IServicingVm<OrderConfirmInitVm.Action, OrderConfirmInitVm.UiState>() {
|
||||
internal class OrderConfirmInitVm : IServicingVm<OrderConfirmInitVm.Action, OrderConfirmInitVm.UiState>() {
|
||||
private val _uiState = MutableStateFlow(UiState())
|
||||
val uiState get() = _uiState
|
||||
override fun updateState(uiState : UiState) {
|
||||
|
@ -82,7 +82,7 @@ import kotlinx.coroutines.delay
|
||||
val primaryColor = Color(0xFF3B82F6)
|
||||
val gradientColors = listOf(Color(0xFF3B82F6), Color(0xFF60A5FA))
|
||||
|
||||
class InputMoneyActivity : BaseActivity() {
|
||||
internal class InputMoneyActivity : BaseActivity() {
|
||||
@Composable
|
||||
override fun ContentView() {
|
||||
InputMoneyScreen(userOrderId = intent.getIntExtra("userOrderId", 0),
|
||||
@ -101,7 +101,7 @@ class InputMoneyActivity : BaseActivity() {
|
||||
|
||||
|
||||
@Composable
|
||||
fun InputMoneyScreen(userOrderId : Int, taskId : Int, vm : InputMoneyVm = viewModel()) {
|
||||
internal fun InputMoneyScreen(userOrderId : Int, taskId : Int, vm : InputMoneyVm = viewModel()) {
|
||||
val context = LocalContext.current
|
||||
val uiState = vm.uiState.collectAsStateWithLifecycle()
|
||||
var showSuccessDialog by remember { mutableStateOf(false) }
|
||||
@ -414,9 +414,3 @@ private fun SuccessDialog(amount : String, onDismiss : () -> Unit) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Preview()
|
||||
@Composable
|
||||
fun PreviewInputMoneyScreen() {
|
||||
InputMoneyScreen(userOrderId = 1, taskId = 1)
|
||||
}
|
@ -20,7 +20,7 @@ import kotlinx.coroutines.flow.asStateFlow
|
||||
import kotlinx.coroutines.isActive
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
class InputMoneyVm : BaseVm<InputMoneyVm.Action, InputMoneyVm.UiState>() {
|
||||
internal class InputMoneyVm : BaseVm<InputMoneyVm.Action, InputMoneyVm.UiState>() {
|
||||
private val _uiState = MutableStateFlow(UiState())
|
||||
val uiState get() = _uiState.asStateFlow()
|
||||
private var timerJob: Job? = null
|
||||
|
@ -5,7 +5,7 @@ import android.content.Intent
|
||||
import androidx.compose.runtime.Composable
|
||||
import com.za.base.BaseActivity
|
||||
|
||||
class ModifyMoneyActivity : BaseActivity() {
|
||||
internal class ModifyMoneyActivity : BaseActivity() {
|
||||
@Composable
|
||||
override fun ContentView() {
|
||||
ModifyMoneyScreen(userOrderId = intent.getIntExtra("userOrderId", 0), taskId = intent.getIntExtra("taskId", 0))
|
||||
|
@ -39,7 +39,7 @@ import com.za.ui.servicing.order_confirm.modify_money.ModifyMoneyViewModel
|
||||
|
||||
|
||||
@Composable
|
||||
fun ModifyMoneyScreen(userOrderId : Int, taskId : Int, vm : ModifyMoneyViewModel = viewModel()) {
|
||||
internal fun ModifyMoneyScreen(userOrderId : Int, taskId : Int, vm : ModifyMoneyViewModel = viewModel()) {
|
||||
|
||||
val uiState = vm.uiState.collectAsStateWithLifecycle()
|
||||
val context = LocalContext.current
|
||||
|
@ -15,7 +15,7 @@ import io.reactivex.rxjava3.schedulers.Schedulers
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
|
||||
class ModifyMoneyViewModel : BaseVm<Action, UiState>() {
|
||||
internal class ModifyMoneyViewModel : BaseVm<Action, UiState>() {
|
||||
private val _uiState = MutableStateFlow(UiState())
|
||||
val uiState get() = _uiState.asStateFlow()
|
||||
|
||||
|
@ -50,7 +50,7 @@ import com.za.ui.servicing.InServicingPhotoWithoutTitleView
|
||||
import com.za.ui.servicing.view.InServicingHeadView
|
||||
|
||||
@Composable
|
||||
fun OrderConfirmScreen(vm : OrderConfirmVm = viewModel()) {
|
||||
internal fun OrderConfirmScreen(vm : OrderConfirmVm = viewModel()) {
|
||||
val context = LocalContext.current
|
||||
val uiState = vm.uiState.collectAsStateWithLifecycle()
|
||||
LaunchedEffect(key1 = Unit) {
|
||||
@ -113,7 +113,7 @@ fun OrderConfirmScreen(vm : OrderConfirmVm = viewModel()) {
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun BaseFeeView(flowType : Int,
|
||||
internal fun BaseFeeView(flowType : Int,
|
||||
startPrice : Int?,
|
||||
unitPrice : Int?,
|
||||
overKm : Int?,
|
||||
@ -173,7 +173,7 @@ fun BaseFeeView(flowType : Int,
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun AuxiliaryFeeView(dilemmaFee : Int?,
|
||||
internal fun AuxiliaryFeeView(dilemmaFee : Int?,
|
||||
basementFee : Int?,
|
||||
abroadFee : Int?,
|
||||
bcRoadFee : Int?,
|
||||
|
@ -22,7 +22,7 @@ import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.rxjava3.schedulers.Schedulers
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
|
||||
class OrderConfirmVm : IServicingVm<OrderConfirmVm.Action, OrderConfirmVm.UiState>() {
|
||||
internal class OrderConfirmVm : IServicingVm<OrderConfirmVm.Action, OrderConfirmVm.UiState>() {
|
||||
private val _uiState = MutableStateFlow(UiState())
|
||||
val uiState get() = _uiState
|
||||
override fun updateState(uiState : UiState) {
|
||||
@ -75,7 +75,7 @@ class OrderConfirmVm : IServicingVm<OrderConfirmVm.Action, OrderConfirmVm.UiStat
|
||||
return
|
||||
}
|
||||
|
||||
uiState.value.photoTemplateList?.forEach {
|
||||
photoTemplateList?.forEach {
|
||||
if (it.photoType == 2) {
|
||||
return@forEach
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ import androidx.compose.runtime.Composable
|
||||
import com.za.base.BaseActivity
|
||||
import com.za.ext.finish
|
||||
|
||||
class RealOrderConfirmActivity : BaseActivity() {
|
||||
internal class RealOrderConfirmActivity : BaseActivity() {
|
||||
@Composable
|
||||
override fun ContentView() {
|
||||
OrderConfirmScreen()
|
||||
|
@ -6,7 +6,7 @@ import androidx.compose.runtime.Composable
|
||||
import com.za.base.BaseActivity
|
||||
import com.za.ext.finish
|
||||
|
||||
class ReceiveMoneyActivity : BaseActivity() {
|
||||
internal class ReceiveMoneyActivity : BaseActivity() {
|
||||
|
||||
@Composable
|
||||
override fun ContentView() {
|
||||
|
@ -90,392 +90,348 @@ val backgroundColor = Color(0xFFF8FAFC)
|
||||
@Preview(showBackground = true)
|
||||
@Composable
|
||||
fun PreviewReceiveMoneyScreen() {
|
||||
ReceiveMoneyScreen(userOrderId = 1, taskId = 1)
|
||||
ReceiveMoneyScreen(userOrderId = 1, taskId = 1)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun ReceiveMoneyScreen(userOrderId: Int,
|
||||
taskId: Int,
|
||||
vm: ReceiveMoneyVm = viewModel()) {
|
||||
val context = LocalContext.current
|
||||
val uiState = vm.uiState.collectAsStateWithLifecycle()
|
||||
var showSuccessDialog by remember { mutableStateOf(false) }
|
||||
internal fun ReceiveMoneyScreen(userOrderId : Int,
|
||||
taskId : Int,
|
||||
vm : ReceiveMoneyVm = viewModel()) {
|
||||
val context = LocalContext.current
|
||||
val uiState = vm.uiState.collectAsStateWithLifecycle()
|
||||
var showSuccessDialog by remember { mutableStateOf(false) }
|
||||
|
||||
val lifecycleOwner = LocalLifecycleOwner.current
|
||||
DisposableEffect(key1 = lifecycleOwner) {
|
||||
val observer = LifecycleEventObserver { _, event ->
|
||||
if (event == Lifecycle.Event.ON_RESUME) {
|
||||
vm.dispatch(action = ReceiveMoneyVm.Action.Init(userOrderId, taskId))
|
||||
}
|
||||
}
|
||||
lifecycleOwner.lifecycle.addObserver(observer)
|
||||
onDispose {
|
||||
lifecycleOwner.lifecycle.removeObserver(observer)
|
||||
}
|
||||
}
|
||||
val lifecycleOwner = LocalLifecycleOwner.current
|
||||
DisposableEffect(key1 = lifecycleOwner) {
|
||||
val observer = LifecycleEventObserver { _, event ->
|
||||
if (event == Lifecycle.Event.ON_RESUME) {
|
||||
vm.dispatch(action = ReceiveMoneyVm.Action.Init(userOrderId, taskId))
|
||||
}
|
||||
}
|
||||
lifecycleOwner.lifecycle.addObserver(observer)
|
||||
onDispose {
|
||||
lifecycleOwner.lifecycle.removeObserver(observer)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (showSuccessDialog) {
|
||||
SuccessDialog(
|
||||
amount = "${uiState.value.paymentInfoBean?.amount ?: 0.00}",
|
||||
onDismiss = { showSuccessDialog = false }
|
||||
)
|
||||
}
|
||||
if (showSuccessDialog) {
|
||||
SuccessDialog(amount = "${uiState.value.paymentInfoBean?.amount ?: 0.00}",
|
||||
onDismiss = { showSuccessDialog = false })
|
||||
}
|
||||
|
||||
if (uiState.value.payState == 3) {
|
||||
CommonDialog(title = "收款成功", message = "收款成功", cancelEnable = false,
|
||||
confirm = {
|
||||
goNextPage(GlobalData.currentOrder?.taskState, context)
|
||||
}, dismiss = {
|
||||
goNextPage(GlobalData.currentOrder?.taskState, context)
|
||||
})
|
||||
}
|
||||
if (uiState.value.payState == 3) {
|
||||
CommonDialog(title = "收款成功", message = "收款成功", cancelEnable = false, confirm = {
|
||||
goNextPage(GlobalData.currentOrder?.taskState, context)
|
||||
}, dismiss = {
|
||||
goNextPage(GlobalData.currentOrder?.taskState, context)
|
||||
})
|
||||
}
|
||||
|
||||
Scaffold(
|
||||
topBar = { HeadView(title = "客户收款", onBack = { context.finish() }) },
|
||||
bottomBar = {
|
||||
AnimatedVisibility(visible = uiState.value.isOnSite == 2) {
|
||||
Column {
|
||||
Spacer(modifier = Modifier.height(32.dp))
|
||||
AnimatedVisibility(visible = uiState.value.payState != 1) {
|
||||
CommonButton("发送短信链接") {
|
||||
if (uiState.value.userPhone.isNullOrEmpty()) {
|
||||
ToastUtils.showLong("请输入客户手机号")
|
||||
return@CommonButton
|
||||
}
|
||||
vm.dispatch(ReceiveMoneyVm.Action.CreatePaymentInfo)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}, containerColor = bgColor) {
|
||||
// Main Content
|
||||
Column(modifier = Modifier
|
||||
Scaffold(topBar = { HeadView(title = "客户收款", onBack = { context.finish() }) }, bottomBar = {
|
||||
AnimatedVisibility(visible = uiState.value.isOnSite == 2) {
|
||||
Column {
|
||||
Spacer(modifier = Modifier.height(32.dp))
|
||||
AnimatedVisibility(visible = uiState.value.payState != 1) {
|
||||
CommonButton("发送短信链接") {
|
||||
if (uiState.value.userPhone.isNullOrEmpty()) {
|
||||
ToastUtils.showLong("请输入客户手机号")
|
||||
return@CommonButton
|
||||
}
|
||||
vm.dispatch(ReceiveMoneyVm.Action.CreatePaymentInfo)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}, containerColor = bgColor) { // Main Content
|
||||
Column(modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.padding(it)
|
||||
.verticalScroll(rememberScrollState())
|
||||
.padding(10.dp)) {
|
||||
// Amount Section
|
||||
AmountSection(paymentInfoBean = uiState.value.paymentInfoBean) {
|
||||
// ModifyMoneyActivity.goModifyMoney(context, uiState.value.paymentInfoBean?.userOrderId
|
||||
// ?: 0, uiState.value.paymentInfoBean?.taskOrderId ?: 0)
|
||||
ModifyMoneyActivity.goModifyMoney(context, uiState.value.paymentInfoBean?.userOrderId
|
||||
?: 0, uiState.value.paymentInfoBean?.taskOrderId ?: 0)
|
||||
}
|
||||
.padding(10.dp)) { // Amount Section
|
||||
AmountSection(paymentInfoBean = uiState.value.paymentInfoBean) { // ModifyMoneyActivity.goModifyMoney(context, uiState.value.paymentInfoBean?.userOrderId
|
||||
// ?: 0, uiState.value.paymentInfoBean?.taskOrderId ?: 0)
|
||||
ModifyMoneyActivity.goModifyMoney(context,
|
||||
uiState.value.paymentInfoBean?.userOrderId ?: 0,
|
||||
uiState.value.paymentInfoBean?.taskOrderId ?: 0)
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.height(32.dp))
|
||||
Spacer(modifier = Modifier.height(32.dp))
|
||||
|
||||
if (!uiState.value.paymentInfoBean?.settlementRule.isNullOrBlank()) {
|
||||
// Rules Section
|
||||
RulesSection(uiState.value.paymentInfoBean?.settlementRule ?: "")
|
||||
Spacer(modifier = Modifier.height(32.dp))
|
||||
}
|
||||
if (! uiState.value.paymentInfoBean?.settlementRule.isNullOrBlank()) { // Rules Section
|
||||
RulesSection(uiState.value.paymentInfoBean?.settlementRule ?: "")
|
||||
Spacer(modifier = Modifier.height(32.dp))
|
||||
}
|
||||
|
||||
// Action Buttons
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
horizontalArrangement = Arrangement.spacedBy(16.dp)
|
||||
) {
|
||||
Row(
|
||||
modifier = if (uiState.value.isOnSite == 1) {
|
||||
Modifier
|
||||
.weight(1f)
|
||||
.background(color = primaryColor, shape = RoundedCornerShape(3.dp))
|
||||
.padding(vertical = 15.dp)
|
||||
} else {
|
||||
Modifier
|
||||
.weight(1f)
|
||||
.noDoubleClick {
|
||||
vm.dispatch(ReceiveMoneyVm.Action.ChangeOnSite(1))
|
||||
}
|
||||
.border(1.dp, color = Color.Gray, shape = RoundedCornerShape(3.dp))
|
||||
.padding(vertical = 15.dp)
|
||||
},
|
||||
horizontalArrangement = Arrangement.Center
|
||||
) {
|
||||
if (uiState.value.isOnSite == 1) {
|
||||
Icon(imageVector = Icons.Default.LocationOn, contentDescription = null, tint = Color.White)
|
||||
Text(text = "在现场", color = Color.White)
|
||||
} else {
|
||||
Icon(imageVector = Icons.Default.LocationOn, contentDescription = null, tint = Color.Gray)
|
||||
Text(text = "在现场", color = Color.Gray)
|
||||
}
|
||||
}
|
||||
// Action Buttons
|
||||
Row(modifier = Modifier.fillMaxWidth(),
|
||||
horizontalArrangement = Arrangement.spacedBy(16.dp)) {
|
||||
Row(modifier = if (uiState.value.isOnSite == 1) {
|
||||
Modifier
|
||||
.weight(1f)
|
||||
.background(color = primaryColor, shape = RoundedCornerShape(3.dp))
|
||||
.padding(vertical = 15.dp)
|
||||
} else {
|
||||
Modifier
|
||||
.weight(1f)
|
||||
.noDoubleClick {
|
||||
vm.dispatch(ReceiveMoneyVm.Action.ChangeOnSite(1))
|
||||
}
|
||||
.border(1.dp, color = Color.Gray, shape = RoundedCornerShape(3.dp))
|
||||
.padding(vertical = 15.dp)
|
||||
}, horizontalArrangement = Arrangement.Center) {
|
||||
if (uiState.value.isOnSite == 1) {
|
||||
Icon(imageVector = Icons.Default.LocationOn,
|
||||
contentDescription = null,
|
||||
tint = Color.White)
|
||||
Text(text = "在现场", color = Color.White)
|
||||
} else {
|
||||
Icon(imageVector = Icons.Default.LocationOn,
|
||||
contentDescription = null,
|
||||
tint = Color.Gray)
|
||||
Text(text = "在现场", color = Color.Gray)
|
||||
}
|
||||
}
|
||||
|
||||
Row(
|
||||
modifier = if (uiState.value.isOnSite == 2) {
|
||||
Modifier
|
||||
.weight(1f)
|
||||
.background(color = primaryColor, shape = RoundedCornerShape(3.dp))
|
||||
.padding(vertical = 15.dp)
|
||||
} else {
|
||||
Modifier
|
||||
.weight(1f)
|
||||
.noDoubleClick {
|
||||
vm.dispatch(ReceiveMoneyVm.Action.ChangeOnSite(2))
|
||||
}
|
||||
.border(1.dp, color = Color.Gray, shape = RoundedCornerShape(3.dp))
|
||||
.padding(vertical = 15.dp)
|
||||
},
|
||||
horizontalArrangement = Arrangement.Center
|
||||
) {
|
||||
if (uiState.value.isOnSite == 2) {
|
||||
Icon(imageVector = Icons.Default.Notifications, contentDescription = null, tint = Color.White)
|
||||
Text(text = "不在现场", color = Color.White)
|
||||
} else {
|
||||
Icon(imageVector = Icons.Default.Notifications, contentDescription = null, tint = Color.Gray)
|
||||
Text(text = "不在现场", color = Color.Gray)
|
||||
}
|
||||
}
|
||||
}
|
||||
Row(modifier = if (uiState.value.isOnSite == 2) {
|
||||
Modifier
|
||||
.weight(1f)
|
||||
.background(color = primaryColor, shape = RoundedCornerShape(3.dp))
|
||||
.padding(vertical = 15.dp)
|
||||
} else {
|
||||
Modifier
|
||||
.weight(1f)
|
||||
.noDoubleClick {
|
||||
vm.dispatch(ReceiveMoneyVm.Action.ChangeOnSite(2))
|
||||
}
|
||||
.border(1.dp, color = Color.Gray, shape = RoundedCornerShape(3.dp))
|
||||
.padding(vertical = 15.dp)
|
||||
}, horizontalArrangement = Arrangement.Center) {
|
||||
if (uiState.value.isOnSite == 2) {
|
||||
Icon(imageVector = Icons.Default.Notifications,
|
||||
contentDescription = null,
|
||||
tint = Color.White)
|
||||
Text(text = "不在现场", color = Color.White)
|
||||
} else {
|
||||
Icon(imageVector = Icons.Default.Notifications,
|
||||
contentDescription = null,
|
||||
tint = Color.Gray)
|
||||
Text(text = "不在现场", color = Color.Gray)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AnimatedVisibility(visible = uiState.value.isOnSite == 1) {
|
||||
Column {
|
||||
Spacer(modifier = Modifier.height(22.dp))
|
||||
QRCodeSection(uiState.value.qrCode ?: "",
|
||||
createPayment = { vm.dispatch(ReceiveMoneyVm.Action.CreatePaymentInfo) })
|
||||
}
|
||||
}
|
||||
AnimatedVisibility(visible = uiState.value.isOnSite == 1) {
|
||||
Column {
|
||||
Spacer(modifier = Modifier.height(22.dp))
|
||||
QRCodeSection(uiState.value.qrCode ?: "",
|
||||
createPayment = { vm.dispatch(ReceiveMoneyVm.Action.CreatePaymentInfo) })
|
||||
}
|
||||
}
|
||||
|
||||
AnimatedVisibility(visible = uiState.value.isOnSite == 2) {
|
||||
Box(modifier = Modifier
|
||||
AnimatedVisibility(visible = uiState.value.isOnSite == 2) {
|
||||
Box(modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 10.dp, vertical = 30.dp)) {
|
||||
OutlinedTextField(
|
||||
value = uiState.value.userPhone ?: "",
|
||||
keyboardOptions = KeyboardOptions.Default.copy(keyboardType = KeyboardType.Phone),
|
||||
onValueChange = { vm.updateState(uiState.value.copy(userPhone = it)) },
|
||||
label = { Text("请输入客户手机号") },
|
||||
leadingIcon = {
|
||||
Icon(
|
||||
imageVector = Icons.Rounded.Phone,
|
||||
contentDescription = null,
|
||||
tint = primaryColor
|
||||
)
|
||||
},
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
shape = RoundedCornerShape(12.dp),
|
||||
colors = OutlinedTextFieldDefaults.colors(
|
||||
focusedBorderColor = primaryColor,
|
||||
unfocusedBorderColor = Color.Gray,
|
||||
focusedLabelColor = primaryColor,
|
||||
unfocusedLabelColor = Color.Gray),
|
||||
singleLine = true
|
||||
)
|
||||
}
|
||||
}
|
||||
OutlinedTextField(value = uiState.value.userPhone ?: "",
|
||||
keyboardOptions = KeyboardOptions.Default.copy(keyboardType = KeyboardType.Phone),
|
||||
onValueChange = { vm.updateState(uiState.value.copy(userPhone = it)) },
|
||||
label = { Text("请输入客户手机号") },
|
||||
leadingIcon = {
|
||||
Icon(imageVector = Icons.Rounded.Phone,
|
||||
contentDescription = null,
|
||||
tint = primaryColor)
|
||||
},
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
shape = RoundedCornerShape(12.dp),
|
||||
colors = OutlinedTextFieldDefaults.colors(focusedBorderColor = primaryColor,
|
||||
unfocusedBorderColor = Color.Gray,
|
||||
focusedLabelColor = primaryColor,
|
||||
unfocusedLabelColor = Color.Gray),
|
||||
singleLine = true)
|
||||
}
|
||||
}
|
||||
|
||||
if (uiState.value.payState == 1) {
|
||||
Column {
|
||||
Spacer(modifier = Modifier.height(32.dp))
|
||||
CountdownRing { vm.updateState(uiState.value.copy(payState = 4, qrCode = null)) }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (uiState.value.payState == 1) {
|
||||
Column {
|
||||
Spacer(modifier = Modifier.height(32.dp))
|
||||
CountdownRing {
|
||||
vm.updateState(uiState.value.copy(payState = 4,
|
||||
qrCode = null))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun AmountSection(paymentInfoBean: PaymentInfoBean? = null, goModifyMoney: () -> Unit = {}) {
|
||||
Column(horizontalAlignment = Alignment.CenterHorizontally, modifier = Modifier.fillMaxWidth()) {
|
||||
Text("收款金额", color = Color.Gray, fontSize = 14.sp)
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
Text("¥", fontSize = 30.sp, fontWeight = FontWeight.Medium, color = black90)
|
||||
Text("${paymentInfoBean?.amount ?: "0.00"}", fontSize = 36.sp, fontWeight = FontWeight.Medium, color = black90)
|
||||
//一口价不允许修改金额
|
||||
if (paymentInfoBean?.contractSettleRule != 2) {
|
||||
IconButton(onClick = { goModifyMoney() }) {
|
||||
Icon(
|
||||
painter = rememberVectorPainter(Icons.Default.Edit),
|
||||
contentDescription = null,
|
||||
tint = primaryColor
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
private fun AmountSection(paymentInfoBean : PaymentInfoBean? = null,
|
||||
goModifyMoney : () -> Unit = {}) {
|
||||
Column(horizontalAlignment = Alignment.CenterHorizontally, modifier = Modifier.fillMaxWidth()) {
|
||||
Text("收款金额", color = Color.Gray, fontSize = 14.sp)
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
Text("¥", fontSize = 30.sp, fontWeight = FontWeight.Medium, color = black90)
|
||||
Text("${paymentInfoBean?.amount ?: "0.00"}",
|
||||
fontSize = 36.sp,
|
||||
fontWeight = FontWeight.Medium,
|
||||
color = black90) //一口价不允许修改金额
|
||||
if (paymentInfoBean?.contractSettleRule != 2) {
|
||||
IconButton(onClick = { goModifyMoney() }) {
|
||||
Icon(painter = rememberVectorPainter(Icons.Default.Edit),
|
||||
contentDescription = null,
|
||||
tint = primaryColor)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
|
||||
Row(
|
||||
horizontalArrangement = Arrangement.spacedBy(32.dp),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
Column(horizontalAlignment = Alignment.CenterHorizontally) {
|
||||
Text("超限单价", color = Color.Gray, fontSize = 14.sp)
|
||||
Row(verticalAlignment = Alignment.Top) {
|
||||
Text("¥", fontSize = 16.sp, color = Color.DarkGray)
|
||||
Text("${paymentInfoBean?.unitPrice ?: ""}", fontSize = 16.sp, color = Color.DarkGray)
|
||||
Text("/公里", fontSize = 12.sp, color = Color.Gray)
|
||||
}
|
||||
}
|
||||
Row(horizontalArrangement = Arrangement.spacedBy(32.dp),
|
||||
verticalAlignment = Alignment.CenterVertically) {
|
||||
Column(horizontalAlignment = Alignment.CenterHorizontally) {
|
||||
Text("超限单价", color = Color.Gray, fontSize = 14.sp)
|
||||
Row(verticalAlignment = Alignment.Top) {
|
||||
Text("¥", fontSize = 16.sp, color = Color.DarkGray)
|
||||
Text("${paymentInfoBean?.unitPrice ?: ""}",
|
||||
fontSize = 16.sp,
|
||||
color = Color.DarkGray)
|
||||
Text("/公里", fontSize = 12.sp, color = Color.Gray)
|
||||
}
|
||||
}
|
||||
|
||||
VerticalDivider(
|
||||
modifier = Modifier
|
||||
.height(32.dp)
|
||||
.width(1.dp),
|
||||
color = Color.LightGray
|
||||
)
|
||||
VerticalDivider(modifier = Modifier
|
||||
.height(32.dp)
|
||||
.width(1.dp), color = Color.LightGray)
|
||||
|
||||
Column(horizontalAlignment = Alignment.CenterHorizontally) {
|
||||
Text("超限公里数", color = Color.Gray, fontSize = 14.sp)
|
||||
Row(verticalAlignment = Alignment.Top) {
|
||||
Text("${paymentInfoBean?.mileage ?: ""}", fontSize = 16.sp, color = Color.DarkGray)
|
||||
Text("公里", fontSize = 12.sp, color = Color.Gray)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Column(horizontalAlignment = Alignment.CenterHorizontally) {
|
||||
Text("超限公里数", color = Color.Gray, fontSize = 14.sp)
|
||||
Row(verticalAlignment = Alignment.Top) {
|
||||
Text("${paymentInfoBean?.mileage ?: ""}",
|
||||
fontSize = 16.sp,
|
||||
color = Color.DarkGray)
|
||||
Text("公里", fontSize = 12.sp, color = Color.Gray)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun RulesSection(rules: String) {
|
||||
Surface(modifier = Modifier.fillMaxWidth(),
|
||||
color = backgroundColor,
|
||||
shape = RoundedCornerShape(8.dp)) {
|
||||
Column(modifier = Modifier.padding(16.dp)) {
|
||||
Text("收款规则说明", fontWeight = FontWeight.Medium, fontSize = 12.sp, color = Color.Gray)
|
||||
Spacer(modifier = Modifier.height(10.dp))
|
||||
RuleItem(rules)
|
||||
Spacer(modifier = Modifier.height(10.dp))
|
||||
}
|
||||
}
|
||||
private fun RulesSection(rules : String) {
|
||||
Surface(modifier = Modifier.fillMaxWidth(),
|
||||
color = backgroundColor,
|
||||
shape = RoundedCornerShape(8.dp)) {
|
||||
Column(modifier = Modifier.padding(16.dp)) {
|
||||
Text("收款规则说明",
|
||||
fontWeight = FontWeight.Medium,
|
||||
fontSize = 12.sp,
|
||||
color = Color.Gray)
|
||||
Spacer(modifier = Modifier.height(10.dp))
|
||||
RuleItem(rules)
|
||||
Spacer(modifier = Modifier.height(10.dp))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun RuleItem(text: String) {
|
||||
Row(verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.Center) {
|
||||
Icon(
|
||||
painter = rememberVectorPainter(Icons.Default.CheckCircle),
|
||||
contentDescription = null,
|
||||
tint = primaryColor,
|
||||
modifier = Modifier.size(12.dp)
|
||||
)
|
||||
Spacer(modifier = Modifier.width(8.dp))
|
||||
Text(text, fontSize = 14.sp, color = Color.DarkGray)
|
||||
}
|
||||
private fun RuleItem(text : String) {
|
||||
Row(verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.Center) {
|
||||
Icon(painter = rememberVectorPainter(Icons.Default.CheckCircle),
|
||||
contentDescription = null,
|
||||
tint = primaryColor,
|
||||
modifier = Modifier.size(12.dp))
|
||||
Spacer(modifier = Modifier.width(8.dp))
|
||||
Text(text, fontSize = 14.sp, color = Color.DarkGray)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun QRCodeSection(qrCode: String? = null, createPayment: () -> Unit = {}) {
|
||||
Surface(
|
||||
color = backgroundColor,
|
||||
shape = RoundedCornerShape(8.dp)
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(16.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally
|
||||
) {
|
||||
private fun QRCodeSection(qrCode : String? = null, createPayment : () -> Unit = {}) {
|
||||
Surface(color = backgroundColor, shape = RoundedCornerShape(8.dp)) {
|
||||
Column(modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(16.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally) {
|
||||
|
||||
if (qrCode.isNullOrEmpty()) {
|
||||
LoadError(message = "收款码失效", onRetry = { createPayment() })
|
||||
} else {
|
||||
Surface(
|
||||
color = Color.White,
|
||||
shape = RoundedCornerShape(8.dp)
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.size(160.dp)
|
||||
.padding(16.dp),
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
// Replace with actual QR code image
|
||||
AsyncImage(model = qrCode, contentDescription = null)
|
||||
}
|
||||
}
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
Text("请顾客扫码支付", color = Color.Gray, fontSize = 14.sp)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (qrCode.isNullOrEmpty()) {
|
||||
LoadError(message = "收款码失效", onRetry = { createPayment() })
|
||||
} else {
|
||||
Surface(color = Color.White, shape = RoundedCornerShape(8.dp)) {
|
||||
Box(modifier = Modifier
|
||||
.size(160.dp)
|
||||
.padding(16.dp),
|
||||
contentAlignment = Alignment.Center) { // Replace with actual QR code image
|
||||
AsyncImage(model = qrCode, contentDescription = null)
|
||||
}
|
||||
}
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
Text("请顾客扫码支付", color = Color.Gray, fontSize = 14.sp)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun CountdownRing(outTime: () -> Unit) {
|
||||
var countdown by remember { mutableIntStateOf(5 * 60) }
|
||||
val progress by animateFloatAsState(
|
||||
targetValue = (countdown / 5 * 60) * 360f,
|
||||
animationSpec = remember { androidx.compose.animation.core.tween(1000) }
|
||||
)
|
||||
private fun CountdownRing(outTime : () -> Unit) {
|
||||
var countdown by remember { mutableIntStateOf(5 * 60) }
|
||||
val progress by animateFloatAsState(targetValue = (countdown / 5 * 60) * 360f,
|
||||
animationSpec = remember { androidx.compose.animation.core.tween(1000) })
|
||||
|
||||
LaunchedEffect(Unit) {
|
||||
while (countdown > 0) {
|
||||
delay(1000)
|
||||
countdown--
|
||||
if (countdown == 0) {
|
||||
outTime()
|
||||
}
|
||||
}
|
||||
}
|
||||
LaunchedEffect(Unit) {
|
||||
while (countdown > 0) {
|
||||
delay(1000)
|
||||
countdown --
|
||||
if (countdown == 0) {
|
||||
outTime()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Box(modifier = Modifier.fillMaxWidth(), contentAlignment = Alignment.Center) {
|
||||
Box(modifier = Modifier.size(50.dp), contentAlignment = Alignment.Center) {
|
||||
Canvas(modifier = Modifier.fillMaxSize()) {
|
||||
drawArc(
|
||||
brush = Brush.sweepGradient(
|
||||
0f to primaryColor,
|
||||
1f to Color.LightGray
|
||||
),
|
||||
startAngle = -90f,
|
||||
sweepAngle = progress,
|
||||
useCenter = false,
|
||||
style = Stroke(width = 8.dp.toPx(), cap = StrokeCap.Round)
|
||||
)
|
||||
}
|
||||
Surface(
|
||||
color = Color.White,
|
||||
shape = CircleShape,
|
||||
modifier = Modifier.size(50.dp)
|
||||
) {}
|
||||
Text(
|
||||
text = countdown.toString(),
|
||||
fontSize = 20.sp,
|
||||
color = black90,
|
||||
fontWeight = FontWeight.Medium
|
||||
)
|
||||
}
|
||||
}
|
||||
Box(modifier = Modifier.fillMaxWidth(), contentAlignment = Alignment.Center) {
|
||||
Box(modifier = Modifier.size(50.dp), contentAlignment = Alignment.Center) {
|
||||
Canvas(modifier = Modifier.fillMaxSize()) {
|
||||
drawArc(brush = Brush.sweepGradient(0f to primaryColor, 1f to Color.LightGray),
|
||||
startAngle = - 90f,
|
||||
sweepAngle = progress,
|
||||
useCenter = false,
|
||||
style = Stroke(width = 8.dp.toPx(), cap = StrokeCap.Round))
|
||||
}
|
||||
Surface(color = Color.White, shape = CircleShape, modifier = Modifier.size(50.dp)) {}
|
||||
Text(text = countdown.toString(),
|
||||
fontSize = 20.sp,
|
||||
color = black90,
|
||||
fontWeight = FontWeight.Medium)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun SuccessDialog(amount: String, onDismiss: () -> Unit) {
|
||||
Dialog(onDismissRequest = onDismiss) {
|
||||
Surface(
|
||||
shape = RoundedCornerShape(16.dp),
|
||||
color = Color.White
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier.padding(24.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.size(64.dp)
|
||||
.background(primaryColor.copy(alpha = 0.1f), CircleShape)
|
||||
.clip(CircleShape),
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
Icon(
|
||||
Icons.Default.Check,
|
||||
contentDescription = null,
|
||||
tint = primaryColor,
|
||||
modifier = Modifier.size(32.dp)
|
||||
)
|
||||
}
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
Text("收款成功", fontWeight = FontWeight.Medium, fontSize = 18.sp)
|
||||
Text("已收款 ¥$amount", color = Color.Gray, fontSize = 14.sp)
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
Button(
|
||||
onClick = onDismiss,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
) {
|
||||
Text("完成")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
private fun SuccessDialog(amount : String, onDismiss : () -> Unit) {
|
||||
Dialog(onDismissRequest = onDismiss) {
|
||||
Surface(shape = RoundedCornerShape(16.dp), color = Color.White) {
|
||||
Column(modifier = Modifier.padding(24.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally) {
|
||||
Box(modifier = Modifier
|
||||
.size(64.dp)
|
||||
.background(primaryColor.copy(alpha = 0.1f), CircleShape)
|
||||
.clip(CircleShape),
|
||||
contentAlignment = Alignment.Center) {
|
||||
Icon(Icons.Default.Check,
|
||||
contentDescription = null,
|
||||
tint = primaryColor,
|
||||
modifier = Modifier.size(32.dp))
|
||||
}
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
Text("收款成功", fontWeight = FontWeight.Medium, fontSize = 18.sp)
|
||||
Text("已收款 ¥$amount", color = Color.Gray, fontSize = 14.sp)
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
Button(onClick = onDismiss, modifier = Modifier.fillMaxWidth()) {
|
||||
Text("完成")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user