build(servicing): 更新构建配置并升级版本号
-禁用 release 和 debug 构建类型的代码压缩 - 添加 publishNonDefault 配置项 -将版本号从 1.0.1.9.9.126 升级到 1.0.1.9.9.127
260
app/proguard-rules.pro
vendored
@ -18,4 +18,262 @@
|
|||||||
|
|
||||||
# If you keep the line number information, uncomment this to
|
# If you keep the line number information, uncomment this to
|
||||||
# hide the original source file name.
|
# hide the original source file name.
|
||||||
#-renamesourcefileattribute SourceFile
|
#-renamesourcefileattribute SourceFile
|
||||||
|
|
||||||
|
-dontwarn java.lang.invoke.StringConcatFactory
|
||||||
|
|
||||||
|
# 保留行号用于调试
|
||||||
|
-keepattributes SourceFile,LineNumberTable
|
||||||
|
-renamesourcefileattribute SourceFile
|
||||||
|
|
||||||
|
# 保留基本属性
|
||||||
|
-keepattributes Signature
|
||||||
|
-keepattributes *Annotation*
|
||||||
|
-keepattributes Exceptions
|
||||||
|
-keepattributes InnerClasses
|
||||||
|
|
||||||
|
-dontwarn com.github.luben.zstd.BufferPool
|
||||||
|
-dontwarn com.github.luben.zstd.ZstdInputStream
|
||||||
|
-dontwarn com.github.luben.zstd.ZstdOutputStream
|
||||||
|
-dontwarn org.brotli.dec.BrotliInputStream
|
||||||
|
-dontwarn org.objectweb.asm.AnnotationVisitor
|
||||||
|
-dontwarn org.objectweb.asm.Attribute
|
||||||
|
-dontwarn org.objectweb.asm.ClassReader
|
||||||
|
-dontwarn org.objectweb.asm.ClassVisitor
|
||||||
|
-dontwarn org.objectweb.asm.FieldVisitor
|
||||||
|
-dontwarn org.objectweb.asm.Label
|
||||||
|
-dontwarn org.objectweb.asm.MethodVisitor
|
||||||
|
-dontwarn org.objectweb.asm.Type
|
||||||
|
|
||||||
|
# 保留R文件
|
||||||
|
-keepclassmembers class **.R$* {
|
||||||
|
public static <fields>;
|
||||||
|
}
|
||||||
|
|
||||||
|
## 保留servicing模块中的所有model类
|
||||||
|
#-keep class com.za.bean.** { *; }
|
||||||
|
#-keep class com.za.bean.db.** { *; }
|
||||||
|
#-keep class com.za.bean.request.** { *; }
|
||||||
|
#
|
||||||
|
## 保留servicing模块中的所有接口
|
||||||
|
#-keep interface com.za.servicing.** { *; }
|
||||||
|
#-keep interface com.za.net.** { *; }
|
||||||
|
#
|
||||||
|
## 保留servicing模块中的所有枚举
|
||||||
|
#-keepclassmembers enum com.za.** { *; }
|
||||||
|
#
|
||||||
|
## 保留Room数据库相关类
|
||||||
|
#-keep class com.za.room.** { *; }
|
||||||
|
#-keep class com.za.room.db.** { *; }
|
||||||
|
#-keep class * extends androidx.room.RoomDatabase
|
||||||
|
#-keep @androidx.room.Entity class *
|
||||||
|
#-keep @androidx.room.Dao interface *
|
||||||
|
|
||||||
|
# 保留Parcelable实现类
|
||||||
|
-keep class * implements android.os.Parcelable {
|
||||||
|
public static final android.os.Parcelable$Creator *;
|
||||||
|
}
|
||||||
|
|
||||||
|
# 保留Serializable实现类
|
||||||
|
-keepnames class * implements java.io.Serializable
|
||||||
|
-keepclassmembers class * implements java.io.Serializable {
|
||||||
|
static final long serialVersionUID;
|
||||||
|
private static final java.io.ObjectStreamField[] serialPersistentFields;
|
||||||
|
!static !transient <fields>;
|
||||||
|
private void writeObject(java.io.ObjectOutputStream);
|
||||||
|
private void readObject(java.io.ObjectInputStream);
|
||||||
|
java.lang.Object writeReplace();
|
||||||
|
java.lang.Object readResolve();
|
||||||
|
}
|
||||||
|
|
||||||
|
# 保留WebView相关
|
||||||
|
-keepclassmembers class * extends android.webkit.WebViewClient {
|
||||||
|
public void *(android.webkit.WebView, java.lang.String, android.graphics.Bitmap);
|
||||||
|
public boolean *(android.webkit.WebView, java.lang.String);
|
||||||
|
}
|
||||||
|
-keepclassmembers class * extends android.webkit.WebViewClient {
|
||||||
|
public void *(android.webkit.WebView, java.lang.String);
|
||||||
|
}
|
||||||
|
|
||||||
|
# 保留native方法
|
||||||
|
-keepclasseswithmembernames class * {
|
||||||
|
native <methods>;
|
||||||
|
}
|
||||||
|
|
||||||
|
## 保留View的getter和setter
|
||||||
|
#-keepclassmembers public class * extends android.view.View {
|
||||||
|
# void set*(***); *** get*();
|
||||||
|
#}
|
||||||
|
|
||||||
|
# CameraX相关
|
||||||
|
#-keep class androidx.camera.** { *; }
|
||||||
|
#-dontwarn androidx.camera.**
|
||||||
|
#
|
||||||
|
## Coil图片加载库
|
||||||
|
#-keep class coil.** { *; }
|
||||||
|
#-dontwarn coil.**
|
||||||
|
#
|
||||||
|
## PermissionX权限库
|
||||||
|
#-keep class com.permissionx.guolindev.** { *; }
|
||||||
|
#
|
||||||
|
## 高德地图相关
|
||||||
|
#-keep class com.amap.api.**{*;}
|
||||||
|
#-keep class com.autonavi.**{*;}
|
||||||
|
#-keep class com.loc.**{*;}
|
||||||
|
#-dontwarn com.amap.api.**
|
||||||
|
#-dontwarn com.autonavi.**
|
||||||
|
#-dontwarn com.loc.**
|
||||||
|
#
|
||||||
|
## JPush相关
|
||||||
|
#-dontoptimize
|
||||||
|
#-dontwarn cn.jpush.**
|
||||||
|
#-keep class cn.jpush.** { *; }
|
||||||
|
#-dontwarn cn.jcore.**
|
||||||
|
#-keep class cn.jcore.** { *; }
|
||||||
|
#
|
||||||
|
## Retrofit网络库
|
||||||
|
#-keepattributes Signature
|
||||||
|
#-keepattributes Exceptions
|
||||||
|
#-dontwarn retrofit2.**
|
||||||
|
#-keep class retrofit2.** { *; }
|
||||||
|
#-keepclasseswithmembers class * {
|
||||||
|
# @retrofit2.http.* <methods>;
|
||||||
|
#}
|
||||||
|
#
|
||||||
|
## OkHttp
|
||||||
|
#-dontwarn okhttp3.**
|
||||||
|
#-dontwarn okio.**
|
||||||
|
#-keep class okhttp3.** { *; }
|
||||||
|
#-keep class okio.** { *; }
|
||||||
|
#
|
||||||
|
## RxJava
|
||||||
|
#-dontwarn io.reactivex.**
|
||||||
|
#-keep class io.reactivex.** { *; }
|
||||||
|
#-dontwarn sun.misc.**
|
||||||
|
#-keepclassmembers class rx.internal.util.unsafe.*ArrayQueue*Field* {
|
||||||
|
# long producerIndex;
|
||||||
|
# long consumerIndex;
|
||||||
|
#}
|
||||||
|
#
|
||||||
|
## BlankJ工具库
|
||||||
|
#-dontwarn com.blankj.utilcode.**
|
||||||
|
#-keep class com.blankj.utilcode.** { *; }
|
||||||
|
#-keepclassmembers class * {
|
||||||
|
# @com.blankj.utilcode.util.BusUtils$Bus <methods>;
|
||||||
|
#}
|
||||||
|
#-keep public class * extends com.blankj.utilcode.util.ApiUtils$BaseApi
|
||||||
|
#-keep,allowobfuscation @interface com.blankj.utilcode.util.ApiUtils$Api
|
||||||
|
#-keep @com.blankj.utilcode.util.ApiUtils$Api class *
|
||||||
|
#
|
||||||
|
##mmkv
|
||||||
|
#-renamesourcefileattribute SourceFile
|
||||||
|
#-keepattributes Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,EnclosingMethod
|
||||||
|
#-keep public class * {
|
||||||
|
# public protected *;
|
||||||
|
#}
|
||||||
|
##
|
||||||
|
### 保留所有类的方法名
|
||||||
|
##-keepclassmembernames class * {
|
||||||
|
## java.lang.Class class$(java.lang.String);
|
||||||
|
## java.lang.Class class$(java.lang.String, boolean);
|
||||||
|
##}
|
||||||
|
#
|
||||||
|
## 保留枚举类中的特殊静态方法
|
||||||
|
#-keepclassmembers class * extends java.lang.Enum {
|
||||||
|
# public static **[] values();
|
||||||
|
# public static ** valueOf(java.lang.String);
|
||||||
|
#}
|
||||||
|
#
|
||||||
|
## MQTT相关
|
||||||
|
#-keep class org.eclipse.paho.** { *; }
|
||||||
|
#-dontwarn org.eclipse.paho.**
|
||||||
|
#
|
||||||
|
## Gson
|
||||||
|
#-keep class com.google.gson.** { *; }
|
||||||
|
#-keepattributes Signature
|
||||||
|
#-keepattributes *Annotation*
|
||||||
|
#-keep class * implements com.google.gson.TypeAdapterFactory
|
||||||
|
#-keep class * implements com.google.gson.JsonSerializer
|
||||||
|
#-keep class * implements com.google.gson.JsonDeserializer
|
||||||
|
#
|
||||||
|
### Kotlin相关
|
||||||
|
###-keep class kotlin.** { *; }
|
||||||
|
##-keep class kotlin.Metadata { *; }
|
||||||
|
##-dontwarn kotlin.**
|
||||||
|
##-keepclassmembers class **$WhenMappings {
|
||||||
|
## <fields>;
|
||||||
|
##}
|
||||||
|
##-keepclassmembers class kotlin.Metadata {
|
||||||
|
## public <methods>;
|
||||||
|
##}
|
||||||
|
#
|
||||||
|
## Kotlin协程
|
||||||
|
##-keepclassmembernames class kotlinx.** {
|
||||||
|
## volatile <fields>;
|
||||||
|
##}
|
||||||
|
##-keepclassmembers class * {
|
||||||
|
## @kotlin.coroutines.jvm.internal.DebugMetadata *;
|
||||||
|
## @kotlin.coroutines.jvm.internal.SuspendLambda *;
|
||||||
|
##}
|
||||||
|
##-keep class kotlinx.coroutines.** { *; }
|
||||||
|
##-dontwarn kotlinx.coroutines.**
|
||||||
|
#
|
||||||
|
## Kotlin反射
|
||||||
|
##-keep class kotlin.reflect.** { *; }
|
||||||
|
##-dontwarn kotlin.reflect.**
|
||||||
|
#
|
||||||
|
## 保留Kotlin数据类
|
||||||
|
##-keepclassmembers class ** {
|
||||||
|
## public ** component*();
|
||||||
|
## public ** copy(...);
|
||||||
|
##}
|
||||||
|
#
|
||||||
|
## 保留Kotlin数据类的toString/hashCode/equals方法
|
||||||
|
##-keepclassmembers class ** {
|
||||||
|
## public java.lang.String toString();
|
||||||
|
## public int hashCode();
|
||||||
|
## public boolean equals(java.lang.Object);
|
||||||
|
##}
|
||||||
|
##
|
||||||
|
### 保留Compose相关
|
||||||
|
##-keep class androidx.compose.** { *; }
|
||||||
|
##-dontwarn androidx.compose.**
|
||||||
|
##
|
||||||
|
### 保留自定义签名相关类
|
||||||
|
##-keep class com.za.signature.** { *; }
|
||||||
|
##
|
||||||
|
### 保留Face Detection相关
|
||||||
|
##-keep class com.google.mlkit.** { *; }
|
||||||
|
##-dontwarn com.google.mlkit.**
|
||||||
|
#
|
||||||
|
## 保留ZXing相关
|
||||||
|
#-keep class com.google.zxing.** { *; }
|
||||||
|
#-dontwarn com.google.zxing.**
|
||||||
|
#
|
||||||
|
## 保留Glide相关
|
||||||
|
#-keep public class * implements com.bumptech.glide.module.GlideModule
|
||||||
|
#-keep class * extends com.bumptech.glide.module.AppGlideModule {
|
||||||
|
# <init>(...);
|
||||||
|
#}
|
||||||
|
#-keep public enum com.bumptech.glide.load.ImageHeaderParser$** {
|
||||||
|
# **[] $VALUES;
|
||||||
|
# public *;
|
||||||
|
#}
|
||||||
|
#-keep class com.bumptech.glide.load.data.ParcelFileDescriptorRewinder$InternalRewinder {
|
||||||
|
# *** rewind();
|
||||||
|
#}
|
||||||
|
#
|
||||||
|
## 保留FastJSON相关
|
||||||
|
#-keep class com.alibaba.fastjson.** { *; }
|
||||||
|
#-dontwarn com.alibaba.fastjson.**
|
||||||
|
#
|
||||||
|
## 保留Bugly相关
|
||||||
|
#-keep class com.tencent.bugly.** { *; }
|
||||||
|
#-dontwarn com.tencent.bugly.**
|
||||||
|
##
|
||||||
|
### 保留自定义UI组件
|
||||||
|
###-keep class com.za.ui.** { *; }
|
||||||
|
###-keep class com.za.base.** { *; }
|
||||||
|
##
|
||||||
|
### 保留Java 8 Lambda表达式
|
||||||
|
##-dontwarn java.lang.invoke.StringConcatFactory
|
@ -1,23 +0,0 @@
|
|||||||
package com.za.sdk.demo
|
|
||||||
|
|
||||||
import androidx.test.platform.app.InstrumentationRegistry
|
|
||||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
|
||||||
|
|
||||||
import org.junit.Test
|
|
||||||
import org.junit.runner.RunWith
|
|
||||||
|
|
||||||
import org.junit.Assert.*
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Instrumented test, which will execute on an Android device.
|
|
||||||
*
|
|
||||||
* See [testing documentation](http://d.android.com/tools/testing).
|
|
||||||
*/
|
|
||||||
@RunWith(AndroidJUnit4::class)
|
|
||||||
class ExampleInstrumentedTest {
|
|
||||||
@Test
|
|
||||||
fun useAppContext() { // Context of the app under test.
|
|
||||||
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
|
|
||||||
assertEquals("com.za.sdk.demo", appContext.packageName)
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,4 +1,5 @@
|
|||||||
[versions]
|
[versions]
|
||||||
|
accompanistPager = "0.32.0"
|
||||||
cameraCore = "1.4.1"
|
cameraCore = "1.4.1"
|
||||||
coilCompose = "2.6.0"
|
coilCompose = "2.6.0"
|
||||||
commonsCompress = "1.23.0"
|
commonsCompress = "1.23.0"
|
||||||
@ -6,15 +7,13 @@ compiler = "4.14.2"
|
|||||||
converterGson = "2.9.0"
|
converterGson = "2.9.0"
|
||||||
core = "3.5.3"
|
core = "3.5.3"
|
||||||
crashreport = "4.0.4"
|
crashreport = "4.0.4"
|
||||||
|
faceDetection = "16.1.7"
|
||||||
fastjson = "1.2.69"
|
fastjson = "1.2.69"
|
||||||
glide = "4.16.0"
|
glide = "4.16.0"
|
||||||
gson = "2.11.0"
|
gson = "2.11.0"
|
||||||
jcore = "5.0.0"
|
|
||||||
faceDetection = "16.1.7"
|
|
||||||
jpush = "5.6.0"
|
jpush = "5.6.0"
|
||||||
location = "5.6.1"
|
location = "5.6.1"
|
||||||
loggingInterceptor = "4.11.0"
|
loggingInterceptor = "4.11.0"
|
||||||
#这是一个长期维护的版本,不建议升级
|
|
||||||
mmkv = "1.3.11"
|
mmkv = "1.3.11"
|
||||||
orgEclipsePahoAndroidService = "1.1.1"
|
orgEclipsePahoAndroidService = "1.1.1"
|
||||||
orgEclipsePahoClientMqttv3 = "1.2.5"
|
orgEclipsePahoClientMqttv3 = "1.2.5"
|
||||||
@ -39,14 +38,19 @@ rxjava = "3.1.7"
|
|||||||
search = "7.3.0"
|
search = "7.3.0"
|
||||||
tbssdk = "44286"
|
tbssdk = "44286"
|
||||||
uiGraphics = "1.7.7"
|
uiGraphics = "1.7.7"
|
||||||
|
uiTooling = "1.7.7"
|
||||||
uiToolingPreview = "1.7.7"
|
uiToolingPreview = "1.7.7"
|
||||||
uiVersion = "1.7.7"
|
uiVersion = "1.7.7"
|
||||||
utilcodex = "1.31.1"
|
utilcodex = "1.31.1"
|
||||||
workRuntimeKtx = "2.10.0"
|
workRuntimeKtx = "2.10.0"
|
||||||
xdmap = "8.1.0"
|
xdmap = "8.1.0"
|
||||||
|
activity = "1.10.0"
|
||||||
xz = "1.9"
|
xz = "1.9"
|
||||||
exifinterface = "1.3.7"
|
exifinterface = "1.3.7"
|
||||||
|
uiToolingVersion = "1.4.0"
|
||||||
[libraries]
|
[libraries]
|
||||||
|
accompanist-pager = { module = "com.google.accompanist:accompanist-pager", version.ref = "accompanistPager" }
|
||||||
|
accompanist-pager-indicators = { module = "com.google.accompanist:accompanist-pager-indicators", version.ref = "accompanistPager" }
|
||||||
adapter-rxjava3 = { module = "com.squareup.retrofit2:adapter-rxjava3", version.ref = "converterGson" }
|
adapter-rxjava3 = { module = "com.squareup.retrofit2:adapter-rxjava3", version.ref = "converterGson" }
|
||||||
androidx-camera-camera2 = { module = "androidx.camera:camera-camera2", version.ref = "cameraCore" }
|
androidx-camera-camera2 = { module = "androidx.camera:camera-camera2", version.ref = "cameraCore" }
|
||||||
androidx-camera-core = { module = "androidx.camera:camera-core", version.ref = "cameraCore" }
|
androidx-camera-core = { module = "androidx.camera:camera-core", version.ref = "cameraCore" }
|
||||||
@ -60,6 +64,7 @@ androidx-ui = { module = "androidx.compose.ui:ui", version.ref = "uiVersion" }
|
|||||||
androidx-ui-graphics = { module = "androidx.compose.ui:ui-graphics", version.ref = "uiGraphics" }
|
androidx-ui-graphics = { module = "androidx.compose.ui:ui-graphics", version.ref = "uiGraphics" }
|
||||||
androidx-ui-test-junit4 = { module = "androidx.compose.ui:ui-test-junit4", version.ref = "uiGraphics" }
|
androidx-ui-test-junit4 = { module = "androidx.compose.ui:ui-test-junit4", version.ref = "uiGraphics" }
|
||||||
androidx-ui-test-manifest = { module = "androidx.compose.ui:ui-test-manifest", version.ref = "uiGraphics" }
|
androidx-ui-test-manifest = { module = "androidx.compose.ui:ui-test-manifest", version.ref = "uiGraphics" }
|
||||||
|
androidx-ui-tooling = { module = "androidx.compose.ui:ui-tooling", version.ref = "uiTooling" }
|
||||||
androidx-ui-tooling-preview = { module = "androidx.compose.ui:ui-tooling-preview", version.ref = "uiToolingPreview" }
|
androidx-ui-tooling-preview = { module = "androidx.compose.ui:ui-tooling-preview", version.ref = "uiToolingPreview" }
|
||||||
androidx-work-runtime-ktx = { module = "androidx.work:work-runtime-ktx", version.ref = "workRuntimeKtx" }
|
androidx-work-runtime-ktx = { module = "androidx.work:work-runtime-ktx", version.ref = "workRuntimeKtx" }
|
||||||
coil-compose = { module = "io.coil-kt:coil-compose", version.ref = "coilCompose" }
|
coil-compose = { module = "io.coil-kt:coil-compose", version.ref = "coilCompose" }
|
||||||
@ -69,6 +74,7 @@ compiler = { module = "com.github.bumptech.glide:compiler", version.ref = "compi
|
|||||||
converter-gson = { module = "com.squareup.retrofit2:converter-gson", version.ref = "converterGson" }
|
converter-gson = { module = "com.squareup.retrofit2:converter-gson", version.ref = "converterGson" }
|
||||||
core = { module = "com.google.zxing:core", version.ref = "core" }
|
core = { module = "com.google.zxing:core", version.ref = "core" }
|
||||||
crashreport = { module = "com.tencent.bugly:crashreport", version.ref = "crashreport" }
|
crashreport = { module = "com.tencent.bugly:crashreport", version.ref = "crashreport" }
|
||||||
|
face-detection = { module = "com.google.mlkit:face-detection", version.ref = "faceDetection" }
|
||||||
fastjson = { module = "com.alibaba:fastjson", version.ref = "fastjson" }
|
fastjson = { module = "com.alibaba:fastjson", version.ref = "fastjson" }
|
||||||
glide = { module = "com.github.bumptech.glide:glide", version.ref = "glide" }
|
glide = { module = "com.github.bumptech.glide:glide", version.ref = "glide" }
|
||||||
gson = { module = "com.google.code.gson:gson", version.ref = "gson" }
|
gson = { module = "com.google.code.gson:gson", version.ref = "gson" }
|
||||||
@ -96,12 +102,13 @@ search = { module = "com.amap.api:search", version.ref = "search" }
|
|||||||
tbssdk = { module = "com.tencent.tbs:tbssdk", version.ref = "tbssdk" }
|
tbssdk = { module = "com.tencent.tbs:tbssdk", version.ref = "tbssdk" }
|
||||||
utilcodex = { module = "com.blankj:utilcodex", version.ref = "utilcodex" }
|
utilcodex = { module = "com.blankj:utilcodex", version.ref = "utilcodex" }
|
||||||
xdmap = { module = "com.amap.api:3dmap", version.ref = "xdmap" }
|
xdmap = { module = "com.amap.api:3dmap", version.ref = "xdmap" }
|
||||||
|
androidx-activity = { group = "androidx.activity", name = "activity", version.ref = "activity" }
|
||||||
xz = { module = "org.tukaani:xz", version.ref = "xz" }
|
xz = { module = "org.tukaani:xz", version.ref = "xz" }
|
||||||
androidx-exifinterface = { group = "androidx.exifinterface", name = "exifinterface", version.ref = "exifinterface" }
|
androidx-exifinterface = { group = "androidx.exifinterface", name = "exifinterface", version.ref = "exifinterface" }
|
||||||
face-detection = { module = "com.google.mlkit:face-detection", version.ref = "faceDetection" }
|
ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling", version.ref = "uiToolingVersion" }
|
||||||
ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling", version.ref = "uiToolingPreview" }
|
|
||||||
|
|
||||||
[plugins]
|
[plugins]
|
||||||
android-application = { id = "com.android.application", version.ref = "agp" }
|
android-application = { id = "com.android.application", version.ref = "agp" }
|
||||||
jetbrains-kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
|
jetbrains-kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
|
||||||
android-library = { id = "com.android.library", version.ref = "agp" }
|
android-library = { id = "com.android.library", version.ref = "agp" }
|
||||||
|
kotlin-compose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
|
||||||
|
@ -31,7 +31,7 @@ android {
|
|||||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||||
}
|
}
|
||||||
|
|
||||||
publishNonDefault true
|
// publishNonDefault true
|
||||||
}
|
}
|
||||||
compileOptions {
|
compileOptions {
|
||||||
sourceCompatibility JavaVersion.VERSION_11
|
sourceCompatibility JavaVersion.VERSION_11
|
||||||
@ -64,7 +64,7 @@ publishing {
|
|||||||
release(MavenPublication) {
|
release(MavenPublication) {
|
||||||
groupId = 'io.github.szl9'
|
groupId = 'io.github.szl9'
|
||||||
artifactId = 'zd_servicing'
|
artifactId = 'zd_servicing'
|
||||||
version = "1.0.1.9.9.127"
|
version = "1.0.1.9.9.138"
|
||||||
|
|
||||||
pom {
|
pom {
|
||||||
packaging = "aar"
|
packaging = "aar"
|
||||||
|
106
servicing/proguard-rules.pro
vendored
@ -1,3 +1,5 @@
|
|||||||
|
-dontwarn java.lang.invoke.StringConcatFactory
|
||||||
|
|
||||||
# 保留行号用于调试
|
# 保留行号用于调试
|
||||||
-keepattributes SourceFile,LineNumberTable
|
-keepattributes SourceFile,LineNumberTable
|
||||||
-renamesourcefileattribute SourceFile
|
-renamesourcefileattribute SourceFile
|
||||||
@ -8,19 +10,42 @@
|
|||||||
-keepattributes Exceptions
|
-keepattributes Exceptions
|
||||||
-keepattributes InnerClasses
|
-keepattributes InnerClasses
|
||||||
|
|
||||||
|
-dontwarn com.github.luben.zstd.BufferPool
|
||||||
|
-dontwarn com.github.luben.zstd.ZstdInputStream
|
||||||
|
-dontwarn com.github.luben.zstd.ZstdOutputStream
|
||||||
|
-dontwarn org.brotli.dec.BrotliInputStream
|
||||||
|
-dontwarn org.objectweb.asm.AnnotationVisitor
|
||||||
|
-dontwarn org.objectweb.asm.Attribute
|
||||||
|
-dontwarn org.objectweb.asm.ClassReader
|
||||||
|
-dontwarn org.objectweb.asm.ClassVisitor
|
||||||
|
-dontwarn org.objectweb.asm.FieldVisitor
|
||||||
|
-dontwarn org.objectweb.asm.Label
|
||||||
|
-dontwarn org.objectweb.asm.MethodVisitor
|
||||||
|
-dontwarn org.objectweb.asm.Type
|
||||||
|
|
||||||
# 保留R文件
|
# 保留R文件
|
||||||
-keepclassmembers class **.R$* {
|
-keepclassmembers class **.R$* {
|
||||||
public static <fields>;
|
public static <fields>;
|
||||||
}
|
}
|
||||||
|
|
||||||
# 保留servicing模块中的所有model类
|
# 保留servicing模块中的所有model类
|
||||||
-keep class com.za.servicing.model.** { *; }
|
-keep class com.za.bean.** { *; }
|
||||||
|
-keep class com.za.bean.db.** { *; }
|
||||||
|
-keep class com.za.bean.request.** { *; }
|
||||||
|
|
||||||
# 保留servicing模块中的所有接口
|
# 保留servicing模块中的所有接口
|
||||||
-keep interface com.za.servicing.** { *; }
|
-keep interface com.za.servicing.** { *; }
|
||||||
|
-keep interface com.za.net.** { *; }
|
||||||
|
|
||||||
# 保留servicing模块中的所有枚举
|
# 保留servicing模块中的所有枚举
|
||||||
-keepclassmembers enum com.za.servicing.** { *; }
|
-keepclassmembers enum com.za.** { *; }
|
||||||
|
|
||||||
|
# 保留Room数据库相关类
|
||||||
|
-keep class com.za.room.** { *; }
|
||||||
|
-keep class com.za.room.db.** { *; }
|
||||||
|
-keep class * extends androidx.room.RoomDatabase
|
||||||
|
-keep @androidx.room.Entity class *
|
||||||
|
-keep @androidx.room.Dao interface *
|
||||||
|
|
||||||
# 保留Parcelable实现类
|
# 保留Parcelable实现类
|
||||||
-keep class * implements android.os.Parcelable {
|
-keep class * implements android.os.Parcelable {
|
||||||
@ -58,6 +83,10 @@
|
|||||||
void set*(***); *** get*();
|
void set*(***); *** get*();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# CameraX相关
|
||||||
|
-keep class androidx.camera.** { *; }
|
||||||
|
-dontwarn androidx.camera.**
|
||||||
|
|
||||||
# Coil图片加载库
|
# Coil图片加载库
|
||||||
-keep class coil.** { *; }
|
-keep class coil.** { *; }
|
||||||
-dontwarn coil.**
|
-dontwarn coil.**
|
||||||
@ -75,7 +104,6 @@
|
|||||||
|
|
||||||
# JPush相关
|
# JPush相关
|
||||||
-dontoptimize
|
-dontoptimize
|
||||||
-dontpreverify
|
|
||||||
-dontwarn cn.jpush.**
|
-dontwarn cn.jpush.**
|
||||||
-keep class cn.jpush.** { *; }
|
-keep class cn.jpush.** { *; }
|
||||||
-dontwarn cn.jcore.**
|
-dontwarn cn.jcore.**
|
||||||
@ -105,13 +133,12 @@
|
|||||||
long consumerIndex;
|
long consumerIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
#blankJ
|
# BlankJ工具库
|
||||||
-dontwarn com.blankj.utilcode.**
|
-dontwarn com.blankj.utilcode.**
|
||||||
|
-keep class com.blankj.utilcode.** { *; }
|
||||||
-keepclassmembers class * {
|
-keepclassmembers class * {
|
||||||
@com.blankj.utilcode.util.BusUtils$Bus <methods>;
|
@com.blankj.utilcode.util.BusUtils$Bus <methods>;
|
||||||
}
|
}
|
||||||
|
|
||||||
-keep public class * extends com.blankj.utilcode.util.ApiUtils$BaseApi
|
-keep public class * extends com.blankj.utilcode.util.ApiUtils$BaseApi
|
||||||
-keep,allowobfuscation @interface com.blankj.utilcode.util.ApiUtils$Api
|
-keep,allowobfuscation @interface com.blankj.utilcode.util.ApiUtils$Api
|
||||||
-keep @com.blankj.utilcode.util.ApiUtils$Api class *
|
-keep @com.blankj.utilcode.util.ApiUtils$Api class *
|
||||||
@ -122,41 +149,27 @@
|
|||||||
-keep public class * {
|
-keep public class * {
|
||||||
public protected *;
|
public protected *;
|
||||||
}
|
}
|
||||||
# Preserve all .class method names.
|
|
||||||
|
|
||||||
|
# 保留所有类的方法名
|
||||||
-keepclassmembernames class * {
|
-keepclassmembernames class * {
|
||||||
java.lang.Class class$(java.lang.String);
|
java.lang.Class class$(java.lang.String);
|
||||||
java.lang.Class class$(java.lang.String, boolean);
|
java.lang.Class class$(java.lang.String, boolean);
|
||||||
}
|
}
|
||||||
|
|
||||||
# Preserve all native method names and the names of their classes.
|
# 保留枚举类中的特殊静态方法
|
||||||
|
|
||||||
-keepclasseswithmembernames class * {
|
|
||||||
native <methods>;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Preserve the special static methods that are required in all enumeration
|
|
||||||
# classes.
|
|
||||||
|
|
||||||
-keepclassmembers class * extends java.lang.Enum {
|
-keepclassmembers class * extends java.lang.Enum {
|
||||||
public static **[] values();
|
public static **[] values();
|
||||||
public static ** valueOf(java.lang.String);
|
public static ** valueOf(java.lang.String);
|
||||||
}
|
}
|
||||||
|
|
||||||
-keepclassmembers class * implements java.io.Serializable {
|
# MQTT相关
|
||||||
static final long serialVersionUID;
|
-keep class org.eclipse.paho.** { *; }
|
||||||
static final java.io.ObjectStreamField[] serialPersistentFields;
|
-dontwarn org.eclipse.paho.**
|
||||||
private void writeObject(java.io.ObjectOutputStream);
|
|
||||||
private void readObject(java.io.ObjectInputStream);
|
|
||||||
java.lang.Object writeReplace();
|
|
||||||
java.lang.Object readResolve();
|
|
||||||
}
|
|
||||||
|
|
||||||
# Gson
|
# Gson
|
||||||
-keep class com.google.gson.** { *; }
|
-keep class com.google.gson.** { *; }
|
||||||
-keepattributes Signature
|
-keepattributes Signature
|
||||||
-keepattributes *Annotation*
|
-keepattributes *Annotation*
|
||||||
-keep class sun.misc.Unsafe { *; }
|
|
||||||
-keep class * implements com.google.gson.TypeAdapterFactory
|
-keep class * implements com.google.gson.TypeAdapterFactory
|
||||||
-keep class * implements com.google.gson.JsonSerializer
|
-keep class * implements com.google.gson.JsonSerializer
|
||||||
-keep class * implements com.google.gson.JsonDeserializer
|
-keep class * implements com.google.gson.JsonDeserializer
|
||||||
@ -192,7 +205,7 @@
|
|||||||
public ** component*();
|
public ** component*();
|
||||||
public ** copy(...);
|
public ** copy(...);
|
||||||
}
|
}
|
||||||
|
#
|
||||||
# 保留Kotlin数据类的toString/hashCode/equals方法
|
# 保留Kotlin数据类的toString/hashCode/equals方法
|
||||||
-keepclassmembers class ** {
|
-keepclassmembers class ** {
|
||||||
public java.lang.String toString();
|
public java.lang.String toString();
|
||||||
@ -200,4 +213,45 @@
|
|||||||
public boolean equals(java.lang.Object);
|
public boolean equals(java.lang.Object);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# 保留Compose相关
|
||||||
|
-keep class androidx.compose.** { *; }
|
||||||
|
-dontwarn androidx.compose.**
|
||||||
|
|
||||||
|
# 保留自定义签名相关类
|
||||||
|
-keep class com.za.signature.** { *; }
|
||||||
|
|
||||||
|
# 保留Face Detection相关
|
||||||
|
-keep class com.google.mlkit.** { *; }
|
||||||
|
-dontwarn com.google.mlkit.**
|
||||||
|
|
||||||
|
# 保留ZXing相关
|
||||||
|
-keep class com.google.zxing.** { *; }
|
||||||
|
-dontwarn com.google.zxing.**
|
||||||
|
|
||||||
|
# 保留Glide相关
|
||||||
|
-keep public class * implements com.bumptech.glide.module.GlideModule
|
||||||
|
-keep class * extends com.bumptech.glide.module.AppGlideModule {
|
||||||
|
<init>(...);
|
||||||
|
}
|
||||||
|
-keep public enum com.bumptech.glide.load.ImageHeaderParser$** {
|
||||||
|
**[] $VALUES;
|
||||||
|
public *;
|
||||||
|
}
|
||||||
|
-keep class com.bumptech.glide.load.data.ParcelFileDescriptorRewinder$InternalRewinder {
|
||||||
|
*** rewind();
|
||||||
|
}
|
||||||
|
|
||||||
|
# 保留FastJSON相关
|
||||||
|
-keep class com.alibaba.fastjson.** { *; }
|
||||||
|
-dontwarn com.alibaba.fastjson.**
|
||||||
|
|
||||||
|
# 保留Bugly相关
|
||||||
|
-keep class com.tencent.bugly.** { *; }
|
||||||
|
-dontwarn com.tencent.bugly.**
|
||||||
|
#
|
||||||
|
# 保留自定义UI组件
|
||||||
|
-keep class com.za.ui.** { *; }
|
||||||
|
-keep class com.za.base.** { *; }
|
||||||
|
|
||||||
|
# 保留Java 8 Lambda表达式
|
||||||
-dontwarn java.lang.invoke.StringConcatFactory
|
-dontwarn java.lang.invoke.StringConcatFactory
|
@ -61,6 +61,7 @@ object Const {
|
|||||||
const val RE_DISPATCH = "reDispatch"
|
const val RE_DISPATCH = "reDispatch"
|
||||||
const val MODIFY = "modify"
|
const val MODIFY = "modify"
|
||||||
const val REVOKE = "revoke"
|
const val REVOKE = "revoke"
|
||||||
|
const val REPORT_HANDLE = "report_handle"
|
||||||
const val GO_MAIN_PAGE = "goMainPage"
|
const val GO_MAIN_PAGE = "goMainPage"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -40,9 +40,7 @@ abstract class IServicingVm<T, U> : BaseVm<T, U>() {
|
|||||||
getCurrentOrder()?.getTaskNode() ?: 0,
|
getCurrentOrder()?.getTaskNode() ?: 0,
|
||||||
getCurrentOrder()?.userOrderId ?: 0)
|
getCurrentOrder()?.userOrderId ?: 0)
|
||||||
success(data)
|
success(data)
|
||||||
}, failed = {
|
}, failed = {})
|
||||||
failure(it)
|
|
||||||
})
|
|
||||||
} else {
|
} else {
|
||||||
success(photoTemplateList)
|
success(photoTemplateList)
|
||||||
}
|
}
|
||||||
|
@ -39,6 +39,12 @@ open class PushMessageActivity : AppCompatActivity() {
|
|||||||
context = this@PushMessageActivity)
|
context = this@PushMessageActivity)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun reportHandle(jpushBean : JpushBean) {
|
||||||
|
sendMessageToMainProcess(type = Const.PushMessageType.REPORT_HANDLE,
|
||||||
|
message = Gson().toJson(jpushBean),
|
||||||
|
context = this@PushMessageActivity)
|
||||||
|
}
|
||||||
|
|
||||||
override fun newOrderMsg(jpushBean : JpushBean) {
|
override fun newOrderMsg(jpushBean : JpushBean) {
|
||||||
sendMessageToMainProcess(type = Const.PushMessageType.NEW_ORDER,
|
sendMessageToMainProcess(type = Const.PushMessageType.NEW_ORDER,
|
||||||
message = Gson().toJson(jpushBean),
|
message = Gson().toJson(jpushBean),
|
||||||
|
@ -15,7 +15,10 @@ import androidx.compose.runtime.CompositionLocalProvider
|
|||||||
import androidx.compose.runtime.SideEffect
|
import androidx.compose.runtime.SideEffect
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.graphics.toArgb
|
import androidx.compose.ui.graphics.toArgb
|
||||||
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
import androidx.compose.ui.platform.LocalDensity
|
||||||
import androidx.compose.ui.platform.LocalView
|
import androidx.compose.ui.platform.LocalView
|
||||||
|
import androidx.compose.ui.unit.Density
|
||||||
import androidx.core.view.ViewCompat
|
import androidx.core.view.ViewCompat
|
||||||
import androidx.core.view.WindowCompat
|
import androidx.core.view.WindowCompat
|
||||||
import androidx.core.view.WindowInsetsCompat
|
import androidx.core.view.WindowInsetsCompat
|
||||||
@ -61,12 +64,17 @@ fun DealerTheme(darkTheme : Boolean = isSystemInDarkTheme(), content : @Composab
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
val fontScale = LocalDensity.current.fontScale
|
||||||
|
val displayMetrics = LocalContext.current.resources.displayMetrics
|
||||||
|
val widthPixels = displayMetrics.widthPixels
|
||||||
|
|
||||||
MaterialTheme(colorScheme = colorScheme) {
|
MaterialTheme(colorScheme = colorScheme) {
|
||||||
CompositionLocalProvider(LocalRippleConfiguration provides RippleConfiguration(rippleAlpha = RippleAlpha(
|
CompositionLocalProvider(LocalRippleConfiguration provides RippleConfiguration(rippleAlpha = RippleAlpha(
|
||||||
0f,
|
0f,
|
||||||
0f,
|
0f,
|
||||||
0f,
|
0f,
|
||||||
0f))) {
|
0f)),
|
||||||
|
LocalDensity provides Density(fontScale = 1f, density = widthPixels / 360f)) {
|
||||||
ProvideTextStyle(value = MaterialTheme.typography.bodyLarge, content = content)
|
ProvideTextStyle(value = MaterialTheme.typography.bodyLarge, content = content)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -174,9 +174,6 @@ data class HistoryPhotoTemplateItem(
|
|||||||
|
|
||||||
//获取拍照时间
|
//获取拍照时间
|
||||||
fun getPhotoTakeTime(taskState : String, historyTaskBean : HistoryTaskBean?) : String? {
|
fun getPhotoTakeTime(taskState : String, historyTaskBean : HistoryTaskBean?) : String? {
|
||||||
if (! takePhotoTime.isNullOrBlank()) {
|
|
||||||
return takePhotoTime
|
|
||||||
}
|
|
||||||
return when (taskState) {
|
return when (taskState) {
|
||||||
"13001", "15001" -> historyTaskBean?.arriveTime
|
"13001", "15001" -> historyTaskBean?.arriveTime
|
||||||
"17001" -> {
|
"17001" -> {
|
||||||
@ -197,9 +194,6 @@ data class HistoryPhotoTemplateItem(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun getPhotoLat(taskState : String, historyTaskBean : HistoryTaskBean?) : Double? {
|
fun getPhotoLat(taskState : String, historyTaskBean : HistoryTaskBean?) : Double? {
|
||||||
if (! lat.isNullOrBlank()) {
|
|
||||||
return lat.toDouble()
|
|
||||||
}
|
|
||||||
return when (taskState) {
|
return when (taskState) {
|
||||||
"13001", "15001" -> historyTaskBean?.lat
|
"13001", "15001" -> historyTaskBean?.lat
|
||||||
"17001", "18001" -> {
|
"17001", "18001" -> {
|
||||||
@ -216,9 +210,6 @@ data class HistoryPhotoTemplateItem(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun getPhotoLng(taskState : String, historyTaskBean : HistoryTaskBean?) : Double? {
|
fun getPhotoLng(taskState : String, historyTaskBean : HistoryTaskBean?) : Double? {
|
||||||
if (! lon.isNullOrBlank()) {
|
|
||||||
return lon.toDouble()
|
|
||||||
}
|
|
||||||
return when (taskState) {
|
return when (taskState) {
|
||||||
"13001", "15001" -> historyTaskBean?.lng
|
"13001", "15001" -> historyTaskBean?.lng
|
||||||
"17001", "18001" -> {
|
"17001", "18001" -> {
|
||||||
@ -235,9 +226,6 @@ data class HistoryPhotoTemplateItem(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun getPhotoAddress(taskState : String, historyTaskBean : HistoryTaskBean?) : String? {
|
fun getPhotoAddress(taskState : String, historyTaskBean : HistoryTaskBean?) : String? {
|
||||||
if (! takeAddress?.replace("[", "")?.replace("]", "").isNullOrBlank()) {
|
|
||||||
return takeAddress
|
|
||||||
}
|
|
||||||
return when (taskState) {
|
return when (taskState) {
|
||||||
"13001", "15001" -> historyTaskBean?.address
|
"13001", "15001" -> historyTaskBean?.address
|
||||||
"17001", "18001" -> {
|
"17001", "18001" -> {
|
||||||
|
@ -31,4 +31,14 @@ data class TaskNotesBean(val taskNotes : String? = null, //救援要求
|
|||||||
val customerNotes : String? = null, //客户提醒
|
val customerNotes : String? = null, //客户提醒
|
||||||
val otherNotes : String? = null, //特殊提醒
|
val otherNotes : String? = null, //特殊提醒
|
||||||
val modelVinNo : String? = null, //车型
|
val modelVinNo : String? = null, //车型
|
||||||
val contract : String? = null) //车型
|
val contract : String? = null) //车型
|
||||||
|
|
||||||
|
|
||||||
|
data class UnifiedOCRWithCompressRequest(
|
||||||
|
val ocrType : Int? = null, // 4为车架号识别 5为车牌号识别
|
||||||
|
val imageUrl : String? = null, // 图片地址
|
||||||
|
val cardSide : String? = null, // FRONT:正面 BACK:反面 默认:FRONT
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
data class SaveSignatureRequest(val signatureUrl : String? = null, val driverId : Int? = null)
|
@ -22,6 +22,7 @@ data class PhotoTemplateInfo(
|
|||||||
val numbering : String? = null, // 图片编号
|
val numbering : String? = null, // 图片编号
|
||||||
val recognizeType : Int? = null, //orc 识别类型 0 无 1 车牌号 2 车架号
|
val recognizeType : Int? = null, //orc 识别类型 0 无 1 车牌号 2 车架号
|
||||||
//以下属性非后台返回属性
|
//以下属性非后台返回属性
|
||||||
|
val serviceTypeName : String? = null, //服务类型名称
|
||||||
val userOrderId : Int? = null,
|
val userOrderId : Int? = null,
|
||||||
val taskCode : String? = null,
|
val taskCode : String? = null,
|
||||||
val taskId : Int? = null,
|
val taskId : Int? = null,
|
||||||
|
@ -7,6 +7,7 @@ import com.tencent.mmkv.MMKV
|
|||||||
import com.za.base.AppConfig
|
import com.za.base.AppConfig
|
||||||
import com.za.base.Const
|
import com.za.base.Const
|
||||||
import com.za.bean.db.order.OrderInfo
|
import com.za.bean.db.order.OrderInfo
|
||||||
|
import com.za.common.log.LogUtil
|
||||||
import com.za.room.RoomHelper
|
import com.za.room.RoomHelper
|
||||||
import com.za.room.db.user.DriverInfoBean
|
import com.za.room.db.user.DriverInfoBean
|
||||||
import com.za.service.location.ZdLocationManager
|
import com.za.service.location.ZdLocationManager
|
||||||
@ -49,14 +50,26 @@ object GlobalData : GlobalLocalData() {
|
|||||||
|
|
||||||
var driverInfoBean : DriverInfoBean? = null
|
var driverInfoBean : DriverInfoBean? = null
|
||||||
get() {
|
get() {
|
||||||
if (field == null) {
|
return try {
|
||||||
field = localDriverInfoBean
|
val driverInfo = MMKV.defaultMMKV()
|
||||||
|
.decodeParcelable("driverInfoBean", DriverInfoBean::class.java)
|
||||||
|
field = driverInfo
|
||||||
|
field
|
||||||
|
} catch (e : Exception) {
|
||||||
|
LogUtil.print("local_driverInfoBean", "获取司机信息失败: ${e.message}")
|
||||||
|
null
|
||||||
}
|
}
|
||||||
return field
|
|
||||||
}
|
}
|
||||||
set(value) {
|
set(value) {
|
||||||
localDriverInfoBean = value
|
try {
|
||||||
field = value
|
MMKV.defaultMMKV().encode("driverInfoBean", value)
|
||||||
|
if (value != null) {
|
||||||
|
lastLoginBean = value
|
||||||
|
}
|
||||||
|
field = value
|
||||||
|
} catch (e : Exception) {
|
||||||
|
LogUtil.print("set local_driverInfoBean", "保存司机信息失败: ${e.message}")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -139,6 +152,45 @@ object GlobalData : GlobalLocalData() {
|
|||||||
mmkv.encode("isShowKeepAlive", value)
|
mmkv.encode("isShowKeepAlive", value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var lastUploadLogTime : Long
|
||||||
|
get() {
|
||||||
|
return mmkv.decodeLong("lastUploadLogTime", 0)
|
||||||
|
}
|
||||||
|
set(value) {
|
||||||
|
mmkv.encode("lastUploadLogTime", value)
|
||||||
|
}
|
||||||
|
|
||||||
|
var vehicleId : Int? = null
|
||||||
|
get() {
|
||||||
|
field = mmkv.decodeInt("vehicleId")
|
||||||
|
return field
|
||||||
|
}
|
||||||
|
set(value) {
|
||||||
|
mmkv.encode("vehicleId", value ?: 0)
|
||||||
|
field = value
|
||||||
|
}
|
||||||
|
|
||||||
|
var driverId : Int? = null
|
||||||
|
get() {
|
||||||
|
field = mmkv.decodeInt("driverId")
|
||||||
|
return field
|
||||||
|
}
|
||||||
|
set(value) {
|
||||||
|
mmkv.encode("driverId", value ?: 0)
|
||||||
|
field = value
|
||||||
|
}
|
||||||
|
|
||||||
|
var deviceId : String? = null
|
||||||
|
get() {
|
||||||
|
field = mmkv.decodeString("deviceId")
|
||||||
|
return field
|
||||||
|
}
|
||||||
|
set(value) {
|
||||||
|
mmkv.encode("deviceId", value)
|
||||||
|
field = value
|
||||||
|
}
|
||||||
|
|
||||||
fun clearUserCache() {
|
fun clearUserCache() {
|
||||||
token = null
|
token = null
|
||||||
aesKey = null
|
aesKey = null
|
||||||
@ -147,6 +199,10 @@ object GlobalData : GlobalLocalData() {
|
|||||||
loginTime = null
|
loginTime = null
|
||||||
isLoginRecognition = null
|
isLoginRecognition = null
|
||||||
isHasShowKeepAlive = false
|
isHasShowKeepAlive = false
|
||||||
|
lastUploadLogTime = 0
|
||||||
|
deviceId = null
|
||||||
|
vehicleId = null
|
||||||
|
driverId = null
|
||||||
|
|
||||||
if (AppConfig.isRelease) {
|
if (AppConfig.isRelease) {
|
||||||
networkEnv = if (AppConfig.isRelease) {
|
networkEnv = if (AppConfig.isRelease) {
|
||||||
|
@ -2,69 +2,72 @@ package com.za.common.log
|
|||||||
|
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.os.Build
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import androidx.work.Configuration
|
import androidx.work.Configuration
|
||||||
import androidx.work.PeriodicWorkRequest
|
import androidx.work.PeriodicWorkRequest
|
||||||
import androidx.work.WorkManager
|
import androidx.work.WorkManager
|
||||||
import androidx.work.Worker
|
import androidx.work.Worker
|
||||||
import androidx.work.WorkerParameters
|
import androidx.work.WorkerParameters
|
||||||
import com.blankj.utilcode.constant.MemoryConstants
|
|
||||||
import com.blankj.utilcode.util.AppUtils
|
import com.blankj.utilcode.util.AppUtils
|
||||||
import com.blankj.utilcode.util.DeviceUtils
|
|
||||||
import com.blankj.utilcode.util.FileUtils
|
import com.blankj.utilcode.util.FileUtils
|
||||||
|
import com.blankj.utilcode.util.LogUtils
|
||||||
import com.blankj.utilcode.util.TimeUtils
|
import com.blankj.utilcode.util.TimeUtils
|
||||||
import com.za.common.GlobalData
|
import com.za.common.GlobalData
|
||||||
import com.za.common.util.AppFileManager
|
|
||||||
import io.reactivex.rxjava3.schedulers.Schedulers
|
import io.reactivex.rxjava3.schedulers.Schedulers
|
||||||
import kotlinx.coroutines.CoroutineScope
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.SupervisorJob
|
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
import kotlinx.coroutines.withContext
|
|
||||||
import okhttp3.MediaType.Companion.toMediaType
|
import okhttp3.MediaType.Companion.toMediaType
|
||||||
import okhttp3.MultipartBody
|
import okhttp3.MultipartBody
|
||||||
import okhttp3.RequestBody
|
import okhttp3.RequestBody
|
||||||
import okhttp3.RequestBody.Companion.asRequestBody
|
import okhttp3.RequestBody.Companion.asRequestBody
|
||||||
import org.apache.commons.compress.compressors.xz.XZCompressorOutputStream
|
import org.apache.commons.compress.compressors.xz.XZCompressorOutputStream
|
||||||
import java.io.BufferedWriter
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.FileInputStream
|
import java.io.FileInputStream
|
||||||
import java.io.FileOutputStream
|
import java.io.FileOutputStream
|
||||||
import java.io.FileWriter
|
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import java.io.PrintWriter
|
import java.io.PrintWriter
|
||||||
import java.io.StringWriter
|
import java.io.StringWriter
|
||||||
|
import java.nio.file.Files
|
||||||
|
import java.nio.file.Paths
|
||||||
|
import java.util.concurrent.ExecutorService
|
||||||
|
import java.util.concurrent.Executors
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
import java.util.concurrent.atomic.AtomicBoolean
|
|
||||||
import kotlin.concurrent.thread
|
|
||||||
|
|
||||||
object LogUtil {
|
object LogUtil {
|
||||||
private var context : Application? = null
|
private var context : Application? = null
|
||||||
private var logDestinationPath : String? = null
|
private var executors : ExecutorService? = null
|
||||||
private var orderLogDirPath : String? = null
|
|
||||||
private var normalLogDirPath : String? = null
|
private var normalLogDirPath : String? = null
|
||||||
private val coroutineScope = CoroutineScope(Dispatchers.IO + SupervisorJob())
|
|
||||||
private val logBuffer = StringBuilder()
|
//日志上报时间间隔
|
||||||
private val isWriting = AtomicBoolean(false)
|
private const val uploadTimeInterval = (30 * 60 * 1000).toLong()
|
||||||
|
|
||||||
fun init(context : Application) {
|
fun init(context : Application) {
|
||||||
this.context = context
|
this.context = context
|
||||||
|
executors = Executors.newSingleThreadExecutor()
|
||||||
logDestinationPath = AppFileManager.getLogPath(context).also { path ->
|
val logDestinationPath : String = context.filesDir.absolutePath + File.separator + "Log"
|
||||||
createDirectoryIfNotExists(path)
|
val logDesFile = File(logDestinationPath)
|
||||||
orderLogDirPath =
|
if (! logDesFile.exists()) {
|
||||||
"$path${File.separator}order_log".also { createDirectoryIfNotExists(it) }
|
logDesFile.mkdir()
|
||||||
normalLogDirPath =
|
|
||||||
"$path${File.separator}normal_log".also { createDirectoryIfNotExists(it) }
|
|
||||||
}
|
}
|
||||||
|
val orderLogDirPath = logDestinationPath + File.separator + "order_log"
|
||||||
|
val orderLogFile = File(orderLogDirPath)
|
||||||
|
if (! orderLogFile.exists()) {
|
||||||
|
orderLogFile.mkdir()
|
||||||
|
}
|
||||||
|
normalLogDirPath = logDestinationPath + File.separator + "normal_log"
|
||||||
|
|
||||||
|
val normalLogFile = File(normalLogDirPath)
|
||||||
|
LogUtils.getConfig().setDir(normalLogDirPath)
|
||||||
|
LogUtils.getConfig().setBorderSwitch(false)
|
||||||
|
LogUtils.getConfig().setLog2FileSwitch(true)
|
||||||
|
LogUtils.getConfig().setStackDeep(1)
|
||||||
|
LogUtils.getConfig().setLogHeadSwitch(false)
|
||||||
|
|
||||||
|
if (! normalLogFile.exists()) {
|
||||||
|
normalLogFile.mkdir()
|
||||||
|
}
|
||||||
initializeWorkManager(context)
|
initializeWorkManager(context)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createDirectoryIfNotExists(path : String) {
|
|
||||||
File(path).apply { if (! exists()) mkdir() }
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun initializeWorkManager(context : Application) {
|
private fun initializeWorkManager(context : Application) {
|
||||||
if (! WorkManager.isInitialized()) {
|
if (! WorkManager.isInitialized()) {
|
||||||
WorkManager.initialize(context,
|
WorkManager.initialize(context,
|
||||||
@ -73,183 +76,157 @@ object LogUtil {
|
|||||||
|
|
||||||
WorkManager.getInstance(context).apply {
|
WorkManager.getInstance(context).apply {
|
||||||
cancelAllWorkByTag("logWorkRequest")
|
cancelAllWorkByTag("logWorkRequest")
|
||||||
enqueue(PeriodicWorkRequest.Builder(LogTask::class.java, 20, TimeUnit.MINUTES)
|
enqueue(PeriodicWorkRequest.Builder(LogTask::class.java, 80, TimeUnit.MINUTES)
|
||||||
.addTag("logWorkRequest").build())
|
.addTag("logWorkRequest").build())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun print(tag : String, content : String) {
|
fun print(tag : String?, throwable : Throwable?) {
|
||||||
val time = getCurrentTime()
|
if (throwable == null) {
|
||||||
val logEntry = "$time---$tag---$content\n"
|
return
|
||||||
Log.e("normal", "$tag---$content")
|
|
||||||
synchronized(logBuffer) {
|
|
||||||
logBuffer.append(logEntry)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (logBuffer.length > 4096) {
|
|
||||||
coroutineScope.launch {
|
|
||||||
flushBuffer()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun print(tag : String, throwable : Throwable) {
|
|
||||||
val content = StringWriter()
|
|
||||||
val printWriter = PrintWriter(content)
|
|
||||||
throwable.printStackTrace(printWriter)
|
|
||||||
print(tag, content.toString())
|
|
||||||
}
|
|
||||||
|
|
||||||
private suspend fun flushBuffer() = withContext(Dispatchers.IO) {
|
|
||||||
if (! isWriting.compareAndSet(false, true)) return@withContext
|
|
||||||
|
|
||||||
val logContent : String
|
|
||||||
synchronized(logBuffer) {
|
|
||||||
if (logBuffer.isEmpty()) {
|
|
||||||
isWriting.set(false)
|
|
||||||
return@withContext
|
|
||||||
}
|
|
||||||
logContent = logBuffer.toString()
|
|
||||||
logBuffer.clear()
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
val fileName = "normal_log.txt"
|
val stringWriter = StringWriter()
|
||||||
val logFile = File("$normalLogDirPath${File.separator}$fileName")
|
val printWriter = PrintWriter(stringWriter)
|
||||||
|
throwable.printStackTrace(printWriter)
|
||||||
logFile.parentFile?.mkdirs()
|
if (System.currentTimeMillis() - GlobalData.lastUploadLogTime > uploadTimeInterval) {
|
||||||
|
updateNormalLog()
|
||||||
if (! logFile.exists()) {
|
|
||||||
logFile.createNewFile()
|
|
||||||
addLogHead(logFile, getCurrentTime())
|
|
||||||
}
|
}
|
||||||
|
LogUtils.getConfig().setFilePrefix(this.vehicleName)
|
||||||
BufferedWriter(FileWriter(logFile, true)).use { writer ->
|
LogUtils.e("$tag---$stringWriter")
|
||||||
writer.write(logContent)
|
|
||||||
writer.flush()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (logFile.length() >= 8 * MemoryConstants.MB) {
|
|
||||||
rotateLogFile(logFile)
|
|
||||||
}
|
|
||||||
} catch (e : IOException) {
|
|
||||||
Log.e("LogUtil", "Error in flushBuffer: ${e.message}")
|
|
||||||
} catch (e : Exception) {
|
} catch (e : Exception) {
|
||||||
Log.e("LogUtil", "Error in flushBuffer: ${e.message}")
|
e.printStackTrace()
|
||||||
} finally {
|
|
||||||
isWriting.set(false)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun rotateLogFile(file : File) {
|
fun print(tag : String?, content : String?) {
|
||||||
if (! file.exists()) return
|
if (content == null || content.isEmpty()) {
|
||||||
|
return
|
||||||
val newFileName = buildString {
|
}
|
||||||
append(AppUtils.getAppVersionCode())
|
if (GlobalData.driverInfoBean == null || GlobalData.driverInfoBean?.vehicleName.isNullOrBlank()) {
|
||||||
append("_")
|
Log.e(tag, content)
|
||||||
append(GlobalData.driverInfoBean?.vehicleName ?: "unknown")
|
return
|
||||||
append("_")
|
|
||||||
append(GlobalData.driverInfoBean?.userName ?: "unknown")
|
|
||||||
append("_")
|
|
||||||
append(TimeUtils.getNowString())
|
|
||||||
append(".txt")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val newFile = File("$normalLogDirPath${File.separator}$newFileName")
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (file.renameTo(newFile)) {
|
if (System.currentTimeMillis() - GlobalData.lastUploadLogTime > uploadTimeInterval) {
|
||||||
compressAndUploadLog(newFile) // 创建新的日志文件
|
updateNormalLog()
|
||||||
file.createNewFile()
|
|
||||||
addLogHead(file, getCurrentTime())
|
|
||||||
} else {
|
|
||||||
print("LogUtil", "Failed to rename log file")
|
|
||||||
}
|
}
|
||||||
|
LogUtils.getConfig().setFilePrefix(this.vehicleName)
|
||||||
|
LogUtils.e("$tag---$content")
|
||||||
} catch (e : Exception) {
|
} catch (e : Exception) {
|
||||||
print("LogUtil", "Error during log rotation: ${e.message}")
|
e.printStackTrace()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun compressAndUploadLog(logFile : File) = coroutineScope.launch {
|
private val vehicleName : String
|
||||||
try {
|
get() {
|
||||||
val compressedFile = File("${logFile.absolutePath}.7z")
|
var name : String? = "未知"
|
||||||
compress(logFile, compressedFile.absolutePath)
|
if (! GlobalData.driverInfoBean?.vehicleName.isNullOrBlank()) {
|
||||||
upload(logFile, compressedFile)
|
try {
|
||||||
} catch (e : Exception) {
|
name = buildString {
|
||||||
print("LogUtil", e.toString())
|
append(GlobalData.driverInfoBean?.vehicleName?.replace("/", "")
|
||||||
|
?.replace(" ", ""))
|
||||||
|
append("_")
|
||||||
|
append(GlobalData.driverInfoBean?.userName ?: "未知")
|
||||||
|
}
|
||||||
|
} catch (e : Exception) {
|
||||||
|
e.printStackTrace()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return name ?: "未知"
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private fun deleteLog(file : File) {
|
private fun deleteLog(file : File) {
|
||||||
try {
|
try {
|
||||||
FileUtils.delete(file.absolutePath)
|
file.delete()
|
||||||
} catch (e : Exception) {
|
} catch (e : Exception) {
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun updateNormalLog() {
|
fun updateNormalLog() {
|
||||||
thread {
|
GlobalData.lastUploadLogTime = System.currentTimeMillis()
|
||||||
if (GlobalData.token.isNullOrBlank()) {
|
val files = File(normalLogDirPath).listFiles()
|
||||||
return@thread
|
if (files.isNullOrEmpty()) {
|
||||||
}
|
return
|
||||||
val fileName = "normal_log.txt"
|
}
|
||||||
val file = File("$normalLogDirPath${File.separator}$fileName")
|
for (file in files) {
|
||||||
val reName =
|
try {
|
||||||
"${AppUtils.getAppVersionCode()}_${GlobalData.driverInfoBean?.vehicleName}_${GlobalData.driverInfoBean?.userName}_${TimeUtils.getNowString()}.txt"
|
if (file.isDirectory()) {
|
||||||
val reNamePath = "$normalLogDirPath${File.separator}$reName"
|
file.delete()
|
||||||
file.renameTo(File(reNamePath))
|
FileUtils.deleteAllInDir(file)
|
||||||
normalLogDirPath?.let { it ->
|
} else if (file.getName().endsWith("7z")) {
|
||||||
File(it).listFiles()?.forEach {
|
uploadFile(null, File(file.absolutePath))
|
||||||
if (it.length() / MemoryConstants.MB >= 10) {
|
} else {
|
||||||
deleteLog(it)
|
executors?.submit {
|
||||||
return@thread
|
val vehicleName = vehicleName
|
||||||
}
|
val zipNamePath =
|
||||||
if (it.exists() && ! it.name.contains("normal_log")) {
|
normalLogDirPath + File.separator + AppUtils.getAppVersionCode() + "_" + vehicleName + "_" + this.currentTime + ".txt.7z"
|
||||||
if (it.name.contains("7z")) {
|
val zipFile = File(zipNamePath)
|
||||||
upload(null, desFile = it)
|
if (! zipFile.exists()) {
|
||||||
} else {
|
try {
|
||||||
val zipNamePath = it.absolutePath + ".7z"
|
zipFile.createNewFile()
|
||||||
val zipFile = File(zipNamePath)
|
compress(file, zipNamePath)
|
||||||
if (! zipFile.exists()) {
|
} catch (e : IOException) {
|
||||||
try {
|
e.printStackTrace()
|
||||||
zipFile.createNewFile()
|
|
||||||
} catch (e : IOException) {
|
|
||||||
e.printStackTrace()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
compress(it, zipNamePath)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} catch (e : Exception) {
|
||||||
|
e.printStackTrace()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun compress(srcFile : File, desFilePath : String) {
|
private fun compress(srcFile : File, desFilePath : String) {
|
||||||
try {
|
try {
|
||||||
val out = XZCompressorOutputStream(FileOutputStream(desFilePath))
|
val out = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
|
XZCompressorOutputStream(Files.newOutputStream(Paths.get(desFilePath)))
|
||||||
|
} else {
|
||||||
|
XZCompressorOutputStream(FileOutputStream(desFilePath))
|
||||||
|
}
|
||||||
addToArchiveCompression(out, srcFile, File(desFilePath))
|
addToArchiveCompression(out, srcFile, File(desFilePath))
|
||||||
} catch (e : Exception) {
|
} catch (e : Exception) {
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun uploadFile(srcFile : File?, desFile : File) {
|
||||||
|
val requestBody : RequestBody = desFile.asRequestBody("multipart/form-data".toMediaType())
|
||||||
|
val part = MultipartBody.Part.createFormData("file", desFile.name, requestBody)
|
||||||
|
|
||||||
|
val disposable =
|
||||||
|
LogRetrofitHelper.getDefaultService().uploadLog(part, desFile.name, "rescue-app")
|
||||||
|
.subscribeOn(Schedulers.io()).subscribe({ it ->
|
||||||
|
if (it.code == 200) {
|
||||||
|
deleteLog(desFile);
|
||||||
|
}
|
||||||
|
if (srcFile != null) {
|
||||||
|
deleteLog(srcFile);
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
if (srcFile != null) {
|
||||||
|
deleteLog(srcFile);
|
||||||
|
}
|
||||||
|
}, {})
|
||||||
|
}
|
||||||
|
|
||||||
private fun addToArchiveCompression(sevenZOutputFile : XZCompressorOutputStream,
|
private fun addToArchiveCompression(sevenZOutputFile : XZCompressorOutputStream,
|
||||||
srcFile : File,
|
srcFile : File,
|
||||||
desFile : File) {
|
desFile : File) {
|
||||||
if (srcFile.isFile) {
|
if (srcFile.isFile()) {
|
||||||
var inputStream : FileInputStream? = null
|
var inputStream : FileInputStream? = null
|
||||||
try {
|
try {
|
||||||
inputStream = FileInputStream(srcFile)
|
inputStream = FileInputStream(srcFile)
|
||||||
val b = ByteArray(2048)
|
val b = ByteArray(2048)
|
||||||
var count : Int
|
var count : Int
|
||||||
while (inputStream.read(b).also { count = it } != - 1) {
|
while ((inputStream.read(b).also { count = it }) != - 1) {
|
||||||
sevenZOutputFile.write(b, 0, count)
|
sevenZOutputFile.write(b, 0, count)
|
||||||
}
|
}
|
||||||
sevenZOutputFile.close()
|
sevenZOutputFile.close()
|
||||||
inputStream.close()
|
inputStream.close()
|
||||||
upload(srcFile, desFile)
|
uploadFile(srcFile, desFile)
|
||||||
} catch (e : Exception) {
|
} catch (e : Exception) {
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
} finally {
|
} finally {
|
||||||
@ -263,42 +240,8 @@ object LogUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun upload(srcFile : File?, desFile : File) {
|
private val currentTime : String?
|
||||||
val requestBody : RequestBody = desFile.asRequestBody("multipart/form-data".toMediaType())
|
get() = TimeUtils.millis2String(System.currentTimeMillis(), "yyyy_MM_dd HH:mm:ss:SS")
|
||||||
val part = MultipartBody.Part.createFormData("file", desFile.name, requestBody)
|
|
||||||
|
|
||||||
val disposable =
|
|
||||||
LogRetrofitHelper.getDefaultService().uploadLog(part, desFile.name, "rescue-app")
|
|
||||||
.subscribeOn(Schedulers.io()).subscribe({ it ->
|
|
||||||
if (it.code == 200) {
|
|
||||||
deleteLog(desFile)
|
|
||||||
}
|
|
||||||
srcFile?.let {
|
|
||||||
deleteLog(it)
|
|
||||||
}
|
|
||||||
}, {}, {})
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun addLogHead(file : File, time : String) {
|
|
||||||
file.appendBytes("${time}---应用版本---${AppUtils.getAppVersionName()}".toByteArray())
|
|
||||||
file.appendBytes("\n".toByteArray())
|
|
||||||
file.appendBytes("$time---系统版本---Android${DeviceUtils.getSDKVersionName()} ${DeviceUtils.getSDKVersionCode()}".toByteArray())
|
|
||||||
file.appendBytes("\n".toByteArray())
|
|
||||||
file.appendBytes("$time---ROM---${DeviceUtils.getManufacturer()} ${DeviceUtils.getModel()}".toByteArray())
|
|
||||||
file.appendBytes("\n".toByteArray())
|
|
||||||
file.appendBytes("$time---build---${AppUtils.getAppVersionCode()}".toByteArray())
|
|
||||||
file.appendBytes("\n".toByteArray())
|
|
||||||
file.appendBytes("$time---APP名称---中道救援-司机端".toByteArray())
|
|
||||||
file.appendBytes("\n".toByteArray())
|
|
||||||
file.appendBytes("$time---车辆名称---${GlobalData.driverInfoBean?.vehicleName}".toByteArray())
|
|
||||||
file.appendBytes("\n".toByteArray())
|
|
||||||
file.appendBytes("$time---司机名称---${GlobalData.driverInfoBean?.userName ?: GlobalData.driverInfoBean?.userName}".toByteArray())
|
|
||||||
file.appendBytes("\n".toByteArray())
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getCurrentTime() : String {
|
|
||||||
return TimeUtils.millis2String(System.currentTimeMillis(), "yyyy/MM/dd HH:mm:ss.SSS")
|
|
||||||
}
|
|
||||||
|
|
||||||
class LogTask(appContext : Context, workerParams : WorkerParameters) :
|
class LogTask(appContext : Context, workerParams : WorkerParameters) :
|
||||||
Worker(appContext, workerParams) {
|
Worker(appContext, workerParams) {
|
||||||
@ -307,4 +250,11 @@ object LogUtil {
|
|||||||
return Result.success()
|
return Result.success()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -5,7 +5,6 @@ import android.media.AudioAttributes
|
|||||||
import android.media.AudioManager
|
import android.media.AudioManager
|
||||||
import android.media.MediaPlayer
|
import android.media.MediaPlayer
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import com.za.base.AppConfig
|
|
||||||
import com.za.bean.request.AppNewOrderVoiceRequest
|
import com.za.bean.request.AppNewOrderVoiceRequest
|
||||||
import com.za.common.GlobalData
|
import com.za.common.GlobalData
|
||||||
import com.za.common.log.LogUtil
|
import com.za.common.log.LogUtil
|
||||||
@ -61,18 +60,21 @@ object SpeechManager {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private var originVolume = 0
|
private var defaultVolume = 10
|
||||||
|
private var originVolume = defaultVolume
|
||||||
|
private var audioManager : AudioManager? = null
|
||||||
private fun setMaxAudioVolume() {
|
private fun setMaxAudioVolume() {
|
||||||
try {
|
try {
|
||||||
if (! AppConfig.isRelease) {
|
audioManager =
|
||||||
|
ContextCompat.getSystemService(GlobalData.application, AudioManager::class.java)
|
||||||
|
|
||||||
|
if (audioManager == null) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
val audioManager =
|
originVolume = audioManager?.getStreamVolume(AudioManager.STREAM_MUSIC) ?: defaultVolume
|
||||||
ContextCompat.getSystemService(GlobalData.application, AudioManager::class.java)
|
|
||||||
originVolume = audioManager?.getStreamVolume(AudioManager.STREAM_MUSIC) ?: 0
|
|
||||||
val maxVolume = audioManager?.getStreamMaxVolume(AudioManager.STREAM_MUSIC)
|
val maxVolume = audioManager?.getStreamMaxVolume(AudioManager.STREAM_MUSIC)
|
||||||
audioManager?.setStreamVolume(AudioManager.STREAM_MUSIC,
|
audioManager?.setStreamVolume(AudioManager.STREAM_MUSIC,
|
||||||
maxVolume ?: 1,
|
maxVolume ?: defaultVolume,
|
||||||
AudioManager.FLAG_PLAY_SOUND)
|
AudioManager.FLAG_PLAY_SOUND)
|
||||||
} catch (e : Exception) {
|
} catch (e : Exception) {
|
||||||
LogUtil.print("setMaxAudioVolume", e)
|
LogUtil.print("setMaxAudioVolume", e)
|
||||||
@ -80,15 +82,12 @@ object SpeechManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun resetAudioVolume() {
|
private fun resetAudioVolume() {
|
||||||
try {
|
try { // val audioManager =
|
||||||
if (! AppConfig.isRelease) {
|
// ContextCompat.getSystemService(GlobalData.application, AudioManager::class.java)
|
||||||
return
|
// audioManager?.setStreamVolume(AudioManager.STREAM_MUSIC,
|
||||||
}
|
// originVolume,
|
||||||
val audioManager =
|
// AudioManager.FLAG_PLAY_SOUND)
|
||||||
ContextCompat.getSystemService(GlobalData.application, AudioManager::class.java)
|
LogUtil.print("resetAudioVolume", "resetAudioVolume")
|
||||||
audioManager?.setStreamVolume(AudioManager.STREAM_MUSIC,
|
|
||||||
originVolume,
|
|
||||||
AudioManager.FLAG_PLAY_SOUND)
|
|
||||||
} catch (e : Exception) {
|
} catch (e : Exception) {
|
||||||
LogUtil.print("resetAudioVolume", e)
|
LogUtil.print("resetAudioVolume", e)
|
||||||
}
|
}
|
||||||
@ -153,9 +152,7 @@ object SpeechManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 设置最大音量
|
// 设置最大音量
|
||||||
setMaxAudioVolume()
|
setMaxAudioVolume() // 开始播放
|
||||||
|
|
||||||
// 开始播放
|
|
||||||
mediaPlayer?.start()
|
mediaPlayer?.start()
|
||||||
} catch (e : Exception) {
|
} catch (e : Exception) {
|
||||||
LogUtil.print("playNewOrder", "播放出错: ${e.message}")
|
LogUtil.print("playNewOrder", "播放出错: ${e.message}")
|
||||||
@ -174,7 +171,7 @@ object SpeechManager {
|
|||||||
|
|
||||||
mediaPlayer?.setDataSource(url)
|
mediaPlayer?.setDataSource(url)
|
||||||
mediaPlayer?.setOnPreparedListener { // 设置最大音量
|
mediaPlayer?.setOnPreparedListener { // 设置最大音量
|
||||||
setMaxAudioVolume() // 准备完成后开始播放
|
// 准备完成后开始播放
|
||||||
it.start()
|
it.start()
|
||||||
}
|
}
|
||||||
mediaPlayer?.setOnCompletionListener { // 播放完成后释放资源
|
mediaPlayer?.setOnCompletionListener { // 播放完成后释放资源
|
||||||
@ -185,8 +182,7 @@ object SpeechManager {
|
|||||||
releaseMediaPlayer()
|
releaseMediaPlayer()
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
setMaxAudioVolume() // 异步准备,避免阻塞UI线程
|
||||||
// 异步准备,避免阻塞UI线程
|
|
||||||
mediaPlayer?.prepareAsync()
|
mediaPlayer?.prepareAsync()
|
||||||
} catch (e : Exception) {
|
} catch (e : Exception) {
|
||||||
LogUtil.print("playNewOrderFromNet", "播放出错: ${e.message}")
|
LogUtil.print("playNewOrderFromNet", "播放出错: ${e.message}")
|
||||||
|
@ -2,80 +2,89 @@ package com.za.common.speech
|
|||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.media.AudioManager
|
||||||
|
import android.os.Bundle
|
||||||
import android.speech.tts.TextToSpeech
|
import android.speech.tts.TextToSpeech
|
||||||
|
import android.speech.tts.TextToSpeech.Engine.KEY_PARAM_VOLUME
|
||||||
import android.speech.tts.UtteranceProgressListener
|
import android.speech.tts.UtteranceProgressListener
|
||||||
import com.za.common.log.LogUtil
|
import com.za.common.log.LogUtil
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
|
|
||||||
|
|
||||||
@SuppressLint("StaticFieldLeak")
|
@SuppressLint("StaticFieldLeak")
|
||||||
object TTSManager {
|
object TTSManager {
|
||||||
private var tts: TextToSpeech? = null
|
private var tts : TextToSpeech? = null
|
||||||
private var context: Context? = null
|
private var context : Context? = null
|
||||||
private var listener: OnTTSListener? = null
|
private var listener : OnTTSListener? = null
|
||||||
|
|
||||||
|
|
||||||
fun init(context: Context?, onTTSListener: OnTTSListener) {
|
fun init(context : Context?, onTTSListener : OnTTSListener) {
|
||||||
this.context = context
|
this.context = context
|
||||||
this.listener = onTTSListener
|
this.listener = onTTSListener
|
||||||
initTTS()
|
initTTS()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun initTTS() {
|
private fun initTTS() {
|
||||||
tts = TextToSpeech(context) { status ->
|
tts = TextToSpeech(context) { status ->
|
||||||
if (status == TextToSpeech.SUCCESS) {
|
if (status == TextToSpeech.SUCCESS) {
|
||||||
val result = tts?.setLanguage(Locale.getDefault())
|
val result = tts?.setLanguage(Locale.getDefault())
|
||||||
if (result == TextToSpeech.LANG_MISSING_DATA || result == TextToSpeech.LANG_NOT_SUPPORTED) {
|
if (result == TextToSpeech.LANG_MISSING_DATA || result == TextToSpeech.LANG_NOT_SUPPORTED) {
|
||||||
LogUtil.print("TTS", "Language not supported")
|
LogUtil.print("TTS", "Language not supported")
|
||||||
listener?.onTTSFailed("Language not supported")
|
listener?.onTTSFailed("Language not supported")
|
||||||
} else {
|
} else {
|
||||||
LogUtil.print("TTS", "TTS initialized successfully")
|
LogUtil.print("TTS", "TTS initialized successfully")
|
||||||
listener?.onTTSInitialized()
|
listener?.onTTSInitialized()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
LogUtil.print("TTS", "Initialization failed")
|
LogUtil.print("TTS", "Initialization failed")
|
||||||
listener?.onTTSFailed("Initialization failed")
|
listener?.onTTSFailed("Initialization failed")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tts?.setOnUtteranceProgressListener(object : UtteranceProgressListener() {
|
tts?.setOnUtteranceProgressListener(object : UtteranceProgressListener() {
|
||||||
override fun onStart(utteranceId: String) {
|
override fun onStart(utteranceId : String) {
|
||||||
LogUtil.print("TTS", "Speech started")
|
LogUtil.print("TTS", "Speech started")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDone(utteranceId: String) {
|
override fun onDone(utteranceId : String) {
|
||||||
LogUtil.print("TTS", "Speech completed")
|
LogUtil.print("TTS", "Speech completed")
|
||||||
listener?.onTTSSuccess()
|
listener?.onTTSSuccess()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onError(utteranceId: String) {
|
override fun onError(utteranceId : String) {
|
||||||
LogUtil.print("TTS", "Speech error")
|
LogUtil.print("TTS", "Speech error")
|
||||||
listener?.onTTSFailed("Speech error")
|
listener?.onTTSFailed("Speech error")
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fun speak(text: String?) {
|
fun speak(text : String?) {
|
||||||
if (tts != null && tts?.isSpeaking == false) {
|
if (tts != null && tts?.isSpeaking == false) { //设置最大音量
|
||||||
tts?.speak(text, TextToSpeech.QUEUE_FLUSH, null, "uniqueId")
|
val am = context?.getSystemService(Context.AUDIO_SERVICE) as AudioManager
|
||||||
}
|
val sb2value = am.getStreamMaxVolume(AudioManager.STREAM_MUSIC)
|
||||||
}
|
am.setStreamVolume(AudioManager.STREAM_MUSIC, sb2value, 0)
|
||||||
|
val bundle = Bundle()
|
||||||
|
bundle.putFloat(KEY_PARAM_VOLUME, 1.0f)
|
||||||
|
tts?.speak(text, TextToSpeech.QUEUE_FLUSH, bundle, "uniqueId")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun stop() {
|
fun stop() {
|
||||||
tts?.takeIf { it.isSpeaking }?.stop()
|
tts?.takeIf { it.isSpeaking }?.stop()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun shutdown() {
|
fun shutdown() {
|
||||||
tts?.apply {
|
tts?.apply {
|
||||||
stop()
|
stop()
|
||||||
shutdown()
|
shutdown()
|
||||||
}
|
}
|
||||||
tts = null
|
tts = null
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface OnTTSListener {
|
interface OnTTSListener {
|
||||||
fun onTTSInitialized()
|
fun onTTSInitialized()
|
||||||
fun onTTSSuccess()
|
fun onTTSSuccess()
|
||||||
fun onTTSFailed(errorMessage: String?)
|
fun onTTSFailed(errorMessage : String?)
|
||||||
}
|
}
|
@ -22,9 +22,11 @@ import com.za.bean.ReportHistoryBean
|
|||||||
import com.za.bean.ReportHistoryRequest
|
import com.za.bean.ReportHistoryRequest
|
||||||
import com.za.bean.ReportInfoRequest
|
import com.za.bean.ReportInfoRequest
|
||||||
import com.za.bean.ReportItem
|
import com.za.bean.ReportItem
|
||||||
|
import com.za.bean.SaveSignatureRequest
|
||||||
import com.za.bean.SettleInfoRequest
|
import com.za.bean.SettleInfoRequest
|
||||||
import com.za.bean.TaskNotesBean
|
import com.za.bean.TaskNotesBean
|
||||||
import com.za.bean.TaskSettlementAndTraceBean
|
import com.za.bean.TaskSettlementAndTraceBean
|
||||||
|
import com.za.bean.UnifiedOCRWithCompressRequest
|
||||||
import com.za.bean.UpdateVersionBean
|
import com.za.bean.UpdateVersionBean
|
||||||
import com.za.bean.UpdateVersionRequest
|
import com.za.bean.UpdateVersionRequest
|
||||||
import com.za.bean.UploadChangeBatteryRequest
|
import com.za.bean.UploadChangeBatteryRequest
|
||||||
@ -289,4 +291,12 @@ interface ApiService {
|
|||||||
|
|
||||||
@POST("driverApp/task/getTaskNotes")
|
@POST("driverApp/task/getTaskNotes")
|
||||||
fun getTaskNotes(@Body request : TaskNotesRequest) : Observable<BaseResponse<TaskNotesBean>>
|
fun getTaskNotes(@Body request : TaskNotesRequest) : Observable<BaseResponse<TaskNotesBean>>
|
||||||
|
|
||||||
|
@POST("driverApp/supplier/unifiedOCRWithCompress")
|
||||||
|
fun unifiedOCRWithCompress(@Body request : UnifiedOCRWithCompressRequest) : Observable<BaseResponse<String>>
|
||||||
|
|
||||||
|
@POST("driverApp/v2/user/saveSignature")
|
||||||
|
fun saveSignature(@Body request : SaveSignatureRequest) : Observable<BaseResponse<String>>
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@ import com.za.base.view.warnBean
|
|||||||
import com.za.bean.BaseResponse
|
import com.za.bean.BaseResponse
|
||||||
import com.za.common.GlobalData
|
import com.za.common.GlobalData
|
||||||
import com.za.common.log.LogUtil
|
import com.za.common.log.LogUtil
|
||||||
|
import com.za.offline.OfflineService
|
||||||
import com.za.service.location.ZdLocationManager
|
import com.za.service.location.ZdLocationManager
|
||||||
import io.reactivex.rxjava3.core.Observer
|
import io.reactivex.rxjava3.core.Observer
|
||||||
import io.reactivex.rxjava3.disposables.Disposable
|
import io.reactivex.rxjava3.disposables.Disposable
|
||||||
@ -128,6 +129,7 @@ abstract class BaseObserver<T> : Observer<BaseResponse<T>> {
|
|||||||
ToastUtils.showShort("登陆信息已过期,请重新登录")
|
ToastUtils.showShort("登陆信息已过期,请重新登录")
|
||||||
ZdLocationManager.stopContinuousLocation()
|
ZdLocationManager.stopContinuousLocation()
|
||||||
GlobalData.clearUserCache()
|
GlobalData.clearUserCache()
|
||||||
|
OfflineService.stop()
|
||||||
ActivityUtils.startLauncherActivity()
|
ActivityUtils.startLauncherActivity()
|
||||||
} catch (e : Exception) {
|
} catch (e : Exception) {
|
||||||
LogUtil.print("handlerTokenExpired", e)
|
LogUtil.print("handlerTokenExpired", e)
|
||||||
|
@ -113,16 +113,15 @@ object CommonMethod {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private var lastFetchGenerateInfoTime : Long = 0L
|
private var lastFetchGenerateInfoTime : Long = 0L
|
||||||
fun getGenerateInfo(vehicleId : Int? = null,
|
fun getGenerateInfo(success : (DriverInfoBean) -> Unit = {}, failed : (String?) -> Unit = {}) {
|
||||||
userId : Int? = null,
|
|
||||||
success : (DriverInfoBean) -> Unit = {},
|
|
||||||
failed : (String?) -> Unit = {}) {
|
|
||||||
val generalInfoRequest =
|
val generalInfoRequest =
|
||||||
GeneralInfoRequest(vehicleId = vehicleId ?: GlobalData.driverInfoBean?.vehicleId,
|
GeneralInfoRequest(vehicleId = GlobalData.vehicleId.takeIf { it != null && it != 0 }
|
||||||
driverId = userId ?: GlobalData.driverInfoBean?.userId,
|
?: GlobalData.driverInfoBean?.vehicleId,
|
||||||
deviceId = DeviceUtil.getAndroidId(ActivityUtils.getTopActivity()))
|
driverId = GlobalData.driverId.takeIf { it != null && it != 0 }
|
||||||
|
?: GlobalData.driverInfoBean?.userId,
|
||||||
|
deviceId = GlobalData.deviceId
|
||||||
|
?: DeviceUtil.getAndroidId(ActivityUtils.getTopActivity()))
|
||||||
|
|
||||||
LogUtil.print("getGenerateInfo", "request=${generalInfoRequest.toJson()}")
|
LogUtil.print("getGenerateInfo", "request=${generalInfoRequest.toJson()}")
|
||||||
RetrofitHelper.getDefaultService().generalInfo(generalInfoRequest)
|
RetrofitHelper.getDefaultService().generalInfo(generalInfoRequest)
|
||||||
@ -130,21 +129,39 @@ object CommonMethod {
|
|||||||
.subscribe(object : BaseObserver<DriverInfoBean>() {
|
.subscribe(object : BaseObserver<DriverInfoBean>() {
|
||||||
override fun doSuccess(it : DriverInfoBean?) {
|
override fun doSuccess(it : DriverInfoBean?) {
|
||||||
if (it == null) {
|
if (it == null) {
|
||||||
failed("获取车辆信息失败")
|
if (GlobalData.driverInfoBean != null) {
|
||||||
|
success(GlobalData.driverInfoBean !!)
|
||||||
|
} else {
|
||||||
|
failed("获取车辆信息失败")
|
||||||
|
}
|
||||||
|
|
||||||
LogUtil.print("getGenerateInfo", "获取车辆信息失败")
|
LogUtil.print("getGenerateInfo", "获取车辆信息失败")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (GlobalData.driverId == null || GlobalData.driverId == 0) {
|
||||||
|
GlobalData.driverId = it.userId
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GlobalData.vehicleId == null || GlobalData.vehicleId == 0) {
|
||||||
|
GlobalData.vehicleId = it.vehicleId
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GlobalData.deviceId.isNullOrBlank()) {
|
||||||
|
GlobalData.deviceId = it.deviceId
|
||||||
|
}
|
||||||
|
|
||||||
if (GlobalData.driverInfoBean != null && (System.currentTimeMillis() - lastFetchGenerateInfoTime < 1000 * 10)) {
|
if (GlobalData.driverInfoBean != null && (System.currentTimeMillis() - lastFetchGenerateInfoTime < 1000 * 10)) {
|
||||||
LogUtil.print("getGenerateInfo",
|
|
||||||
"获取车辆信息成功,但是时间间隔小于10秒,不更新车辆信息")
|
|
||||||
success(it)
|
success(it)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
GlobalData.driverInfoBean = it
|
|
||||||
lastFetchGenerateInfoTime = System.currentTimeMillis()
|
|
||||||
LogUtil.print("GlobalData.driverInfoBean",
|
|
||||||
"${GlobalData.driverInfoBean?.toJson()}}")
|
|
||||||
|
|
||||||
|
GlobalData.driverInfoBean = it
|
||||||
|
|
||||||
|
|
||||||
|
lastFetchGenerateInfoTime = System.currentTimeMillis()
|
||||||
|
LogUtil.print("GlobalData.driverInfoBean", "${it.toJson()}}")
|
||||||
success(it)
|
success(it)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -197,7 +214,7 @@ object CommonMethod {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun doFailure(code : Int, msg : String?) {
|
override fun doFailure(code : Int, msg : String?) {
|
||||||
|
LogUtil.print("getNewOrder", "doFailure=$msg")
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -233,92 +250,45 @@ object CommonMethod {
|
|||||||
?.getOfflineTaskFromTaskId(inServicingOrder.taskId ?: 0).isNullOrEmpty()
|
?.getOfflineTaskFromTaskId(inServicingOrder.taskId ?: 0).isNullOrEmpty()
|
||||||
) {
|
) {
|
||||||
LogUtil.print("queryOrderList", "走离线任务逻辑")
|
LogUtil.print("queryOrderList", "走离线任务逻辑")
|
||||||
inServicingOrder = inServicingOrder.copy(taskState = RoomHelper.db?.orderDao()
|
val offlineTaskState =
|
||||||
?.getCurrentOrder()?.taskState)
|
RoomHelper.db?.orderDao()?.getCurrentOrder()?.taskState
|
||||||
|
?: inServicingOrder.taskState
|
||||||
if (GlobalData.currentOrder?.serviceTypeName != inServicingOrder.serviceTypeName) {
|
inServicingOrder = inServicingOrder.copy(taskState = offlineTaskState)
|
||||||
LogUtil.print("queryOrderList", "订单类型发生变化")
|
|
||||||
RoomHelper.db?.photoTemplateDao()
|
|
||||||
?.deleteOrderPhotoTemplateFromTaskId(taskId = inServicingOrder.taskId
|
|
||||||
?: 0)
|
|
||||||
fetchPhotoTemplate(orderInfo = inServicingOrder,
|
|
||||||
isNeedUpload = true,
|
|
||||||
success = {
|
|
||||||
GlobalData.currentOrder = inServicingOrder
|
|
||||||
|
|
||||||
OfflineManager.start(GlobalData.currentOrder?.taskId)
|
|
||||||
|
|
||||||
context?.let {
|
|
||||||
ReportFloatingManager.startService(it)
|
|
||||||
}
|
|
||||||
success(inServicingOrder, waitServiceOrders)
|
|
||||||
},
|
|
||||||
failed = {
|
|
||||||
GlobalData.currentOrder = inServicingOrder
|
|
||||||
|
|
||||||
OfflineManager.start(GlobalData.currentOrder?.taskId)
|
|
||||||
|
|
||||||
context?.let {
|
|
||||||
ReportFloatingManager.startService(it)
|
|
||||||
}
|
|
||||||
success(inServicingOrder, waitServiceOrders)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GlobalData.currentOrder?.serviceTypeName != inServicingOrder.serviceTypeName) {
|
|
||||||
LogUtil.print("queryOrderList", "订单类型发生变化")
|
|
||||||
RoomHelper.db?.photoTemplateDao()
|
|
||||||
?.deleteOrderPhotoTemplateFromTaskId(taskId = inServicingOrder.taskId
|
|
||||||
?: 0)
|
|
||||||
fetchPhotoTemplate(orderInfo = inServicingOrder,
|
|
||||||
isNeedUpload = true,
|
|
||||||
success = {
|
|
||||||
GlobalData.currentOrder = inServicingOrder
|
|
||||||
|
|
||||||
OfflineManager.start(GlobalData.currentOrder?.taskId)
|
|
||||||
|
|
||||||
context?.let {
|
|
||||||
ReportFloatingManager.startService(it)
|
|
||||||
}
|
|
||||||
success(inServicingOrder, waitServiceOrders)
|
|
||||||
},
|
|
||||||
failed = {
|
|
||||||
GlobalData.currentOrder = inServicingOrder
|
|
||||||
|
|
||||||
OfflineManager.start(GlobalData.currentOrder?.taskId)
|
|
||||||
|
|
||||||
context?.let {
|
|
||||||
ReportFloatingManager.startService(it)
|
|
||||||
}
|
|
||||||
success(inServicingOrder, waitServiceOrders)
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GlobalData.currentOrder = inServicingOrder
|
GlobalData.currentOrder = inServicingOrder
|
||||||
|
success(inServicingOrder, waitServiceOrders)
|
||||||
|
|
||||||
|
|
||||||
|
val listData = RoomHelper.db?.photoTemplateDao()
|
||||||
|
?.queryCurrentOrderHasTaskNode(inServicingOrder.userOrderId ?: 0)
|
||||||
|
LogUtil.print("queryOrderList", "listData=${listData.toJson()}")
|
||||||
|
if (listData.isNullOrEmpty() || (! listData[0].serviceTypeName.isNullOrBlank() && listData[0].serviceTypeName != inServicingOrder.serviceTypeName)) {
|
||||||
|
RoomHelper.db?.photoTemplateDao()
|
||||||
|
?.deleteOrderPhotoTemplateFromTaskId(taskId = inServicingOrder.taskId
|
||||||
|
?: 0)
|
||||||
|
fetchPhotoTemplate(orderInfo = inServicingOrder)
|
||||||
|
LogUtil.print("queryOrderList", "照片模版为空,重新获取照片模版")
|
||||||
|
}
|
||||||
|
|
||||||
it.forEach {
|
it.forEach {
|
||||||
if (RoomHelper.db?.orderDao()
|
val task = RoomHelper.db?.orderDao()?.getOrderInfoFromTaskId(it.taskId ?: 0)
|
||||||
?.getOrderInfoFromTaskId(it.taskId ?: 0) != null
|
if (task != null) {
|
||||||
) {
|
RoomHelper.db?.orderDao()
|
||||||
RoomHelper.db?.orderDao()?.update(orderInfo = it)
|
?.update(orderInfo = it.copy(taskState = task.taskState))
|
||||||
} else {
|
} else {
|
||||||
RoomHelper.db?.orderDao()?.insertOrder(orderInfo = it)
|
RoomHelper.db?.orderDao()?.insertOrder(orderInfo = it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fetchPhotoTemplate(inServicingOrder)
|
|
||||||
queryElectronOrder(orderInfo = inServicingOrder)
|
queryElectronOrder(orderInfo = inServicingOrder)
|
||||||
WaterMarkerTemplateManager.fetchWaterTemplate(inServicingOrder.taskCode ?: "",
|
WaterMarkerTemplateManager.fetchWaterTemplate(inServicingOrder.taskCode ?: "",
|
||||||
taskId = inServicingOrder.taskId ?: 0,
|
taskId = inServicingOrder.taskId ?: 0,
|
||||||
inServicingOrder.userOrderId ?: 0)
|
inServicingOrder.userOrderId ?: 0)
|
||||||
OfflineManager.start(GlobalData.currentOrder?.taskId)
|
OfflineManager.start(GlobalData.currentOrder?.taskId)
|
||||||
|
|
||||||
context?.let {
|
context?.let {
|
||||||
ReportFloatingManager.startService(it)
|
ReportFloatingManager.startService(it)
|
||||||
}
|
}
|
||||||
|
|
||||||
success(inServicingOrder, waitServiceOrders)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun doFailure(code : Int, msg : String?) {
|
override fun doFailure(code : Int, msg : String?) {
|
||||||
@ -334,7 +304,6 @@ object CommonMethod {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun fetchPhotoTemplate(orderInfo : OrderInfo?,
|
fun fetchPhotoTemplate(orderInfo : OrderInfo?,
|
||||||
isNeedUpload : Boolean? = false,
|
|
||||||
success : () -> Unit = {},
|
success : () -> Unit = {},
|
||||||
failed : (String?) -> Unit = {}) {
|
failed : (String?) -> Unit = {}) {
|
||||||
val photoTemplateRequest = PhotoTemplateRequest(orderInfo?.userOrderId)
|
val photoTemplateRequest = PhotoTemplateRequest(orderInfo?.userOrderId)
|
||||||
@ -343,13 +312,6 @@ object CommonMethod {
|
|||||||
.subscribe(object : BaseObserver<List<PhotoTemplateInfo>>() {
|
.subscribe(object : BaseObserver<List<PhotoTemplateInfo>>() {
|
||||||
override fun doSuccess(it : List<PhotoTemplateInfo>?) {
|
override fun doSuccess(it : List<PhotoTemplateInfo>?) {
|
||||||
if (it.isNullOrEmpty()) {
|
if (it.isNullOrEmpty()) {
|
||||||
LogUtil.print("fetchPhotoTemplate",
|
|
||||||
"模板为null ${photoTemplateRequest.toJson()}")
|
|
||||||
failed("未找到模版")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isNeedUpload == false) {
|
|
||||||
val listData = RoomHelper.db?.photoTemplateDao()
|
val listData = RoomHelper.db?.photoTemplateDao()
|
||||||
?.queryCurrentOrderHasTaskNode(orderInfo?.userOrderId ?: 0)
|
?.queryCurrentOrderHasTaskNode(orderInfo?.userOrderId ?: 0)
|
||||||
if (! listData.isNullOrEmpty()) {
|
if (! listData.isNullOrEmpty()) {
|
||||||
@ -358,6 +320,31 @@ object CommonMethod {
|
|||||||
success()
|
success()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val list = LocalPhotoTemplateControl.buildPhotoTemplate(orderInfo)
|
||||||
|
list.forEachIndexed { _, item ->
|
||||||
|
val photoTemplateInfo = item.copy(userOrderId = orderInfo?.userOrderId,
|
||||||
|
taskCode = orderInfo?.taskCode,
|
||||||
|
myCustomPhotoType = Const.PhotoType.InServicing,
|
||||||
|
advanceTime = orderInfo?.advanceTime,
|
||||||
|
taskId = orderInfo?.taskId,
|
||||||
|
serviceTypeName = orderInfo?.serviceTypeName,
|
||||||
|
needWaterMarker = orderInfo?.needWaterMarker,
|
||||||
|
needShowPhoneBrand = orderInfo?.needShowPhoneBrand,
|
||||||
|
photoSource = 0)
|
||||||
|
RoomHelper.db?.photoTemplateDao()?.insert(photoTemplateInfo)
|
||||||
|
}
|
||||||
|
LogUtil.print("queryPhotoTemplate", "使用本地模版==${listData.toJson()}")
|
||||||
|
success()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
val listData = RoomHelper.db?.photoTemplateDao()
|
||||||
|
?.queryCurrentOrderHasTaskNode(orderInfo?.userOrderId ?: 0)
|
||||||
|
if (! listData.isNullOrEmpty()) {
|
||||||
|
LogUtil.print("queryPhotoTemplate", "模板已经存在==${listData.toJson()}")
|
||||||
|
success()
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
it.forEachIndexed { _, item ->
|
it.forEachIndexed { _, item ->
|
||||||
@ -365,6 +352,7 @@ object CommonMethod {
|
|||||||
taskCode = orderInfo?.taskCode,
|
taskCode = orderInfo?.taskCode,
|
||||||
myCustomPhotoType = Const.PhotoType.InServicing,
|
myCustomPhotoType = Const.PhotoType.InServicing,
|
||||||
advanceTime = orderInfo?.advanceTime,
|
advanceTime = orderInfo?.advanceTime,
|
||||||
|
serviceTypeName = orderInfo?.serviceTypeName,
|
||||||
taskId = orderInfo?.taskId,
|
taskId = orderInfo?.taskId,
|
||||||
needWaterMarker = orderInfo?.needWaterMarker,
|
needWaterMarker = orderInfo?.needWaterMarker,
|
||||||
needShowPhoneBrand = orderInfo?.needShowPhoneBrand,
|
needShowPhoneBrand = orderInfo?.needShowPhoneBrand,
|
||||||
@ -377,7 +365,30 @@ object CommonMethod {
|
|||||||
|
|
||||||
override fun doFailure(code : Int, msg : String?) {
|
override fun doFailure(code : Int, msg : String?) {
|
||||||
LogUtil.print("fetchPhotoTemplate", "err==$msg")
|
LogUtil.print("fetchPhotoTemplate", "err==$msg")
|
||||||
failed(msg)
|
val listData = RoomHelper.db?.photoTemplateDao()
|
||||||
|
?.queryCurrentOrderHasTaskNode(orderInfo?.userOrderId ?: 0)
|
||||||
|
if (! listData.isNullOrEmpty()) {
|
||||||
|
LogUtil.print("queryPhotoTemplate", "模板已经存在==${listData.toJson()}")
|
||||||
|
success()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
val list = LocalPhotoTemplateControl.buildPhotoTemplate(orderInfo)
|
||||||
|
list.forEachIndexed { _, item ->
|
||||||
|
val photoTemplateInfo = item.copy(userOrderId = orderInfo?.userOrderId,
|
||||||
|
taskCode = orderInfo?.taskCode,
|
||||||
|
myCustomPhotoType = Const.PhotoType.InServicing,
|
||||||
|
advanceTime = orderInfo?.advanceTime,
|
||||||
|
serviceTypeName = orderInfo?.serviceTypeName,
|
||||||
|
taskId = orderInfo?.taskId,
|
||||||
|
needWaterMarker = orderInfo?.needWaterMarker,
|
||||||
|
needShowPhoneBrand = orderInfo?.needShowPhoneBrand,
|
||||||
|
photoSource = 0)
|
||||||
|
RoomHelper.db?.photoTemplateDao()?.insert(photoTemplateInfo)
|
||||||
|
}
|
||||||
|
LogUtil.print("queryPhotoTemplate", "使用本地模版==${listData.toJson()}")
|
||||||
|
success()
|
||||||
|
return
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -406,7 +417,8 @@ object CommonMethod {
|
|||||||
carVin = it?.vinNo,
|
carVin = it?.vinNo,
|
||||||
serviceContent = it?.serviceTerm,
|
serviceContent = it?.serviceTerm,
|
||||||
serverAcceptCarSignPath = it?.recipientSignPath,
|
serverAcceptCarSignPath = it?.recipientSignPath,
|
||||||
serverServicePeopleSignPath = it?.waitstaffSignPath,
|
serverServicePeopleSignPath = it?.waitstaffSignPath
|
||||||
|
?: GlobalData.driverInfoBean?.signatureUrl,
|
||||||
orderType = it?.serviceName)
|
orderType = it?.serviceName)
|
||||||
it?.damageFileList?.forEach { item ->
|
it?.damageFileList?.forEach { item ->
|
||||||
val damagePhotoBean = EleCarDamagePhotoBean(userOrderId = it.userOrderId,
|
val damagePhotoBean = EleCarDamagePhotoBean(userOrderId = it.userOrderId,
|
||||||
@ -417,6 +429,7 @@ object CommonMethod {
|
|||||||
RoomHelper.db?.eleCarDamagePhotoDao()?.insert(damagePhotoBean)
|
RoomHelper.db?.eleCarDamagePhotoDao()?.insert(damagePhotoBean)
|
||||||
}
|
}
|
||||||
RoomHelper.db?.eleWorkOrderDao()?.insertEleWorkOrder(temp)
|
RoomHelper.db?.eleWorkOrderDao()?.insertEleWorkOrder(temp)
|
||||||
|
LogUtil.print("queryElectronOrder", "插入成功 ${temp.toJson()}")
|
||||||
success(temp)
|
success(temp)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
1121
servicing/src/main/java/com/za/net/LocalPhotoTemplateControl.kt
Normal file
@ -91,7 +91,7 @@ object OfflineManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun stop() {
|
fun stop() {
|
||||||
uploadDispose?.dispose()
|
uploadDispose?.dispose()
|
||||||
uploadDispose = null
|
uploadDispose = null
|
||||||
isUploading = false
|
isUploading = false
|
||||||
|
@ -11,7 +11,7 @@ import com.za.room.db.GlobalRoom
|
|||||||
|
|
||||||
@SuppressLint("StaticFieldLeak")
|
@SuppressLint("StaticFieldLeak")
|
||||||
object RoomHelper {
|
object RoomHelper {
|
||||||
const val VERSION: Int = 41
|
const val VERSION: Int = 43
|
||||||
private lateinit var mContext: Context
|
private lateinit var mContext: Context
|
||||||
var db: GlobalRoom? = null
|
var db: GlobalRoom? = null
|
||||||
|
|
||||||
|
@ -16,6 +16,9 @@ interface OrderDao {
|
|||||||
@Query("select * from order_info where taskId =:taskId")
|
@Query("select * from order_info where taskId =:taskId")
|
||||||
fun getOrderInfoFromTaskId(taskId: Int): OrderInfo?
|
fun getOrderInfoFromTaskId(taskId: Int): OrderInfo?
|
||||||
|
|
||||||
|
@Query("select * from order_info where taskCode =:taskCode")
|
||||||
|
fun getOrderInfoFromTaskCode(taskCode: String): OrderInfo?
|
||||||
|
|
||||||
//获取当前正在执行的订单
|
//获取当前正在执行的订单
|
||||||
@Query("select * from order_info where isCurrent ==1")
|
@Query("select * from order_info where isCurrent ==1")
|
||||||
fun getCurrentOrder(): OrderInfo?
|
fun getCurrentOrder(): OrderInfo?
|
||||||
|
@ -23,4 +23,5 @@ data class DriverInfoBean(
|
|||||||
val vehicleState : Int? = null, //车辆状态 0 空闲 1 忙碌
|
val vehicleState : Int? = null, //车辆状态 0 空闲 1 忙碌
|
||||||
val plateNumber : String? = null, //车牌号
|
val plateNumber : String? = null, //车牌号
|
||||||
val deviceId : String? = null,
|
val deviceId : String? = null,
|
||||||
|
val signatureUrl : String? = null, //手写签名照地址
|
||||||
) : Parcelable
|
) : Parcelable
|
@ -30,6 +30,7 @@ interface PushListener {
|
|||||||
fun reDispatchOrder(jpushBean : JpushBean)
|
fun reDispatchOrder(jpushBean : JpushBean)
|
||||||
fun broadcast(string : String)
|
fun broadcast(string : String)
|
||||||
fun importantTip(jpushBean : JpushBean)
|
fun importantTip(jpushBean : JpushBean)
|
||||||
|
fun reportHandle(jpushBean : JpushBean)
|
||||||
}
|
}
|
||||||
|
|
||||||
data class LastJPushBean(val msg : String, val time : Long = System.currentTimeMillis())
|
data class LastJPushBean(val msg : String, val time : Long = System.currentTimeMillis())
|
||||||
@ -67,33 +68,49 @@ object ServiceManager {
|
|||||||
private fun setupPushMessageReceiver(context : Context) { // 注册推送消息接收器
|
private fun setupPushMessageReceiver(context : Context) { // 注册推送消息接收器
|
||||||
registerPushListener(object : PushListener {
|
registerPushListener(object : PushListener {
|
||||||
override fun broadcast(msg : String) {
|
override fun broadcast(msg : String) {
|
||||||
sendMessageToMainProcess(context = context, "broadcast", msg)
|
sendMessageToMainProcess(context = context, Const.PushMessageType.BROADCAST, msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun giveUpOrder(jpushBean : JpushBean) {
|
override fun giveUpOrder(jpushBean : JpushBean) {
|
||||||
sendMessageToMainProcess(context = context, "giveUp", Gson().toJson(jpushBean))
|
sendMessageToMainProcess(context = context,
|
||||||
|
Const.PushMessageType.GIVE_UP,
|
||||||
|
Gson().toJson(jpushBean))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun importantTip(jpushBean : JpushBean) {
|
override fun importantTip(jpushBean : JpushBean) {
|
||||||
sendMessageToMainProcess(context = context,
|
sendMessageToMainProcess(context = context,
|
||||||
"importantTip",
|
Const.PushMessageType.IMPORTANT_TIP,
|
||||||
Gson().toJson(jpushBean))
|
Gson().toJson(jpushBean))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun newOrderMsg(jpushBean : JpushBean) {
|
override fun newOrderMsg(jpushBean : JpushBean) {
|
||||||
sendMessageToMainProcess(context = context, "newOrder", Gson().toJson(jpushBean))
|
sendMessageToMainProcess(context = context,
|
||||||
|
Const.PushMessageType.NEW_ORDER,
|
||||||
|
Gson().toJson(jpushBean))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun reDispatchOrder(jpushBean : JpushBean) {
|
override fun reDispatchOrder(jpushBean : JpushBean) {
|
||||||
sendMessageToMainProcess(context = context, "reDispatch", Gson().toJson(jpushBean))
|
sendMessageToMainProcess(context = context,
|
||||||
|
Const.PushMessageType.RE_DISPATCH,
|
||||||
|
Gson().toJson(jpushBean))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun revokeOrder(jpushBean : JpushBean) {
|
override fun revokeOrder(jpushBean : JpushBean) {
|
||||||
sendMessageToMainProcess(context = context, "revoke", Gson().toJson(jpushBean))
|
sendMessageToMainProcess(context = context,
|
||||||
|
Const.PushMessageType.REVOKE,
|
||||||
|
Gson().toJson(jpushBean))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun modifyOrder(jpushBean : JpushBean) {
|
override fun modifyOrder(jpushBean : JpushBean) {
|
||||||
sendMessageToMainProcess(context = context, "modify", Gson().toJson(jpushBean))
|
sendMessageToMainProcess(context = context,
|
||||||
|
Const.PushMessageType.MODIFY,
|
||||||
|
Gson().toJson(jpushBean))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun reportHandle(jpushBean : JpushBean) {
|
||||||
|
sendMessageToMainProcess(context = context,
|
||||||
|
Const.PushMessageType.REPORT_HANDLE,
|
||||||
|
Gson().toJson(jpushBean))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -145,6 +162,7 @@ object ServiceManager {
|
|||||||
1 -> handleTypeOneMessage(jpushOrderInfoBean)
|
1 -> handleTypeOneMessage(jpushOrderInfoBean)
|
||||||
2 -> handlerModifyOrderMessage(jpushOrderInfoBean)
|
2 -> handlerModifyOrderMessage(jpushOrderInfoBean)
|
||||||
3 -> importantTip(jpushOrderInfoBean)
|
3 -> importantTip(jpushOrderInfoBean)
|
||||||
|
4 -> reportHandler(jpushOrderInfoBean)
|
||||||
else -> LogUtil.print("JpushMessage",
|
else -> LogUtil.print("JpushMessage",
|
||||||
"Unknown push type: ${jpushOrderInfoBean.pushType}")
|
"Unknown push type: ${jpushOrderInfoBean.pushType}")
|
||||||
}
|
}
|
||||||
@ -171,9 +189,9 @@ object ServiceManager {
|
|||||||
// Handle type one messages
|
// Handle type one messages
|
||||||
private fun handleTypeOneMessage(jpushOrderBean : JpushBean) {
|
private fun handleTypeOneMessage(jpushOrderBean : JpushBean) {
|
||||||
when (jpushOrderBean.typeDesc) {
|
when (jpushOrderBean.typeDesc) {
|
||||||
"giveUp" -> giveUpOrder(jpushOrderBean)
|
Const.PushMessageType.GIVE_UP -> giveUpOrder(jpushOrderBean)
|
||||||
"revoke" -> revokeOrder(jpushOrderBean)
|
Const.PushMessageType.REVOKE -> revokeOrder(jpushOrderBean)
|
||||||
"reDispatch" -> reDispatchOrder(jpushOrderBean)
|
Const.PushMessageType.RE_DISPATCH -> reDispatchOrder(jpushOrderBean)
|
||||||
else -> LogUtil.print("JpushMessage", "Unknown typeDesc: ${jpushOrderBean.typeDesc}")
|
else -> LogUtil.print("JpushMessage", "Unknown typeDesc: ${jpushOrderBean.typeDesc}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -218,6 +236,10 @@ object ServiceManager {
|
|||||||
pushListener?.importantTip(jpushOrderBean)
|
pushListener?.importantTip(jpushOrderBean)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun reportHandler(jpushOrderBean : JpushBean) {
|
||||||
|
pushListener?.reportHandle(jpushOrderBean)
|
||||||
|
}
|
||||||
|
|
||||||
// Disconnect from JPush and MQTT
|
// Disconnect from JPush and MQTT
|
||||||
fun disconnect(context : Context) {
|
fun disconnect(context : Context) {
|
||||||
Handler(Looper.getMainLooper()).post {
|
Handler(Looper.getMainLooper()).post {
|
||||||
@ -259,13 +281,13 @@ object ServiceManager {
|
|||||||
|
|
||||||
1 -> {
|
1 -> {
|
||||||
when (jpushOrderInfoBean.typeDesc) {
|
when (jpushOrderInfoBean.typeDesc) {
|
||||||
"giveUp" -> sendNotification(GlobalData.application,
|
Const.PushMessageType.GIVE_UP -> sendNotification(GlobalData.application,
|
||||||
"订单:${jpushOrderInfoBean.taskCode ?: ""}已被放弃!")
|
"订单:${jpushOrderInfoBean.taskCode ?: ""}已被放弃!")
|
||||||
|
|
||||||
"revoke" -> sendNotification(GlobalData.application,
|
Const.PushMessageType.REVOKE -> sendNotification(GlobalData.application,
|
||||||
"订单:${jpushOrderInfoBean.taskCode ?: ""}已被撤回!")
|
"订单:${jpushOrderInfoBean.taskCode ?: ""}已被撤回!")
|
||||||
|
|
||||||
"reDispatch" -> sendNotification(GlobalData.application,
|
Const.PushMessageType.RE_DISPATCH -> sendNotification(GlobalData.application,
|
||||||
"订单:${jpushOrderInfoBean.taskCode ?: ""}被改派!")
|
"订单:${jpushOrderInfoBean.taskCode ?: ""}被改派!")
|
||||||
|
|
||||||
else -> {}
|
else -> {}
|
||||||
|
@ -22,7 +22,9 @@ import com.za.bean.JpushBean
|
|||||||
import com.za.common.GlobalData
|
import com.za.common.GlobalData
|
||||||
import com.za.common.log.LogUtil
|
import com.za.common.log.LogUtil
|
||||||
import com.za.common.speech.SpeechManager
|
import com.za.common.speech.SpeechManager
|
||||||
|
import com.za.room.RoomHelper
|
||||||
import com.za.servicing.R
|
import com.za.servicing.R
|
||||||
|
import com.za.ui.order_report.ReportFloatingManager
|
||||||
import com.za.ui.servicing.order_give_up.OrderGiveUpActivity
|
import com.za.ui.servicing.order_give_up.OrderGiveUpActivity
|
||||||
import com.za.ui.view.CommonDialogFragment
|
import com.za.ui.view.CommonDialogFragment
|
||||||
|
|
||||||
@ -113,6 +115,20 @@ class ZdPushServiceReceive : BroadcastReceiver() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Const.PushMessageType.REPORT_HANDLE -> {
|
||||||
|
try {
|
||||||
|
val jpushBean = Gson().fromJson(message, JpushBean::class.java)
|
||||||
|
val activity = BaseActivityLifecycleCallbacks.Companion.getCurrentActivity()
|
||||||
|
?: ActivityUtils.getTopActivity()
|
||||||
|
if (activity is AppCompatActivity) {
|
||||||
|
handeReportMessage(jpushBean = jpushBean)
|
||||||
|
}
|
||||||
|
} catch (e : Exception) {
|
||||||
|
LogUtil.print("PushActivityLifecycleCallbacks",
|
||||||
|
"处理重要提示消息失败: ${e.message}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -183,6 +199,24 @@ class ZdPushServiceReceive : BroadcastReceiver() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun handeReportMessage(jpushBean : JpushBean) {
|
||||||
|
SpeechManager.speech("您提交的报批已经处理!")
|
||||||
|
BaseActivityLifecycleCallbacks.getCurrentActivity()?.let { currentActivity ->
|
||||||
|
if (currentActivity is AppCompatActivity) {
|
||||||
|
AlertDialog.Builder(currentActivity).setTitle("提醒")
|
||||||
|
.setMessage("您提交的报批已经处理,是否前往查看?")
|
||||||
|
.setPositiveButton("确定") { dialog, _ ->
|
||||||
|
dialog.dismiss()
|
||||||
|
currentActivity.finish()
|
||||||
|
val order = RoomHelper.db?.orderDao()
|
||||||
|
?.getOrderInfoFromTaskCode(taskCode = jpushBean.taskCode ?: "")
|
||||||
|
ReportFloatingManager.goReportPage(context = currentActivity,
|
||||||
|
orderInfo = order)
|
||||||
|
}.show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Handle broadcast messages
|
// Handle broadcast messages
|
||||||
private fun handleBroadcast(msg : String) {
|
private fun handleBroadcast(msg : String) {
|
||||||
try {
|
try {
|
||||||
|
@ -21,6 +21,7 @@ class ConnectionOptionWrapper(
|
|||||||
isCleanSession = true
|
isCleanSession = true
|
||||||
keepAliveInterval = 90 // Keep alive interval in seconds
|
keepAliveInterval = 90 // Keep alive interval in seconds
|
||||||
isAutomaticReconnect = true
|
isAutomaticReconnect = true
|
||||||
|
maxInflight = 1000
|
||||||
mqttVersion = MqttConnectOptions.MQTT_VERSION_3_1_1
|
mqttVersion = MqttConnectOptions.MQTT_VERSION_3_1_1
|
||||||
connectionTimeout = 30 // Connection timeout in seconds
|
connectionTimeout = 30 // Connection timeout in seconds
|
||||||
}
|
}
|
||||||
|
@ -1,67 +1,54 @@
|
|||||||
package com.za.service.mqtt
|
package com.za.service.mqtt
|
||||||
|
|
||||||
import android.os.Handler
|
import android.annotation.SuppressLint
|
||||||
import android.os.Looper
|
|
||||||
import android.util.Log
|
|
||||||
import com.za.common.GlobalData
|
import com.za.common.GlobalData
|
||||||
import com.za.common.log.LogUtil
|
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 com.za.service.ServiceManager
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import org.eclipse.paho.android.service.MqttAndroidClient
|
||||||
import kotlinx.coroutines.Dispatchers
|
import org.eclipse.paho.client.mqttv3.IMqttActionListener
|
||||||
import kotlinx.coroutines.SupervisorJob
|
|
||||||
import kotlinx.coroutines.cancel
|
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
import kotlinx.coroutines.withContext
|
|
||||||
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken
|
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken
|
||||||
import org.eclipse.paho.client.mqttv3.MqttCallbackExtended
|
import org.eclipse.paho.client.mqttv3.IMqttToken
|
||||||
import org.eclipse.paho.client.mqttv3.MqttClient
|
import org.eclipse.paho.client.mqttv3.MqttCallback
|
||||||
|
import org.eclipse.paho.client.mqttv3.MqttConnectOptions
|
||||||
import org.eclipse.paho.client.mqttv3.MqttException
|
import org.eclipse.paho.client.mqttv3.MqttException
|
||||||
import org.eclipse.paho.client.mqttv3.MqttMessage
|
import org.eclipse.paho.client.mqttv3.MqttMessage
|
||||||
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence
|
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence
|
||||||
|
import kotlin.concurrent.Volatile
|
||||||
|
|
||||||
|
|
||||||
object MyMqttClient {
|
object MyMqttClient {
|
||||||
private lateinit var clientId : String
|
private lateinit var clientId : String
|
||||||
private lateinit var topic : String
|
private lateinit var topic : String
|
||||||
|
|
||||||
private val mqttClient : MqttClient by lazy {
|
@SuppressLint("StaticFieldLeak")
|
||||||
MqttClient("tcp://${MqttConfig.END_POINT}:1883", clientId, MemoryPersistence())
|
private var mqttClient : MqttAndroidClient? = null
|
||||||
}
|
|
||||||
|
|
||||||
private val coroutineScope = CoroutineScope(SupervisorJob() + Dispatchers.IO)
|
|
||||||
private val _connectionState = MutableStateFlow(false)
|
|
||||||
private val connectionState : StateFlow<Boolean> = _connectionState
|
|
||||||
|
|
||||||
fun initialize(deviceId : String?) {
|
fun initialize(deviceId : String?) {
|
||||||
clientId = "${MqttConfig.GROUP_ID}@@@$deviceId"
|
clientId = "${MqttConfig.GROUP_ID}@@@$deviceId"
|
||||||
topic = "${MqttConfig.TOPIC_PREFIX}/$clientId"
|
topic = "${MqttConfig.TOPIC_PREFIX}/$clientId"
|
||||||
|
mqttClient = MqttAndroidClient(GlobalData.application,
|
||||||
|
"tcp://${MqttConfig.END_POINT}:1883",
|
||||||
|
clientId,
|
||||||
|
MemoryPersistence())
|
||||||
setupMqttCallbacks()
|
setupMqttCallbacks()
|
||||||
connect()
|
connect()
|
||||||
LogUtil.print("MyMqttClient ", "initialize success")
|
LogUtil.print("MyMqttClient ", "initialize success")
|
||||||
Log.e("MyMqttClient ", "initialize success")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setupMqttCallbacks() {
|
private fun setupMqttCallbacks() {
|
||||||
mqttClient.setCallback(object : MqttCallbackExtended {
|
mqttClient?.setCallback(object : MqttCallback {
|
||||||
override fun connectComplete(reconnect : Boolean, serverURI : String) {
|
|
||||||
val status = if (reconnect) "Reconnected" else "Connected"
|
|
||||||
LogUtil.print("MyMqttClient ", "$status to: $serverURI")
|
|
||||||
_connectionState.value = true
|
|
||||||
subscribeTopic()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun connectionLost(throwable : Throwable) {
|
override fun connectionLost(throwable : Throwable) {
|
||||||
LogUtil.print("MyMqttClient ", "Connection lost: ${throwable.message}")
|
LogUtil.print("MyMqttClient ",
|
||||||
_connectionState.value = false
|
"Connection lost: ${throwable.message}") // connect()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun messageArrived(topic : String, mqttMessage : MqttMessage) {
|
override fun messageArrived(topic : String, mqttMessage : MqttMessage) {
|
||||||
Handler(Looper.getMainLooper()).post {
|
val message = String(mqttMessage.payload)
|
||||||
val message = String(mqttMessage.payload)
|
LogUtil.print("MyMqttClient ", "Message arrived: $message")
|
||||||
LogUtil.print("MyMqttClient ", "Message arrived: $message")
|
ServiceManager.handlerPushMsg(message)
|
||||||
ServiceManager.handlerPushMsg(message)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun deliveryComplete(token : IMqttDeliveryToken) {
|
override fun deliveryComplete(token : IMqttDeliveryToken) {
|
||||||
@ -70,64 +57,102 @@ object MyMqttClient {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Volatile
|
||||||
|
private var isConnecting : Boolean? = null
|
||||||
private fun connect() {
|
private fun connect() {
|
||||||
if (connectionState.value && mqttClient.isConnected) {
|
if (isConnecting == true) {
|
||||||
LogUtil.print("MyMqttClient ", "Already connected")
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
try {
|
||||||
|
isConnecting = true
|
||||||
|
|
||||||
coroutineScope.launch {
|
val mqttConnectOption = MqttConnectOptions()
|
||||||
try {
|
mqttConnectOption.userName =
|
||||||
val options = ConnectionOptionWrapper(MqttConfig.INSTANCE_ID,
|
"Signature|" + MqttConfig.ACCESS_KEY + "|" + MqttConfig.INSTANCE_ID
|
||||||
MqttConfig.ACCESS_KEY,
|
mqttConnectOption.password = macSignature(clientId, MqttConfig.SECRET_KEY).toCharArray()
|
||||||
clientId,
|
mqttConnectOption.isCleanSession = true
|
||||||
MqttConfig.SECRET_KEY).mqttConnectOptions
|
mqttConnectOption.keepAliveInterval = 90
|
||||||
|
mqttConnectOption.isAutomaticReconnect = true
|
||||||
|
mqttConnectOption.maxInflight = 1000
|
||||||
|
mqttConnectOption.maxReconnectDelay = 30 * 1000
|
||||||
|
mqttConnectOption.mqttVersion = MqttConnectOptions.MQTT_VERSION_3_1_1
|
||||||
|
mqttConnectOption.connectionTimeout = 30
|
||||||
|
|
||||||
withContext(Dispatchers.IO) {
|
mqttClient?.connect(mqttConnectOption, null, object : IMqttActionListener {
|
||||||
mqttClient.connect(options)
|
override fun onSuccess(asyncActionToken : IMqttToken?) {
|
||||||
|
isConnecting = false
|
||||||
|
LogUtil.print("MyMqttClient ", "connect success==")
|
||||||
|
subscribeTopic()
|
||||||
}
|
}
|
||||||
_connectionState.value = true // Update connection state after successful connection
|
|
||||||
} catch (e : MqttException) {
|
override fun onFailure(asyncActionToken : IMqttToken?, exception : Throwable?) {
|
||||||
LogUtil.print("MyMqttClient ", "Connection failed: ${e.message}")
|
isConnecting = false
|
||||||
_connectionState.value = false // Update connection state on failure
|
LogUtil.print("MyMqttClient ", "connect failed== ${exception?.message}")
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
} catch (e : MqttException) {
|
||||||
|
LogUtil.print("MyMqttClient ", "Connection failed2: ${e.message}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//检测mqtt连接状态
|
//检测mqtt连接状态
|
||||||
fun publishMessage() {
|
fun publishMessage() {
|
||||||
if (mqttClient.isConnected) {
|
|
||||||
|
if (mqttClient == null) {
|
||||||
|
initialize(deviceId = DeviceUtil.getAndroidId(GlobalData.application))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mqttClient?.isConnected == true) {
|
||||||
LogUtil.print("MyMqttClient ", "mqttClient.hasConnected")
|
LogUtil.print("MyMqttClient ", "mqttClient.hasConnected")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
connect()
|
||||||
LogUtil.print("MyMqttClient ", "mqttClient 断开重新初始化")
|
LogUtil.print("MyMqttClient ", "mqttClient 断开重新初始化")
|
||||||
ServiceManager.initialize(GlobalData.application)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun subscribeTopic() {
|
private fun subscribeTopic() {
|
||||||
coroutineScope.launch {
|
try {
|
||||||
try {
|
if (mqttClient?.isConnected == true) {
|
||||||
mqttClient.subscribe(topic, MqttConfig.QOS_LEVEL)
|
mqttClient?.subscribe(topic,
|
||||||
LogUtil.print("MyMqttClient ", "Subscribed to topic: $topic")
|
MqttConfig.QOS_LEVEL,
|
||||||
} catch (e : MqttException) {
|
null,
|
||||||
LogUtil.print("MyMqttClient ", "Subscribe failed: ${e.message}")
|
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}")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
LogUtil.print("MyMqttClient ", "Cannot subscribe: MQTT client is not connected")
|
||||||
}
|
}
|
||||||
|
} catch (e : MqttException) {
|
||||||
|
LogUtil.print("MyMqttClient ", "Subscribe failed2: ${e.message}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun disconnect() {
|
fun disconnect() {
|
||||||
coroutineScope.launch {
|
try {
|
||||||
try {
|
if (mqttClient?.isConnected == true) {
|
||||||
if (connectionState.value) {
|
mqttClient?.disconnect(null, object : IMqttActionListener {
|
||||||
mqttClient.disconnect()
|
override fun onSuccess(asyncActionToken : IMqttToken?) {
|
||||||
_connectionState.value = false
|
LogUtil.print("MyMqttClient ", "Disconnected")
|
||||||
LogUtil.print("MyMqttClient ", "Disconnected successfully")
|
}
|
||||||
}
|
|
||||||
} catch (e : MqttException) {
|
override fun onFailure(asyncActionToken : IMqttToken?, exception : Throwable) {
|
||||||
LogUtil.print("MyMqttClient ", "Disconnect failed: ${e.message}")
|
LogUtil.print("MyMqttClient ", "Disconnect failed")
|
||||||
} finally {
|
}
|
||||||
coroutineScope.cancel()
|
})
|
||||||
}
|
}
|
||||||
|
} catch (e : MqttException) {
|
||||||
|
LogUtil.print("MyMqttClient ", "Disconnect failed: ${e.message}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,11 +6,13 @@ import android.graphics.Color
|
|||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.webkit.JavascriptInterface
|
import android.webkit.JavascriptInterface
|
||||||
import androidx.activity.compose.BackHandler
|
import androidx.activity.compose.BackHandler
|
||||||
|
import androidx.compose.foundation.clickable
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.layout.size
|
||||||
import androidx.compose.material3.LinearProgressIndicator
|
import androidx.compose.material3.LinearProgressIndicator
|
||||||
import androidx.compose.material3.Scaffold
|
import androidx.compose.material3.Scaffold
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
@ -23,6 +25,8 @@ import androidx.compose.ui.Modifier
|
|||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.viewinterop.AndroidView
|
import androidx.compose.ui.viewinterop.AndroidView
|
||||||
|
import androidx.core.net.toUri
|
||||||
|
import coil.compose.AsyncImage
|
||||||
import com.blankj.utilcode.util.ToastUtils
|
import com.blankj.utilcode.util.ToastUtils
|
||||||
import com.tencent.smtt.sdk.WebChromeClient
|
import com.tencent.smtt.sdk.WebChromeClient
|
||||||
import com.tencent.smtt.sdk.WebSettings
|
import com.tencent.smtt.sdk.WebSettings
|
||||||
@ -35,6 +39,7 @@ import com.za.base.view.HeadView
|
|||||||
import com.za.common.GlobalData
|
import com.za.common.GlobalData
|
||||||
import com.za.common.log.LogUtil
|
import com.za.common.log.LogUtil
|
||||||
import com.za.ext.finish
|
import com.za.ext.finish
|
||||||
|
import com.za.servicing.R
|
||||||
|
|
||||||
class CommonH5Activity : BaseActivity() {
|
class CommonH5Activity : BaseActivity() {
|
||||||
private var webView : WebView? = null
|
private var webView : WebView? = null
|
||||||
@ -45,7 +50,6 @@ class CommonH5Activity : BaseActivity() {
|
|||||||
val url = intent.getStringExtra(EXTRA_URL)
|
val url = intent.getStringExtra(EXTRA_URL)
|
||||||
val title = intent.getStringExtra(EXTRA_TITLE)
|
val title = intent.getStringExtra(EXTRA_TITLE)
|
||||||
val isCanBack = intent.getBooleanExtra(EXTRA_CAN_BACK, true)
|
val isCanBack = intent.getBooleanExtra(EXTRA_CAN_BACK, true)
|
||||||
|
|
||||||
if (url.isNullOrBlank()) {
|
if (url.isNullOrBlank()) {
|
||||||
ToastUtils.showLong("无效的URL")
|
ToastUtils.showLong("无效的URL")
|
||||||
finish()
|
finish()
|
||||||
@ -165,7 +169,15 @@ private fun CommonH5Screen(url : String,
|
|||||||
|
|
||||||
Scaffold(topBar = {
|
Scaffold(topBar = {
|
||||||
if (title.isNotBlank()) {
|
if (title.isNotBlank()) {
|
||||||
HeadView(title = title, onBack = { handleBackPress(context, webView) })
|
HeadView(title = title, onBack = { handleBackPress(context, webView) }, action = {
|
||||||
|
AsyncImage(model = R.drawable.sv_browth,
|
||||||
|
contentDescription = "",
|
||||||
|
modifier = Modifier.size(24.dp).clickable{
|
||||||
|
val intent = Intent(Intent.ACTION_VIEW)
|
||||||
|
intent.setData(url.toUri())
|
||||||
|
context.startActivity(intent)
|
||||||
|
})
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}) { paddingValues ->
|
}) { paddingValues ->
|
||||||
Box(modifier = Modifier
|
Box(modifier = Modifier
|
||||||
@ -186,6 +198,7 @@ private fun CommonH5Screen(url : String,
|
|||||||
webView = this
|
webView = this
|
||||||
onWebViewCreated(this)
|
onWebViewCreated(this)
|
||||||
loadUrl(url)
|
loadUrl(url)
|
||||||
|
LogUtil.print("H5Activity url", url)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -228,6 +241,7 @@ private fun setupWebViewClients(webView : WebView,
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun shouldOverrideUrlLoading(p0 : WebView?, p1 : String?) : Boolean {
|
override fun shouldOverrideUrlLoading(p0 : WebView?, p1 : String?) : Boolean {
|
||||||
|
LogUtil.print("H5Activity url", "$p1")
|
||||||
p0?.loadUrl(p1)
|
p0?.loadUrl(p1)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
@ -104,20 +104,34 @@ class ServicingMainActivity : BaseActivity() {
|
|||||||
Gson().toJson(jpushBean))
|
Gson().toJson(jpushBean))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun reportHandle(jpushBean : JpushBean) {
|
||||||
|
sendMessageToMainProcess(context = context,
|
||||||
|
Const.PushMessageType.REPORT_HANDLE,
|
||||||
|
Gson().toJson(jpushBean))
|
||||||
|
}
|
||||||
|
|
||||||
override fun newOrderMsg(jpushBean : JpushBean) {
|
override fun newOrderMsg(jpushBean : JpushBean) {
|
||||||
sendMessageToMainProcess(context = context, Const.PushMessageType.NEW_ORDER, Gson().toJson(jpushBean))
|
sendMessageToMainProcess(context = context,
|
||||||
|
Const.PushMessageType.NEW_ORDER,
|
||||||
|
Gson().toJson(jpushBean))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun reDispatchOrder(jpushBean : JpushBean) {
|
override fun reDispatchOrder(jpushBean : JpushBean) {
|
||||||
sendMessageToMainProcess(context = context, Const.PushMessageType.RE_DISPATCH, Gson().toJson(jpushBean))
|
sendMessageToMainProcess(context = context,
|
||||||
|
Const.PushMessageType.RE_DISPATCH,
|
||||||
|
Gson().toJson(jpushBean))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun revokeOrder(jpushBean : JpushBean) {
|
override fun revokeOrder(jpushBean : JpushBean) {
|
||||||
sendMessageToMainProcess(context = context, Const.PushMessageType.REVOKE, Gson().toJson(jpushBean))
|
sendMessageToMainProcess(context = context,
|
||||||
|
Const.PushMessageType.REVOKE,
|
||||||
|
Gson().toJson(jpushBean))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun modifyOrder(jpushBean : JpushBean) {
|
override fun modifyOrder(jpushBean : JpushBean) {
|
||||||
sendMessageToMainProcess(context = context, Const.PushMessageType.MODIFY, Gson().toJson(jpushBean))
|
sendMessageToMainProcess(context = context,
|
||||||
|
Const.PushMessageType.MODIFY,
|
||||||
|
Gson().toJson(jpushBean))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -87,9 +87,7 @@ class ServicingMainVm : BaseVm<ServicingMainVm.Action, ServicingMainVm.UiState>(
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
GlobalData.token = it.token
|
GlobalData.token = it.token
|
||||||
CommonMethod.getGenerateInfo(vehicleId = it.vehicleId,
|
CommonMethod.getGenerateInfo(success = { success() },
|
||||||
userId = it.userId,
|
|
||||||
success = { success() },
|
|
||||||
failed = { failure(it ?: "") })
|
failed = { failure(it ?: "") })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,8 +26,12 @@ import android.widget.ImageView
|
|||||||
import androidx.core.app.NotificationCompat
|
import androidx.core.app.NotificationCompat
|
||||||
import com.blankj.utilcode.util.ActivityUtils
|
import com.blankj.utilcode.util.ActivityUtils
|
||||||
import com.blankj.utilcode.util.ServiceUtils
|
import com.blankj.utilcode.util.ServiceUtils
|
||||||
|
import com.za.base.AppConfig
|
||||||
|
import com.za.bean.db.order.OrderInfo
|
||||||
|
import com.za.common.GlobalData
|
||||||
import com.za.common.log.LogUtil
|
import com.za.common.log.LogUtil
|
||||||
import com.za.servicing.R
|
import com.za.servicing.R
|
||||||
|
import com.za.ui.h5.CommonH5Activity
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
@ -66,7 +70,7 @@ class ReportFloatingManager : Service() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onBind(intent : Intent?) : IBinder?{
|
override fun onBind(intent : Intent?) : IBinder? {
|
||||||
LogUtil.print("ReportFloatingManager service", "onBind")
|
LogUtil.print("ReportFloatingManager service", "onBind")
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
@ -183,7 +187,7 @@ class ReportFloatingManager : Service() {
|
|||||||
|
|
||||||
if (! isMoving && System.currentTimeMillis() - startClickTime < CLICK_THRESHOLD) {
|
if (! isMoving && System.currentTimeMillis() - startClickTime < CLICK_THRESHOLD) {
|
||||||
openMainActivity()
|
openMainActivity()
|
||||||
} else if (isDragging) { // 只保存位置,不执行吸附
|
} else if (isDragging) {
|
||||||
savePosition()
|
savePosition()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -195,9 +199,11 @@ class ReportFloatingManager : Service() {
|
|||||||
if (ActivityUtils.getTopActivity() is OrderReportActivity) {
|
if (ActivityUtils.getTopActivity() is OrderReportActivity) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
val intent = Intent(this, OrderReportActivity::class.java).apply {
|
|
||||||
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP
|
// goReportPage(orderInfo = GlobalData.currentOrder, context = this)
|
||||||
}
|
val intent = Intent(this, OrderReportActivity::class.java).apply {
|
||||||
|
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP
|
||||||
|
}
|
||||||
startActivity(intent)
|
startActivity(intent)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -296,6 +302,13 @@ class ReportFloatingManager : Service() {
|
|||||||
ServiceUtils.stopService(ReportFloatingManager::class.java)
|
ServiceUtils.stopService(ReportFloatingManager::class.java)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun goReportPage(orderInfo : OrderInfo?, context : Context) {
|
||||||
|
val url =
|
||||||
|
"${AppConfig.Resource_URL.replace("/res","")}/h5/supplier/dispatch/reportIndex?userOrderId=${orderInfo?.userOrderId}&type=2&userOrderCode=${orderInfo?.taskCode}&driverId=${GlobalData.driverInfoBean?.userId}"
|
||||||
|
CommonH5Activity.goH5Activity(context, url, "")
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -17,6 +17,7 @@ import androidx.compose.foundation.layout.height
|
|||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.size
|
import androidx.compose.foundation.layout.size
|
||||||
import androidx.compose.foundation.layout.width
|
import androidx.compose.foundation.layout.width
|
||||||
|
import androidx.compose.foundation.layout.wrapContentWidth
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
@ -392,7 +393,11 @@ fun InServicingPhotoView(modifier : Modifier = Modifier,
|
|||||||
Text(text = photoTemplateInfo.imageTitle ?: "其他",
|
Text(text = photoTemplateInfo.imageTitle ?: "其他",
|
||||||
fontWeight = FontWeight.Medium,
|
fontWeight = FontWeight.Medium,
|
||||||
fontSize = 14.sp,
|
fontSize = 14.sp,
|
||||||
color = Color.Black)
|
maxLines = 2,
|
||||||
|
overflow = TextOverflow.Ellipsis,
|
||||||
|
color = Color.Black,
|
||||||
|
modifier = Modifier.wrapContentWidth().takeIf { photoTemplateInfo.doHaveFilm == 1 }
|
||||||
|
?: Modifier.fillMaxWidth(0.7f))
|
||||||
Spacer(modifier = Modifier.width(5.dp))
|
Spacer(modifier = Modifier.width(5.dp))
|
||||||
if (photoTemplateInfo.doHaveFilm == 1) {
|
if (photoTemplateInfo.doHaveFilm == 1) {
|
||||||
Text(text = "* 必拍",
|
Text(text = "* 必拍",
|
||||||
@ -474,10 +479,12 @@ fun InServicingPhotoViewIsCanClick(modifier : Modifier = Modifier,
|
|||||||
|
|
||||||
Text(text = photoTemplateInfo.imageTitle ?: "其他",
|
Text(text = photoTemplateInfo.imageTitle ?: "其他",
|
||||||
fontWeight = FontWeight.Medium,
|
fontWeight = FontWeight.Medium,
|
||||||
maxLines = 1,
|
|
||||||
overflow = TextOverflow.Ellipsis,
|
|
||||||
fontSize = 14.sp,
|
fontSize = 14.sp,
|
||||||
color = Color.Black)
|
maxLines = 2,
|
||||||
|
overflow = TextOverflow.Ellipsis,
|
||||||
|
color = Color.Black,
|
||||||
|
modifier = Modifier.wrapContentWidth().takeIf { photoTemplateInfo.doHaveFilm == 1 }
|
||||||
|
?: Modifier.fillMaxWidth(0.7f))
|
||||||
Spacer(modifier = Modifier.width(5.dp))
|
Spacer(modifier = Modifier.width(5.dp))
|
||||||
if (photoTemplateInfo.doHaveFilm == 1 && isCanClick) {
|
if (photoTemplateInfo.doHaveFilm == 1 && isCanClick) {
|
||||||
Text(text = "* 必拍",
|
Text(text = "* 必拍",
|
||||||
@ -722,7 +729,8 @@ fun InServicingPhotoItemView(modifier : Modifier = Modifier,
|
|||||||
.clip(shape = RoundedCornerShape(3.dp)),
|
.clip(shape = RoundedCornerShape(3.dp)),
|
||||||
contentScale = ContentScale.FillBounds)
|
contentScale = ContentScale.FillBounds)
|
||||||
} else {
|
} else {
|
||||||
AsyncImage(model = photoTemplateInfo.getFormatPhotoUrl(),
|
AsyncImage(model = photoTemplateInfo.getFormatPhotoUrl()?.toIntOrNull()
|
||||||
|
?: photoTemplateInfo.getFormatPhotoUrl(),
|
||||||
contentDescription = "",
|
contentDescription = "",
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
@ -746,16 +754,16 @@ fun InServicingPhotoItemView(modifier : Modifier = Modifier,
|
|||||||
contentDescription = "",
|
contentDescription = "",
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
.clickable {
|
.noDoubleClick {
|
||||||
if (! isCanClick) {
|
if (! isCanClick) {
|
||||||
return@clickable
|
return@noDoubleClick
|
||||||
}
|
}
|
||||||
if (photoTemplateInfo.photoLocalPath.isNullOrBlank()) {
|
if (photoTemplateInfo.photoLocalPath.isNullOrBlank()) {
|
||||||
if (! PermissionX.isGranted(context,
|
if (! PermissionX.isGranted(context,
|
||||||
android.Manifest.permission.ACCESS_FINE_LOCATION)
|
android.Manifest.permission.ACCESS_FINE_LOCATION)
|
||||||
) {
|
) {
|
||||||
ToastUtils.showShort("定位权限未开启!")
|
ToastUtils.showShort("定位权限未开启!")
|
||||||
return@clickable
|
return@noDoubleClick
|
||||||
}
|
}
|
||||||
LoadingManager.showLoading()
|
LoadingManager.showLoading()
|
||||||
ZdLocationManager.getSingleLocation(isNeedAddress = true, success = {
|
ZdLocationManager.getSingleLocation(isNeedAddress = true, success = {
|
||||||
@ -771,7 +779,7 @@ fun InServicingPhotoItemView(modifier : Modifier = Modifier,
|
|||||||
LogUtil.print("上传图片定位获取失败",
|
LogUtil.print("上传图片定位获取失败",
|
||||||
"使用全局定位,location==${GlobalData.currentLocation.toJson()}")
|
"使用全局定位,location==${GlobalData.currentLocation.toJson()}")
|
||||||
})
|
})
|
||||||
return@clickable
|
return@noDoubleClick
|
||||||
}
|
}
|
||||||
showReTakePhotoDialog.value = true
|
showReTakePhotoDialog.value = true
|
||||||
}
|
}
|
||||||
|
@ -88,6 +88,7 @@ class CheckVehicleVm : IServicingVm<CheckVehicleVm.Action, CheckVehicleVm.UiStat
|
|||||||
LoadingManager.showLoading()
|
LoadingManager.showLoading()
|
||||||
ZdLocationManager.getSingleLocation(isNeedAddress = true, success = {
|
ZdLocationManager.getSingleLocation(isNeedAddress = true, success = {
|
||||||
LoadingManager.hideLoading()
|
LoadingManager.hideLoading()
|
||||||
|
doUploadOfflineTask(it, tempPhotoList = tempPhotoList)
|
||||||
}, failed = {
|
}, failed = {
|
||||||
LoadingManager.hideLoading()
|
LoadingManager.hideLoading()
|
||||||
if (GlobalData.currentLocation != null) {
|
if (GlobalData.currentLocation != null) {
|
||||||
@ -114,28 +115,26 @@ class CheckVehicleVm : IServicingVm<CheckVehicleVm.Action, CheckVehicleVm.UiStat
|
|||||||
address = it?.address,
|
address = it?.address,
|
||||||
templatePhotoInfoList = tempPhotoList.toList())
|
templatePhotoInfoList = tempPhotoList.toList())
|
||||||
|
|
||||||
if (! getCurrentOrderOfflineTask().isNullOrEmpty()) {
|
val offlineUpdateTaskBean = OfflineUpdateTaskBean(type = taskRequest.type,
|
||||||
val offlineUpdateTaskBean = OfflineUpdateTaskBean(type = taskRequest.type,
|
taskId = taskRequest.taskId,
|
||||||
taskId = taskRequest.taskId,
|
userId = taskRequest.userId,
|
||||||
userId = taskRequest.userId,
|
vehicleId = taskRequest.vehicleId,
|
||||||
vehicleId = taskRequest.vehicleId,
|
currentState = taskRequest.currentState,
|
||||||
currentState = taskRequest.currentState,
|
offlineMode = 1,
|
||||||
offlineMode = 1,
|
operateTime = taskRequest.operateTime,
|
||||||
operateTime = taskRequest.operateTime,
|
updateTaskLat = taskRequest.lat,
|
||||||
updateTaskLat = taskRequest.lat,
|
updateTaskLng = taskRequest.lng,
|
||||||
updateTaskLng = taskRequest.lng,
|
updateTaskAddress = taskRequest.address,
|
||||||
updateTaskAddress = taskRequest.address,
|
templatePhotoInfoList = taskRequest.templatePhotoInfoList,
|
||||||
templatePhotoInfoList = taskRequest.templatePhotoInfoList,
|
advanceTime = getCurrentOrder()?.advanceTime,
|
||||||
advanceTime = getCurrentOrder()?.advanceTime,
|
taskCode = getCurrentOrder()?.taskCode,
|
||||||
taskCode = getCurrentOrder()?.taskCode,
|
userOrderId = getCurrentOrder()?.userOrderId,
|
||||||
userOrderId = getCurrentOrder()?.userOrderId,
|
offlineTitle = "现场验车",
|
||||||
offlineTitle = "现场验车",
|
offlineType = 1)
|
||||||
offlineType = 1)
|
insertOfflineTask(offlineUpdateTaskBean)
|
||||||
insertOfflineTask(offlineUpdateTaskBean)
|
updateOrder(getCurrentOrder()?.copy(taskState = getCurrentOrder()?.getNextStatus()))
|
||||||
updateOrder(getCurrentOrder()?.copy(taskState = getCurrentOrder()?.getNextStatus()))
|
updateState(uiState.value.copy(goNextPage = UpdateTaskBean(nextState = getCurrentOrder()?.taskState),
|
||||||
updateState(uiState.value.copy(goNextPage = UpdateTaskBean(nextState = getCurrentOrder()?.taskState),
|
orderInfo = getCurrentOrder()))
|
||||||
orderInfo = getCurrentOrder()))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateTemplate() {
|
private fun updateTemplate() {
|
||||||
|
@ -39,6 +39,7 @@ import com.za.ext.finish
|
|||||||
import com.za.ext.navigationActivity
|
import com.za.ext.navigationActivity
|
||||||
import com.za.ext.noDoubleClick
|
import com.za.ext.noDoubleClick
|
||||||
import com.za.ui.order_report.OrderReportActivity
|
import com.za.ui.order_report.OrderReportActivity
|
||||||
|
import com.za.ui.order_report.ReportFloatingManager
|
||||||
import com.za.ui.servicing.order_give_up.OrderGiveUpActivity
|
import com.za.ui.servicing.order_give_up.OrderGiveUpActivity
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
@ -58,10 +59,8 @@ fun OrderDetailScreen(orderInfo : OrderInfo?) {
|
|||||||
Box(modifier = Modifier
|
Box(modifier = Modifier
|
||||||
.weight(1f)
|
.weight(1f)
|
||||||
.height(60.dp)
|
.height(60.dp)
|
||||||
.noDoubleClick { // val url =
|
.noDoubleClick {
|
||||||
// "${AppConfig.BASE_URL}/h5/supplier/dispatch/reportIndex?userOrderId=${GlobalData.currentOrder?.userOrderId}&type=2&userOrderCode=${GlobalData.currentOrder?.taskCode}&driverId=${GlobalData.driverInfoBean?.userId}"
|
// ReportFloatingManager.goReportPage(orderInfo = orderInfo, context = context)
|
||||||
//
|
|
||||||
// CommonH5Activity.goH5Activity(context, url, "")
|
|
||||||
|
|
||||||
context.navigationActivity(OrderReportActivity::class.java)
|
context.navigationActivity(OrderReportActivity::class.java)
|
||||||
}
|
}
|
||||||
|
@ -121,30 +121,27 @@ class InOperationVm : IServicingVm<InOperationVm.Action, InOperationVm.UiState>(
|
|||||||
address = it?.address,
|
address = it?.address,
|
||||||
templatePhotoInfoList = tempPhotoList.toList())
|
templatePhotoInfoList = tempPhotoList.toList())
|
||||||
|
|
||||||
if (! getCurrentOrderOfflineTask().isNullOrEmpty()) {
|
val offlineUpdateTaskBean = OfflineUpdateTaskBean(type = taskRequest.type,
|
||||||
val offlineUpdateTaskBean = OfflineUpdateTaskBean(type = taskRequest.type,
|
taskId = taskRequest.taskId,
|
||||||
taskId = taskRequest.taskId,
|
userId = taskRequest.userId,
|
||||||
userId = taskRequest.userId,
|
vehicleId = taskRequest.vehicleId,
|
||||||
vehicleId = taskRequest.vehicleId,
|
currentState = taskRequest.currentState,
|
||||||
currentState = taskRequest.currentState,
|
offlineMode = 1,
|
||||||
offlineMode = 1,
|
operateTime = taskRequest.operateTime,
|
||||||
operateTime = taskRequest.operateTime,
|
updateTaskLat = taskRequest.lat,
|
||||||
updateTaskLat = taskRequest.lat,
|
updateTaskLng = taskRequest.lng,
|
||||||
updateTaskLng = taskRequest.lng,
|
flowType = taskRequest.flowType,
|
||||||
flowType = taskRequest.flowType,
|
templatePhotoInfoList = taskRequest.templatePhotoInfoList,
|
||||||
templatePhotoInfoList = taskRequest.templatePhotoInfoList,
|
updateTaskAddress = taskRequest.address,
|
||||||
updateTaskAddress = taskRequest.address,
|
advanceTime = uiState.value.orderInfo?.advanceTime,
|
||||||
advanceTime = uiState.value.orderInfo?.advanceTime,
|
taskCode = uiState.value.orderInfo?.taskCode,
|
||||||
taskCode = uiState.value.orderInfo?.taskCode,
|
userOrderId = uiState.value.orderInfo?.userOrderId,
|
||||||
userOrderId = uiState.value.orderInfo?.userOrderId,
|
offlineTitle = "准备拖车",
|
||||||
offlineTitle = "准备拖车",
|
offlineType = 1)
|
||||||
offlineType = 1)
|
insertOfflineTask(offlineUpdateTaskBean)
|
||||||
insertOfflineTask(offlineUpdateTaskBean)
|
updateOrder(getCurrentOrder()?.copy(taskState = getCurrentOrder()?.getNextStatus()))
|
||||||
|
updateState(uiState.value.copy(goNextPage = UpdateTaskBean(nextState = getCurrentOrder()?.taskState),
|
||||||
updateOrder(getCurrentOrder()?.copy(taskState = getCurrentOrder()?.getNextStatus()))
|
orderInfo = getCurrentOrder()))
|
||||||
updateState(uiState.value.copy(goNextPage = UpdateTaskBean(nextState = getCurrentOrder()?.taskState),
|
|
||||||
orderInfo = getCurrentOrder()))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateTask() {
|
private fun updateTask() {
|
||||||
|
@ -50,7 +50,6 @@ import androidx.compose.ui.unit.sp
|
|||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||||
import coil.compose.AsyncImage
|
import coil.compose.AsyncImage
|
||||||
import com.blankj.utilcode.util.FileUtils
|
|
||||||
import com.blankj.utilcode.util.TimeUtils
|
import com.blankj.utilcode.util.TimeUtils
|
||||||
import com.blankj.utilcode.util.ToastUtils
|
import com.blankj.utilcode.util.ToastUtils
|
||||||
import com.za.base.Const
|
import com.za.base.Const
|
||||||
@ -64,14 +63,12 @@ import com.za.base.view.HeadView
|
|||||||
import com.za.bean.db.ele.EleCarDamagePhotoBean
|
import com.za.bean.db.ele.EleCarDamagePhotoBean
|
||||||
import com.za.bean.db.ele.EleWorkOrderBean
|
import com.za.bean.db.ele.EleWorkOrderBean
|
||||||
import com.za.common.GlobalData
|
import com.za.common.GlobalData
|
||||||
import com.za.common.util.AppFileManager
|
|
||||||
import com.za.common.util.ServicingSpeechManager
|
import com.za.common.util.ServicingSpeechManager
|
||||||
import com.za.ext.finish
|
import com.za.ext.finish
|
||||||
import com.za.ext.getLastSix
|
import com.za.ext.getLastSix
|
||||||
import com.za.ext.goNextPage
|
import com.za.ext.goNextPage
|
||||||
import com.za.servicing.R
|
import com.za.servicing.R
|
||||||
import com.za.ui.view.SignatureView
|
import com.za.ui.view.SignatureView
|
||||||
import java.io.File
|
|
||||||
import kotlin.math.ceil
|
import kotlin.math.ceil
|
||||||
|
|
||||||
@Preview
|
@Preview
|
||||||
@ -127,33 +124,6 @@ fun ConfirmEleScreen(vm : ConfirmEleVm = viewModel()) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
if (uiState.value.showServicePeopleSignDialog == true) {
|
|
||||||
CommonDialog(cancelText = "取消",
|
|
||||||
confirmText = "保存",
|
|
||||||
title = "是否将签名保存,以后的工单中默认使用此签名",
|
|
||||||
cancelEnable = true,
|
|
||||||
cancel = {
|
|
||||||
vm.dispatch(ConfirmEleVm.Action.UpdateState(uiState.value.copy(
|
|
||||||
showServicePeopleSignDialog = false)))
|
|
||||||
},
|
|
||||||
dismiss = {
|
|
||||||
vm.dispatch(ConfirmEleVm.Action.UpdateState(uiState.value.copy(
|
|
||||||
showServicePeopleSignDialog = false)))
|
|
||||||
},
|
|
||||||
confirm = {
|
|
||||||
if (uiState.value.eleWorkOrderBean?.localServicePeopleSignPath.isNullOrEmpty()) {
|
|
||||||
ToastUtils.showShort("请先进行签名")
|
|
||||||
vm.dispatch(ConfirmEleVm.Action.UpdateState(uiState.value.copy(
|
|
||||||
showServicePeopleSignDialog = false)))
|
|
||||||
return@CommonDialog
|
|
||||||
}
|
|
||||||
File(uiState.value.eleWorkOrderBean?.localServicePeopleSignPath ?: "").copyTo(File(
|
|
||||||
AppFileManager.getDriverSignPath(context)), true)
|
|
||||||
vm.dispatch(ConfirmEleVm.Action.UpdateState(uiState.value.copy(
|
|
||||||
showServicePeopleSignDialog = false)))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
if (uiState.value.showServiceSignatureUploadFailedDialog == true) {
|
if (uiState.value.showServiceSignatureUploadFailedDialog == true) {
|
||||||
CommonDialog(cancelText = "取消",
|
CommonDialog(cancelText = "取消",
|
||||||
confirmText = "离线上传",
|
confirmText = "离线上传",
|
||||||
@ -408,8 +378,8 @@ fun ConfirmEleScreen(vm : ConfirmEleVm = viewModel()) {
|
|||||||
}
|
}
|
||||||
vm.dispatch(ConfirmEleVm.Action.UpdateAcceptSignature(it))
|
vm.dispatch(ConfirmEleVm.Action.UpdateAcceptSignature(it))
|
||||||
},
|
},
|
||||||
serverPath = uiState.value.eleWorkOrderBean?.serverAcceptCarSignPath
|
serverPath = uiState.value.eleWorkOrderBean?.localAcceptCarSignPath
|
||||||
?: uiState.value.eleWorkOrderBean?.localAcceptCarSignPath)
|
?: uiState.value.eleWorkOrderBean?.serverAcceptCarSignPath)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -442,15 +412,9 @@ fun ConfirmEleScreen(vm : ConfirmEleVm = viewModel()) {
|
|||||||
return@SignatureView
|
return@SignatureView
|
||||||
}
|
}
|
||||||
vm.dispatch(ConfirmEleVm.Action.UploadServiceSignature(it))
|
vm.dispatch(ConfirmEleVm.Action.UploadServiceSignature(it))
|
||||||
|
|
||||||
if (! FileUtils.isFileExists(File(AppFileManager.getDriverSignPath(
|
|
||||||
context)))
|
|
||||||
) {
|
|
||||||
vm.updateState(uiState.value.copy(showServicePeopleSignDialog = true))
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
serverPath = uiState.value.eleWorkOrderBean?.serverServicePeopleSignPath
|
serverPath = uiState.value.eleWorkOrderBean?.localServicePeopleSignPath
|
||||||
?: uiState.value.eleWorkOrderBean?.localServicePeopleSignPath)
|
?: uiState.value.eleWorkOrderBean?.serverServicePeopleSignPath)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,8 +3,6 @@ package com.za.ui.servicing.order_confirm
|
|||||||
|
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import com.amap.api.location.AMapLocation
|
import com.amap.api.location.AMapLocation
|
||||||
import com.blankj.utilcode.util.ActivityUtils
|
|
||||||
import com.blankj.utilcode.util.FileUtils
|
|
||||||
import com.blankj.utilcode.util.NetworkUtils
|
import com.blankj.utilcode.util.NetworkUtils
|
||||||
import com.blankj.utilcode.util.ToastUtils
|
import com.blankj.utilcode.util.ToastUtils
|
||||||
import com.za.base.Const
|
import com.za.base.Const
|
||||||
@ -17,7 +15,6 @@ import com.za.bean.request.SaveEleOrderRequest
|
|||||||
import com.za.bean.request.UpdateTaskBean
|
import com.za.bean.request.UpdateTaskBean
|
||||||
import com.za.common.GlobalData
|
import com.za.common.GlobalData
|
||||||
import com.za.common.log.LogUtil
|
import com.za.common.log.LogUtil
|
||||||
import com.za.common.util.AppFileManager
|
|
||||||
import com.za.ext.toJson
|
import com.za.ext.toJson
|
||||||
import com.za.net.BaseObserver
|
import com.za.net.BaseObserver
|
||||||
import com.za.net.CommonMethod
|
import com.za.net.CommonMethod
|
||||||
@ -186,7 +183,8 @@ class ConfirmEleVm : IServicingVm<ConfirmEleVm.Action, ConfirmEleVm.UiState>() {
|
|||||||
} else null,
|
} else null,
|
||||||
hasSuccess = eleWorkOrderBean.isSuccess,
|
hasSuccess = eleWorkOrderBean.isSuccess,
|
||||||
recipientSignPath = eleWorkOrderBean.serverAcceptCarSignPath,
|
recipientSignPath = eleWorkOrderBean.serverAcceptCarSignPath,
|
||||||
waitstaffSignPath = eleWorkOrderBean.serverServicePeopleSignPath,
|
waitstaffSignPath = eleWorkOrderBean.serverServicePeopleSignPath
|
||||||
|
?: GlobalData.driverInfoBean?.signatureUrl,
|
||||||
eleState = 3,
|
eleState = 3,
|
||||||
userOrderId = getCurrentOrder()?.userOrderId)
|
userOrderId = getCurrentOrder()?.userOrderId)
|
||||||
insertOfflineTask(offlineUpdateTaskBean)
|
insertOfflineTask(offlineUpdateTaskBean)
|
||||||
@ -206,7 +204,8 @@ class ConfirmEleVm : IServicingVm<ConfirmEleVm.Action, ConfirmEleVm.UiState>() {
|
|||||||
} else null,
|
} else null,
|
||||||
hasSuccess = eleWorkOrderBean.isSuccess,
|
hasSuccess = eleWorkOrderBean.isSuccess,
|
||||||
recipientSignPath = eleWorkOrderBean.serverAcceptCarSignPath,
|
recipientSignPath = eleWorkOrderBean.serverAcceptCarSignPath,
|
||||||
waitstaffSignPath = eleWorkOrderBean.serverServicePeopleSignPath,
|
waitstaffSignPath = eleWorkOrderBean.serverServicePeopleSignPath
|
||||||
|
?: GlobalData.driverInfoBean?.signatureUrl,
|
||||||
eleState = 3,
|
eleState = 3,
|
||||||
userOrderId = getCurrentOrder()?.userOrderId)
|
userOrderId = getCurrentOrder()?.userOrderId)
|
||||||
insertOfflineTask(offlineUpdateTaskBean)
|
insertOfflineTask(offlineUpdateTaskBean)
|
||||||
@ -223,11 +222,12 @@ class ConfirmEleVm : IServicingVm<ConfirmEleVm.Action, ConfirmEleVm.UiState>() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getCurrentOrder()?.flowType != 2 && eleWorkOrderBean.isSuccess == null) {
|
if (getCurrentOrder()?.flowType != Const.TUO_CHE && eleWorkOrderBean.isSuccess == null) {
|
||||||
showTipDialog("请选择服务是否成功!")
|
showTipDialog("请选择服务是否成功!")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (uiState.value.isAddSmallWheel == true && uiState.value.wheelNum == null || uiState.value.wheelNum == 0) {
|
if (uiState.value.isAddSmallWheel == true && uiState.value.wheelNum == null || uiState.value.wheelNum == 0) {
|
||||||
showTipDialog("请输入辅助轮个数")
|
showTipDialog("请输入辅助轮个数")
|
||||||
return
|
return
|
||||||
@ -243,11 +243,16 @@ class ConfirmEleVm : IServicingVm<ConfirmEleVm.Action, ConfirmEleVm.UiState>() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (eleWorkOrderBean.localAcceptCarSignPath.isNullOrBlank() || eleWorkOrderBean.localServicePeopleSignPath.isNullOrBlank()) {
|
if (eleWorkOrderBean.localAcceptCarSignPath.isNullOrBlank()) {
|
||||||
showTipDialog("请先上传签名!")
|
showTipDialog("请先上传签名!")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (eleWorkOrderBean.serverServicePeopleSignPath.isNullOrBlank() && eleWorkOrderBean.localServicePeopleSignPath.isNullOrBlank()) {
|
||||||
|
showTipDialog("请上传服务人员签名!")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
LoadingManager.showLoading()
|
LoadingManager.showLoading()
|
||||||
ZdLocationManager.getSingleLocation(success = {
|
ZdLocationManager.getSingleLocation(success = {
|
||||||
LoadingManager.hideLoading()
|
LoadingManager.hideLoading()
|
||||||
@ -314,14 +319,7 @@ class ConfirmEleVm : IServicingVm<ConfirmEleVm.Action, ConfirmEleVm.UiState>() {
|
|||||||
orderInfo = getCurrentOrder()))
|
orderInfo = getCurrentOrder()))
|
||||||
|
|
||||||
LogUtil.print("电子表单更新车辆损伤照片", "eleWorkOrderBean==${photoList.toJson()}")
|
LogUtil.print("电子表单更新车辆损伤照片", "eleWorkOrderBean==${photoList.toJson()}")
|
||||||
|
LogUtil.print("电子表单", "eleWorkOrderBean==${it.toJson()}")
|
||||||
if (! it.localServicePeopleSignPath.isNullOrBlank() || ! it.serverServicePeopleSignPath.isNullOrBlank()) {
|
|
||||||
return@queryElectronOrder
|
|
||||||
}
|
|
||||||
|
|
||||||
if (FileUtils.isFileExists(File(AppFileManager.getDriverSignPath(context = ActivityUtils.getTopActivity())))) {
|
|
||||||
updateServiceSignature(AppFileManager.getDriverSignPath(context = ActivityUtils.getTopActivity()))
|
|
||||||
}
|
|
||||||
|
|
||||||
}, failed = {
|
}, failed = {
|
||||||
LoadingManager.hideLoading()
|
LoadingManager.hideLoading()
|
||||||
@ -354,6 +352,5 @@ class ConfirmEleVm : IServicingVm<ConfirmEleVm.Action, ConfirmEleVm.UiState>() {
|
|||||||
val showOfflineDialog : Boolean? = null,
|
val showOfflineDialog : Boolean? = null,
|
||||||
val showAcceptCarSignUploadFailedDialog : Boolean? = null,
|
val showAcceptCarSignUploadFailedDialog : Boolean? = null,
|
||||||
val showServiceSignatureUploadFailedDialog : Boolean? = null,
|
val showServiceSignatureUploadFailedDialog : Boolean? = null,
|
||||||
val showServicePeopleSignDialog : Boolean? = null, //服务人员签名弹窗
|
|
||||||
)
|
)
|
||||||
}
|
}
|
@ -21,9 +21,12 @@ import androidx.compose.foundation.layout.size
|
|||||||
import androidx.compose.foundation.layout.width
|
import androidx.compose.foundation.layout.width
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
|
import androidx.compose.foundation.text.KeyboardOptions
|
||||||
import androidx.compose.material3.HorizontalDivider
|
import androidx.compose.material3.HorizontalDivider
|
||||||
import androidx.compose.material3.Scaffold
|
import androidx.compose.material3.Scaffold
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.material3.TextField
|
||||||
|
import androidx.compose.material3.TextFieldDefaults
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
@ -35,7 +38,9 @@ import androidx.compose.ui.Modifier
|
|||||||
import androidx.compose.ui.draw.alpha
|
import androidx.compose.ui.draw.alpha
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
import androidx.compose.ui.text.TextStyle
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
|
import androidx.compose.ui.text.input.KeyboardType
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
@ -44,6 +49,7 @@ import coil.compose.AsyncImage
|
|||||||
import com.blankj.utilcode.util.ConvertUtils
|
import com.blankj.utilcode.util.ConvertUtils
|
||||||
import com.blankj.utilcode.util.ToastUtils
|
import com.blankj.utilcode.util.ToastUtils
|
||||||
import com.za.base.BaseActivity
|
import com.za.base.BaseActivity
|
||||||
|
import com.za.base.theme.bgColor
|
||||||
import com.za.base.theme.black65
|
import com.za.base.theme.black65
|
||||||
import com.za.base.theme.buttonBgColor
|
import com.za.base.theme.buttonBgColor
|
||||||
import com.za.base.view.CommonDialog
|
import com.za.base.view.CommonDialog
|
||||||
@ -195,6 +201,9 @@ fun VerifyOrderScreen(vm : VerifyOrderVm = viewModel()) {
|
|||||||
VerifyCarView(orderInfo = uiState.value.orderInfo,
|
VerifyCarView(orderInfo = uiState.value.orderInfo,
|
||||||
newCarVin = uiState.value.newCarVin,
|
newCarVin = uiState.value.newCarVin,
|
||||||
newCarVinPath = uiState.value.newCarPhotoPath,
|
newCarVinPath = uiState.value.newCarPhotoPath,
|
||||||
|
newCarChanged = {
|
||||||
|
vm.updateState(uiState.value.copy(newCarVin = it))
|
||||||
|
},
|
||||||
recognize = {
|
recognize = {
|
||||||
vm.dispatch(VerifyOrderVm.Action.Recognize(it))
|
vm.dispatch(VerifyOrderVm.Action.Recognize(it))
|
||||||
})
|
})
|
||||||
@ -237,6 +246,7 @@ fun VerifyOrderScreen(vm : VerifyOrderVm = viewModel()) {
|
|||||||
private fun VerifyCarView(
|
private fun VerifyCarView(
|
||||||
orderInfo : OrderInfo?,
|
orderInfo : OrderInfo?,
|
||||||
newCarVin : String? = null,
|
newCarVin : String? = null,
|
||||||
|
newCarChanged : (String?) -> Unit,
|
||||||
newCarVinPath : String? = null,
|
newCarVinPath : String? = null,
|
||||||
recognize : (String) -> Unit,
|
recognize : (String) -> Unit,
|
||||||
) {
|
) {
|
||||||
@ -298,10 +308,19 @@ private fun VerifyCarView(
|
|||||||
fontSize = 13.sp,
|
fontSize = 13.sp,
|
||||||
fontWeight = FontWeight.Medium)
|
fontWeight = FontWeight.Medium)
|
||||||
Spacer(modifier = Modifier.width(10.dp))
|
Spacer(modifier = Modifier.width(10.dp))
|
||||||
Text(text = newCarVin ?: "",
|
TextField(value = newCarVin ?: "",
|
||||||
fontWeight = FontWeight.Medium,
|
onValueChange = { newCarChanged(it) },
|
||||||
fontSize = 16.sp,
|
modifier = Modifier.background(color = bgColor,
|
||||||
color = Color.Black)
|
shape = RoundedCornerShape(4.dp)),
|
||||||
|
colors = TextFieldDefaults.colors()
|
||||||
|
.copy(focusedContainerColor = Color.Transparent,
|
||||||
|
focusedIndicatorColor = Color.Transparent,
|
||||||
|
unfocusedIndicatorColor = Color.Transparent,
|
||||||
|
unfocusedContainerColor = Color.Transparent),
|
||||||
|
keyboardOptions = KeyboardOptions.Default.copy(keyboardType = KeyboardType.Text),
|
||||||
|
textStyle = TextStyle.Default.copy(fontSize = 16.sp,
|
||||||
|
color = Color.Black,
|
||||||
|
fontWeight = FontWeight.Medium))
|
||||||
}
|
}
|
||||||
|
|
||||||
Spacer(modifier = Modifier.height(10.dp))
|
Spacer(modifier = Modifier.height(10.dp))
|
||||||
|
@ -5,6 +5,7 @@ import com.blankj.utilcode.util.ToastUtils
|
|||||||
import com.za.base.Const
|
import com.za.base.Const
|
||||||
import com.za.base.IServicingVm
|
import com.za.base.IServicingVm
|
||||||
import com.za.base.view.LoadingManager
|
import com.za.base.view.LoadingManager
|
||||||
|
import com.za.bean.UnifiedOCRWithCompressRequest
|
||||||
import com.za.bean.db.order.OrderInfo
|
import com.za.bean.db.order.OrderInfo
|
||||||
import com.za.bean.request.OrderPhotoOcrRecognizeRequest
|
import com.za.bean.request.OrderPhotoOcrRecognizeRequest
|
||||||
import com.za.bean.request.UpdateTaskBean
|
import com.za.bean.request.UpdateTaskBean
|
||||||
@ -45,7 +46,7 @@ class VerifyOrderVm : IServicingVm<VerifyOrderVm.Action, VerifyOrderVm.UiState>(
|
|||||||
LoadingManager.showLoading()
|
LoadingManager.showLoading()
|
||||||
CommonMethod.uploadImage(file = File(localPath), success = {
|
CommonMethod.uploadImage(file = File(localPath), success = {
|
||||||
LoadingManager.hideLoading()
|
LoadingManager.hideLoading()
|
||||||
if (it.isNullOrBlank() == true) {
|
if (it.isNullOrBlank()) {
|
||||||
return@uploadImage
|
return@uploadImage
|
||||||
}
|
}
|
||||||
doRecognize(it)
|
doRecognize(it)
|
||||||
@ -60,7 +61,8 @@ class VerifyOrderVm : IServicingVm<VerifyOrderVm.Action, VerifyOrderVm.UiState>(
|
|||||||
val orderPhotoOcrRecognizeRequest =
|
val orderPhotoOcrRecognizeRequest =
|
||||||
OrderPhotoOcrRecognizeRequest(GlobalData.currentOrder?.userOrderId, 2, uploadPath)
|
OrderPhotoOcrRecognizeRequest(GlobalData.currentOrder?.userOrderId, 2, uploadPath)
|
||||||
LogUtil.print("$tag doRecognize", "请求参数==${orderPhotoOcrRecognizeRequest.toJson()}")
|
LogUtil.print("$tag doRecognize", "请求参数==${orderPhotoOcrRecognizeRequest.toJson()}")
|
||||||
RetrofitHelper.getDefaultService().orderPhotoOcrRecognize(orderPhotoOcrRecognizeRequest)
|
val unifiedOCRWithCompressRequest= UnifiedOCRWithCompressRequest(ocrType = 4, imageUrl = uploadPath)
|
||||||
|
RetrofitHelper.getDefaultService().unifiedOCRWithCompress(unifiedOCRWithCompressRequest)
|
||||||
.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
|
.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
|
||||||
.subscribe(object : BaseObserver<String>() {
|
.subscribe(object : BaseObserver<String>() {
|
||||||
override fun doSuccess(it : String?) {
|
override fun doSuccess(it : String?) {
|
||||||
|
@ -13,12 +13,13 @@ import androidx.compose.foundation.layout.height
|
|||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.size
|
import androidx.compose.foundation.layout.size
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
import androidx.compose.material3.CenterAlignedTopAppBar
|
import androidx.compose.material.icons.Icons
|
||||||
|
import androidx.compose.material.icons.filled.KeyboardArrowLeft
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.material3.HorizontalDivider
|
import androidx.compose.material3.HorizontalDivider
|
||||||
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.ModalBottomSheet
|
import androidx.compose.material3.ModalBottomSheet
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.material3.TopAppBarDefaults
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
@ -27,6 +28,7 @@ import androidx.compose.ui.Alignment
|
|||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
import androidx.compose.ui.text.TextStyle
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
@ -40,7 +42,6 @@ import com.za.base.view.CommonDialog
|
|||||||
import com.za.bean.db.order.OrderInfo
|
import com.za.bean.db.order.OrderInfo
|
||||||
import com.za.common.util.MapUtil
|
import com.za.common.util.MapUtil
|
||||||
import com.za.ext.callPhone
|
import com.za.ext.callPhone
|
||||||
import com.za.ext.finish
|
|
||||||
import com.za.servicing.R
|
import com.za.servicing.R
|
||||||
import com.za.ui.servicing.in_servicing_setting.OrderRequirementsActivity
|
import com.za.ui.servicing.in_servicing_setting.OrderRequirementsActivity
|
||||||
import com.za.ui.servicing.order_give_up.OrderGiveUpActivity
|
import com.za.ui.servicing.order_give_up.OrderGiveUpActivity
|
||||||
@ -207,23 +208,25 @@ fun InServicingHeadView(title : String,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Column {
|
|
||||||
|
|
||||||
CenterAlignedTopAppBar(modifier = Modifier.fillMaxWidth(),
|
Column {
|
||||||
colors = TopAppBarDefaults.centerAlignedTopAppBarColors()
|
Box(modifier = Modifier
|
||||||
.copy(containerColor = headBgColor, titleContentColor = Color.White),
|
.fillMaxWidth()
|
||||||
title = { Text(text = title, fontSize = 15.sp, fontWeight = FontWeight.Medium) },
|
.background(color = headBgColor)
|
||||||
navigationIcon = {
|
.padding(horizontal = 10.dp, vertical = 5.dp), contentAlignment = Alignment.Center) {
|
||||||
|
|
||||||
|
Row(modifier = Modifier.fillMaxWidth(),
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
horizontalArrangement = Arrangement.SpaceBetween) {
|
||||||
|
|
||||||
if (isCanBack) {
|
if (isCanBack) {
|
||||||
AsyncImage(model = R.drawable.sv_back,
|
Icon(Icons.Default.KeyboardArrowLeft,
|
||||||
contentDescription = "",
|
contentDescription = "",
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.size(40.dp)
|
|
||||||
.clickable { onBack() }
|
.clickable { onBack() }
|
||||||
.padding(10.dp))
|
.padding(5.dp),
|
||||||
|
tint = Color.White)
|
||||||
}
|
}
|
||||||
},
|
|
||||||
actions = {
|
|
||||||
Box(modifier = Modifier
|
Box(modifier = Modifier
|
||||||
.size(46.dp)
|
.size(46.dp)
|
||||||
.clickable {
|
.clickable {
|
||||||
@ -236,7 +239,16 @@ fun InServicingHeadView(title : String,
|
|||||||
contentDescription = "",
|
contentDescription = "",
|
||||||
modifier = Modifier.fillMaxSize())
|
modifier = Modifier.fillMaxSize())
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
|
||||||
|
Box(modifier = Modifier.fillMaxWidth(), contentAlignment = Alignment.Center) {
|
||||||
|
Text(text = title,
|
||||||
|
fontSize = 16.sp,
|
||||||
|
color = Color.White.copy(alpha = 0.95f),
|
||||||
|
fontWeight = FontWeight.Medium,
|
||||||
|
style = TextStyle.Default.copy())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
AppTipsView()
|
AppTipsView()
|
||||||
}
|
}
|
||||||
|
12
servicing/src/main/res/drawable/sv_browth.xml
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="128dp"
|
||||||
|
android:height="128dp"
|
||||||
|
android:viewportWidth="1024"
|
||||||
|
android:viewportHeight="1024">
|
||||||
|
<path
|
||||||
|
android:pathData="M664.9,359.1a35.2,35.2 0,0 1,8.5 36l-64,192a35.2,35.2 0,0 1,-22.3 22.3l-192,64a35.2,35.2 0,0 1,-44.5 -44.5l64,-192a35.2,35.2 0,0 1,22.3 -22.3l192,-64a35.2,35.2 0,0 1,36 8.5zM475.8,475.8L439.7,584.3l108.5,-36.2 36.2,-108.5 -108.5,36.2z"
|
||||||
|
android:fillColor="#ffffff"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M512,819.2a307.2,307.2 0,1 0,0 -614.4,307.2 307.2,0 0,0 0,614.4zM896,512A384,384 0,1 1,128 512a384,384 0,0 1,768 0z"
|
||||||
|
android:fillColor="#ffffff"/>
|
||||||
|
</vector>
|
BIN
servicing/src/main/res/mipmap-xhdpi/bg_car_left_back.jpg
Normal file
After Width: | Height: | Size: 18 KiB |
BIN
servicing/src/main/res/mipmap-xhdpi/bg_car_left_front.jpg
Normal file
After Width: | Height: | Size: 21 KiB |
BIN
servicing/src/main/res/mipmap-xhdpi/bg_car_right_back.jpg
Normal file
After Width: | Height: | Size: 17 KiB |
BIN
servicing/src/main/res/mipmap-xhdpi/bg_car_right_front.jpg
Normal file
After Width: | Height: | Size: 21 KiB |
BIN
servicing/src/main/res/mipmap-xhdpi/bg_dest_car_oil.jpg
Normal file
After Width: | Height: | Size: 34 KiB |
BIN
servicing/src/main/res/mipmap-xhdpi/bg_dilemma_left_back.jpg
Normal file
After Width: | Height: | Size: 30 KiB |
BIN
servicing/src/main/res/mipmap-xhdpi/bg_dilemma_left_front.jpg
Normal file
After Width: | Height: | Size: 28 KiB |
BIN
servicing/src/main/res/mipmap-xhdpi/bg_dilemma_right_back.jpg
Normal file
After Width: | Height: | Size: 57 KiB |
BIN
servicing/src/main/res/mipmap-xhdpi/bg_dilemma_right_front.jpg
Normal file
After Width: | Height: | Size: 75 KiB |
BIN
servicing/src/main/res/mipmap-xhdpi/bg_licenses.jpg
Normal file
After Width: | Height: | Size: 54 KiB |
BIN
servicing/src/main/res/mipmap-xhdpi/bg_water_tank_empty.jpg
Normal file
After Width: | Height: | Size: 21 KiB |
BIN
servicing/src/main/res/mipmap-xhdpi/bg_water_tank_full.jpg
Normal file
After Width: | Height: | Size: 21 KiB |
BIN
servicing/src/main/res/mipmap-xhdpi/car_and_driver.jpg
Normal file
After Width: | Height: | Size: 76 KiB |
BIN
servicing/src/main/res/mipmap-xhdpi/car_and_driver_pingan.jpg
Normal file
After Width: | Height: | Size: 23 KiB |
BIN
servicing/src/main/res/mipmap-xhdpi/car_front.jpg
Normal file
After Width: | Height: | Size: 47 KiB |
BIN
servicing/src/main/res/mipmap-xhdpi/dadian.png
Normal file
After Width: | Height: | Size: 259 KiB |
BIN
servicing/src/main/res/mipmap-xhdpi/dadian_device.jpg
Normal file
After Width: | Height: | Size: 36 KiB |
BIN
servicing/src/main/res/mipmap-xhdpi/dashboard_photo.jpg
Normal file
After Width: | Height: | Size: 212 KiB |
BIN
servicing/src/main/res/mipmap-xhdpi/ferry_sample.jpg
Normal file
After Width: | Height: | Size: 24 KiB |
BIN
servicing/src/main/res/mipmap-xhdpi/finish_loading.jpg
Normal file
After Width: | Height: | Size: 135 KiB |
BIN
servicing/src/main/res/mipmap-xhdpi/huantai_photo.png
Normal file
After Width: | Height: | Size: 163 KiB |
BIN
servicing/src/main/res/mipmap-xhdpi/huantai_success.jpg
Normal file
After Width: | Height: | Size: 55 KiB |
BIN
servicing/src/main/res/mipmap-xhdpi/invoice_sample.png
Normal file
After Width: | Height: | Size: 394 KiB |
BIN
servicing/src/main/res/mipmap-xhdpi/kunjing.jpg
Normal file
After Width: | Height: | Size: 153 KiB |
After Width: | Height: | Size: 52 KiB |
After Width: | Height: | Size: 93 KiB |
BIN
servicing/src/main/res/mipmap-xhdpi/no_oil.jpg
Normal file
After Width: | Height: | Size: 47 KiB |
BIN
servicing/src/main/res/mipmap-xhdpi/plight_vehicle.png
Normal file
After Width: | Height: | Size: 153 KiB |
BIN
servicing/src/main/res/mipmap-xhdpi/trailer_3.jpg
Normal file
After Width: | Height: | Size: 87 KiB |
BIN
servicing/src/main/res/mipmap-xhdpi/tyre_inflate_ing.jpg
Normal file
After Width: | Height: | Size: 21 KiB |
BIN
servicing/src/main/res/mipmap-xhdpi/tyre_inflate_ing_success.jpg
Normal file
After Width: | Height: | Size: 45 KiB |
BIN
servicing/src/main/res/mipmap-xhdpi/tyre_inflate_pre.jpg
Normal file
After Width: | Height: | Size: 25 KiB |
BIN
servicing/src/main/res/mipmap-xhdpi/tyre_pre.jpg
Normal file
After Width: | Height: | Size: 192 KiB |
BIN
servicing/src/main/res/mipmap-xhdpi/vehicle_escape.png
Normal file
After Width: | Height: | Size: 134 KiB |
BIN
servicing/src/main/res/mipmap-xhdpi/vin_photo.jpg
Normal file
After Width: | Height: | Size: 68 KiB |
BIN
servicing/src/main/res/mipmap-xhdpi/work_order1.png
Normal file
After Width: | Height: | Size: 105 KiB |
BIN
servicing/src/main/res/mipmap-xxhdpi/bg_byd_dest_car_mans.jpg
Normal file
After Width: | Height: | Size: 37 KiB |
BIN
servicing/src/main/res/mipmap-xxhdpi/bg_underground.jpg
Normal file
After Width: | Height: | Size: 70 KiB |
BIN
servicing/src/main/res/mipmap-xxhdpi/damage_photo.jpg
Normal file
After Width: | Height: | Size: 70 KiB |