diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..0296a22
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,28 @@
+# ---> Kotlin
+# Compiled class file
+*.class
+
+# Log file
+*.log
+
+# BlueJ files
+*.ctxt
+
+# Mobile Tools for Java (J2ME)
+.mtj.tmp/
+
+# Package Files #
+*.jar
+*.war
+*.nar
+*.ear
+*.zip
+*.tar.gz
+*.rar
+
+# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
+hs_err_pid*
+replay_pid*
+
+# Kotlin Gradle plugin data, see https://kotlinlang.org/docs/whatsnew20.html#new-directory-for-kotlin-data-in-gradle-projects
+.kotlin/
diff --git a/.gradle/8.13/checksums/checksums.lock b/.gradle/8.13/checksums/checksums.lock
new file mode 100644
index 0000000..599a56d
Binary files /dev/null and b/.gradle/8.13/checksums/checksums.lock differ
diff --git a/.gradle/8.13/checksums/md5-checksums.bin b/.gradle/8.13/checksums/md5-checksums.bin
new file mode 100644
index 0000000..b286f8c
Binary files /dev/null and b/.gradle/8.13/checksums/md5-checksums.bin differ
diff --git a/.gradle/8.13/checksums/sha1-checksums.bin b/.gradle/8.13/checksums/sha1-checksums.bin
new file mode 100644
index 0000000..3876b6b
Binary files /dev/null and b/.gradle/8.13/checksums/sha1-checksums.bin differ
diff --git a/.gradle/8.13/executionHistory/executionHistory.bin b/.gradle/8.13/executionHistory/executionHistory.bin
new file mode 100644
index 0000000..e7e43d9
Binary files /dev/null and b/.gradle/8.13/executionHistory/executionHistory.bin differ
diff --git a/.gradle/8.13/executionHistory/executionHistory.lock b/.gradle/8.13/executionHistory/executionHistory.lock
new file mode 100644
index 0000000..4439e13
Binary files /dev/null and b/.gradle/8.13/executionHistory/executionHistory.lock differ
diff --git a/.gradle/8.13/fileChanges/last-build.bin b/.gradle/8.13/fileChanges/last-build.bin
new file mode 100644
index 0000000..f76dd23
Binary files /dev/null and b/.gradle/8.13/fileChanges/last-build.bin differ
diff --git a/.gradle/8.13/fileHashes/fileHashes.bin b/.gradle/8.13/fileHashes/fileHashes.bin
new file mode 100644
index 0000000..ad6a029
Binary files /dev/null and b/.gradle/8.13/fileHashes/fileHashes.bin differ
diff --git a/.gradle/8.13/fileHashes/fileHashes.lock b/.gradle/8.13/fileHashes/fileHashes.lock
new file mode 100644
index 0000000..a01f6c6
Binary files /dev/null and b/.gradle/8.13/fileHashes/fileHashes.lock differ
diff --git a/.gradle/8.13/fileHashes/resourceHashesCache.bin b/.gradle/8.13/fileHashes/resourceHashesCache.bin
new file mode 100644
index 0000000..b2a8d69
Binary files /dev/null and b/.gradle/8.13/fileHashes/resourceHashesCache.bin differ
diff --git a/.gradle/8.13/gc.properties b/.gradle/8.13/gc.properties
new file mode 100644
index 0000000..e69de29
diff --git a/.gradle/buildOutputCleanup/buildOutputCleanup.lock b/.gradle/buildOutputCleanup/buildOutputCleanup.lock
new file mode 100644
index 0000000..2b92173
Binary files /dev/null and b/.gradle/buildOutputCleanup/buildOutputCleanup.lock differ
diff --git a/.gradle/buildOutputCleanup/cache.properties b/.gradle/buildOutputCleanup/cache.properties
new file mode 100644
index 0000000..4d839be
--- /dev/null
+++ b/.gradle/buildOutputCleanup/cache.properties
@@ -0,0 +1,2 @@
+#Thu Jul 30 09:08:42 CST 2026
+gradle.version=8.13
diff --git a/.gradle/buildOutputCleanup/outputFiles.bin b/.gradle/buildOutputCleanup/outputFiles.bin
new file mode 100644
index 0000000..98a73af
Binary files /dev/null and b/.gradle/buildOutputCleanup/outputFiles.bin differ
diff --git a/.gradle/config.properties b/.gradle/config.properties
new file mode 100644
index 0000000..fbc4ecd
--- /dev/null
+++ b/.gradle/config.properties
@@ -0,0 +1,2 @@
+#Thu Jul 30 09:08:52 CST 2026
+java.home=D\:\\Program Files\\Android\\Android Studio\\jbr
diff --git a/.gradle/file-system.probe b/.gradle/file-system.probe
new file mode 100644
index 0000000..924a278
Binary files /dev/null and b/.gradle/file-system.probe differ
diff --git a/.gradle/vcs-1/gc.properties b/.gradle/vcs-1/gc.properties
new file mode 100644
index 0000000..e69de29
diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..26d3352
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/.idea/.name b/.idea/.name
new file mode 100644
index 0000000..7027b29
--- /dev/null
+++ b/.idea/.name
@@ -0,0 +1 @@
+CkCollar_app
\ No newline at end of file
diff --git a/.idea/AndroidProjectSystem.xml b/.idea/AndroidProjectSystem.xml
new file mode 100644
index 0000000..4a53bee
--- /dev/null
+++ b/.idea/AndroidProjectSystem.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/caches/deviceStreaming.xml b/.idea/caches/deviceStreaming.xml
new file mode 100644
index 0000000..f5d5fce
--- /dev/null
+++ b/.idea/caches/deviceStreaming.xml
@@ -0,0 +1,2229 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
new file mode 100644
index 0000000..b86273d
--- /dev/null
+++ b/.idea/compiler.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/deploymentTargetSelector.xml b/.idea/deploymentTargetSelector.xml
new file mode 100644
index 0000000..ca16a99
--- /dev/null
+++ b/.idea/deploymentTargetSelector.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/gradle.xml b/.idea/gradle.xml
new file mode 100644
index 0000000..639c779
--- /dev/null
+++ b/.idea/gradle.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/markdown.xml b/.idea/markdown.xml
new file mode 100644
index 0000000..c61ea33
--- /dev/null
+++ b/.idea/markdown.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/migrations.xml b/.idea/migrations.xml
new file mode 100644
index 0000000..f8051a6
--- /dev/null
+++ b/.idea/migrations.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..f7608ed
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules/app/CkCollar_app.app.main.iml b/.idea/modules/app/CkCollar_app.app.main.iml
new file mode 100644
index 0000000..acdd03a
--- /dev/null
+++ b/.idea/modules/app/CkCollar_app.app.main.iml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml
new file mode 100644
index 0000000..16660f1
--- /dev/null
+++ b/.idea/runConfigurations.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..35eb1dd
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 0000000..c5f3f6b
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,3 @@
+{
+ "java.configuration.updateBuildConfiguration": "interactive"
+}
\ No newline at end of file
diff --git a/android_123456.keystore b/android_123456.keystore
new file mode 100644
index 0000000..bf7debb
Binary files /dev/null and b/android_123456.keystore differ
diff --git a/app/.gitignore b/app/.gitignore
new file mode 100644
index 0000000..42afabf
--- /dev/null
+++ b/app/.gitignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
new file mode 100644
index 0000000..9e4f9c0
--- /dev/null
+++ b/app/build.gradle
@@ -0,0 +1,159 @@
+plugins {
+ alias(libs.plugins.android.application)
+ alias(libs.plugins.kotlin.android)
+ id('kotlin-kapt')
+
+}
+
+android {
+ signingConfigs {
+ release {
+ storeFile file('../android_123456.keystore')
+ keyAlias 'tangtang_app'
+ keyPassword '123456'
+ storePassword '123456'
+ }
+ debug {
+ storeFile file('../android_123456.keystore')
+ keyAlias 'tangtang_app'
+ keyPassword '123456'
+ storePassword '123456'
+ }
+ config {
+ storeFile file('../android_123456.keystore')
+ keyAlias 'tangtang_app'
+ keyPassword '123456'
+ storePassword '123456'
+ }
+ }
+ namespace 'com.ck.ckcollar.app'
+ compileSdk {
+ version = release(36)
+ }
+
+ defaultConfig {
+ applicationId "com.ck.ckcollar.app"
+ minSdk 24
+ targetSdk 36
+ versionCode 1
+ versionName "1.0.1"
+
+ testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+ }
+
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+ }
+ }
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_11
+ targetCompatibility JavaVersion.VERSION_11
+
+ }
+ kotlinOptions {
+ jvmTarget = '11'
+ }
+ buildFeatures {
+ viewBinding = true
+ }
+}
+
+tasks.register('testClasses') {
+ dependsOn 'compileDebugUnitTestSources'
+}
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
+ implementation(name: 'library', ext: 'aar')
+ implementation(name: 'changeskin', ext: 'aar')
+ implementation(name: 'pickerview', ext: 'aar')
+ implementation(name: 'wheelview', ext: 'aar')
+ implementation(name: 'MNMLKitScanner', ext: 'aar')
+ implementation(name: 'Flowlayout', ext: 'aar')
+ implementation(name: 'photoview', ext: 'aar')
+
+ implementation libs.androidx.core.ktx
+ implementation libs.androidx.lifecycle.runtime.ktx
+ implementation libs.androidx.activity.compose
+ implementation platform(libs.androidx.compose.bom)
+ implementation libs.androidx.compose.ui
+ implementation libs.androidx.compose.ui.graphics
+ implementation libs.androidx.compose.ui.tooling.preview
+ implementation libs.androidx.compose.material3
+ implementation libs.material
+ implementation libs.appcompat
+ testImplementation libs.junit
+ androidTestImplementation libs.androidx.junit
+ androidTestImplementation libs.androidx.espresso.core
+ androidTestImplementation platform(libs.androidx.compose.bom)
+ androidTestImplementation libs.androidx.compose.ui.test.junit4
+ debugImplementation libs.androidx.compose.ui.tooling
+ debugImplementation libs.androidx.compose.ui.test.manifest
+
+ //可侧滑recyclerview
+ implementation 'com.yanzhenjie.recyclerview:x:1.3.2'
+
+ //glide
+ //implementation("com.github.bumptech.glide:glide:4.16.0")
+ implementation 'com.github.bumptech.glide:glide:5.0.5'
+ kapt 'com.github.bumptech.glide:compiler:5.0.5' // 对于Kotlin项目
+
+
+ implementation 'com.squareup.okhttp3:okhttp:4.12.0'
+ implementation 'com.squareup.okhttp3:logging-interceptor:4.12.0'
+ implementation 'com.squareup.okhttp3:okhttp-sse:4.12.0'
+
+ implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
+ implementation("pub.devrel:easypermissions:3.0.0")
+
+ implementation 'com.readystatesoftware.systembartint:systembartint:1.0.3'
+ implementation("org.osmdroid:osmdroid-android:6.1.20")
+
+ api 'com.alipay.sdk:alipaysdk-android:+@aar'
+// implementation 'com.alipay.sdk:zmcredit-face:3.8.2'
+//
+// implementation 'com.alipay.sdk:zmcert-sdk:3.8.0'
+
+ api 'com.tencent.mm.opensdk:wechat-sdk-android:6.8.0'
+
+ //二维码三方库
+// implementation 'com.github.maning0303:MNMLKitScanner:V1.0.4'
+ implementation 'com.google.mlkit:barcode-scanning:17.0.2'
+ implementation "androidx.camera:camera-core:1.0.2"
+ implementation "androidx.camera:camera-camera2:1.0.2"
+ implementation "androidx.camera:camera-lifecycle:1.0.2"
+ implementation "androidx.camera:camera-view:1.0.0-alpha25"
+
+
+ implementation ("com.huawei.hms:scanplus:2.9.0.300")
+
+ //
+ implementation("com.geyifeng.immersionbar:immersionbar:3.2.2")
+ // kotlin扩展(可选)
+ implementation("com.geyifeng.immersionbar:immersionbar-ktx:3.2.2")
+
+ implementation 'io.github.youth5201314:banner:2.2.3'
+
+ implementation 'com.kyleduo.switchbutton:library:2.1.0'
+ implementation 'com.github.zcweng:switch-button:0.0.3@aar'
+
+ implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.1.0-alpha-14'
+ implementation 'com.scwang.smart:refresh-header-classics:2.0.1'
+ implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.1.0")
+
+ //图片
+ //支付宝
+ api 'com.alipay.sdk:alipaysdk-android:+@aar'
+
+ //websocket
+ implementation 'org.java-websocket:Java-WebSocket:1.5.2'
+
+ implementation 'com.umeng.umsdk:common:9.4.7'// 必选
+ implementation 'com.umeng.umsdk:asms:1.4.0'// 必选
+ implementation 'com.umeng.umsdk:apm:+'
+
+ implementation 'com.github.yyued:SVGAPlayer-Android:2.6.1'
+
+}
\ No newline at end of file
diff --git a/app/libs/Flowlayout.aar b/app/libs/Flowlayout.aar
new file mode 100644
index 0000000..6e69816
Binary files /dev/null and b/app/libs/Flowlayout.aar differ
diff --git a/app/libs/MNMLKitScanner.aar b/app/libs/MNMLKitScanner.aar
new file mode 100644
index 0000000..2bd4356
Binary files /dev/null and b/app/libs/MNMLKitScanner.aar differ
diff --git a/app/libs/changeskin.aar b/app/libs/changeskin.aar
new file mode 100644
index 0000000..ba03e5c
Binary files /dev/null and b/app/libs/changeskin.aar differ
diff --git a/app/libs/library.aar b/app/libs/library.aar
new file mode 100644
index 0000000..79790cf
Binary files /dev/null and b/app/libs/library.aar differ
diff --git a/app/libs/photoview.aar b/app/libs/photoview.aar
new file mode 100644
index 0000000..e386645
Binary files /dev/null and b/app/libs/photoview.aar differ
diff --git a/app/libs/pickerview.aar b/app/libs/pickerview.aar
new file mode 100644
index 0000000..c2655c7
Binary files /dev/null and b/app/libs/pickerview.aar differ
diff --git a/app/libs/wheelview.aar b/app/libs/wheelview.aar
new file mode 100644
index 0000000..c650cd0
Binary files /dev/null and b/app/libs/wheelview.aar differ
diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro
new file mode 100644
index 0000000..bc4cbea
--- /dev/null
+++ b/app/proguard-rules.pro
@@ -0,0 +1,51 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
+
+-keep class com.tencent.mm.opensdk.** {
+ *;
+}
+
+-keep class com.tencent.wxop.** {
+ *;
+}
+
+-keep class com.tencent.mm.sdk.** {
+ *;
+}
+-keep class com.uc.** {*;}
+
+-keep class com.efs.** {*;}
+
+-keep class com.umeng.** {*;}
+
+-keep class org.repackage.** {*;}
+
+-keep class com.uyumao.** { *; }
+
+-keepclassmembers class * {
+ public (org.json.JSONObject);
+}
+
+-keepclassmembers enum * {
+ public static **[] values();
+ public static ** valueOf(java.lang.String);
+}
\ No newline at end of file
diff --git a/app/release/baselineProfiles/0/app-release.dm b/app/release/baselineProfiles/0/app-release.dm
new file mode 100644
index 0000000..82988b1
Binary files /dev/null and b/app/release/baselineProfiles/0/app-release.dm differ
diff --git a/app/release/baselineProfiles/1/app-release.dm b/app/release/baselineProfiles/1/app-release.dm
new file mode 100644
index 0000000..2c26658
Binary files /dev/null and b/app/release/baselineProfiles/1/app-release.dm differ
diff --git a/app/release/output-metadata.json b/app/release/output-metadata.json
new file mode 100644
index 0000000..6f3af63
--- /dev/null
+++ b/app/release/output-metadata.json
@@ -0,0 +1,37 @@
+{
+ "version": 3,
+ "artifactType": {
+ "type": "APK",
+ "kind": "Directory"
+ },
+ "applicationId": "com.ck.ckcollar.app",
+ "variantName": "release",
+ "elements": [
+ {
+ "type": "SINGLE",
+ "filters": [],
+ "attributes": [],
+ "versionCode": 1,
+ "versionName": "1.0.1",
+ "outputFile": "app-release.apk"
+ }
+ ],
+ "elementType": "File",
+ "baselineProfiles": [
+ {
+ "minApi": 28,
+ "maxApi": 30,
+ "baselineProfiles": [
+ "baselineProfiles/1/app-release.dm"
+ ]
+ },
+ {
+ "minApi": 31,
+ "maxApi": 2147483647,
+ "baselineProfiles": [
+ "baselineProfiles/0/app-release.dm"
+ ]
+ }
+ ],
+ "minSdkVersionForDexing": 24
+}
\ No newline at end of file
diff --git a/app/src/androidTest/java/com/ck/ckcollar/app/ExampleInstrumentedTest.kt b/app/src/androidTest/java/com/ck/ckcollar/app/ExampleInstrumentedTest.kt
new file mode 100644
index 0000000..7107436
--- /dev/null
+++ b/app/src/androidTest/java/com/ck/ckcollar/app/ExampleInstrumentedTest.kt
@@ -0,0 +1,24 @@
+package com.ck.ckcollar.app
+
+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.ck.ckcollar.app", appContext.packageName)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..cc983e8
--- /dev/null
+++ b/app/src/main/AndroidManifest.xml
@@ -0,0 +1,329 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/assets/province.json b/app/src/main/assets/province.json
new file mode 100644
index 0000000..2166cb4
--- /dev/null
+++ b/app/src/main/assets/province.json
@@ -0,0 +1,5354 @@
+[
+ {
+ "name": "北京市",
+ "city": [
+ {
+ "name": "北京市",
+ "area": [
+ "东城区",
+ "西城区",
+ "崇文区",
+ "宣武区",
+ "朝阳区",
+ "丰台区",
+ "石景山区",
+ "海淀区",
+ "门头沟区",
+ "房山区",
+ "通州区",
+ "顺义区",
+ "昌平区",
+ "大兴区",
+ "平谷区",
+ "怀柔区",
+ "密云县",
+ "延庆县"
+ ]
+ }
+ ]
+ },
+ {
+ "name": "天津市",
+ "city": [
+ {
+ "name": "天津市",
+ "area": [
+ "和平区",
+ "河东区",
+ "河西区",
+ "南开区",
+ "河北区",
+ "红桥区",
+ "塘沽区",
+ "汉沽区",
+ "大港区",
+ "东丽区",
+ "西青区",
+ "津南区",
+ "北辰区",
+ "武清区",
+ "宝坻区",
+ "宁河县",
+ "静海县",
+ "蓟 县"
+ ]
+ }
+ ]
+ },
+ {
+ "name": "河北省",
+ "city": [
+ {
+ "name": "石家庄市",
+ "area": [
+ "长安区",
+ "桥东区",
+ "桥西区",
+ "新华区",
+ "郊 区",
+ "井陉矿区",
+ "井陉县",
+ "正定县",
+ "栾城县",
+ "行唐县",
+ "灵寿县",
+ "高邑县",
+ "深泽县",
+ "赞皇县",
+ "无极县",
+ "平山县",
+ "元氏县",
+ "赵 县",
+ "辛集市",
+ "藁",
+ "晋州市",
+ "新乐市",
+ "鹿泉市"
+ ]
+ },
+ {
+ "name": "唐山市",
+ "area": [
+ "路南区",
+ "路北区",
+ "古冶区",
+ "开平区",
+ "新 区",
+ "丰润县",
+ "滦 县",
+ "滦南县",
+ "乐亭县",
+ "迁西县",
+ "玉田县",
+ "唐海县",
+ "遵化市",
+ "丰南市",
+ "迁安市"
+ ]
+ },
+ {
+ "name": "秦皇岛市",
+ "area": [
+ "海港区",
+ "山海关区",
+ "北戴河区",
+ "青龙满族自治县",
+ "昌黎县",
+ "抚宁县",
+ "卢龙县"
+ ]
+ },
+ {
+ "name": "邯郸市",
+ "area": [
+ "邯山区",
+ "丛台区",
+ "复兴区",
+ "峰峰矿区",
+ "邯郸县",
+ "临漳县",
+ "成安县",
+ "大名县",
+ "涉 县",
+ "磁 县",
+ "肥乡县",
+ "永年县",
+ "邱 县",
+ "鸡泽县",
+ "广平县",
+ "馆陶县",
+ "魏 县",
+ "曲周县",
+ "武安市"
+ ]
+ },
+ {
+ "name": "邢台市",
+ "area": [
+ "桥东区",
+ "桥西区",
+ "邢台县",
+ "临城县",
+ "内丘县",
+ "柏乡县",
+ "隆尧县",
+ "任 县",
+ "南和县",
+ "宁晋县",
+ "巨鹿县",
+ "新河县",
+ "广宗县",
+ "平乡县",
+ "威 县",
+ "清河县",
+ "临西县",
+ "南宫市",
+ "沙河市"
+ ]
+ },
+ {
+ "name": "保定市",
+ "area": [
+ "新市区",
+ "北市区",
+ "南市区",
+ "满城县",
+ "清苑县",
+ "涞水县",
+ "阜平县",
+ "徐水县",
+ "定兴县",
+ "唐 县",
+ "高阳县",
+ "容城县",
+ "涞源县",
+ "望都县",
+ "安新县",
+ "易 县",
+ "曲阳县",
+ "蠡 县",
+ "顺平县",
+ "博野",
+ "雄县",
+ "涿州市",
+ "定州市",
+ "安国市",
+ "高碑店市"
+ ]
+ },
+ {
+ "name": "张家口",
+ "area": [
+ "桥东区",
+ "桥西区",
+ "宣化区",
+ "下花园区",
+ "宣化县",
+ "张北县",
+ "康保县",
+ "沽源县",
+ "尚义县",
+ "蔚 县",
+ "阳原县",
+ "怀安县",
+ "万全县",
+ "怀来县",
+ "涿鹿县",
+ "赤城县",
+ "崇礼县"
+ ]
+ },
+ {
+ "name": "承德市",
+ "area": [
+ "双桥区",
+ "双滦区",
+ "鹰手营子矿区",
+ "承德县",
+ "兴隆县",
+ "平泉县",
+ "滦平县",
+ "隆化县",
+ "丰宁满族自治县",
+ "宽城满族自治县",
+ "围场满族蒙古族自治县"
+ ]
+ },
+ {
+ "name": "沧州市",
+ "area": [
+ "新华区",
+ "运河区",
+ "沧 县",
+ "青 县",
+ "东光县",
+ "海兴县",
+ "盐山县",
+ "肃宁县",
+ "南皮县",
+ "吴桥县",
+ "献 县",
+ "孟村回族自治县",
+ "泊头市",
+ "任丘市",
+ "黄骅市",
+ "河间市"
+ ]
+ },
+ {
+ "name": "廊坊市",
+ "area": [
+ "安次区",
+ "固安县",
+ "永清县",
+ "香河县",
+ "大城县",
+ "文安县",
+ "大厂回族自治县",
+ "霸州市",
+ "三河市"
+ ]
+ },
+ {
+ "name": "衡水市",
+ "area": [
+ "桃城区",
+ "枣强县",
+ "武邑县",
+ "武强县",
+ "饶阳县",
+ "安平县",
+ "故城县",
+ "景 县",
+ "阜城县",
+ "冀州市",
+ "深州市"
+ ]
+ }
+ ]
+ },
+ {
+ "name": "山西省",
+ "city": [
+ {
+ "name": "太原市",
+ "area": [
+ "小店区",
+ "迎泽区",
+ "杏花岭区",
+ "尖草坪区",
+ "万柏林区",
+ "晋源区",
+ "清徐县",
+ "阳曲县",
+ "娄烦县",
+ "古交市"
+ ]
+ },
+ {
+ "name": "大同市",
+ "area": [
+ "城 区",
+ "矿 区",
+ "南郊区",
+ "新荣区",
+ "阳高县",
+ "天镇县",
+ "广灵县",
+ "灵丘县",
+ "浑源县",
+ "左云县",
+ "大同县"
+ ]
+ },
+ {
+ "name": "阳泉市",
+ "area": [
+ "城 区",
+ "矿 区",
+ "郊 区",
+ "平定县",
+ "盂 县"
+ ]
+ },
+ {
+ "name": "长治市",
+ "area": [
+ "城 区",
+ "郊 区",
+ "长治县",
+ "襄垣县",
+ "屯留县",
+ "平顺县",
+ "黎城县",
+ "壶关县",
+ "长子县",
+ "武乡县",
+ "沁 县",
+ "沁源县",
+ "潞城市"
+ ]
+ },
+ {
+ "name": "晋城市",
+ "area": [
+ "城 区",
+ "沁水县",
+ "阳城县",
+ "陵川县",
+ "泽州县",
+ "高平市"
+ ]
+ },
+ {
+ "name": "朔州市",
+ "area": [
+ "朔城区",
+ "平鲁区",
+ "山阴县",
+ "应 县",
+ "右玉县",
+ "怀仁县"
+ ]
+ },
+ {
+ "name": "忻州市",
+ "area": [
+ "忻府区",
+ "原平市",
+ "定襄县",
+ "五台县",
+ "代 县",
+ "繁峙县",
+ "宁武县",
+ "静乐县",
+ "神池县",
+ "五寨县",
+ "岢岚县",
+ "河曲县",
+ "保德县",
+ "偏关县"
+ ]
+ },
+ {
+ "name": "吕梁市",
+ "area": [
+ "离石区",
+ "孝义市",
+ "汾阳市",
+ "文水县",
+ "交城县",
+ "兴 县",
+ "临 县",
+ "柳林县",
+ "石楼县",
+ "岚 县",
+ "方山县",
+ "中阳县",
+ "交口县"
+ ]
+ },
+ {
+ "name": "晋中市",
+ "area": [
+ "榆次市",
+ "介休市",
+ "榆社县",
+ "左权县",
+ "和顺县",
+ "昔阳县",
+ "寿阳县",
+ "太谷县",
+ "祁 县",
+ "平遥县",
+ "灵石县"
+ ]
+ },
+ {
+ "name": "临汾市",
+ "area": [
+ "临汾市",
+ "侯马市",
+ "霍州市",
+ "曲沃县",
+ "翼城县",
+ "襄汾县",
+ "洪洞县",
+ "古 县",
+ "安泽县",
+ "浮山县",
+ "吉 县",
+ "乡宁县",
+ "蒲 县",
+ "大宁县",
+ "永和县",
+ "隰 县",
+ "汾西县"
+ ]
+ },
+ {
+ "name": "运城市",
+ "area": [
+ "运城市",
+ "永济市",
+ "河津市",
+ "芮城县",
+ "临猗县",
+ "万荣县",
+ "新绛县",
+ "稷山县",
+ "闻喜县",
+ "夏 县",
+ "绛 县",
+ "平陆县",
+ "垣曲县"
+ ]
+ }
+ ]
+ },
+ {
+ "name": "内蒙古",
+ "city": [
+ {
+ "name": "呼和浩特市",
+ "area": [
+ "新城区",
+ "回民区",
+ "玉泉区",
+ "郊 区",
+ "土默特左旗",
+ "托克托县",
+ "和林格尔县",
+ "清水河县",
+ "武川县"
+ ]
+ },
+ {
+ "name": "包头市",
+ "area": [
+ "东河区",
+ "昆都伦区",
+ "青山区",
+ "石拐矿区",
+ "白云矿区",
+ "郊 区",
+ "土默特右旗",
+ "固阳县",
+ "达尔罕茂明安联合旗"
+ ]
+ },
+ {
+ "name": "乌海市",
+ "area": [
+ "海勃湾区",
+ "海南区",
+ "乌达区"
+ ]
+ },
+ {
+ "name": "赤峰市",
+ "area": [
+ "红山区",
+ "元宝山区",
+ "松山区",
+ "阿鲁科尔沁旗",
+ "巴林左旗",
+ "巴林右旗",
+ "林西县",
+ "克什克腾旗",
+ "翁牛特旗",
+ "喀喇沁旗",
+ "宁城县",
+ "敖汉旗"
+ ]
+ },
+ {
+ "name": "呼伦贝尔市",
+ "area": [
+ "海拉尔市",
+ "满洲里市",
+ "扎兰屯市",
+ "牙克石市",
+ "根河市",
+ "额尔古纳市",
+ "阿荣旗",
+ "莫力达瓦达斡尔族自治旗",
+ "鄂伦春自治旗",
+ "鄂温克族自治旗",
+ "新巴尔虎右旗",
+ "新巴尔虎左旗",
+ "陈巴尔虎旗"
+ ]
+ },
+ {
+ "name": "兴安盟",
+ "area": [
+ "乌兰浩特市",
+ "阿尔山市",
+ "科尔沁右翼前旗",
+ "科尔沁右翼中旗",
+ "扎赉特旗",
+ "突泉县"
+ ]
+ },
+ {
+ "name": "通辽市",
+ "area": [
+ "科尔沁区",
+ "霍林郭勒市",
+ "科尔沁左翼中旗",
+ "科尔沁左翼后旗",
+ "开鲁县",
+ "库伦旗",
+ "奈曼旗",
+ "扎鲁特旗"
+ ]
+ },
+ {
+ "name": "锡林郭勒盟",
+ "area": [
+ "二连浩特市",
+ "锡林浩特市",
+ "阿巴嘎旗",
+ "苏尼特左旗",
+ "苏尼特右旗",
+ "东乌珠穆沁旗",
+ "西乌珠穆沁旗",
+ "太仆寺旗",
+ "镶黄旗",
+ "正镶白旗",
+ "正蓝旗",
+ "多伦县"
+ ]
+ },
+ {
+ "name": "乌兰察布盟",
+ "area": [
+ "集宁市",
+ "丰镇市",
+ "卓资县",
+ "化德县",
+ "商都县",
+ "兴和县",
+ "凉城县",
+ "察哈尔右翼前旗",
+ "察哈尔右翼中旗",
+ "察哈尔右翼后旗",
+ "四子王旗"
+ ]
+ },
+ {
+ "name": "伊克昭盟",
+ "area": [
+ "东胜市",
+ "达拉特旗",
+ "准格尔旗",
+ "鄂托克前旗",
+ "鄂托克旗",
+ "杭锦旗",
+ "乌审旗",
+ "伊金霍洛旗"
+ ]
+ },
+ {
+ "name": "巴彦淖尔盟",
+ "area": [
+ "临河市",
+ "五原县",
+ "磴口县",
+ "乌拉特前旗",
+ "乌拉特中旗",
+ "乌拉特后旗",
+ "杭锦后旗"
+ ]
+ },
+ {
+ "name": "阿拉善盟",
+ "area": [
+ "阿拉善左旗",
+ "阿拉善右旗",
+ "额济纳旗"
+ ]
+ }
+ ]
+ },
+ {
+ "name": "辽宁省",
+ "city": [
+ {
+ "name": "沈阳市",
+ "area": [
+ "沈河区",
+ "皇姑区",
+ "和平区",
+ "大东区",
+ "铁西区",
+ "苏家屯区",
+ "东陵区",
+ "于洪区",
+ "新民市",
+ "法库县",
+ "辽中县",
+ "康平县",
+ "新城子区",
+ "其他"
+ ]
+ },
+ {
+ "name": "大连市",
+ "area": [
+ "西岗区",
+ "中山区",
+ "沙河口区",
+ "甘井子区",
+ "旅顺口区",
+ "金州区",
+ "瓦房店市",
+ "普兰店市",
+ "庄河市",
+ "长海县",
+ "其他"
+ ]
+ },
+ {
+ "name": "鞍山市",
+ "area": [
+ "铁东区",
+ "铁西区",
+ "立山区",
+ "千山区",
+ "海城市",
+ "台安县",
+ "岫岩满族自治县",
+ "其他"
+ ]
+ },
+ {
+ "name": "抚顺市",
+ "area": [
+ "顺城区",
+ "新抚区",
+ "东洲区",
+ "望花区",
+ "抚顺县",
+ "清原满族自治县",
+ "新宾满族自治县",
+ "其他"
+ ]
+ },
+ {
+ "name": "本溪市",
+ "area": [
+ "平山区",
+ "明山区",
+ "溪湖区",
+ "南芬区",
+ "本溪满族自治县",
+ "桓仁满族自治县",
+ "其他"
+ ]
+ },
+ {
+ "name": "丹东市",
+ "area": [
+ "振兴区",
+ "元宝区",
+ "振安区",
+ "东港市",
+ "凤城市",
+ "宽甸满族自治县",
+ "其他"
+ ]
+ },
+ {
+ "name": "锦州市",
+ "area": [
+ "太和区",
+ "古塔区",
+ "凌河区",
+ "凌海市",
+ "黑山县",
+ "义县",
+ "北宁市",
+ "其他"
+ ]
+ },
+ {
+ "name": "营口市",
+ "area": [
+ "站前区",
+ "西市区",
+ "鲅鱼圈区",
+ "老边区",
+ "大石桥市",
+ "盖州市",
+ "其他"
+ ]
+ },
+ {
+ "name": "阜新市",
+ "area": [
+ "海州区",
+ "新邱区",
+ "太平区",
+ "清河门区",
+ "细河区",
+ "彰武县",
+ "阜新蒙古族自治县",
+ "其他"
+ ]
+ },
+ {
+ "name": "辽阳市",
+ "area": [
+ "白塔区",
+ "文圣区",
+ "宏伟区",
+ "太子河区",
+ "弓长岭区",
+ "灯塔市",
+ "辽阳县",
+ "其他"
+ ]
+ },
+ {
+ "name": "盘锦",
+ "area": [
+ "双台子区",
+ "兴隆台区",
+ "盘山县",
+ "大洼县",
+ "其他"
+ ]
+ },
+ {
+ "name": "铁岭市",
+ "area": [
+ "银州区",
+ "清河区",
+ "调兵山市",
+ "开原市",
+ "铁岭县",
+ "昌图县",
+ "西丰县",
+ "其他"
+ ]
+ },
+ {
+ "name": "朝阳市",
+ "area": [
+ "双塔区",
+ "龙城区",
+ "凌源市",
+ "北票市",
+ "朝阳县",
+ "建平县",
+ "喀喇沁左翼蒙古族自治县",
+ "其他"
+ ]
+ },
+ {
+ "name": "葫芦岛市",
+ "area": [
+ "龙港区",
+ "南票区",
+ "连山区",
+ "兴城市",
+ "绥中县",
+ "建昌县",
+ "其他"
+ ]
+ },
+ {
+ "name": "其他",
+ "area": [
+ "其他"
+ ]
+ }
+ ]
+ },
+ {
+ "name": "吉林省",
+ "city": [
+ {
+ "name": "长春市",
+ "area": [
+ "朝阳区",
+ "宽城区",
+ "二道区",
+ "南关区",
+ "绿园区",
+ "双阳区",
+ "九台市",
+ "榆树市",
+ "德惠市",
+ "农安县",
+ "其他"
+ ]
+ },
+ {
+ "name": "吉林市",
+ "area": [
+ "船营区",
+ "昌邑区",
+ "龙潭区",
+ "丰满区",
+ "舒兰市",
+ "桦甸市",
+ "蛟河市",
+ "磐石市",
+ "永吉县",
+ "其他"
+ ]
+ },
+ {
+ "name": "四平",
+ "area": [
+ "铁西区",
+ "铁东区",
+ "公主岭市",
+ "双辽市",
+ "梨树县",
+ "伊通满族自治县",
+ "其他"
+ ]
+ },
+ {
+ "name": "辽源市",
+ "area": [
+ "龙山区",
+ "西安区",
+ "东辽县",
+ "东丰县",
+ "其他"
+ ]
+ },
+ {
+ "name": "通化市",
+ "area": [
+ "东昌区",
+ "二道江区",
+ "梅河口市",
+ "集安市",
+ "通化县",
+ "辉南县",
+ "柳河县",
+ "其他"
+ ]
+ },
+ {
+ "name": "白山市",
+ "area": [
+ "八道江区",
+ "江源区",
+ "临江市",
+ "靖宇县",
+ "抚松县",
+ "长白朝鲜族自治县",
+ "其他"
+ ]
+ },
+ {
+ "name": "松原市",
+ "area": [
+ "宁江区",
+ "乾安县",
+ "长岭县",
+ "扶余县",
+ "前郭尔罗斯蒙古族自治县",
+ "其他"
+ ]
+ },
+ {
+ "name": "白城市",
+ "area": [
+ "洮北区",
+ "大安市",
+ "洮南市",
+ "镇赉县",
+ "通榆县",
+ "其他"
+ ]
+ },
+ {
+ "name": "延边朝鲜族自治州",
+ "area": [
+ "延吉市",
+ "图们市",
+ "敦化市",
+ "龙井市",
+ "珲春市",
+ "和龙市",
+ "安图县",
+ "汪清县",
+ "其他"
+ ]
+ },
+ {
+ "name": "其他",
+ "area": [
+ "其他"
+ ]
+ }
+ ]
+ },
+ {
+ "name": "黑龙江省",
+ "city": [
+ {
+ "name": "哈尔滨市",
+ "area": [
+ "松北区",
+ "道里区",
+ "南岗区",
+ "平房区",
+ "香坊区",
+ "道外区",
+ "呼兰区",
+ "阿城区",
+ "双城市",
+ "尚志市",
+ "五常市",
+ "宾县",
+ "方正县",
+ "通河县",
+ "巴彦县",
+ "延寿县",
+ "木兰县",
+ "依兰县",
+ "其他"
+ ]
+ },
+ {
+ "name": "齐齐哈尔市",
+ "area": [
+ "龙沙区",
+ "昂昂溪区",
+ "铁锋区",
+ "建华区",
+ "富拉尔基区",
+ "碾子山区",
+ "梅里斯达斡尔族区",
+ "讷河市",
+ "富裕县",
+ "拜泉县",
+ "甘南县",
+ "依安县",
+ "克山县",
+ "泰来县",
+ "克东县",
+ "龙江县",
+ "其他"
+ ]
+ },
+ {
+ "name": "鹤岗市",
+ "area": [
+ "兴山区",
+ "工农区",
+ "南山区",
+ "兴安区",
+ "向阳区",
+ "东山区",
+ "萝北县",
+ "绥滨县",
+ "其他"
+ ]
+ },
+ {
+ "name": "双鸭山",
+ "area": [
+ "尖山区",
+ "岭东区",
+ "四方台区",
+ "宝山区",
+ "集贤县",
+ "宝清县",
+ "友谊县",
+ "饶河县",
+ "其他"
+ ]
+ },
+ {
+ "name": "鸡西市",
+ "area": [
+ "鸡冠区",
+ "恒山区",
+ "城子河区",
+ "滴道区",
+ "梨树区",
+ "麻山区",
+ "密山市",
+ "虎林市",
+ "鸡东县",
+ "其他"
+ ]
+ },
+ {
+ "name": "大庆市",
+ "area": [
+ "萨尔图区",
+ "红岗区",
+ "龙凤区",
+ "让胡路区",
+ "大同区",
+ "林甸县",
+ "肇州县",
+ "肇源县",
+ "杜尔伯特蒙古族自治县",
+ "其他"
+ ]
+ },
+ {
+ "name": "伊春市",
+ "area": [
+ "伊春区",
+ "带岭区",
+ "南岔区",
+ "金山屯区",
+ "西林区",
+ "美溪区",
+ "乌马河区",
+ "翠峦区",
+ "友好区",
+ "上甘岭区",
+ "五营区",
+ "红星区",
+ "新青区",
+ "汤旺河区",
+ "乌伊岭区",
+ "铁力市",
+ "嘉荫县",
+ "其他"
+ ]
+ },
+ {
+ "name": "牡丹江市",
+ "area": [
+ "爱民区",
+ "东安区",
+ "阳明区",
+ "西安区",
+ "绥芬河市",
+ "宁安市",
+ "海林市",
+ "穆棱市",
+ "林口县",
+ "东宁县",
+ "其他"
+ ]
+ },
+ {
+ "name": "佳木斯市",
+ "area": [
+ "向阳区",
+ "前进区",
+ "东风区",
+ "郊区",
+ "同江市",
+ "富锦市",
+ "桦川县",
+ "抚远县",
+ "桦南县",
+ "汤原县",
+ "其他"
+ ]
+ },
+ {
+ "name": "七台河市",
+ "area": [
+ "桃山区",
+ "新兴区",
+ "茄子河区",
+ "勃利县",
+ "其他"
+ ]
+ },
+ {
+ "name": "黑河市",
+ "area": [
+ "爱辉区",
+ "北安市",
+ "五大连池市",
+ "逊克县",
+ "嫩江县",
+ "孙吴县",
+ "其他"
+ ]
+ },
+ {
+ "name": "绥化市",
+ "area": [
+ "北林区",
+ "安达市",
+ "肇东市",
+ "海伦市",
+ "绥棱县",
+ "兰西县",
+ "明水县",
+ "青冈县",
+ "庆安县",
+ "望奎县",
+ "其他"
+ ]
+ },
+ {
+ "name": "大兴安岭地区",
+ "area": [
+ "呼玛县",
+ "塔河县",
+ "漠河县",
+ "大兴安岭辖区",
+ "其他"
+ ]
+ },
+ {
+ "name": "其他",
+ "area": [
+ "其他"
+ ]
+ }
+ ]
+ },
+ {
+ "name": "上海市",
+ "city": [
+ {
+ "name": "上海市",
+ "area": [
+ "黄浦区",
+ "卢湾区",
+ "徐汇区",
+ "长宁区",
+ "静安区",
+ "普陀区",
+ "闸北区",
+ "虹口区",
+ "杨浦区",
+ "宝山区",
+ "闵行区",
+ "嘉定区",
+ "松江区",
+ "金山区",
+ "青浦区",
+ "南汇区",
+ "奉贤区",
+ "浦东新区",
+ "崇明县",
+ "其他"
+ ]
+ }
+ ]
+ },
+ {
+ "name": "江苏省",
+ "city": [
+ {
+ "name": "南京市",
+ "area": [
+ "玄武区",
+ "白下区",
+ "秦淮区",
+ "建邺区",
+ "鼓楼区",
+ "下关区",
+ "栖霞区",
+ "雨花台区",
+ "浦口区",
+ "江宁区",
+ "六合区",
+ "溧水县",
+ "高淳县",
+ "其他"
+ ]
+ },
+ {
+ "name": "苏州市",
+ "area": [
+ "金阊区",
+ "平江区",
+ "沧浪区",
+ "虎丘区",
+ "吴中区",
+ "相城区",
+ "常熟市",
+ "张家港市",
+ "昆山市",
+ "吴江市",
+ "太仓市",
+ "其他"
+ ]
+ },
+ {
+ "name": "无锡市",
+ "area": [
+ "崇安区",
+ "南长区",
+ "北塘区",
+ "滨湖区",
+ "锡山区",
+ "惠山区",
+ "江阴市",
+ "宜兴市",
+ "其他"
+ ]
+ },
+ {
+ "name": "常州市",
+ "area": [
+ "钟楼区",
+ "天宁区",
+ "戚墅堰区",
+ "新北区",
+ "武进区",
+ "金坛市",
+ "溧阳市",
+ "其他"
+ ]
+ },
+ {
+ "name": "镇江市",
+ "area": [
+ "京口区",
+ "润州区",
+ "丹徒区",
+ "丹阳市",
+ "扬中市",
+ "句容市",
+ "其他"
+ ]
+ },
+ {
+ "name": "南通市",
+ "area": [
+ "崇川区",
+ "港闸区",
+ "通州市",
+ "如皋市",
+ "海门市",
+ "启东市",
+ "海安县",
+ "如东县",
+ "其他"
+ ]
+ },
+ {
+ "name": "泰州市",
+ "area": [
+ "海陵区",
+ "高港区",
+ "姜堰市",
+ "泰兴市",
+ "靖江市",
+ "兴化市",
+ "其他"
+ ]
+ },
+ {
+ "name": "扬州市",
+ "area": [
+ "广陵区",
+ "维扬区",
+ "邗江区",
+ "江都市",
+ "仪征市",
+ "高邮市",
+ "宝应县",
+ "其他"
+ ]
+ },
+ {
+ "name": "盐城市",
+ "area": [
+ "亭湖区",
+ "盐都区",
+ "大丰市",
+ "东台市",
+ "建湖县",
+ "射阳县",
+ "阜宁县",
+ "滨海县",
+ "响水县",
+ "其他"
+ ]
+ },
+ {
+ "name": "连云港市",
+ "area": [
+ "新浦区",
+ "海州区",
+ "连云区",
+ "东海县",
+ "灌云县",
+ "赣榆县",
+ "灌南县",
+ "其他"
+ ]
+ },
+ {
+ "name": "徐州市",
+ "area": [
+ "云龙区",
+ "鼓楼区",
+ "九里区",
+ "泉山区",
+ "贾汪区",
+ "邳州市",
+ "新沂市",
+ "铜山县",
+ "睢宁县",
+ "沛县",
+ "丰县",
+ "其他"
+ ]
+ },
+ {
+ "name": "淮安市",
+ "area": [
+ "清河区",
+ "清浦区",
+ "楚州区",
+ "淮阴区",
+ "涟水县",
+ "洪泽县",
+ "金湖县",
+ "盱眙县",
+ "其他"
+ ]
+ },
+ {
+ "name": "宿迁市",
+ "area": [
+ "宿城区",
+ "宿豫区",
+ "沭阳县",
+ "泗阳县",
+ "泗洪县",
+ "其他"
+ ]
+ },
+ {
+ "name": "其他",
+ "area": [
+ "其他"
+ ]
+ }
+ ]
+ },
+ {
+ "name": "浙江省",
+ "city": [
+ {
+ "name": "杭州市",
+ "area": [
+ "拱墅区",
+ "西湖区",
+ "上城区",
+ "下城区",
+ "江干区",
+ "滨江区",
+ "余杭区",
+ "萧山区",
+ "建德市",
+ "富阳市",
+ "临安市",
+ "桐庐县",
+ "淳安县",
+ "其他"
+ ]
+ },
+ {
+ "name": "宁波市",
+ "area": [
+ "海曙区",
+ "江东区",
+ "江北区",
+ "镇海区",
+ "北仑区",
+ "鄞州区",
+ "余姚市",
+ "慈溪市",
+ "奉化市",
+ "宁海县",
+ "象山县",
+ "其他"
+ ]
+ },
+ {
+ "name": "温州市",
+ "area": [
+ "鹿城区",
+ "龙湾区",
+ "瓯海区",
+ "瑞安市",
+ "乐清市",
+ "永嘉县",
+ "洞头县",
+ "平阳县",
+ "苍南县",
+ "文成县",
+ "泰顺县",
+ "其他"
+ ]
+ },
+ {
+ "name": "嘉兴市",
+ "area": [
+ "秀城区",
+ "秀洲区",
+ "海宁市",
+ "平湖市",
+ "桐乡市",
+ "嘉善县",
+ "海盐县",
+ "其他"
+ ]
+ },
+ {
+ "name": "湖州市",
+ "area": [
+ "吴兴区",
+ "南浔区",
+ "长兴县",
+ "德清县",
+ "安吉县",
+ "其他"
+ ]
+ },
+ {
+ "name": "绍兴市",
+ "area": [
+ "越城区",
+ "诸暨市",
+ "上虞市",
+ "嵊州市",
+ "绍兴县",
+ "新昌县",
+ "其他"
+ ]
+ },
+ {
+ "name": "金华市",
+ "area": [
+ "婺城区",
+ "金东区",
+ "兰溪市",
+ "义乌市",
+ "东阳市",
+ "永康市",
+ "武义县",
+ "浦江县",
+ "磐安县",
+ "其他"
+ ]
+ },
+ {
+ "name": "衢州市",
+ "area": [
+ "柯城区",
+ "衢江区",
+ "江山市",
+ "龙游县",
+ "常山县",
+ "开化县",
+ "其他"
+ ]
+ },
+ {
+ "name": "舟山市",
+ "area": [
+ "定海区",
+ "普陀区",
+ "岱山县",
+ "嵊泗县",
+ "其他"
+ ]
+ },
+ {
+ "name": "台州市",
+ "area": [
+ "椒江区",
+ "黄岩区",
+ "路桥区",
+ "临海市",
+ "温岭市",
+ "玉环县",
+ "天台县",
+ "仙居县",
+ "三门县",
+ "其他"
+ ]
+ },
+ {
+ "name": "丽水市",
+ "area": [
+ "莲都区",
+ "龙泉市",
+ "缙云县",
+ "青田县",
+ "云和县",
+ "遂昌县",
+ "松阳县",
+ "庆元县",
+ "景宁畲族自治县",
+ "其他"
+ ]
+ },
+ {
+ "name": "其他市",
+ "area": [
+ "其他"
+ ]
+ }
+ ]
+ },
+ {
+ "name": "安徽省",
+ "city": [
+ {
+ "name": "合肥市",
+ "area": [
+ "庐阳区",
+ "瑶海区",
+ "蜀山区",
+ "包河区",
+ "长丰县",
+ "肥东县",
+ "肥西县",
+ "其他"
+ ]
+ },
+ {
+ "name": "芜湖市",
+ "area": [
+ "镜湖区",
+ "弋江区",
+ "鸠江区",
+ "三山区",
+ "芜湖县",
+ "南陵县",
+ "繁昌县",
+ "其他"
+ ]
+ },
+ {
+ "name": "蚌埠市",
+ "area": [
+ "蚌山区",
+ "龙子湖区",
+ "禹会区",
+ "淮上区",
+ "怀远县",
+ "固镇县",
+ "五河县",
+ "其他"
+ ]
+ },
+ {
+ "name": "淮南市",
+ "area": [
+ "田家庵区",
+ "大通区",
+ "谢家集区",
+ "八公山区",
+ "潘集区",
+ "凤台县",
+ "其他"
+ ]
+ },
+ {
+ "name": "马鞍山市",
+ "area": [
+ "雨山区",
+ "花山区",
+ "金家庄区",
+ "当涂县",
+ "其他"
+ ]
+ },
+ {
+ "name": "淮北市",
+ "area": [
+ "相山区",
+ "杜集区",
+ "烈山区",
+ "濉溪县",
+ "其他"
+ ]
+ },
+ {
+ "name": "铜陵市",
+ "area": [
+ "铜官山区",
+ "狮子山区",
+ "郊区",
+ "铜陵县",
+ "其他"
+ ]
+ },
+ {
+ "name": "安庆市",
+ "area": [
+ "迎江区",
+ "大观区",
+ "宜秀区",
+ "桐城市",
+ "宿松县",
+ "枞阳县",
+ "太湖县",
+ "怀宁县",
+ "岳西县",
+ "望江县",
+ "潜山县",
+ "其他"
+ ]
+ },
+ {
+ "name": "黄山市",
+ "area": [
+ "屯溪区",
+ "黄山区",
+ "徽州区",
+ "休宁县",
+ "歙县",
+ "祁门县",
+ "黟县",
+ "其他"
+ ]
+ },
+ {
+ "name": "滁州市",
+ "area": [
+ "琅琊区",
+ "南谯区",
+ "天长市",
+ "明光市",
+ "全椒县",
+ "来安县",
+ "定远县",
+ "凤阳县",
+ "其他"
+ ]
+ },
+ {
+ "name": "阜阳市",
+ "area": [
+ "颍州区",
+ "颍东区",
+ "颍泉区",
+ "界首市",
+ "临泉县",
+ "颍上县",
+ "阜南县",
+ "太和县",
+ "其他"
+ ]
+ },
+ {
+ "name": "宿州市",
+ "area": [
+ "埇桥区",
+ "萧县",
+ "泗县",
+ "砀山县",
+ "灵璧县",
+ "其他"
+ ]
+ },
+ {
+ "name": "巢湖市",
+ "area": [
+ "居巢区",
+ "含山县",
+ "无为县",
+ "庐江县",
+ "和县",
+ "其他"
+ ]
+ },
+ {
+ "name": "六安市",
+ "area": [
+ "金安区",
+ "裕安区",
+ "寿县",
+ "霍山县",
+ "霍邱县",
+ "舒城县",
+ "金寨县",
+ "其他"
+ ]
+ },
+ {
+ "name": "亳州市",
+ "area": [
+ "谯城区",
+ "利辛县",
+ "涡阳县",
+ "蒙城县",
+ "其他"
+ ]
+ },
+ {
+ "name": "池州市",
+ "area": [
+ "贵池区",
+ "东至县",
+ "石台县",
+ "青阳县",
+ "其他"
+ ]
+ },
+ {
+ "name": "宣城市",
+ "area": [
+ "宣州区",
+ "宁国市",
+ "广德县",
+ "郎溪县",
+ "泾县",
+ "旌德县",
+ "绩溪县",
+ "其他"
+ ]
+ },
+ {
+ "name": "其他市",
+ "area": [
+ "其他"
+ ]
+ }
+ ]
+ },
+ {
+ "name": "福建省",
+ "city": [
+ {
+ "name": "福州市",
+ "area": [
+ "鼓楼区",
+ "台江区",
+ "仓山区",
+ "马尾区",
+ "晋安区",
+ "福清市",
+ "长乐市",
+ "闽侯县",
+ "闽清县",
+ "永泰县",
+ "连江县",
+ "罗源县",
+ "平潭县",
+ "其他"
+ ]
+ },
+ {
+ "name": "厦门市",
+ "area": [
+ "思明区",
+ "海沧区",
+ "湖里区",
+ "集美区",
+ "同安区",
+ "翔安区",
+ "其他"
+ ]
+ },
+ {
+ "name": "莆田市",
+ "area": [
+ "城厢区",
+ "涵江区",
+ "荔城区",
+ "秀屿区",
+ "仙游县",
+ "其他"
+ ]
+ },
+ {
+ "name": "三明市",
+ "area": [
+ "梅列区",
+ "三元区",
+ "永安市",
+ "明溪县",
+ "将乐县",
+ "大田县",
+ "宁化县",
+ "建宁县",
+ "沙县",
+ "尤溪县",
+ "清流县",
+ "泰宁县",
+ "其他"
+ ]
+ },
+ {
+ "name": "泉州市",
+ "area": [
+ "鲤城区",
+ "丰泽区",
+ "洛江区",
+ "泉港区",
+ "石狮市",
+ "晋江市",
+ "南安市",
+ "惠安县",
+ "永春县",
+ "安溪县",
+ "德化县",
+ "金门县",
+ "其他"
+ ]
+ },
+ {
+ "name": "漳州市",
+ "area": [
+ "芗城区",
+ "龙文区",
+ "龙海市",
+ "平和县",
+ "南靖县",
+ "诏安县",
+ "漳浦县",
+ "华安县",
+ "东山县",
+ "长泰县",
+ "云霄县",
+ "其他"
+ ]
+ },
+ {
+ "name": "南平市",
+ "area": [
+ "延平区",
+ "建瓯市",
+ "邵武市",
+ "武夷山市",
+ "建阳市",
+ "松溪县",
+ "光泽县",
+ "顺昌县",
+ "浦城县",
+ "政和县",
+ "其他"
+ ]
+ },
+ {
+ "name": "龙岩市",
+ "area": [
+ "新罗区",
+ "漳平市",
+ "长汀县",
+ "武平县",
+ "上杭县",
+ "永定县",
+ "连城县",
+ "其他"
+ ]
+ },
+ {
+ "name": "宁德市",
+ "area": [
+ "蕉城区",
+ "福安市",
+ "福鼎市",
+ "寿宁县",
+ "霞浦县",
+ "柘荣县",
+ "屏南县",
+ "古田县",
+ "周宁县",
+ "其他"
+ ]
+ },
+ {
+ "name": "其他",
+ "area": [
+ "其他"
+ ]
+ }
+ ]
+ },
+ {
+ "name": "江西省",
+ "city": [
+ {
+ "name": "南昌市",
+ "area": [
+ "东湖区",
+ "西湖区",
+ "青云谱区",
+ "湾里区",
+ "青山湖区",
+ "新建县",
+ "南昌县",
+ "进贤县",
+ "安义县",
+ "其他"
+ ]
+ },
+ {
+ "name": "景德镇市",
+ "area": [
+ "珠山区",
+ "昌江区",
+ "乐平市",
+ "浮梁县",
+ "其他"
+ ]
+ },
+ {
+ "name": "萍乡市",
+ "area": [
+ "安源区",
+ "湘东区",
+ "莲花县",
+ "上栗县",
+ "芦溪县",
+ "其他"
+ ]
+ },
+ {
+ "name": "九江市",
+ "area": [
+ "浔阳区",
+ "庐山区",
+ "瑞昌市",
+ "九江县",
+ "星子县",
+ "武宁县",
+ "彭泽县",
+ "永修县",
+ "修水县",
+ "湖口县",
+ "德安县",
+ "都昌县",
+ "其他"
+ ]
+ },
+ {
+ "name": "新余市",
+ "area": [
+ "渝水区",
+ "分宜县",
+ "其他"
+ ]
+ },
+ {
+ "name": "鹰潭市",
+ "area": [
+ "月湖区",
+ "贵溪市",
+ "余江县",
+ "其他"
+ ]
+ },
+ {
+ "name": "赣州市",
+ "area": [
+ "章贡区",
+ "瑞金市",
+ "南康市",
+ "石城县",
+ "安远县",
+ "赣县",
+ "宁都县",
+ "寻乌县",
+ "兴国县",
+ "定南县",
+ "上犹县",
+ "于都县",
+ "龙南县",
+ "崇义县",
+ "信丰县",
+ "全南县",
+ "大余县",
+ "会昌县",
+ "其他"
+ ]
+ },
+ {
+ "name": "吉安市",
+ "area": [
+ "吉州区",
+ "青原区",
+ "井冈山市",
+ "吉安县",
+ "永丰县",
+ "永新县",
+ "新干县",
+ "泰和县",
+ "峡江县",
+ "遂川县",
+ "安福县",
+ "吉水县",
+ "万安县",
+ "其他"
+ ]
+ },
+ {
+ "name": "宜春市",
+ "area": [
+ "袁州区",
+ "丰城市",
+ "樟树市",
+ "高安市",
+ "铜鼓县",
+ "靖安县",
+ "宜丰县",
+ "奉新县",
+ "万载县",
+ "上高县",
+ "其他"
+ ]
+ },
+ {
+ "name": "抚州市",
+ "area": [
+ "临川区",
+ "南丰县",
+ "乐安县",
+ "金溪县",
+ "南城县",
+ "东乡县",
+ "资溪县",
+ "宜黄县",
+ "广昌县",
+ "黎川县",
+ "崇仁县",
+ "其他"
+ ]
+ },
+ {
+ "name": "上饶市",
+ "area": [
+ "信州区",
+ "德兴市",
+ "上饶县",
+ "广丰县",
+ "鄱阳县",
+ "婺源县",
+ "铅山县",
+ "余干县",
+ "横峰县",
+ "弋阳县",
+ "玉山县",
+ "万年县",
+ "其他"
+ ]
+ },
+ {
+ "name": "其他",
+ "area": [
+ "其他"
+ ]
+ }
+ ]
+ },
+ {
+ "name": "山东省",
+ "city": [
+ {
+ "name": "济南市",
+ "area": [
+ "市中区",
+ "历下区",
+ "天桥区",
+ "槐荫区",
+ "历城区",
+ "长清区",
+ "章丘市",
+ "平阴县",
+ "济阳县",
+ "商河县",
+ "其他"
+ ]
+ },
+ {
+ "name": "青岛市",
+ "area": [
+ "市南区",
+ "市北区",
+ "城阳区",
+ "四方区",
+ "李沧区",
+ "黄岛区",
+ "崂山区",
+ "胶南市",
+ "胶州市",
+ "平度市",
+ "莱西市",
+ "即墨市",
+ "其他"
+ ]
+ },
+ {
+ "name": "淄博市",
+ "area": [
+ "张店区",
+ "临淄区",
+ "淄川区",
+ "博山区",
+ "周村区",
+ "桓台县",
+ "高青县",
+ "沂源县",
+ "其他"
+ ]
+ },
+ {
+ "name": "枣庄市",
+ "area": [
+ "市中区",
+ "山亭区",
+ "峄城区",
+ "台儿庄区",
+ "薛城区",
+ "滕州市",
+ "其他"
+ ]
+ },
+ {
+ "name": "东营市",
+ "area": [
+ "东营区",
+ "河口区",
+ "垦利县",
+ "广饶县",
+ "利津县",
+ "其他"
+ ]
+ },
+ {
+ "name": "烟台市",
+ "area": [
+ "芝罘区",
+ "福山区",
+ "牟平区",
+ "莱山区",
+ "龙口市",
+ "莱阳市",
+ "莱州市",
+ "招远市",
+ "蓬莱市",
+ "栖霞市",
+ "海阳市",
+ "长岛县",
+ "其他"
+ ]
+ },
+ {
+ "name": "潍坊市",
+ "area": [
+ "潍城区",
+ "寒亭区",
+ "坊子区",
+ "奎文区",
+ "青州市",
+ "诸城市",
+ "寿光市",
+ "安丘市",
+ "高密市",
+ "昌邑市",
+ "昌乐县",
+ "临朐县",
+ "其他"
+ ]
+ },
+ {
+ "name": "济宁市",
+ "area": [
+ "市中区",
+ "任城区",
+ "曲阜市",
+ "兖州市",
+ "邹城市",
+ "鱼台县",
+ "金乡县",
+ "嘉祥县",
+ "微山县",
+ "汶上县",
+ "泗水县",
+ "梁山县",
+ "其他"
+ ]
+ },
+ {
+ "name": "泰安市",
+ "area": [
+ "泰山区",
+ "岱岳区",
+ "新泰市",
+ "肥城市",
+ "宁阳县",
+ "东平县",
+ "其他"
+ ]
+ },
+ {
+ "name": "威海市",
+ "area": [
+ "环翠区",
+ "乳山市",
+ "文登市",
+ "荣成市",
+ "其他"
+ ]
+ },
+ {
+ "name": "日照市",
+ "area": [
+ "东港区",
+ "岚山区",
+ "五莲县",
+ "莒县",
+ "其他"
+ ]
+ },
+ {
+ "name": "莱芜市",
+ "area": [
+ "莱城区",
+ "钢城区",
+ "其他"
+ ]
+ },
+ {
+ "name": "临沂市",
+ "area": [
+ "兰山区",
+ "罗庄区",
+ "河东区",
+ "沂南县",
+ "郯城县",
+ "沂水县",
+ "苍山县",
+ "费县",
+ "平邑县",
+ "莒南县",
+ "蒙阴县",
+ "临沭县",
+ "其他"
+ ]
+ },
+ {
+ "name": "德州市",
+ "area": [
+ "德城区",
+ "乐陵市",
+ "禹城市",
+ "陵县",
+ "宁津县",
+ "齐河县",
+ "武城县",
+ "庆云县",
+ "平原县",
+ "夏津县",
+ "临邑县",
+ "其他"
+ ]
+ },
+ {
+ "name": "聊城市",
+ "area": [
+ "东昌府区",
+ "临清市",
+ "高唐县",
+ "阳谷县",
+ "茌平县",
+ "莘县",
+ "东阿县",
+ "冠县",
+ "其他"
+ ]
+ },
+ {
+ "name": "滨州市",
+ "area": [
+ "滨城区",
+ "邹平县",
+ "沾化县",
+ "惠民县",
+ "博兴县",
+ "阳信县",
+ "无棣县",
+ "其他"
+ ]
+ },
+ {
+ "name": "菏泽市",
+ "area": [
+ "牡丹区",
+ "鄄城县",
+ "单县",
+ "郓城县",
+ "曹县",
+ "定陶县",
+ "巨野县",
+ "东明县",
+ "成武县",
+ "其他"
+ ]
+ },
+ {
+ "name": "其他",
+ "area": [
+ "其他"
+ ]
+ }
+ ]
+ },
+ {
+ "name": "河南省",
+ "city": [
+ {
+ "name": "郑州市",
+ "area": [
+ "中原区",
+ "金水区",
+ "二七区",
+ "管城回族区",
+ "上街区",
+ "惠济区",
+ "巩义市",
+ "新郑市",
+ "新密市",
+ "登封市",
+ "荥阳市",
+ "中牟县",
+ "其他"
+ ]
+ },
+ {
+ "name": "开封市",
+ "area": [
+ "鼓楼区",
+ "龙亭区",
+ "顺河回族区",
+ "禹王台区",
+ "金明区",
+ "开封县",
+ "尉氏县",
+ "兰考县",
+ "杞县",
+ "通许县",
+ "其他"
+ ]
+ },
+ {
+ "name": "洛阳市",
+ "area": [
+ "西工区",
+ "老城区",
+ "涧西区",
+ "瀍河回族区",
+ "洛龙区",
+ "吉利区",
+ "偃师市",
+ "孟津县",
+ "汝阳县",
+ "伊川县",
+ "洛宁县",
+ "嵩县",
+ "宜阳县",
+ "新安县",
+ "栾川县",
+ "其他"
+ ]
+ },
+ {
+ "name": "平顶山市",
+ "area": [
+ "新华区",
+ "卫东区",
+ "湛河区",
+ "石龙区",
+ "汝州市",
+ "舞钢市",
+ "宝丰县",
+ "叶县",
+ "郏县",
+ "鲁山县",
+ "其他"
+ ]
+ },
+ {
+ "name": "安阳市",
+ "area": [
+ "北关区",
+ "文峰区",
+ "殷都区",
+ "龙安区",
+ "林州市",
+ "安阳县",
+ "滑县",
+ "内黄县",
+ "汤阴县",
+ "其他"
+ ]
+ },
+ {
+ "name": "鹤壁市",
+ "area": [
+ "淇滨区",
+ "山城区",
+ "鹤山区",
+ "浚县",
+ "淇县",
+ "其他"
+ ]
+ },
+ {
+ "name": "新乡市",
+ "area": [
+ "卫滨区",
+ "红旗区",
+ "凤泉区",
+ "牧野区",
+ "卫辉市",
+ "辉县市",
+ "新乡县",
+ "获嘉县",
+ "原阳县",
+ "长垣县",
+ "封丘县",
+ "延津县",
+ "其他"
+ ]
+ },
+ {
+ "name": "焦作市",
+ "area": [
+ "解放区",
+ "中站区",
+ "马村区",
+ "山阳区",
+ "沁阳市",
+ "孟州市",
+ "修武县",
+ "温县",
+ "武陟县",
+ "博爱县",
+ "其他"
+ ]
+ },
+ {
+ "name": "濮阳市",
+ "area": [
+ "华龙区",
+ "濮阳县",
+ "南乐县",
+ "台前县",
+ "清丰县",
+ "范县",
+ "其他"
+ ]
+ },
+ {
+ "name": "许昌市",
+ "area": [
+ "魏都区",
+ "禹州市",
+ "长葛市",
+ "许昌县",
+ "鄢陵县",
+ "襄城县",
+ "其他"
+ ]
+ },
+ {
+ "name": "漯河市",
+ "area": [
+ "源汇区",
+ "郾城区",
+ "召陵区",
+ "临颍县",
+ "舞阳县",
+ "其他"
+ ]
+ },
+ {
+ "name": "三门峡市",
+ "area": [
+ "湖滨区",
+ "义马市",
+ "灵宝市",
+ "渑池县",
+ "卢氏县",
+ "陕县",
+ "其他"
+ ]
+ },
+ {
+ "name": "南阳市",
+ "area": [
+ "卧龙区",
+ "宛城区",
+ "邓州市",
+ "桐柏县",
+ "方城县",
+ "淅川县",
+ "镇平县",
+ "唐河县",
+ "南召县",
+ "内乡县",
+ "新野县",
+ "社旗县",
+ "西峡县",
+ "其他"
+ ]
+ },
+ {
+ "name": "商丘市",
+ "area": [
+ "梁园区",
+ "睢阳区",
+ "永城市",
+ "宁陵县",
+ "虞城县",
+ "民权县",
+ "夏邑县",
+ "柘城县",
+ "睢县",
+ "其他"
+ ]
+ },
+ {
+ "name": "信阳市",
+ "area": [
+ "浉河区",
+ "平桥区",
+ "潢川县",
+ "淮滨县",
+ "息县",
+ "新县",
+ "商城县",
+ "固始县",
+ "罗山县",
+ "光山县",
+ "其他"
+ ]
+ },
+ {
+ "name": "周口市",
+ "area": [
+ "川汇区",
+ "项城市",
+ "商水县",
+ "淮阳县",
+ "太康县",
+ "鹿邑县",
+ "西华县",
+ "扶沟县",
+ "沈丘县",
+ "郸城县",
+ "其他"
+ ]
+ },
+ {
+ "name": "驻马店市",
+ "area": [
+ "驿城区",
+ "确山县",
+ "新蔡县",
+ "上蔡县",
+ "西平县",
+ "泌阳县",
+ "平舆县",
+ "汝南县",
+ "遂平县",
+ "正阳县",
+ "其他"
+ ]
+ },
+ {
+ "name": "焦作市",
+ "area": [
+ "济源市",
+ "其他"
+ ]
+ },
+ {
+ "name": "其他",
+ "area": [
+ "其他"
+ ]
+ }
+ ]
+ },
+ {
+ "name": "湖北省",
+ "city": [
+ {
+ "name": "武汉市",
+ "area": [
+ "江岸区",
+ "武昌区",
+ "江汉区",
+ "硚口区",
+ "汉阳区",
+ "青山区",
+ "洪山区",
+ "东西湖区",
+ "汉南区",
+ "蔡甸区",
+ "江夏区",
+ "黄陂区",
+ "新洲区",
+ "其他"
+ ]
+ },
+ {
+ "name": "黄石市",
+ "area": [
+ "黄石港区",
+ "西塞山区",
+ "下陆区",
+ "铁山区",
+ "大冶市",
+ "阳新县",
+ "其他"
+ ]
+ },
+ {
+ "name": "十堰市",
+ "area": [
+ "张湾区",
+ "茅箭区",
+ "丹江口市",
+ "郧县",
+ "竹山县",
+ "房县",
+ "郧西县",
+ "竹溪县",
+ "其他"
+ ]
+ },
+ {
+ "name": "荆州市",
+ "area": [
+ "沙市区",
+ "荆州区",
+ "洪湖市",
+ "石首市",
+ "松滋市",
+ "监利县",
+ "公安县",
+ "江陵县",
+ "其他"
+ ]
+ },
+ {
+ "name": "宜昌市",
+ "area": [
+ "西陵区",
+ "伍家岗区",
+ "点军区",
+ "猇亭区",
+ "夷陵区",
+ "宜都市",
+ "当阳市",
+ "枝江市",
+ "秭归县",
+ "远安县",
+ "兴山县",
+ "五峰土家族自治县",
+ "长阳土家族自治县",
+ "其他"
+ ]
+ },
+ {
+ "name": "襄樊市",
+ "area": [
+ "襄城区",
+ "樊城区",
+ "襄阳区",
+ "老河口市",
+ "枣阳市",
+ "宜城市",
+ "南漳县",
+ "谷城县",
+ "保康县",
+ "其他"
+ ]
+ },
+ {
+ "name": "鄂州市",
+ "area": [
+ "鄂城区",
+ "华容区",
+ "梁子湖区",
+ "其他"
+ ]
+ },
+ {
+ "name": "荆门市",
+ "area": [
+ "东宝区",
+ "掇刀区",
+ "钟祥市",
+ "京山县",
+ "沙洋县",
+ "其他"
+ ]
+ },
+ {
+ "name": "孝感市",
+ "area": [
+ "孝南区",
+ "应城市",
+ "安陆市",
+ "汉川市",
+ "云梦县",
+ "大悟县",
+ "孝昌县",
+ "其他"
+ ]
+ },
+ {
+ "name": "黄冈市",
+ "area": [
+ "黄州区",
+ "麻城市",
+ "武穴市",
+ "红安县",
+ "罗田县",
+ "浠水县",
+ "蕲春县",
+ "黄梅县",
+ "英山县",
+ "团风县",
+ "其他"
+ ]
+ },
+ {
+ "name": "咸宁市",
+ "area": [
+ "咸安区",
+ "赤壁市",
+ "嘉鱼县",
+ "通山县",
+ "崇阳县",
+ "通城县",
+ "其他"
+ ]
+ },
+ {
+ "name": "随州市",
+ "area": [
+ "曾都区",
+ "广水市",
+ "其他"
+ ]
+ },
+ {
+ "name": "恩施土家族苗族自治州",
+ "area": [
+ "恩施市",
+ "利川市",
+ "建始县",
+ "来凤县",
+ "巴东县",
+ "鹤峰县",
+ "宣恩县",
+ "咸丰县",
+ "其他"
+ ]
+ },
+ {
+ "name": "仙桃市",
+ "area": [
+ "仙桃"
+ ]
+ },
+ {
+ "name": "天门市",
+ "area": [
+ "天门"
+ ]
+ },
+ {
+ "name": "潜江市",
+ "area": [
+ "潜江"
+ ]
+ },
+ {
+ "name": "神农架林区",
+ "area": [
+ "神农架林区"
+ ]
+ },
+ {
+ "name": "其他",
+ "area": [
+ "其他"
+ ]
+ }
+ ]
+ },
+ {
+ "name": "湖南省",
+ "city": [
+ {
+ "name": "长沙市",
+ "area": [
+ "岳麓区",
+ "芙蓉区",
+ "天心区",
+ "开福区",
+ "雨花区",
+ "浏阳市",
+ "长沙县",
+ "望城县",
+ "宁乡县",
+ "其他"
+ ]
+ },
+ {
+ "name": "株洲市",
+ "area": [
+ "天元区",
+ "荷塘区",
+ "芦淞区",
+ "石峰区",
+ "醴陵市",
+ "株洲县",
+ "炎陵县",
+ "茶陵县",
+ "攸县",
+ "其他"
+ ]
+ },
+ {
+ "name": "湘潭市",
+ "area": [
+ "岳塘区",
+ "雨湖区",
+ "湘乡市",
+ "韶山市",
+ "湘潭县",
+ "其他"
+ ]
+ },
+ {
+ "name": "衡阳市",
+ "area": [
+ "雁峰区",
+ "珠晖区",
+ "石鼓区",
+ "蒸湘区",
+ "南岳区",
+ "耒阳市",
+ "常宁市",
+ "衡阳县",
+ "衡东县",
+ "衡山县",
+ "衡南县",
+ "祁东县",
+ "其他"
+ ]
+ },
+ {
+ "name": "邵阳市",
+ "area": [
+ "双清区",
+ "大祥区",
+ "北塔区",
+ "武冈市",
+ "邵东县",
+ "洞口县",
+ "新邵县",
+ "绥宁县",
+ "新宁县",
+ "邵阳县",
+ "隆回县",
+ "城步苗族自治县",
+ "其他"
+ ]
+ },
+ {
+ "name": "岳阳市",
+ "area": [
+ "岳阳楼区",
+ "云溪区",
+ "君山区",
+ "临湘市",
+ "汨罗市",
+ "岳阳县",
+ "湘阴县",
+ "平江县",
+ "华容县",
+ "其他"
+ ]
+ },
+ {
+ "name": "常德市",
+ "area": [
+ "武陵区",
+ "鼎城区",
+ "津市市",
+ "澧县",
+ "临澧县",
+ "桃源县",
+ "汉寿县",
+ "安乡县",
+ "石门县",
+ "其他"
+ ]
+ },
+ {
+ "name": "张家界市",
+ "area": [
+ "永定区",
+ "武陵源区",
+ "慈利县",
+ "桑植县",
+ "其他"
+ ]
+ },
+ {
+ "name": "益阳市",
+ "area": [
+ "赫山区",
+ "资阳区",
+ "沅江市",
+ "桃江县",
+ "南县",
+ "安化县",
+ "其他"
+ ]
+ },
+ {
+ "name": "郴州市",
+ "area": [
+ "北湖区",
+ "苏仙区",
+ "资兴市",
+ "宜章县",
+ "汝城县",
+ "安仁县",
+ "嘉禾县",
+ "临武县",
+ "桂东县",
+ "永兴县",
+ "桂阳县",
+ "其他"
+ ]
+ },
+ {
+ "name": "永州市",
+ "area": [
+ "冷水滩区",
+ "零陵区",
+ "祁阳县",
+ "蓝山县",
+ "宁远县",
+ "新田县",
+ "东安县",
+ "江永县",
+ "道县",
+ "双牌县",
+ "江华瑶族自治县",
+ "其他"
+ ]
+ },
+ {
+ "name": "怀化市",
+ "area": [
+ "鹤城区",
+ "洪江市",
+ "会同县",
+ "沅陵县",
+ "辰溪县",
+ "溆浦县",
+ "中方县",
+ "新晃侗族自治县",
+ "芷江侗族自治县",
+ "通道侗族自治县",
+ "靖州苗族侗族自治县",
+ "麻阳苗族自治县",
+ "其他"
+ ]
+ },
+ {
+ "name": "娄底市",
+ "area": [
+ "娄星区",
+ "冷水江市",
+ "涟源市",
+ "新化县",
+ "双峰县",
+ "其他"
+ ]
+ },
+ {
+ "name": "湘西土家族苗族自治州",
+ "area": [
+ "吉首市",
+ "古丈县",
+ "龙山县",
+ "永顺县",
+ "凤凰县",
+ "泸溪县",
+ "保靖县",
+ "花垣县",
+ "其他"
+ ]
+ },
+ {
+ "name": "其他",
+ "area": [
+ "其他"
+ ]
+ }
+ ]
+ },
+ {
+ "name": "广东省",
+ "city": [
+ {
+ "name": "广州市",
+ "area": [
+ "越秀区",
+ "荔湾区",
+ "海珠区",
+ "天河区",
+ "白云区",
+ "黄埔区",
+ "番禺区",
+ "花都区",
+ "南沙区",
+ "萝岗区",
+ "增城市",
+ "从化市",
+ "其他"
+ ]
+ },
+ {
+ "name": "深圳市",
+ "area": [
+ "福田区",
+ "罗湖区",
+ "南山区",
+ "宝安区",
+ "龙岗区",
+ "盐田区",
+ "其他"
+ ]
+ },
+ {
+ "name": "东莞市",
+ "area": [
+ "莞城",
+ "常平",
+ "塘厦",
+ "塘厦",
+ "塘厦",
+ "其他"
+ ]
+ },
+ {
+ "name": "中山市",
+ "area": [
+ "中山"
+ ]
+ },
+ {
+ "name": "潮州市",
+ "area": [
+ "湘桥区",
+ "潮安县",
+ "饶平县",
+ "其他"
+ ]
+ },
+ {
+ "name": "揭阳市",
+ "area": [
+ "榕城区",
+ "揭东县",
+ "揭西县",
+ "惠来县",
+ "普宁市",
+ "其他"
+ ]
+ },
+ {
+ "name": "云浮市",
+ "area": [
+ "云城区",
+ "新兴县",
+ "郁南县",
+ "云安县",
+ "罗定市",
+ "其他"
+ ]
+ },
+ {
+ "name": "珠海市",
+ "area": [
+ "香洲区",
+ "斗门区",
+ "金湾区",
+ "其他"
+ ]
+ },
+ {
+ "name": "汕头市",
+ "area": [
+ "金平区",
+ "濠江区",
+ "龙湖区",
+ "潮阳区",
+ "潮南区",
+ "澄海区",
+ "南澳县",
+ "其他"
+ ]
+ },
+ {
+ "name": "韶关市",
+ "area": [
+ "浈江区",
+ "武江区",
+ "曲江区",
+ "乐昌市",
+ "南雄市",
+ "始兴县",
+ "仁化县",
+ "翁源县",
+ "新丰县",
+ "乳源瑶族自治县",
+ "其他"
+ ]
+ },
+ {
+ "name": "佛山市",
+ "area": [
+ "禅城区",
+ "南海区",
+ "顺德区",
+ "三水区",
+ "高明区",
+ "其他"
+ ]
+ },
+ {
+ "name": "江门市",
+ "area": [
+ "蓬江区",
+ "江海区",
+ "新会区",
+ "恩平市",
+ "台山市",
+ "开平市",
+ "鹤山市",
+ "其他"
+ ]
+ },
+ {
+ "name": "湛江市",
+ "area": [
+ "赤坎区",
+ "霞山区",
+ "坡头区",
+ "麻章区",
+ "吴川市",
+ "廉江市",
+ "雷州市",
+ "遂溪县",
+ "徐闻县",
+ "其他"
+ ]
+ },
+ {
+ "name": "茂名市",
+ "area": [
+ "茂南区",
+ "茂港区",
+ "化州市",
+ "信宜市",
+ "高州市",
+ "电白县",
+ "其他"
+ ]
+ },
+ {
+ "name": "肇庆市",
+ "area": [
+ "端州区",
+ "鼎湖区",
+ "高要市",
+ "四会市",
+ "广宁县",
+ "怀集县",
+ "封开县",
+ "德庆县",
+ "其他"
+ ]
+ },
+ {
+ "name": "惠州市",
+ "area": [
+ "惠城区",
+ "惠阳区",
+ "博罗县",
+ "惠东县",
+ "龙门县",
+ "其他"
+ ]
+ },
+ {
+ "name": "梅州市",
+ "area": [
+ "梅江区",
+ "兴宁市",
+ "梅县",
+ "大埔县",
+ "丰顺县",
+ "五华县",
+ "平远县",
+ "蕉岭县",
+ "其他"
+ ]
+ },
+ {
+ "name": "汕尾市",
+ "area": [
+ "城区",
+ "陆丰市",
+ "海丰县",
+ "陆河县",
+ "其他"
+ ]
+ },
+ {
+ "name": "河源市",
+ "area": [
+ "源城区",
+ "紫金县",
+ "龙川县",
+ "连平县",
+ "和平县",
+ "东源县",
+ "其他"
+ ]
+ },
+ {
+ "name": "阳江市",
+ "area": [
+ "江城区",
+ "阳春市",
+ "阳西县",
+ "阳东县",
+ "其他"
+ ]
+ },
+ {
+ "name": "清远市",
+ "area": [
+ "清城区",
+ "英德市",
+ "连州市",
+ "佛冈县",
+ "阳山县",
+ "清新县",
+ "连山壮族瑶族自治县",
+ "连南瑶族自治县",
+ "其他"
+ ]
+ }
+ ]
+ },
+ {
+ "name": "广西",
+ "city": [
+ {
+ "name": "南宁市",
+ "area": [
+ "青秀区",
+ "兴宁区",
+ "西乡塘区",
+ "良庆区",
+ "江南区",
+ "邕宁区",
+ "武鸣县",
+ "隆安县",
+ "马山县",
+ "上林县",
+ "宾阳县",
+ "横县",
+ "其他"
+ ]
+ },
+ {
+ "name": "柳州市",
+ "area": [
+ "城中区",
+ "鱼峰区",
+ "柳北区",
+ "柳南区",
+ "柳江县",
+ "柳城县",
+ "鹿寨县",
+ "融安县",
+ "融水苗族自治县",
+ "三江侗族自治县",
+ "其他"
+ ]
+ },
+ {
+ "name": "桂林市",
+ "area": [
+ "象山区",
+ "秀峰区",
+ "叠彩区",
+ "七星区",
+ "雁山区",
+ "阳朔县",
+ "临桂县",
+ "灵川县",
+ "全州县",
+ "平乐县",
+ "兴安县",
+ "灌阳县",
+ "荔浦县",
+ "资源县",
+ "永福县",
+ "龙胜各族自治县",
+ "恭城瑶族自治县",
+ "其他"
+ ]
+ },
+ {
+ "name": "梧州市",
+ "area": [
+ "万秀区",
+ "蝶山区",
+ "长洲区",
+ "岑溪市",
+ "苍梧县",
+ "藤县",
+ "蒙山县",
+ "其他"
+ ]
+ },
+ {
+ "name": "北海市",
+ "area": [
+ "海城区",
+ "银海区",
+ "铁山港区",
+ "合浦县",
+ "其他"
+ ]
+ },
+ {
+ "name": "防城港市",
+ "area": [
+ "港口区",
+ "防城区",
+ "东兴市",
+ "上思县",
+ "其他"
+ ]
+ },
+ {
+ "name": "钦州市",
+ "area": [
+ "钦南区",
+ "钦北区",
+ "灵山县",
+ "浦北县",
+ "其他"
+ ]
+ },
+ {
+ "name": "贵港市",
+ "area": [
+ "港北区",
+ "港南区",
+ "覃塘区",
+ "桂平市",
+ "平南县",
+ "其他"
+ ]
+ },
+ {
+ "name": "玉林市",
+ "area": [
+ "玉州区",
+ "北流市",
+ "容县",
+ "陆川县",
+ "博白县",
+ "兴业县",
+ "其他"
+ ]
+ },
+ {
+ "name": "百色市",
+ "area": [
+ "右江区",
+ "凌云县",
+ "平果县",
+ "西林县",
+ "乐业县",
+ "德保县",
+ "田林县",
+ "田阳县",
+ "靖西县",
+ "田东县",
+ "那坡县",
+ "隆林各族自治县",
+ "其他"
+ ]
+ },
+ {
+ "name": "贺州市",
+ "area": [
+ "八步区",
+ "钟山县",
+ "昭平县",
+ "富川瑶族自治县",
+ "其他"
+ ]
+ },
+ {
+ "name": "河池市",
+ "area": [
+ "金城江区",
+ "宜州市",
+ "天峨县",
+ "凤山县",
+ "南丹县",
+ "东兰县",
+ "都安瑶族自治县",
+ "罗城仫佬族自治县",
+ "巴马瑶族自治县",
+ "环江毛南族自治县",
+ "大化瑶族自治县",
+ "其他"
+ ]
+ },
+ {
+ "name": "来宾市",
+ "area": [
+ "兴宾区",
+ "合山市",
+ "象州县",
+ "武宣县",
+ "忻城县",
+ "金秀瑶族自治县",
+ "其他"
+ ]
+ },
+ {
+ "name": "崇左市",
+ "area": [
+ "江州区",
+ "凭祥市",
+ "宁明县",
+ "扶绥县",
+ "龙州县",
+ "大新县",
+ "天等县",
+ "其他"
+ ]
+ },
+ {
+ "name": "其他市",
+ "area": [
+ "其他"
+ ]
+ }
+ ]
+ },
+ {
+ "name": "海南省",
+ "city": [
+ {
+ "name": "海口市",
+ "area": [
+ "龙华区",
+ "秀英区",
+ "琼山区",
+ "美兰区",
+ "其他"
+ ]
+ },
+ {
+ "name": "三亚市",
+ "area": [
+ "三亚市",
+ "其他"
+ ]
+ },
+ {
+ "name": "五指山市",
+ "area": [
+ "五指山"
+ ]
+ },
+ {
+ "name": "琼海市",
+ "area": [
+ "琼海"
+ ]
+ },
+ {
+ "name": "儋州市",
+ "area": [
+ "儋州"
+ ]
+ },
+ {
+ "name": "文昌市",
+ "area": [
+ "文昌"
+ ]
+ },
+ {
+ "name": "万宁市",
+ "area": [
+ "万宁"
+ ]
+ },
+ {
+ "name": "东方市",
+ "area": [
+ "东方"
+ ]
+ },
+ {
+ "name": "澄迈县",
+ "area": [
+ "澄迈县"
+ ]
+ },
+ {
+ "name": "定安县",
+ "area": [
+ "定安县"
+ ]
+ },
+ {
+ "name": "屯昌县",
+ "area": [
+ "屯昌县"
+ ]
+ },
+ {
+ "name": "临高县",
+ "area": [
+ "临高县"
+ ]
+ },
+ {
+ "name": "白沙黎族自治县",
+ "area": [
+ "白沙黎族自治县"
+ ]
+ },
+ {
+ "name": "昌江黎族自治县",
+ "area": [
+ "昌江黎族自治县"
+ ]
+ },
+ {
+ "name": "乐东黎族自治县",
+ "area": [
+ "乐东黎族自治县"
+ ]
+ },
+ {
+ "name": "陵水黎族自治县",
+ "area": [
+ "陵水黎族自治县"
+ ]
+ },
+ {
+ "name": "保亭黎族苗族自治县",
+ "area": [
+ "保亭黎族苗族自治县"
+ ]
+ },
+ {
+ "name": "琼中黎族苗族自治县",
+ "area": [
+ "琼中黎族苗族自治县"
+ ]
+ },
+ {
+ "name": "其他",
+ "area": [
+ "其他"
+ ]
+ }
+ ]
+ },
+ {
+ "name": "重庆市",
+ "city": [
+ {
+ "name": "重庆市",
+ "area": [
+ "渝中区",
+ "大渡口区",
+ "江北区",
+ "南岸区",
+ "北碚区",
+ "渝北区",
+ "巴南区",
+ "长寿区",
+ "双桥区",
+ "沙坪坝区",
+ "万盛区",
+ "万州区",
+ "涪陵区",
+ "黔江区",
+ "永川区",
+ "合川区",
+ "江津区",
+ "九龙坡区",
+ "南川区",
+ "綦江县",
+ "潼南县",
+ "荣昌县",
+ "璧山县",
+ "大足县",
+ "铜梁县",
+ "梁平县",
+ "开县",
+ "忠县",
+ "城口县",
+ "垫江县",
+ "武隆县",
+ "丰都县",
+ "奉节县",
+ "云阳县",
+ "巫溪县",
+ "巫山县",
+ "石柱土家族自治县",
+ "秀山土家族苗族自治县",
+ "酉阳土家族苗族自治县",
+ "彭水苗族土家族自治县",
+ "其他"
+ ]
+ }
+ ]
+ },
+ {
+ "name": "四川省",
+ "city": [
+ {
+ "name": "成都市",
+ "area": [
+ "青羊区",
+ "锦江区",
+ "金牛区",
+ "武侯区",
+ "成华区",
+ "龙泉驿区",
+ "青白江区",
+ "新都区",
+ "温江区",
+ "都江堰市",
+ "彭州市",
+ "邛崃市",
+ "崇州市",
+ "金堂县",
+ "郫县",
+ "新津县",
+ "双流县",
+ "蒲江县",
+ "大邑县",
+ "其他"
+ ]
+ },
+ {
+ "name": "自贡市",
+ "area": [
+ "大安区",
+ "自流井区",
+ "贡井区",
+ "沿滩区",
+ "荣县",
+ "富顺县",
+ "其他"
+ ]
+ },
+ {
+ "name": "攀枝花市",
+ "area": [
+ "仁和区",
+ "米易县",
+ "盐边县",
+ "东区",
+ "西区",
+ "其他"
+ ]
+ },
+ {
+ "name": "泸州市",
+ "area": [
+ "江阳区",
+ "纳溪区",
+ "龙马潭区",
+ "泸县",
+ "合江县",
+ "叙永县",
+ "古蔺县",
+ "其他"
+ ]
+ },
+ {
+ "name": "德阳市",
+ "area": [
+ "旌阳区",
+ "广汉市",
+ "什邡市",
+ "绵竹市",
+ "罗江县",
+ "中江县",
+ "其他"
+ ]
+ },
+ {
+ "name": "绵阳市",
+ "area": [
+ "涪城区",
+ "游仙区",
+ "江油市",
+ "盐亭县",
+ "三台县",
+ "平武县",
+ "安县",
+ "梓潼县",
+ "北川羌族自治县",
+ "其他"
+ ]
+ },
+ {
+ "name": "广元市",
+ "area": [
+ "元坝区",
+ "朝天区",
+ "青川县",
+ "旺苍县",
+ "剑阁县",
+ "苍溪县",
+ "市中区",
+ "其他"
+ ]
+ },
+ {
+ "name": "遂宁市",
+ "area": [
+ "船山区",
+ "安居区",
+ "射洪县",
+ "蓬溪县",
+ "大英县",
+ "其他"
+ ]
+ },
+ {
+ "name": "内江市",
+ "area": [
+ "市中区",
+ "东兴区",
+ "资中县",
+ "隆昌县",
+ "威远县",
+ "其他"
+ ]
+ },
+ {
+ "name": "乐山市",
+ "area": [
+ "市中区",
+ "五通桥区",
+ "沙湾区",
+ "金口河区",
+ "峨眉山市",
+ "夹江县",
+ "井研县",
+ "犍为县",
+ "沐川县",
+ "马边彝族自治县",
+ "峨边彝族自治县",
+ "其他"
+ ]
+ },
+ {
+ "name": "南充",
+ "area": [
+ "顺庆区",
+ "高坪区",
+ "嘉陵区",
+ "阆中市",
+ "营山县",
+ "蓬安县",
+ "仪陇县",
+ "南部县",
+ "西充县",
+ "其他"
+ ]
+ },
+ {
+ "name": "眉山市",
+ "area": [
+ "东坡区",
+ "仁寿县",
+ "彭山县",
+ "洪雅县",
+ "丹棱县",
+ "青神县",
+ "其他"
+ ]
+ },
+ {
+ "name": "宜宾市",
+ "area": [
+ "翠屏区",
+ "宜宾县",
+ "兴文县",
+ "南溪县",
+ "珙县",
+ "长宁县",
+ "高县",
+ "江安县",
+ "筠连县",
+ "屏山县",
+ "其他"
+ ]
+ },
+ {
+ "name": "广安市",
+ "area": [
+ "广安区",
+ "华蓥市",
+ "岳池县",
+ "邻水县",
+ "武胜县",
+ "其他"
+ ]
+ },
+ {
+ "name": "达州市",
+ "area": [
+ "通川区",
+ "万源市",
+ "达县",
+ "渠县",
+ "宣汉县",
+ "开江县",
+ "大竹县",
+ "其他"
+ ]
+ },
+ {
+ "name": "雅安市",
+ "area": [
+ "雨城区",
+ "芦山县",
+ "石棉县",
+ "名山县",
+ "天全县",
+ "荥经县",
+ "宝兴县",
+ "汉源县",
+ "其他"
+ ]
+ },
+ {
+ "name": "巴中市",
+ "area": [
+ "巴州区",
+ "南江县",
+ "平昌县",
+ "通江县",
+ "其他"
+ ]
+ },
+ {
+ "name": "资阳市",
+ "area": [
+ "雁江区",
+ "简阳市",
+ "安岳县",
+ "乐至县",
+ "其他"
+ ]
+ },
+ {
+ "name": "阿坝藏族羌族自治州",
+ "area": [
+ "马尔康县",
+ "九寨沟县",
+ "红原县",
+ "汶川县",
+ "阿坝县",
+ "理县",
+ "若尔盖县",
+ "小金县",
+ "黑水县",
+ "金川县",
+ "松潘县",
+ "壤塘县",
+ "茂县",
+ "其他"
+ ]
+ },
+ {
+ "name": "甘孜藏族自治州",
+ "area": [
+ "康定县",
+ "丹巴县",
+ "炉霍县",
+ "九龙县",
+ "甘孜县",
+ "雅江县",
+ "新龙县",
+ "道孚县",
+ "白玉县",
+ "理塘县",
+ "德格县",
+ "乡城县",
+ "石渠县",
+ "稻城县",
+ "色达县",
+ "巴塘县",
+ "泸定县",
+ "得荣县",
+ "其他"
+ ]
+ },
+ {
+ "name": "凉山彝族自治州",
+ "area": [
+ "西昌市",
+ "美姑县",
+ "昭觉县",
+ "金阳县",
+ "甘洛县",
+ "布拖县",
+ "雷波县",
+ "普格县",
+ "宁南县",
+ "喜德县",
+ "会东县",
+ "越西县",
+ "会理县",
+ "盐源县",
+ "德昌县",
+ "冕宁县",
+ "木里藏族自治县",
+ "其他"
+ ]
+ },
+ {
+ "name": "其他",
+ "area": [
+ "其他"
+ ]
+ }
+ ]
+ },
+ {
+ "name": "贵州省",
+ "city": [
+ {
+ "name": "贵阳市",
+ "area": [
+ "南明区",
+ "云岩区",
+ "花溪区",
+ "乌当区",
+ "白云区",
+ "小河区",
+ "清镇市",
+ "开阳县",
+ "修文县",
+ "息烽县",
+ "其他"
+ ]
+ },
+ {
+ "name": "六盘水市",
+ "area": [
+ "钟山区",
+ "水城县",
+ "盘县",
+ "六枝特区",
+ "其他"
+ ]
+ },
+ {
+ "name": "遵义市",
+ "area": [
+ "红花岗区",
+ "汇川区",
+ "赤水市",
+ "仁怀市",
+ "遵义县",
+ "绥阳县",
+ "桐梓县",
+ "习水县",
+ "凤冈县",
+ "正安县",
+ "余庆县",
+ "湄潭县",
+ "道真仡佬族苗族自治县",
+ "务川仡佬族苗族自治县",
+ "其他"
+ ]
+ },
+ {
+ "name": "安顺市",
+ "area": [
+ "西秀区",
+ "普定县",
+ "平坝县",
+ "镇宁布依族苗族自治县",
+ "紫云苗族布依族自治县",
+ "关岭布依族苗族自治县",
+ "其他"
+ ]
+ },
+ {
+ "name": "铜仁地区",
+ "area": [
+ "铜仁市",
+ "德江县",
+ "江口县",
+ "思南县",
+ "石阡县",
+ "玉屏侗族自治县",
+ "松桃苗族自治县",
+ "印江土家族苗族自治县",
+ "沿河土家族自治县",
+ "万山特区",
+ "其他"
+ ]
+ },
+ {
+ "name": "毕节地区",
+ "area": [
+ "毕节市",
+ "黔西县",
+ "大方县",
+ "织金县",
+ "金沙县",
+ "赫章县",
+ "纳雍县",
+ "威宁彝族回族苗族自治县",
+ "其他"
+ ]
+ },
+ {
+ "name": "黔西南布依族苗族自治州",
+ "area": [
+ "兴义市",
+ "望谟县",
+ "兴仁县",
+ "普安县",
+ "册亨县",
+ "晴隆县",
+ "贞丰县",
+ "安龙县",
+ "其他"
+ ]
+ },
+ {
+ "name": "黔东南苗族侗族自治州",
+ "area": [
+ "凯里市",
+ "施秉县",
+ "从江县",
+ "锦屏县",
+ "镇远县",
+ "麻江县",
+ "台江县",
+ "天柱县",
+ "黄平县",
+ "榕江县",
+ "剑河县",
+ "三穗县",
+ "雷山县",
+ "黎平县",
+ "岑巩县",
+ "丹寨县",
+ "其他"
+ ]
+ },
+ {
+ "name": "黔南布依族苗族自治州",
+ "area": [
+ "都匀市",
+ "福泉市",
+ "贵定县",
+ "惠水县",
+ "罗甸县",
+ "瓮安县",
+ "荔波县",
+ "龙里县",
+ "平塘县",
+ "长顺县",
+ "独山县",
+ "三都水族自治县",
+ "其他"
+ ]
+ },
+ {
+ "name": "其他",
+ "area": [
+ "其他"
+ ]
+ }
+ ]
+ },
+ {
+ "name": "云南省",
+ "city": [
+ {
+ "name": "昆明市",
+ "area": [
+ "盘龙区",
+ "五华区",
+ "官渡区",
+ "西山区",
+ "东川区",
+ "安宁市",
+ "呈贡县",
+ "晋宁县",
+ "富民县",
+ "宜良县",
+ "嵩明县",
+ "石林彝族自治县",
+ "禄劝彝族苗族自治县",
+ "寻甸回族彝族自治县",
+ "其他"
+ ]
+ },
+ {
+ "name": "曲靖市",
+ "area": [
+ "麒麟区",
+ "宣威市",
+ "马龙县",
+ "沾益县",
+ "富源县",
+ "罗平县",
+ "师宗县",
+ "陆良县",
+ "会泽县",
+ "其他"
+ ]
+ },
+ {
+ "name": "玉溪市",
+ "area": [
+ "红塔区",
+ "江川县",
+ "澄江县",
+ "通海县",
+ "华宁县",
+ "易门县",
+ "峨山彝族自治县",
+ "新平彝族傣族自治县",
+ "元江哈尼族彝族傣族自治县",
+ "其他"
+ ]
+ },
+ {
+ "name": "保山市",
+ "area": [
+ "隆阳区",
+ "施甸县",
+ "腾冲县",
+ "龙陵县",
+ "昌宁县",
+ "其他"
+ ]
+ },
+ {
+ "name": "昭通市",
+ "area": [
+ "昭阳区",
+ "鲁甸县",
+ "巧家县",
+ "盐津县",
+ "大关县",
+ "永善县",
+ "绥江县",
+ "镇雄县",
+ "彝良县",
+ "威信县",
+ "水富县",
+ "其他"
+ ]
+ },
+ {
+ "name": "丽江市",
+ "area": [
+ "古城区",
+ "永胜县",
+ "华坪县",
+ "玉龙纳西族自治县",
+ "宁蒗彝族自治县",
+ "其他"
+ ]
+ },
+ {
+ "name": "普洱市",
+ "area": [
+ "思茅区",
+ "普洱哈尼族彝族自治县",
+ "墨江哈尼族自治县",
+ "景东彝族自治县",
+ "景谷傣族彝族自治县",
+ "镇沅彝族哈尼族拉祜族自治县",
+ "江城哈尼族彝族自治县",
+ "孟连傣族拉祜族佤族自治县",
+ "澜沧拉祜族自治县",
+ "西盟佤族自治县",
+ "其他"
+ ]
+ },
+ {
+ "name": "临沧市",
+ "area": [
+ "临翔区",
+ "凤庆县",
+ "云县",
+ "永德县",
+ "镇康县",
+ "双江拉祜族佤族布朗族傣族自治县",
+ "耿马傣族佤族自治县",
+ "沧源佤族自治县",
+ "其他"
+ ]
+ },
+ {
+ "name": "德宏傣族景颇族自治州",
+ "area": [
+ "潞西市",
+ "瑞丽市",
+ "梁河县",
+ "盈江县",
+ "陇川县",
+ "其他"
+ ]
+ },
+ {
+ "name": "怒江傈僳族自治州",
+ "area": [
+ "泸水县",
+ "福贡县",
+ "贡山独龙族怒族自治县",
+ "兰坪白族普米族自治县",
+ "其他"
+ ]
+ },
+ {
+ "name": "迪庆藏族自治州",
+ "area": [
+ "香格里拉县",
+ "德钦县",
+ "维西傈僳族自治县",
+ "其他"
+ ]
+ },
+ {
+ "name": "大理白族自治州",
+ "area": [
+ "大理市",
+ "祥云县",
+ "宾川县",
+ "弥渡县",
+ "永平县",
+ "云龙县",
+ "洱源县",
+ "剑川县",
+ "鹤庆县",
+ "漾濞彝族自治县",
+ "南涧彝族自治县",
+ "巍山彝族回族自治县",
+ "其他"
+ ]
+ },
+ {
+ "name": "楚雄彝族自治州",
+ "area": [
+ "楚雄市",
+ "双柏县",
+ "牟定县",
+ "南华县",
+ "姚安县",
+ "大姚县",
+ "永仁县",
+ "元谋县",
+ "武定县",
+ "禄丰县",
+ "其他"
+ ]
+ },
+ {
+ "name": "红河哈尼族彝族自治州",
+ "area": [
+ "蒙自县",
+ "个旧市",
+ "开远市",
+ "绿春县",
+ "建水县",
+ "石屏县",
+ "弥勒县",
+ "泸西县",
+ "元阳县",
+ "红河县",
+ "金平苗族瑶族傣族自治县",
+ "河口瑶族自治县",
+ "屏边苗族自治县",
+ "其他"
+ ]
+ },
+ {
+ "name": "文山壮族苗族自治州",
+ "area": [
+ "文山县",
+ "砚山县",
+ "西畴县",
+ "麻栗坡县",
+ "马关县",
+ "丘北县",
+ "广南县",
+ "富宁县",
+ "其他"
+ ]
+ },
+ {
+ "name": "西双版纳傣族自治州",
+ "area": [
+ "景洪市",
+ "勐海县",
+ "勐腊县",
+ "其他"
+ ]
+ },
+ {
+ "name": "其他",
+ "area": [
+ "其他"
+ ]
+ }
+ ]
+ },
+ {
+ "name": "西藏",
+ "city": [
+ {
+ "name": "拉萨市",
+ "area": [
+ "城关区",
+ "林周县",
+ "当雄县",
+ "尼木县",
+ "曲水县",
+ "堆龙德庆县",
+ "达孜县",
+ "墨竹工卡县",
+ "其他"
+ ]
+ },
+ {
+ "name": "那曲地区",
+ "area": [
+ "那曲县",
+ "嘉黎县",
+ "比如县",
+ "聂荣县",
+ "安多县",
+ "申扎县",
+ "索县",
+ "班戈县",
+ "巴青县",
+ "尼玛县",
+ "其他"
+ ]
+ },
+ {
+ "name": "昌都地区",
+ "area": [
+ "昌都县",
+ "江达县",
+ "贡觉县",
+ "类乌齐县",
+ "丁青县",
+ "察雅县",
+ "八宿县",
+ "左贡县",
+ "芒康县",
+ "洛隆县",
+ "边坝县",
+ "其他"
+ ]
+ },
+ {
+ "name": "林芝地区",
+ "area": [
+ "林芝县",
+ "工布江达县",
+ "米林县",
+ "墨脱县",
+ "波密县",
+ "察隅县",
+ "朗县",
+ "其他"
+ ]
+ },
+ {
+ "name": "山南地区",
+ "area": [
+ "乃东县",
+ "扎囊县",
+ "贡嘎县",
+ "桑日县",
+ "琼结县",
+ "曲松县",
+ "措美县",
+ "洛扎县",
+ "加查县",
+ "隆子县",
+ "错那县",
+ "浪卡子县",
+ "其他"
+ ]
+ },
+ {
+ "name": "日喀则地区",
+ "area": [
+ "日喀则市",
+ "南木林县",
+ "江孜县",
+ "定日县",
+ "萨迦县",
+ "拉孜县",
+ "昂仁县",
+ "谢通门县",
+ "白朗县",
+ "仁布县",
+ "康马县",
+ "定结县",
+ "仲巴县",
+ "亚东县",
+ "吉隆县",
+ "聂拉木县",
+ "萨嘎县",
+ "岗巴县",
+ "其他"
+ ]
+ },
+ {
+ "name": "阿里地区",
+ "area": [
+ "噶尔县",
+ "普兰县",
+ "札达县",
+ "日土县",
+ "革吉县",
+ "改则县",
+ "措勤县",
+ "其他"
+ ]
+ },
+ {
+ "name": "其他",
+ "area": [
+ "其他"
+ ]
+ }
+ ]
+ },
+ {
+ "name": "陕西省",
+ "city": [
+ {
+ "name": "西安市",
+ "area": [
+ "莲湖区",
+ "新城区",
+ "碑林区",
+ "雁塔区",
+ "灞桥区",
+ "未央区",
+ "阎良区",
+ "临潼区",
+ "长安区",
+ "高陵县",
+ "蓝田县",
+ "户县",
+ "周至县",
+ "其他"
+ ]
+ },
+ {
+ "name": "铜川市",
+ "area": [
+ "耀州区",
+ "王益区",
+ "印台区",
+ "宜君县",
+ "其他"
+ ]
+ },
+ {
+ "name": "宝鸡市",
+ "area": [
+ "渭滨区",
+ "金台区",
+ "陈仓区",
+ "岐山县",
+ "凤翔县",
+ "陇县",
+ "太白县",
+ "麟游县",
+ "扶风县",
+ "千阳县",
+ "眉县",
+ "凤县",
+ "其他"
+ ]
+ },
+ {
+ "name": "咸阳市",
+ "area": [
+ "秦都区",
+ "渭城区",
+ "杨陵区",
+ "兴平市",
+ "礼泉县",
+ "泾阳县",
+ "永寿县",
+ "三原县",
+ "彬县",
+ "旬邑县",
+ "长武县",
+ "乾县",
+ "武功县",
+ "淳化县",
+ "其他"
+ ]
+ },
+ {
+ "name": "渭南市",
+ "area": [
+ "临渭区",
+ "韩城市",
+ "华阴市",
+ "蒲城县",
+ "潼关县",
+ "白水县",
+ "澄城县",
+ "华县",
+ "合阳县",
+ "富平县",
+ "大荔县",
+ "其他"
+ ]
+ },
+ {
+ "name": "延安市",
+ "area": [
+ "宝塔区",
+ "安塞县",
+ "洛川县",
+ "子长县",
+ "黄陵县",
+ "延川县",
+ "富县",
+ "延长县",
+ "甘泉县",
+ "宜川县",
+ "志丹县",
+ "黄龙县",
+ "吴起县",
+ "其他"
+ ]
+ },
+ {
+ "name": "汉中市",
+ "area": [
+ "汉台区",
+ "留坝县",
+ "镇巴县",
+ "城固县",
+ "南郑县",
+ "洋县",
+ "宁强县",
+ "佛坪县",
+ "勉县",
+ "西乡县",
+ "略阳县",
+ "其他"
+ ]
+ },
+ {
+ "name": "榆林市",
+ "area": [
+ "榆阳区",
+ "清涧县",
+ "绥德县",
+ "神木县",
+ "佳县",
+ "府谷县",
+ "子洲县",
+ "靖边县",
+ "横山县",
+ "米脂县",
+ "吴堡县",
+ "定边县",
+ "其他"
+ ]
+ },
+ {
+ "name": "安康市",
+ "area": [
+ "汉滨区",
+ "紫阳县",
+ "岚皋县",
+ "旬阳县",
+ "镇坪县",
+ "平利县",
+ "石泉县",
+ "宁陕县",
+ "白河县",
+ "汉阴县",
+ "其他"
+ ]
+ },
+ {
+ "name": "商洛市",
+ "area": [
+ "商州区",
+ "镇安县",
+ "山阳县",
+ "洛南县",
+ "商南县",
+ "丹凤县",
+ "柞水县",
+ "其他"
+ ]
+ },
+ {
+ "name": "其他",
+ "area": [
+ "其他"
+ ]
+ }
+ ]
+ },
+ {
+ "name": "甘肃省",
+ "city": [
+ {
+ "name": "兰州市",
+ "area": [
+ "城关区",
+ "七里河区",
+ "西固区",
+ "安宁区",
+ "红古区",
+ "永登县",
+ "皋兰县",
+ "榆中县",
+ "其他"
+ ]
+ },
+ {
+ "name": "嘉峪关市",
+ "area": [
+ "嘉峪关市",
+ "其他"
+ ]
+ },
+ {
+ "name": "金昌市",
+ "area": [
+ "金川区",
+ "永昌县",
+ "其他"
+ ]
+ },
+ {
+ "name": "白银市",
+ "area": [
+ "白银区",
+ "平川区",
+ "靖远县",
+ "会宁县",
+ "景泰县",
+ "其他"
+ ]
+ },
+ {
+ "name": "天水市",
+ "area": [
+ "清水县",
+ "秦安县",
+ "甘谷县",
+ "武山县",
+ "张家川回族自治县",
+ "北道区",
+ "秦城区",
+ "其他"
+ ]
+ },
+ {
+ "name": "武威市",
+ "area": [
+ "凉州区",
+ "民勤县",
+ "古浪县",
+ "天祝藏族自治县",
+ "其他"
+ ]
+ },
+ {
+ "name": "酒泉市",
+ "area": [
+ "肃州区",
+ "玉门市",
+ "敦煌市",
+ "金塔县",
+ "肃北蒙古族自治县",
+ "阿克塞哈萨克族自治县",
+ "安西县",
+ "其他"
+ ]
+ },
+ {
+ "name": "张掖市",
+ "area": [
+ "甘州区",
+ "民乐县",
+ "临泽县",
+ "高台县",
+ "山丹县",
+ "肃南裕固族自治县",
+ "其他"
+ ]
+ },
+ {
+ "name": "庆阳市",
+ "area": [
+ "西峰区",
+ "庆城县",
+ "环县",
+ "华池县",
+ "合水县",
+ "正宁县",
+ "宁县",
+ "镇原县",
+ "其他"
+ ]
+ },
+ {
+ "name": "平凉市",
+ "area": [
+ "崆峒区",
+ "泾川县",
+ "灵台县",
+ "崇信县",
+ "华亭县",
+ "庄浪县",
+ "静宁县",
+ "其他"
+ ]
+ },
+ {
+ "name": "定西市",
+ "area": [
+ "安定区",
+ "通渭县",
+ "临洮县",
+ "漳县",
+ "岷县",
+ "渭源县",
+ "陇西县",
+ "其他"
+ ]
+ },
+ {
+ "name": "陇南市",
+ "area": [
+ "武都区",
+ "成县",
+ "宕昌县",
+ "康县",
+ "文县",
+ "西和县",
+ "礼县",
+ "两当县",
+ "徽县",
+ "其他"
+ ]
+ },
+ {
+ "name": "临夏回族自治州",
+ "area": [
+ "临夏市",
+ "临夏县",
+ "康乐县",
+ "永靖县",
+ "广河县",
+ "和政县",
+ "东乡族自治县",
+ "积石山保安族东乡族撒拉族自治县",
+ "其他"
+ ]
+ },
+ {
+ "name": "甘南藏族自治州",
+ "area": [
+ "合作市",
+ "临潭县",
+ "卓尼县",
+ "舟曲县",
+ "迭部县",
+ "玛曲县",
+ "碌曲县",
+ "夏河县",
+ "其他"
+ ]
+ },
+ {
+ "name": "其他",
+ "area": [
+ "其他"
+ ]
+ }
+ ]
+ },
+ {
+ "name": "青海省",
+ "city": [
+ {
+ "name": "西宁市",
+ "area": [
+ "城中区",
+ "城东区",
+ "城西区",
+ "城北区",
+ "湟源县",
+ "湟中县",
+ "大通回族土族自治县",
+ "其他"
+ ]
+ },
+ {
+ "name": "海东地区",
+ "area": [
+ "平安县",
+ "乐都县",
+ "民和回族土族自治县",
+ "互助土族自治县",
+ "化隆回族自治县",
+ "循化撒拉族自治县",
+ "其他"
+ ]
+ },
+ {
+ "name": "海北藏族自治州",
+ "area": [
+ "海晏县",
+ "祁连县",
+ "刚察县",
+ "门源回族自治县",
+ "其他"
+ ]
+ },
+ {
+ "name": "海南藏族自治州",
+ "area": [
+ "共和县",
+ "同德县",
+ "贵德县",
+ "兴海县",
+ "贵南县",
+ "其他"
+ ]
+ },
+ {
+ "name": "黄南藏族自治州",
+ "area": [
+ "同仁县",
+ "尖扎县",
+ "泽库县",
+ "河南蒙古族自治县",
+ "其他"
+ ]
+ },
+ {
+ "name": "果洛藏族自治州",
+ "area": [
+ "玛沁县",
+ "班玛县",
+ "甘德县",
+ "达日县",
+ "久治县",
+ "玛多县",
+ "其他"
+ ]
+ },
+ {
+ "name": "玉树藏族自治州",
+ "area": [
+ "玉树县",
+ "杂多县",
+ "称多县",
+ "治多县",
+ "囊谦县",
+ "曲麻莱县",
+ "其他"
+ ]
+ },
+ {
+ "name": "海西蒙古族藏族自治州",
+ "area": [
+ "德令哈市",
+ "格尔木市",
+ "乌兰县",
+ "都兰县",
+ "天峻县",
+ "其他"
+ ]
+ },
+ {
+ "name": "其他",
+ "area": [
+ "其他"
+ ]
+ }
+ ]
+ },
+ {
+ "name": "宁夏",
+ "city": [
+ {
+ "name": "银川市",
+ "area": [
+ "兴庆区",
+ "西夏区",
+ "金凤区",
+ "灵武市",
+ "永宁县",
+ "贺兰县",
+ "其他"
+ ]
+ },
+ {
+ "name": "石嘴山市",
+ "area": [
+ "大武口区",
+ "惠农区",
+ "平罗县",
+ "其他"
+ ]
+ },
+ {
+ "name": "吴忠市",
+ "area": [
+ "利通区",
+ "青铜峡市",
+ "盐池县",
+ "同心县",
+ "其他"
+ ]
+ },
+ {
+ "name": "固原市",
+ "area": [
+ "原州区",
+ "西吉县",
+ "隆德县",
+ "泾源县",
+ "彭阳县",
+ "其他"
+ ]
+ },
+ {
+ "name": "中卫市",
+ "area": [
+ "沙坡头区",
+ "中宁县",
+ "海原县",
+ "其他"
+ ]
+ },
+ {
+ "name": "其他",
+ "area": [
+ "其他"
+ ]
+ }
+ ]
+ },
+ {
+ "name": "新疆",
+ "city": [
+ {
+ "name": "乌鲁木齐市",
+ "area": [
+ "天山区",
+ "沙依巴克区",
+ "新市区",
+ "水磨沟区",
+ "头屯河区",
+ "达坂城区",
+ "东山区",
+ "乌鲁木齐县",
+ "其他"
+ ]
+ },
+ {
+ "name": "克拉玛依市",
+ "area": [
+ "克拉玛依区",
+ "独山子区",
+ "白碱滩区",
+ "乌尔禾区",
+ "其他"
+ ]
+ },
+ {
+ "name": "吐鲁番地区",
+ "area": [
+ "吐鲁番市",
+ "托克逊县",
+ "鄯善县",
+ "其他"
+ ]
+ },
+ {
+ "name": "哈密地区",
+ "area": [
+ "哈密市",
+ "伊吾县",
+ "巴里坤哈萨克自治县",
+ "其他"
+ ]
+ },
+ {
+ "name": "和田地区",
+ "area": [
+ "和田市",
+ "和田县",
+ "洛浦县",
+ "民丰县",
+ "皮山县",
+ "策勒县",
+ "于田县",
+ "墨玉县",
+ "其他"
+ ]
+ },
+ {
+ "name": "阿克苏地区",
+ "area": [
+ "阿克苏市",
+ "温宿县",
+ "沙雅县",
+ "拜城县",
+ "阿瓦提县",
+ "库车县",
+ "柯坪县",
+ "新和县",
+ "乌什县",
+ "其他"
+ ]
+ },
+ {
+ "name": "喀什地区",
+ "area": [
+ "喀什市",
+ "巴楚县",
+ "泽普县",
+ "伽师县",
+ "叶城县",
+ "岳普湖县",
+ "疏勒县",
+ "麦盖提县",
+ "英吉沙县",
+ "莎车县",
+ "疏附县",
+ "塔什库尔干塔吉克自治县",
+ "其他"
+ ]
+ },
+ {
+ "name": "克孜勒苏柯尔克孜自治州",
+ "area": [
+ "阿图什市",
+ "阿合奇县",
+ "乌恰县",
+ "阿克陶县",
+ "其他"
+ ]
+ },
+ {
+ "name": "巴音郭楞蒙古自治州",
+ "area": [
+ "库尔勒市",
+ "和静县",
+ "尉犁县",
+ "和硕县",
+ "且末县",
+ "博湖县",
+ "轮台县",
+ "若羌县",
+ "焉耆回族自治县",
+ "其他"
+ ]
+ },
+ {
+ "name": "昌吉回族自治州",
+ "area": [
+ "昌吉市",
+ "阜康市",
+ "奇台县",
+ "玛纳斯县",
+ "吉木萨尔县",
+ "呼图壁县",
+ "木垒哈萨克自治县",
+ "米泉市",
+ "其他"
+ ]
+ },
+ {
+ "name": "博尔塔拉蒙古自治州",
+ "area": [
+ "博乐市",
+ "精河县",
+ "温泉县",
+ "其他"
+ ]
+ },
+ {
+ "name": "石河子",
+ "area": [
+ "石河子"
+ ]
+ },
+ {
+ "name": "阿拉尔",
+ "area": [
+ "阿拉尔"
+ ]
+ },
+ {
+ "name": "图木舒克",
+ "area": [
+ "图木舒克"
+ ]
+ },
+ {
+ "name": "五家渠",
+ "area": [
+ "五家渠"
+ ]
+ },
+ {
+ "name": "伊犁哈萨克自治州",
+ "area": [
+ "伊宁市",
+ "奎屯市",
+ "伊宁县",
+ "特克斯县",
+ "尼勒克县",
+ "昭苏县",
+ "新源县",
+ "霍城县",
+ "巩留县",
+ "察布查尔锡伯自治县",
+ "塔城地区",
+ "阿勒泰地区",
+ "其他"
+ ]
+ },
+ {
+ "name": "其他",
+ "area": [
+ "其他"
+ ]
+ }
+ ]
+ },
+ {
+ "name": "台湾省",
+ "city": [
+ {
+ "name": "台北市",
+ "area": [
+ "内湖区",
+ "南港区",
+ "中正区",
+ "万华区",
+ "大同区",
+ "中山区",
+ "松山区",
+ "大安区",
+ "信义区",
+ "文山区",
+ "士林区",
+ "北投区"
+ ]
+ },
+ {
+ "name": "新北市",
+ "area": [
+ "板桥区",
+ "汐止区",
+ "新店区",
+ "其他"
+ ]
+ },
+ {
+ "name": "桃园市",
+ "area": [
+ "其他"
+ ]
+ },
+ {
+ "name": "台中市",
+ "area": [
+ "其他"
+ ]
+ },
+ {
+ "name": "台南市",
+ "area": [
+ "其他"
+ ]
+ },
+ {
+ "name": "高雄市",
+ "area": [
+ "其他"
+ ]
+ }
+ ]
+ },
+ {
+ "name": "澳门",
+ "city": [
+ {
+ "name": "澳门",
+ "area": [
+ "花地玛堂区",
+ "圣安多尼堂区",
+ "大堂区",
+ "望德堂区",
+ "风顺堂区",
+ "嘉模堂区",
+ "圣方济各堂区",
+ "路凼",
+ "其他"
+ ]
+ }
+ ]
+ },
+ {
+ "name": "香港",
+ "city": [
+ {
+ "name": "香港",
+ "area": [
+ "深水埗区",
+ "油尖旺区",
+ "九龙城区",
+ "黄大仙区",
+ "观塘区",
+ "北区",
+ "大埔区",
+ "沙田区",
+ "西贡区",
+ "元朗区",
+ "屯门区",
+ "荃湾区",
+ "葵青区",
+ "离岛区",
+ "中西区",
+ "湾仔区",
+ "东区",
+ "南区",
+ "其他"
+ ]
+ }
+ ]
+ }
+]
diff --git a/app/src/main/java/com/ck/ckcollar/app/CKApp.kt b/app/src/main/java/com/ck/ckcollar/app/CKApp.kt
new file mode 100644
index 0000000..97e3456
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/CKApp.kt
@@ -0,0 +1,66 @@
+package com.ck.ckcollar.app
+
+import android.app.Application
+import android.text.TextUtils
+import com.bumptech.glide.Glide
+import com.bumptech.glide.GlideBuilder
+import com.bumptech.glide.load.DecodeFormat
+import com.bumptech.glide.request.RequestOptions
+import com.ck.ckcollar.app.exception.ExceptionHandler
+import com.ck.ckcollar.app.model.UserInfoModel
+import com.ck.ckcollar.app.utils.Const
+import com.cyclone.shadowsocks.utils.PreferencesUtils
+import com.google.gson.Gson
+import com.tt.kit.base.TTBaseActivity
+import com.tt.kit.utils.TTLog
+import com.umeng.analytics.MobclickAgent
+import com.umeng.commonsdk.UMConfigure
+import com.umeng.umcrash.customlog.UAPMCustomLog
+
+
+class CKApp : Application() {
+
+ var activitys = mutableListOf()
+ lateinit var token : String
+ var wxJump = 0
+ var userInfo : UserInfoModel? = null
+ companion object {
+ lateinit var app: CKApp
+
+ }
+
+ override fun onCreate() {
+ super.onCreate()
+ app = this
+
+ token = PreferencesUtils.getString(this, Const.TOKEN,"").toString()
+ var userData = PreferencesUtils.getString(this, Const.USER_DATA,"").toString()
+ if (!TextUtils.isEmpty(userData)){
+ userInfo = Gson().fromJson(userData, UserInfoModel::class.java)
+ }
+
+ ExceptionHandler.instance.init(this)
+
+ val defaultOptions = RequestOptions()
+ .format(DecodeFormat.PREFER_RGB_565) // 设置图片格式为RGB_565以减少内存使用
+ .disallowHardwareConfig()
+ // 禁止硬件位图配置以避免潜在的颜色问题
+ // 可以添加更多配置...
+
+
+ Glide.init(this, GlideBuilder().setDefaultRequestOptions(defaultOptions))
+ //SkinManager.getInstance().init(this);
+
+ UMConfigure.setLogEnabled(true)
+ MobclickAgent.setPageCollectionMode(MobclickAgent.PageMode.MANUAL);
+
+ UMConfigure.preInit(this, "6a618cf0e88ae439bf379f37", "UM");
+
+
+ UMConfigure.init(this, "6a618cf0e88ae439bf379f37", "UM", UMConfigure.DEVICE_TYPE_PHONE, "");
+
+ TTLog.isLogEable(true)
+ }
+
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/action/ActionCode.kt b/app/src/main/java/com/ck/ckcollar/app/action/ActionCode.kt
new file mode 100644
index 0000000..3d8ea99
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/action/ActionCode.kt
@@ -0,0 +1,182 @@
+package com.ck.ckcollar.app.action
+
+import com.tt.kit.utils.TTLog
+
+object ActionCode {
+ //const val BASE_URL = "https://oval-discolor-onshore.ngrok-free.dev";
+ //const val BASE_URL = "https://ragged-parting-unrushed.ngrok-free.dev";
+ //const val BASE_URL = "https://ragged-parting-unrushed.ngrok-free.dev";
+ // const val BASE_URL = "https://ragged-parting-unrushed.ngrok-free.dev";
+ const val BASE_URL = "https://d.chongdunpet.com"
+ const val CUSTOMER_URL = "wss://d.chongdunpet.com/ws/chat?role=customer&token=";
+
+
+
+
+ fun getUrl(actionCode: String): String {
+ var url = ""
+ when (actionCode) {
+ "demo" -> url = "/sys/dept/list/enterprise"
+
+ "登录" -> url = "/app/login"
+ "微信登录" -> url = "/app/login/wx"
+
+ "宠物列表" -> url = "/app/pet/list"
+
+ "添加宠物" -> url = "/app/pet"
+
+ "上传照片" -> url = "/minio/upload"
+
+ "上传照片s" -> url = "/minio/uploads"
+
+ "宠物档案" -> url = "/app/pet"
+
+ "编辑宠物" -> url = "/app/pet"
+
+ "删除宠物" -> url = "/app/pet"
+
+ "首页" -> url = "/app/home/data"
+
+ "绑定设备" -> url = "/app/device/bind"
+
+ "切换设备" -> url = "/app/device/switchCurrentPet"
+
+ "解绑设备" -> url = "/app/device/unbind"
+
+ "设备信息" -> url = "/app/device/info"
+
+ "协议" -> url = "/app/setting/pageContent"
+
+ "用户注销检查" -> url = "/app/setting/accountDeleteCheck"
+
+ "用户注销" -> url = "/app/setting/deleteAccount"
+
+ "宠物知识列表" -> url = "/app/health/knowledge/list"
+
+ "宠物知识明细" -> url = "/app/health/knowledge"
+
+ "客服在线状态" -> url = "/app/health/consult/status"
+
+ "会话消息列表" -> url = "/app/health/consult/messages"
+
+ "发送会话消息" -> url = "/app/health/ai/chat"
+ "发送会话消息stream" -> url = "/app/health/ai/chat/stream"
+
+ "发送人工会话消息" -> url = "/app/health/consult/message"
+
+
+ "获取会话消息" -> url = "/app/health/consult/session"
+
+ "商品列表" -> url = "/commodityApp/list/list"
+
+ "商品明细" -> url = "/commodityApp/list"
+
+ "精选好物" -> url = "/commodityApp/list/recommended_slot"
+ "商品分类列表" -> url = "/colcategory/category/app/list"
+
+ "发送验证码" -> url = "/app/sms/send"
+
+ "验证码登录" -> url = "/app/login/sms"
+
+ "注册" -> url = "/app/register"
+
+ "找回密码" -> url = "/app/password/reset"
+ "添加购物车" -> url = "/app/cart/add"
+ "购物车列表" -> url = "/app/cart/list"
+ "购物车数量和合计" -> url = "/app/cart/cartInfo"
+ "购物车全部选中" -> url = "/app/cart/selectAll"
+ "购物车更新数量" -> url = "/app/cart/quantity"
+ "购物车更新选中" -> url = "/app/cart/selected"
+ "购物车删除商品" -> url = "/app/cart"
+
+ "个人资料" -> url = "/app/profile/detail"
+
+ "收货地址列表" -> url = "/user/address/list"
+ "新增收货地址" -> url = "/user/address/add"
+ "收货地址明细" -> url = "/user/address"
+ "编辑收货地址" -> url = "/user/address/edit"
+ "删除收货地址" -> url = "/user/address"
+ "设置默认地址" -> url = "/user/address/setDefault"
+
+ "地址标签列表" -> url = "/user/address/label/list"
+ "新增标签" -> url = "/user/address/label/add"
+ "删除标签" -> url = "/user/address/label"
+ "商品种类" -> url = "/colcategory/category/app/list"
+
+ "余额明细列表" -> url = "/app/balance/list"
+ "余额" -> url = "/app/balance/overview"
+ "余额明细" -> url = "/app/balance/detail"
+
+ "充值" -> url = "/app/balance/recharge"
+ "提现" -> url = "/app/balance/withdraw"
+ "修改登录密码" -> url = "/app/setting/loginPassword/change"
+
+ "积分总览" -> url = "/app/points/overview"
+ "积分明细" -> url = "/app/points/list"
+
+
+ "会员信息" -> url = "/app/member/info"
+ "会员套餐列表" -> url = "/app/member/packages"
+ "开通会员" -> url = "/app/member/pay"
+
+ "我的订单" -> url = "/orderApp/list/query"
+ "我的订单明细" -> url = "/orderApp/list/queryDetails"
+ "取消订单" -> url = "/orderApp/list/cancel"
+ "删除订单" -> url = "/orderApp/list/delete"
+ "确认收货" -> url = "/orderItemsApp/list/confirmReceive"
+ "修改收货地址" -> url = "/orderItemsApp/list/updateAddress"
+ "查看物流信息" -> url = "/orderItemsApp/list/logistics"
+ "查看物流信息" -> url = "/orderItemsApp/list/logistics"
+
+ "直接购买确认订单" -> url = "/orderApp/list/confirmDirect"
+ "购物车购买确认订单" -> url = "/orderApp/list/confirm"
+ "下单" -> url = "/app/order/createAndPay"
+ "申请售后" -> url = "/orderItemsApp/list/refund/apply"
+ "售后进度" -> url = "/orderItemsApp/list/refundApply"
+ "物流公司" -> url = "/orderItemsApp/list/enums"
+ "填写快递单号" -> url = "/orderItemsApp/list/refund/returnLogistics"
+
+
+ "AI拍照识别" -> url = "/app/home/ai/pet-recognition"
+ "消息通知列表" -> url = "/app/notice/list"
+ "读取消息" -> url = "/app/notice/markRead"
+ "读取全部消息" -> url = "/app/notice/markReadAll"
+
+
+ "意见反馈" -> url = "/app/feedback/submit"
+ "设备退回" -> url = "/app/return/submit"
+
+ "单条余额明细" -> url = "/app/balance/detail"
+
+ "修改支付密码" -> url = "/app/setting/payPassword/change"
+ "找回支付密码" -> url = "/app/setting/payPassword/reset"
+ "查询支付密码状态" -> url = "/app/setting/payPassword/status"
+ "订单支付" -> url = "/app/order/pay"
+
+
+ "修改个人信息" -> url = "/app/profile/update"
+ "修改绑定手机" -> url = "/app/profile/phone/update"
+
+ "押金信息" -> url = "/app/deposit/info"
+ "芝麻授权" -> url = "/app/deposit/free"
+ "退还押金" -> url = "/app/deposit/refund"
+
+
+ "获取我的联系客服会话" -> url = "/app/chat/consult/session"
+ "订单ID获取确认信息" -> url = "/orderApp/list/confirmByOrderId"
+
+ "微信绑定手机" -> url = "/app/wx/bindPhone"
+ "商城轮训图" -> url = "/app/home/bannerMallData"
+
+ "取消退款" -> url = "/orderItemsApp/list/refund/cancel"
+
+ "更新" -> url = "/app/update"
+ "未读消息数量" -> url = "/app/notice/unreadCount"
+ "绑定微信" -> url = "/app/profile/wx/bind"
+
+
+ }
+ TTLog.e(url)
+ return url;
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/config/Config.kt b/app/src/main/java/com/ck/ckcollar/app/config/Config.kt
new file mode 100644
index 0000000..3752055
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/config/Config.kt
@@ -0,0 +1,37 @@
+package com.ck.ckcollar.app.config
+
+import android.util.Log
+import org.osmdroid.tileprovider.tilesource.OnlineTileSourceBase
+import org.osmdroid.tileprovider.tilesource.TileSourceFactory
+import org.osmdroid.tileprovider.tilesource.XYTileSource
+import org.osmdroid.util.GeoPoint
+import org.osmdroid.util.MapTileIndex
+
+object Config : TileSourceFactory() {
+
+ const val MAP_KEY = "9ada0ca4ea55f17b72ff46c7a88d9225"
+
+ // 默认GeoPoint
+ val defaultGeoPoint = GeoPoint(39.909, 116.39742)
+
+ /**
+ * 天地图 有标注电子地图
+ */
+ var TDTCIA_W: OnlineTileSourceBase = object : XYTileSource(
+ "Tian Di Tu CIA",
+ 0, 20, 256, "",
+ arrayOf(
+ "http://t0.tianditu.com/DataServer?T=cia_w&tk=$MAP_KEY",
+ "http://t1.tianditu.com/DataServer?T=cia_w&tk=$MAP_KEY",
+ "http://t2.tianditu.com/DataServer?T=cia_w&tk=$MAP_KEY",
+ "http://t3.tianditu.com/DataServer?T=cia_w&tk=$MAP_KEY",
+ "http://t4.tianditu.com/DataServer?T=cia_w&tk=$MAP_KEY",
+ "http://t5.tianditu.com/DataServer?T=cia_w&tk=$MAP_KEY",
+ "http://t6.tianditu.com/DataServer?T=cia_w&tk=$MAP_KEY",
+ "http://t7.tianditu.com/DataServer?T=cia_w&tk=$MAP_KEY"
+ )
+ ) {
+ override fun getTileURLString(pMapTileIndex: Long) =
+ ("$baseUrl&X=${MapTileIndex.getX(pMapTileIndex)}&Y=${MapTileIndex.getY(pMapTileIndex)}&L=${MapTileIndex.getZoom(pMapTileIndex)}")
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/exception/ExceptionHandler.kt b/app/src/main/java/com/ck/ckcollar/app/exception/ExceptionHandler.kt
new file mode 100644
index 0000000..ba6d6ba
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/exception/ExceptionHandler.kt
@@ -0,0 +1,283 @@
+package com.ck.ckcollar.app.exception
+
+import android.content.Context
+import android.content.pm.PackageManager
+import android.os.Build
+import android.os.Environment
+import android.os.Looper
+import android.os.Process
+import android.util.Log
+import com.cyclone.shadowsocks.utils.PreferencesUtils
+import com.tt.kit.utils.ToastHelper
+import com.umeng.umcrash.UMCrash
+import com.umeng.umcrash.customlog.UAPMCustomLog
+import java.io.File
+import java.io.FileOutputStream
+import java.io.PrintWriter
+import java.io.StringWriter
+import java.net.UnknownHostException
+import java.text.DateFormat
+import java.text.SimpleDateFormat
+import java.util.Date
+import java.lang.Thread.UncaughtExceptionHandler
+
+class ExceptionHandler : UncaughtExceptionHandler {
+ // 系统默认的UncaughtException处理类
+ private var mDefaultHandler: Thread.UncaughtExceptionHandler? = null
+
+ // 程序的Context对象
+ private var mContext: Context? = null
+
+ // 用来存储设备信息和异常信息
+ private val infos: MutableMap = HashMap()
+
+ // 用于格式化日期,作为日志文件名的一部分
+ private val formatter: DateFormat = SimpleDateFormat("yyyyMMdd_HHmmss")
+
+ /**
+ * 初始化
+ *
+ * @param context
+ */
+ fun init(context: Context) {
+ mContext = context
+ // 获取系统默认的UncaughtException处理器
+ mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler()
+ // 设置该CrashHandler为程序的默认处理器
+ Thread.setDefaultUncaughtExceptionHandler(this)
+ }
+
+ /**
+ * 当UncaughtException发生时会转入该函数来处理
+ */
+ override fun uncaughtException(thread: Thread?, ex: Throwable?) {
+ if (!handleException(ex) && mDefaultHandler != null) {
+ // 如果用户没有处理则让系统默认的异常处理器来处理
+ mDefaultHandler!!.uncaughtException(thread, ex)
+ }
+ val crashFileName = saveInfoToSD(ex)
+ // 3. 缓存崩溃日志文件
+ cacheCrashFile(crashFileName)
+
+ Process.killProcess(Process.myPid())
+ }
+
+ /**
+ * 缓存崩溃日志文件
+ *
+ * @param fileName
+ */
+ private fun cacheCrashFile(fileName: String?) {
+ PreferencesUtils.putString(mContext!!, "CRASH_FILE_NAME", fileName!!)
+ }
+
+ val crashFile: File
+ /**
+ * 获取崩溃文件名称
+ *
+ * @return
+ */
+ get() {
+ val crashFileName: String =
+ PreferencesUtils
+ .getString(mContext!!, "CRASH_FILE_NAME", "")!!
+ return File(crashFileName)
+ }
+
+ /**
+ * 保存获取的 软件信息,设备信息和出错信息保存在SDcard中
+ *
+ * @param ex
+ *
+ * @return
+ */
+ private fun saveInfoToSD(ex: Throwable?): String? {
+ var fileName: String? = null
+ val sb = StringBuffer()
+
+ for (entry in collectDeviceInfo(mContext!!).entries) {
+ val key = entry.key
+ val value = entry.value
+ sb.append(key).append(" = ").append(value).append("\n")
+ }
+
+
+ // sb.append(obtainExceptionInfo(ex));
+ sb.append("exception").append(" = ").append(getStackTraceString(ex))
+
+ UAPMCustomLog.e("chong_dun",sb.toString())
+ UMCrash.generateCustomLog(ex,"chongdunException");
+ if (Environment.getExternalStorageState() == Environment.MEDIA_MOUNTED) {
+ val dir = File(
+ mContext!!.getFilesDir().toString() + File.separator + "crash" + File.separator
+ )
+ // 先删除之前的异常信息
+ if (dir.exists()) {
+ deleteDir(dir)
+ }
+ // 再从新创建文件夹
+ if (!dir.exists()) {
+ dir.mkdir()
+ }
+ try {
+ fileName =
+ dir.toString() + File.separator + SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(
+ Date()
+ ) + ".txt"
+ val fos = FileOutputStream(fileName)
+ fos.write(sb.toString().toByteArray())
+ fos.flush()
+ fos.close()
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ }
+ return fileName
+ }
+
+ /**
+ * 获取系统未捕捉的错误信息
+ *
+ * @param throwable
+ *
+ * @return
+ */
+ private fun obtainExceptionInfo(throwable: Throwable): String? {
+ val stringWriter = StringWriter()
+ val printWriter = PrintWriter(stringWriter)
+ throwable.printStackTrace(printWriter)
+ printWriter.close()
+ return stringWriter.toString()
+ }
+
+ /**
+ * 自定义错误处理,收集错误信息 发送错误报告等操作均在此完成.
+ *
+ * @param ex
+ *
+ * @return true:如果处理了该异常信息;否则返回false.
+ */
+ private fun handleException(ex: Throwable?): Boolean {
+ if (ex == null) {
+ return false
+ }
+
+
+ // 使用Toast来显示异常信息
+ object : Thread() {
+ override fun run() {
+ Looper.prepare()
+ //new TuiChuHttp(mContext).execute();
+ ToastHelper.show(mContext!!, "程序出现异常,自行重新启动")
+ // Toast.makeText(mContext, "程序出现异常,自行重新启动", Toast.LENGTH_SHORT).show();
+ Looper.loop()
+ }
+ }.start()
+
+
+ // 收集设备参数信息
+ // collectDeviceInfo(mContext);
+
+ // 保存日志文件
+ val str = saveCrashInfo2File(ex)
+ Log.e("错误日志:::", str)
+ // submitLog(str);
+ return true
+ }
+
+ /**
+ * 收集设备参数信息
+ *
+ * @param ctx
+ */
+ fun collectDeviceInfo(ctx: Context): MutableMap {
+ try {
+ val pm = ctx.getPackageManager()
+ val pi = pm.getPackageInfo(ctx.getPackageName(), PackageManager.GET_ACTIVITIES)
+ if (pi != null) {
+ val versionName: String = (if (pi.versionName == null) "null" else pi.versionName)!!
+ infos.put("apkversion", versionName)
+ infos.put("devicename", Build.BRAND)
+ infos.put("devicetype", Build.MODEL)
+ infos.put("android", Build.VERSION.RELEASE)
+ infos.put("time", SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(Date()))
+ }
+ } catch (e: PackageManager.NameNotFoundException) {
+ Log.e(TAG, "an error occured when collect package info", e)
+ }
+ return infos
+ }
+
+ /**
+ * 保存错误信息到文件中
+ *
+ * @param ex
+ *
+ * @return 返回文件名称, 便于将文件传送到服务器
+ */
+ private fun saveCrashInfo2File(ex: Throwable?): String {
+ val sb = StringBuffer()
+ for (entry in infos.entries) {
+ val key = entry.key
+ val value = entry.value
+ sb.append("[" + key + ", " + value + "]\n")
+ }
+ sb.append("\n" + getStackTraceString(ex))
+ return sb.toString() //sb接到完成异常报告,可在此断点获取错误信息
+ }
+
+ companion object {
+ val TAG: String = ExceptionHandler::class.java.getCanonicalName()
+
+ /**
+ * 获取实例 ,单例模式
+ */
+ // CrashHandler实例
+ val instance: ExceptionHandler = ExceptionHandler()
+
+ /**
+ * 递归删除目录下的所有文件及子目录下所有文件
+ *
+ * @param dir 将要删除的文件目录
+ *
+ * @return boolean Returns "true" if all deletions were successful. If a deletion fails, the
+ * method stops attempting to delete and returns "false".
+ */
+ fun deleteDir(dir: File): Boolean {
+ if (dir.isDirectory()) {
+ val children = dir.list()
+ // 递归删除目录中的子目录下
+ for (i in children!!.indices) {
+ val success = deleteDir(File(dir, children[i]))
+ if (!success) {
+ return false
+ }
+ }
+ }
+ // 目录此时为空,可以删除
+ return true
+ }
+
+ /**
+ * 获取捕捉到的异常的字符串
+ */
+ fun getStackTraceString(tr: Throwable?): String? {
+ if (tr == null) {
+ return ""
+ }
+
+ var t: Throwable? = tr
+ while (t != null) {
+ if (t is UnknownHostException) {
+ return ""
+ }
+ t = t.cause
+ }
+
+ val sw = StringWriter()
+ val pw = PrintWriter(sw)
+ tr.printStackTrace(pw)
+ return sw.toString()
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/listenner/OnItemClickListenner.kt b/app/src/main/java/com/ck/ckcollar/app/listenner/OnItemClickListenner.kt
new file mode 100644
index 0000000..b632616
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/listenner/OnItemClickListenner.kt
@@ -0,0 +1,7 @@
+package com.ck.ckcollar.app.listenner
+
+import com.ck.ckcollar.app.model.HealthNoteModel
+
+interface OnItemClickListenner {
+ fun onClick(pos : Int,model : Any)
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/listenner/OnItemLongClickListenner.kt b/app/src/main/java/com/ck/ckcollar/app/listenner/OnItemLongClickListenner.kt
new file mode 100644
index 0000000..e41d62c
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/listenner/OnItemLongClickListenner.kt
@@ -0,0 +1,7 @@
+package com.ck.ckcollar.app.listenner
+
+import com.ck.ckcollar.app.model.HealthNoteModel
+
+interface OnItemLongClickListenner {
+ fun onClick(pos : Int,model : Any)
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/listenner/OnPasswordInputFinish.kt b/app/src/main/java/com/ck/ckcollar/app/listenner/OnPasswordInputFinish.kt
new file mode 100644
index 0000000..d8e2c3e
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/listenner/OnPasswordInputFinish.kt
@@ -0,0 +1,8 @@
+package com.ck.ckcollar.app.listenner
+
+/**
+ * 自定义接口,用于给密码输入完成添加回掉事�?
+ */
+interface OnPasswordInputFinish {
+ fun inputFinish();
+}
diff --git a/app/src/main/java/com/ck/ckcollar/app/model/AIMessageModel.kt b/app/src/main/java/com/ck/ckcollar/app/model/AIMessageModel.kt
new file mode 100644
index 0000000..bcc2d87
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/model/AIMessageModel.kt
@@ -0,0 +1,8 @@
+package com.ck.ckcollar.app.model
+
+class AIMessageModel: CkBaseModel() {
+ var answer :String? = ""
+ var chatId :String? = ""
+ var conversationId :String? = ""
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/model/AIPhotoModel.kt b/app/src/main/java/com/ck/ckcollar/app/model/AIPhotoModel.kt
new file mode 100644
index 0000000..56c5b2e
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/model/AIPhotoModel.kt
@@ -0,0 +1,12 @@
+package com.ck.ckcollar.app.model
+
+class AIPhotoModel : CkBaseModel() {
+ var chatId: String? = "" // 聊天ID
+ var species: String? = "" // 物种
+ var variety: String? = "" // 品种
+ var rawAnswer: String? = "" // 原始回答
+ var conversationId: String? = "" // 会话ID
+ var imageUrl: String? = "" // 图片URL
+ var speciesCode: String? = "" // 物种编码
+ var confidence: String? = "" // 置信度
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/model/AddressModel.kt b/app/src/main/java/com/ck/ckcollar/app/model/AddressModel.kt
new file mode 100644
index 0000000..88e1bae
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/model/AddressModel.kt
@@ -0,0 +1,27 @@
+package com.ck.ckcollar.app.model
+
+class AddressModel {
+ var addressTag: String? = "" // 地址标签
+ var areaName: String? = "" // 区名
+ var cityName: String? = "" // 城市名
+ var createBy: String? = "" // 创建人
+ var createTime: String? = "" // 创建时间
+ var customTag: String? = "" // 自定义标签标识
+ var detailAddress: String? = "" // 详细地址
+ var fullAddress: String? = "" // 完整地址
+ var id: Int = 0 // ID
+ var isDefault: String? = "" // 是否默认地址
+ var postalCode: String? = "" // 邮政编码
+ var provinceName: String? = "" // 省份名称
+ var receiverName: String? = "" // 收货人姓名
+ var receiverPhone: String? = "" // 收货人电话
+ var remark: String? = "" // 备注
+ var updateBy: String? = "" // 更新人
+ var updateTime: String? = "" // 更新时间
+ var userAddressLables: String? = "" // 用户地址标签
+ var userId: Int = 0 // 用户ID
+
+
+ var colUserAddressLabel : TagModel? = null
+}
+
diff --git a/app/src/main/java/com/ck/ckcollar/app/model/AfterSalesPrograss.kt b/app/src/main/java/com/ck/ckcollar/app/model/AfterSalesPrograss.kt
new file mode 100644
index 0000000..bd5355c
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/model/AfterSalesPrograss.kt
@@ -0,0 +1,68 @@
+package com.ck.ckcollar.app.model
+
+class AfterSalesPrograss {
+ var applyStatus: String? = "" // 申请状态 case "0": return "待审核case "1": return "审核通过 case "2": return "审核拒绝"
+ var applyTime: String? = "" // 申请时间
+ var areaName: String? = "" // 区名
+ var attachmentUrls: String? = "" // 附件URL
+ var auditResult: String? = "" // 审核结果
+ var auditTime: String? = "" // 审核时间
+ var cityName: String? = "" // 城市名
+ var colLogistics: String? = "" // 物流信息
+ var colOrderItems: String? = "" // 订单商品列表
+ var colOrderProgresses: List? = null // 订单进度列表
+ var commodityState: String? = "" // 商品状态
+ var confirmInfo: String? = "" // 确认信息
+ var confirmSign: String? = "" // 确认标识
+ var confirmTime: String? = "" // 确认时间
+ var createBy: String? = "" // 创建人
+ var createTime: String? = "" // 创建时间
+ var currentStage: Int = 0 // 当前阶段
+ var deliveryMethod: String? = "" // 配送方式
+ var detailAddress: String? = "" // 详细地址
+ var discountAmount: Double = 0.0 // 优惠金额
+ var exchangeItemId: String? = "" // 换货商品ID
+ var exchangeLogisticsNo: String? = "" // 换货物流单号
+ var exchangecolLogistics: String? = "" // 换货物流信息
+ var id: Int = 0 // ID
+ var logisticsCode: String? = "" // 物流编码
+ var logisticsNo: String? = "" // 物流单号
+ var orderId: Int = 0 // 订单ID
+ var orderNo: String? = "" // 订单编号
+ var postalCode: String? = "" // 邮政编码
+ var provinceName: String? = "" // 省份名称
+ var quantity: Int = 0 // 数量
+ var receiverName: String? = "" // 收货人姓名
+ var receiverPhone: String? = "" // 收货人电话
+ var refundAmount: Double = 0.0 // 退款金额
+ var refundReason: String? = "" // 退款原因
+ var refundType: String? = "" // 退款类型
+ var remark: String? = "" // 备注
+ var returnItemId: String? = "" // 退货商品ID
+ var returnLogisticsNo: String? = "" // 退货物流单号
+ var returncolLogistics: String? = "" // 退货物流信息
+ var shipmentSign: String? = "" // 发货标识
+ var shipmentTime: String? = "" // 发货时间
+ var subtotalAmount: Double = 0.0 // 小计金额
+ var supplementInfo: String? = "" // 补充信息
+ var unitPrice: Double = 0.0 // 单价
+ var updateBy: String? = "" // 更新人
+ var updateTime: String? = "" // 更新时间
+ var userId: Int = 0 // 用户ID
+ var userName: String? = "" // 用户姓名
+ var userPhone: String? = "" // 用户电话
+
+ class OrderProgress {
+ var completeTime: String? = "" // 完成时间
+ var createBy: String? = "" // 创建人
+ var createTime: String? = "" // 创建时间
+ var id: Int = 0 // ID
+ var orderId: Int = 0 // 订单ID
+ var remark: String? = "" // 备注
+ var stageName: String? = "" // 阶段名称
+ var stageNo: Int = 0 // 阶段编号
+ var stageType: String? = "" // 阶段类型
+ var updateBy: String? = "" // 更新人
+ var updateTime: String? = "" // 更新时间
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/model/AgreementModel.kt b/app/src/main/java/com/ck/ckcollar/app/model/AgreementModel.kt
new file mode 100644
index 0000000..0f34ef9
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/model/AgreementModel.kt
@@ -0,0 +1,12 @@
+package com.ck.ckcollar.app.model
+
+class AgreementModel : CkBaseModel() {
+ var createBy: String? = "" // 创建人
+ var createTime: String? = "" // 创建时间
+ var id: Int = 0 // ID
+ var pageMsg: String? = "" // 页面内容
+ var pageType: String? = "" // 页面类型
+ var remark: String? = "" // 备注
+ var updateBy: String? = "" // 更新人
+ var updateTime: String? = "" // 更新时间
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/model/BalanceModle.kt b/app/src/main/java/com/ck/ckcollar/app/model/BalanceModle.kt
new file mode 100644
index 0000000..38bcd8a
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/model/BalanceModle.kt
@@ -0,0 +1,8 @@
+package com.ck.ckcollar.app.model
+
+class BalanceModle : CkBaseModel() {
+
+ var balance : Double = 0.0
+ var totalExpense : Double = 0.0
+ var totalRecharge : Double = 0.0
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/model/BannarModel.kt b/app/src/main/java/com/ck/ckcollar/app/model/BannarModel.kt
new file mode 100644
index 0000000..3d14e1f
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/model/BannarModel.kt
@@ -0,0 +1,14 @@
+package com.ck.ckcollar.app.model
+
+class BannarModel : CkBaseModel(){
+ var bannerStatus: String? = ""
+ var bannerUrl: String? = ""
+ var createBy: String? = ""
+ var createTime: String? = ""
+ var id: Int = 0
+ var pageName: String? = ""
+ var remark: String? = ""
+ var sortOrder: Int = 0
+ var updateBy: String? = ""
+ var updateTime: String? = ""
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/model/CancelModel.kt b/app/src/main/java/com/ck/ckcollar/app/model/CancelModel.kt
new file mode 100644
index 0000000..107d149
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/model/CancelModel.kt
@@ -0,0 +1,15 @@
+package com.ck.ckcollar.app.model
+
+class CancelModel : CkBaseModel() {
+ var allPassed: Boolean = false // 是否全部通过
+ var conditions: List? = null // 注销条件列表
+ var phoneNumber: String? = "" // 手机号
+
+ var assetsUncleared: Boolean = false //账户是否仍有未结清的余额或积分
+}
+
+ class Condition {
+ var name: String? = "" // 条件名称
+ var passed: Boolean = false // 是否通过
+ var message: String? = "" // 提示消息
+ }
diff --git a/app/src/main/java/com/ck/ckcollar/app/model/CkBaseModel.kt b/app/src/main/java/com/ck/ckcollar/app/model/CkBaseModel.kt
new file mode 100644
index 0000000..7e2356c
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/model/CkBaseModel.kt
@@ -0,0 +1,6 @@
+package com.ck.ckcollar.app.model
+
+import com.google.gson.annotations.SerializedName
+import java.io.Serializable
+open class CkBaseModel : Serializable {
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/model/CollarModel.kt b/app/src/main/java/com/ck/ckcollar/app/model/CollarModel.kt
new file mode 100644
index 0000000..ea7b2e2
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/model/CollarModel.kt
@@ -0,0 +1,5 @@
+package com.ck.ckcollar.app.model
+
+class CollarModel {
+ var name : String? = ""
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/model/CollarTypeModel.kt b/app/src/main/java/com/ck/ckcollar/app/model/CollarTypeModel.kt
new file mode 100644
index 0000000..c657b74
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/model/CollarTypeModel.kt
@@ -0,0 +1,33 @@
+package com.ck.ckcollar.app.model
+
+class CollarTypeModel : CkBaseModel(){
+
+
+ var total : Int = 0
+ var rows : List = listOf()
+ class TypeDataModel : CkBaseModel(){
+
+ var createBy: String = ""
+ var createTime: String = ""
+ var updateBy: String = ""
+ var updateTime: String = ""
+ var remark: String = ""
+ var id: Long = 0
+ var customerId: Int = 0
+ var patName: String = ""
+ var patSpecies: String = ""
+ var patVariety: String = ""
+ var patAge: String = ""
+ var patHeight: String = ""
+ var patWeight: String = ""
+ var patBodytype: String = ""
+ var patColor: String = ""
+ var patProphylactic: String = ""
+ var patUser: String = ""
+ var collNum: String = ""
+ var patPhoto: String = ""
+ var tenantId: String = ""
+ var createDept: Int = 0
+
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/model/ConfirmOrderModel.kt b/app/src/main/java/com/ck/ckcollar/app/model/ConfirmOrderModel.kt
new file mode 100644
index 0000000..9c675b8
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/model/ConfirmOrderModel.kt
@@ -0,0 +1,50 @@
+package com.ck.ckcollar.app.model
+
+class ConfirmOrderModel {
+ var address: AddressModel? = null // 地址信息
+ var addressId: Int = 0 // 地址ID
+ var availablePoints: Double = 0.0 // 可用积分
+ var buyerNote: String? = "" // 买家备注
+ var discountAmount: Double = 0.0 // 优惠金额
+ var freightAmount: Double = 0.0 // 运费金额
+ var goodsTotalAmount: Double = 0.0 // 商品总金额
+ var items: List? = null // 订单商品列表
+ var memberAmount: Double = 0.0 // 会员价金额
+ var memberDiscount: Double = 0.0 // 会员折扣金额
+ var orderId: Int = 0 // 订单ID
+ var orderSource: String? = "" // 订单来源
+ var payAmount: Double = 0.0 // 支付金额
+ var payAmounts: String? = "" // 支付金额列表
+ var payType: String? = "" // 支付方式
+ var payTypes: String? = "" // 支付方式列表
+ var pointsDeduction: Double = 0.0 // 积分抵扣金额
+ var userId: Int = 0 // 用户ID
+ var isPoint : Int = 0 //积分是否足够(0足够1不足)
+
+ class OrderItem {
+ var cartId: Int = 0 // 购物车ID
+ var comCover: String? = "" // 商品封面图
+ var comId: Int = 0 // 商品ID
+ var comName: String? = "" // 商品名称
+ var comNum: Long = 0L // 商品编号
+ var comPrice: Double = 0.0 // 商品价格
+ var memPrice: Double = 0.0 // 会员价格
+ var memSubtotal: Double = 0.0 // 会员价小计金额
+ var quantity: Int = 0 // 数量
+ var specId: Int = 0 // 规格ID
+ var specName: String? = "" // 规格名称
+ var subtotal: Double = 0.0 // 小计金额
+ }
+
+ class AddressModel {
+ var areaName: String? = "" // 区名
+ var cityName: String? = "" // 城市名
+ var detailAddress: String? = "" // 详细地址
+ var fullAddress: String? = "" // 完整地址
+ var id: Int = 0 // ID
+ var postalCode: String? = "" // 邮政编码
+ var provinceName: String? = "" // 省份名称
+ var receiverName: String? = "" // 收货人姓名
+ var receiverPhone: String? = "" // 收货人电话
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/model/CreateOrderModel.kt b/app/src/main/java/com/ck/ckcollar/app/model/CreateOrderModel.kt
new file mode 100644
index 0000000..9a214f3
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/model/CreateOrderModel.kt
@@ -0,0 +1,47 @@
+package com.ck.ckcollar.app.model
+
+class CreateOrderModel : CkBaseModel() {
+ var userId: Int = 0 // 用户ID
+ var orderId: Int = 0 // 订单ID
+ var addressId: Int = 0 // 地址ID
+ var orderSource: String? = "" // 订单来源
+ var address: OrderAddress? = null // 收货地址
+ var items: List? = null // 订单商品列表
+ var goodsTotalAmount: Double = 0.0 // 商品总金额
+ var memberDiscount: Double = 0.0 // 会员折扣金额
+ var memberAmount: Double = 0.0 // 会员价金额
+ var freightAmount: Double = 0.0 // 运费金额
+ var discountAmount: Double = 0.0 // 优惠金额
+ var availablePoints: Double = 0.0 // 可用积分
+ var pointsDeduction: Double = 0.0 // 积分抵扣金额
+ var payAmount: Double = 0.0 // 实付金额
+ var payType: String? = "" // 支付方式
+ var buyerNote: String? = "" // 买家备注
+
+ class OrderAddress {
+ var id: Int = 0 // 地址ID
+ var receiverName: String? = "" // 收货人姓名
+ var receiverPhone: String? = "" // 收货人电话
+ var provinceName: String? = "" // 省份名称
+ var cityName: String? = "" // 城市名
+ var areaName: String? = "" // 区名
+ var detailAddress: String? = "" // 详细地址
+ var postalCode: String? = "" // 邮政编码
+ var fullAddress: String? = "" // 完整地址
+ }
+
+ class OrderItem {
+ var cartId: Int = 0 // 购物车ID
+ var comId: Int = 0 // 商品ID
+ var comNum: Long = 0L // 商品编号
+ var comName: String? = "" // 商品名称
+ var comCover: String? = "" // 商品封面图
+ var comPrice: Double = 0.0 // 商品价格
+ var memPrice: Double = 0.0 // 会员价格
+ var quantity: Int = 0 // 数量
+ var specName: String? = "" // 规格名称
+ var specId: Int = 0 // 规格ID
+ var subtotal: Double = 0.0 // 小计金额
+ var memSubtotal: Double = 0.0 // 会员价小计金额
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/model/CustomerMessageModel.kt b/app/src/main/java/com/ck/ckcollar/app/model/CustomerMessageModel.kt
new file mode 100644
index 0000000..c2ac802
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/model/CustomerMessageModel.kt
@@ -0,0 +1,29 @@
+package com.ck.ckcollar.app.model
+
+class CustomerMessageModel {
+ var total : Int = 0
+ var rows: List? = null
+
+ class MessageItemModel {
+ var content: String? = "" // 消息内容
+ var createBy: String? = "" // 创建人
+ var createTime: String? = "" // 创建时间
+ var customerId: Int = 0 // 客户ID
+ var delFlag: String? = "" // 删除标记
+ var isRead: String? = "" // 是否已读
+ var msgId: Int = 0 // 消息ID
+ var readTime: String? = "" // 读取时间
+ var remark: String? = "" // 备注
+ var senderAvatar: String? = "" // 发送者头像
+ var senderId: Int = 0 // 发送者ID
+ var senderName: String? = "" // 发送者名称
+ var senderType: String? = "" // 发送者类型
+ var updateBy: String? = "" // 更新人
+ var updateTime: String? = "" // 更新时间
+
+ var url : String? = ""
+
+ var uuid : String? = ""
+
+ }
+}
diff --git a/app/src/main/java/com/ck/ckcollar/app/model/CustomerStatusModel.kt b/app/src/main/java/com/ck/ckcollar/app/model/CustomerStatusModel.kt
new file mode 100644
index 0000000..823db24
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/model/CustomerStatusModel.kt
@@ -0,0 +1,12 @@
+package com.ck.ckcollar.app.model
+
+class CustomerStatusModel : CkBaseModel(){
+
+ var tip : String? = null
+ var agentOnline : Boolean =false
+
+ var servicePhone :String? = ""
+
+ var serviceStartTime : String? = ""
+ var serviceEndTime : String? = ""
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/model/DepositModel.kt b/app/src/main/java/com/ck/ckcollar/app/model/DepositModel.kt
new file mode 100644
index 0000000..bcb802f
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/model/DepositModel.kt
@@ -0,0 +1,9 @@
+package com.ck.ckcollar.app.model
+
+class DepositModel : CkBaseModel(){
+
+ var depositType: String? = "" // 押金类型
+ var outOrderNo: String? = "" // 外部订单号
+ var orderStr: String? = "" // 订单字符串
+ var amount: Double = 0.0 // 金额
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/model/ExpressModel.kt b/app/src/main/java/com/ck/ckcollar/app/model/ExpressModel.kt
new file mode 100644
index 0000000..03ea119
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/model/ExpressModel.kt
@@ -0,0 +1,35 @@
+package com.ck.ckcollar.app.model
+
+class ExpressModel {
+ var createBy: String? = "" // 创建人
+ var createTime: String? = "" // 创建时间
+ var updateBy: String? = "" // 更新人
+ var updateTime: String? = "" // 更新时间
+ var remark: String? = "" // 备注
+ var params: Map? = null // 参数
+ var id: Int = 0 // ID
+ var orderId: Int = 0 // 订单ID
+ var orderNo: String? = "" // 订单编号
+ var logisticsCode: String? = "" // 物流编码
+ var logisticsCompanyName: String? = "" // 物流公司名称
+ var logisticsNo: String? = "" // 物流单号
+ var logisticsStatus: String? = "" // 物流状态
+ var signTime: String? = "" // 签收时间
+ var deliveryMethod: String? = "" // 配送方式
+ var routeMapUrl: String? = "" // 路线地图URL
+ var logisticsPhone: String? = "" // 物流电话
+ var colLogisticsInfos: List? = null // 物流信息列表
+
+ class ColLogisticsInfo {
+ var createBy: String? = "" // 创建人
+ var createTime: String? = "" // 创建时间
+ var updateBy: String? = "" // 更新人
+ var updateTime: String? = "" // 更新时间
+ var remark: String? = "" // 备注
+ var params: Map? = null // 参数
+ var id: Int = 0 // ID
+ var logisticsId: Int = 0 // 物流ID
+ var logisticsTime: String? = "" // 物流时间
+ var logisticsDesc: String? = "" // 物流描述
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/model/HealthNoteModel.kt b/app/src/main/java/com/ck/ckcollar/app/model/HealthNoteModel.kt
new file mode 100644
index 0000000..15fdf4f
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/model/HealthNoteModel.kt
@@ -0,0 +1,21 @@
+package com.ck.ckcollar.app.model
+
+class HealthNoteModel : CkBaseModel(){
+ var total : Int = 0
+ var rows : List = listOf()
+ class NoteModel : CkBaseModel(){
+ var createBy: String? = "" // 创建人
+ var createTime: String? = "" // 创建时间
+ var id: Int = 0 // ID
+ var knowledgeMsg: String? = "" // 知识内容
+ var imageUrl: String? = "" // 图片
+ var pageName: String? = "" // 页面名称
+ var pageStatus: String? = "" // 页面状态
+ var remark: String? = "" // 备注
+ var sortOrder: Int = 0 // 排序顺序
+ var updateBy: String? = "" // 更新人
+ var updateTime: String? = "" // 更新时间
+ }
+
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/model/HomeModel.kt b/app/src/main/java/com/ck/ckcollar/app/model/HomeModel.kt
new file mode 100644
index 0000000..b46edfd
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/model/HomeModel.kt
@@ -0,0 +1,46 @@
+package com.ck.ckcollar.app.model
+
+class HomeModel : CkBaseModel() {
+
+ var banners: List? = listOf()
+
+ var equipment: EquipmentModel? = null
+
+ var lowBattery: Boolean? = false
+
+ class EquipmentModel : CkBaseModel() {
+ var collNum: String? = "" // 设备编号
+ var createBy: String? = "" // 创建人
+ var createDept: String? = "" // 创建部门
+ var createTime: String? = "" // 创建时间
+ var custName: String? = "" // 客户名称
+ var customerId: Int = 0 // 客户ID
+ var equStatus: String? = "" // 设备状态
+ var equUpdatetime: String? = "" // 设备更新时间
+ var firmVersion: String? = "" // 固件版本
+ var healthVitality: String? = "" // 健康活力值
+ var id: Int = 0 // 设备ID
+ var lastLocation: String? = "" // 最后位置
+ var latitude: Double = 0.0 // 纬度
+ var longitude: Double = 0.0 // 经度
+ var mileage: Double = 0.0 // 里程
+ var patId: Int = 0 // 宠物ID
+ var patName: String? = "" // 宠物名称
+ var powerLevel: String? = "" // 电量等级
+ var remark: String? = "" // 备注
+ var steps: String? = "" // 步数
+ var tenantId: String? = "" // 租户ID
+ var updateBy: String? = "" // 更新人
+ var updateTime: String? = "" // 更新时间
+
+ /**
+
+ 是否无法接收经纬度(即无法定位):设备当前拿不到有效GPS(如进入遮挡/地下/盲区),
+
+ 或已离线/超时无法上报位置。前端可在该值为 true 时展示
+
+ “当前位置无法接收信号,最后一次定位是:xxx”
+ */
+ var noSignal : Boolean = false //
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/model/ImageModel.kt b/app/src/main/java/com/ck/ckcollar/app/model/ImageModel.kt
new file mode 100644
index 0000000..8d8bd4f
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/model/ImageModel.kt
@@ -0,0 +1,9 @@
+package com.ck.ckcollar.app.model
+
+class ImageModel {
+
+ var isAdd : Boolean = false
+ var path : String? = ""
+ var url : String? = ""
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/model/JsonBean.kt b/app/src/main/java/com/ck/ckcollar/app/model/JsonBean.kt
new file mode 100644
index 0000000..d34c817
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/model/JsonBean.kt
@@ -0,0 +1,28 @@
+
+import com.contrarywind.interfaces.IPickerViewData
+
+class JsonBean : IPickerViewData {
+ /**
+ * name : 省份
+ * city : [{"name":"北京市","area":["东城区","西城区","崇文区","宣武区","朝阳区"]}]
+ */
+ var name: String? = null
+ var city: MutableList? = null
+
+ // 实现 IPickerViewData 接口,
+ // 这个用来显示在PickerView上面的字符串,
+ // PickerView会通过IPickerViewData获取getPickerViewText方法显示出来。
+ override fun getPickerViewText(): String? {
+ return this.name
+ }
+
+
+ class CityBean {
+ /**
+ * name : 城市
+ * area : ["东城区","西城区","崇文区","昌平区"]
+ */
+ var name: String? = null
+ var area: MutableList? = null
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/model/LoginModel.kt b/app/src/main/java/com/ck/ckcollar/app/model/LoginModel.kt
new file mode 100644
index 0000000..f151645
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/model/LoginModel.kt
@@ -0,0 +1,12 @@
+package com.ck.ckcollar.app.model
+
+class LoginModel{
+
+ var token : String ? = ""
+
+ var needBindPhone : Boolean = false
+
+ var wxAvatar : String? = ""
+ var wxNickname : String? = ""
+ var openid : String? = ""
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/model/LogisticsModel.kt b/app/src/main/java/com/ck/ckcollar/app/model/LogisticsModel.kt
new file mode 100644
index 0000000..43642d4
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/model/LogisticsModel.kt
@@ -0,0 +1,6 @@
+package com.ck.ckcollar.app.model
+
+class LogisticsModel : CkBaseModel() {
+ var code : String? = ""
+ var name : String? = ""
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/model/MemberModel.kt b/app/src/main/java/com/ck/ckcollar/app/model/MemberModel.kt
new file mode 100644
index 0000000..87d06dc
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/model/MemberModel.kt
@@ -0,0 +1,36 @@
+package com.ck.ckcollar.app.model
+
+class MemberModel {
+ var balance: Double = 0.0 // 余额
+ var deadlineTime: String? = "" // 截止时间
+ var isMember: Boolean = false // 是否会员
+ var points: Double = 0.0 // 积分
+ var registrationTime: String? = "" // 注册时间
+ var orderStr: String? = "" // 订单字符串
+ var amount: Double = 0.0 // 金额
+ var payType: String? = "" // 支付方式
+ var orderNo: String? = "" // 订单编号
+ var order: MemberOrder? = null // 订单信息
+
+ class MemberOrder {
+ var createBy: String? = "" // 创建人
+ var createTime: String? = "" // 创建时间
+ var durationMonths: Int = 0 // 持续月份数
+ var id: Int = 0 // ID
+ var memberEndTime: String? = "" // 会员结束时间
+ var memberStartTime: String? = "" // 会员开始时间
+ var orderNo: String? = "" // 订单编号
+ var orderStatus: Int = 0 // 订单状态
+ var packageId: Int = 0 // 套餐ID
+ var packageName: String? = "" // 套餐名称
+ var payAmount: Double = 0.0 // 支付金额
+ var payTime: String? = "" // 支付时间
+ var payType: String? = "" // 支付方式
+ var placeTime: String? = "" // 下单时间
+ var remark: String? = "" // 备注
+ var transactionId: String? = "" // 交易ID
+ var updateBy: String? = "" // 更新人
+ var updateTime: String? = "" // 更新时间
+ var userId: Int = 0 // 用户ID
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/model/MemberPriceModel.kt b/app/src/main/java/com/ck/ckcollar/app/model/MemberPriceModel.kt
new file mode 100644
index 0000000..8bf93ff
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/model/MemberPriceModel.kt
@@ -0,0 +1,10 @@
+package com.ck.ckcollar.app.model
+
+class MemberPriceModel {
+ var actualPrice: Double = 0.0 // 实际价格
+ var durationMonths: Int = 0 // 持续月份数
+ var id: Int = 0 // ID
+ var memDesc: String? = "" // 会员描述
+ var packageName: String? = "" // 套餐名称
+ var price: Double = 0.0 // 价格
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/model/MessageModel.kt b/app/src/main/java/com/ck/ckcollar/app/model/MessageModel.kt
new file mode 100644
index 0000000..c48daf8
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/model/MessageModel.kt
@@ -0,0 +1,17 @@
+package com.ck.ckcollar.app.model
+
+class MessageModel : CkBaseModel() {
+ var userId: Int = 0 // 用户ID
+ var noticeType: String? = "" // 通知类型
+ var noticeTitle: String? = "" // 通知标题
+ var noticeContent: String? = "" // 通知内容
+ var businessType: String? = "" // 业务类型
+ var businessId: String? = "" // 业务ID
+ var isRead: Int = 0 // 是否已读
+ var createBy: String? = "" // 创建人
+ var createTime: String? = "" // 创建时间
+ var id: Int = 0 // ID
+ var remark: String? = "" // 备注
+ var updateBy: String? = "" // 更新人
+ var updateTime: String? = "" // 更新时间
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/model/OrderModel.kt b/app/src/main/java/com/ck/ckcollar/app/model/OrderModel.kt
new file mode 100644
index 0000000..ede5e6c
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/model/OrderModel.kt
@@ -0,0 +1,155 @@
+package com.ck.ckcollar.app.model
+
+import com.ck.ckcollar.app.R
+import com.ck.ckcollar.app.ui.act.order.AfterSalesActivity
+import com.ck.ckcollar.app.ui.act.order.AfterSalesProgressActivity
+import com.ck.ckcollar.app.ui.act.order.InputLogisticsNumActivity
+import com.ck.ckcollar.app.ui.act.order.LogisticsInfoActivity
+import com.ck.ckcollar.app.ui.act.setting.AddressActivity
+import com.ck.ckcollar.app.ui.dialog.CKAlertDialog
+import com.ck.ckcollar.app.utils.networkone.ICallback
+import com.ck.ckcollar.app.utils.networkone.TTHttpClient
+import com.ck.ckcollar.app.utils.networkone.model.TTRequestData
+import com.ck.ckcollar.app.utils.networkone.model.TTRequestParam
+import com.google.gson.Gson
+import com.tt.kit.model.Data
+import com.tt.kit.model.DataCollection
+
+class OrderModel {
+
+ var total : Int = 0
+ var rows : List? = null
+
+ class Order{
+ var buyerNote: String? = "" // 买家备注
+ // var colLogistics: List? = null // 物流信息
+ var colOrderItems: List? = null // 订单商品列表
+ // var colOrderProgressList: String? = "" // 订单进度列表
+ var createBy: String? = "" // 创建人
+ var createTime: String? = "" // 创建时间
+ var createTimeScope: String? = "" // 创建时间范围
+ var currentStage: Int = 0 // 当前阶段
+ var delFlag: String? = "" // 删除标记
+ var deliveryType: String? = "" // 配送类型
+ var discountAmount: Double = 0.0 // 优惠金额
+ var finishTime: String? = "" // 完成时间
+ var freightAmount: Double = 0.0 // 运费金额
+ var goodsTotalAmount: Double = 0.0 // 商品总金额
+ var id: Int = 0 // ID
+ var integral: Double = 0.0 // 积分
+ var lastLoginTime: String? = "" // 最后登录时间
+ var nickname: String? = "" // 昵称
+ var orderNo: String? = "" // 订单编号
+ var orderSource: String? = "" // 订单来源
+ /**
+ * 0待付款 1待发货 2已发货 3已收货 4已完成 5已关闭 6已取消 7待审核 8已退款 9退款中 10拒绝退款
+ */
+ var orderStatus: Int = 0 // 订单状态
+ var orderType: String? = "" // 订单类型
+ var packageId: String? = "" // 套餐ID
+ var payAmount: Double = 0.0 // 支付金额
+ var payTime: String? = "" // 支付时间
+ var payType: String? = "" // 支付方式
+ var placeTime: String? = "" // 下单时间
+ var placeTimeArr: String? = "" // 下单时间数组
+ var receiveTime: String? = "" // 收货时间
+ var receiverAddress: String? = "" // 收货地址
+ var receiverName: String? = "" // 收货人姓名
+ var receiverPhone: String? = "" // 收货人电话
+ var registerTime: String? = "" // 注册时间
+ var remark: String? = "" // 备注
+ var shipTime: String? = "" // 发货时间
+ var updateBy: String? = "" // 更新人
+ var updateTime: String? = "" // 更新时间
+ var userAge: String? = "" // 用户年龄
+ var userGender: Int = 0 // 用户性别
+ var userId: Int = 0 // 用户ID
+ var userName: String? = "" // 用户姓名
+ var userPhone: String? = "" // 用户电话
+ var shopName: String? = "" // 商店名称
+
+
+ var colRefundApply : RefundApply? = null //退货信息
+
+ var islogisticsNo :String? = null // 0未填写1已填写
+ }
+ class OrderItem {
+ var createBy: String? = "" // 创建人
+ var createTime: String? = "" // 创建时间
+ var deliveryStatus: String? = "" // 配送状态
+ var discountAmount: Double = 0.0 // 优惠金额
+ var goodsId: Int = 0 // 商品ID
+ var goodsImg: String? = "" // 商品图片
+ var goodsName: String? = "" // 商品名称
+ var id: Int = 0 // ID
+ var orderId: Int = 0 // 订单ID
+ var orderNo: String? = "" // 订单编号
+ var quantity: Int = 0 // 数量
+ var remark: String? = "" // 备注
+ var specId: Int = 0 // 规格ID
+ var specInfo: String? = "" // 规格信息
+ var subtotalAmount: Double = 0.0 // 小计金额
+ var unitPrice: Double = 0.0 // 单价
+ var updateBy: String? = "" // 更新人
+ var updateTime: String? = "" // 更新时间
+ }
+
+ /**
+ * 物流信息表
+ */
+ class ColLogistics {
+ /**
+ * 创建者
+ */
+ var createBy: String? = null
+
+ /**
+ * 创建时间
+ */
+ var createTime: String? = null
+
+ /**
+ * ID
+ */
+ private var id: Long = 0
+
+ /**
+ * 物流
+ */
+ var logisticsCode: String? = null
+
+ /**
+ * 订单ID
+ */
+ var orderId: Long = 0
+
+ /**
+ * 订单号
+ */
+ var orderNo: String? = null
+
+ /**
+ * 备注
+ */
+ var remark: String? = null
+
+ /**
+ * 更新者
+ */
+ var updateBy: String? = null
+
+ /**
+ * 更新时间
+ */
+ var updateTime: String? = null
+
+ }
+
+
+ class RefundApply{
+ var id: Int = 0
+ var applyStatus : String? = ""
+ var returnLogisticsNo : String? = ""
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/model/PayOrderModel.kt b/app/src/main/java/com/ck/ckcollar/app/model/PayOrderModel.kt
new file mode 100644
index 0000000..5f40db5
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/model/PayOrderModel.kt
@@ -0,0 +1,8 @@
+package com.ck.ckcollar.app.model
+
+class PayOrderModel : CkBaseModel(){
+ var orderStr: String? = "" // 订单字符串
+ var amount: String? = "" // 金额
+ var orderNo: String? = "" // 订单编号
+ var info : String? = ""
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/model/PayPasswordStatus.kt b/app/src/main/java/com/ck/ckcollar/app/model/PayPasswordStatus.kt
new file mode 100644
index 0000000..4ae6ac4
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/model/PayPasswordStatus.kt
@@ -0,0 +1,7 @@
+package com.ck.ckcollar.app.model
+
+class PayPasswordStatus : CkBaseModel(){
+
+ var isSet : Boolean = false
+ var status : String? = ""
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/model/PayResult.kt b/app/src/main/java/com/ck/ckcollar/app/model/PayResult.kt
new file mode 100644
index 0000000..c469844
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/model/PayResult.kt
@@ -0,0 +1,48 @@
+package com.ck.ckcollar.app.model
+
+import android.text.TextUtils
+
+
+class PayResult(rawResult: Map?) {
+ /**
+ * @return the resultStatus
+ */
+ var resultStatus: String? = null
+ private set
+
+ /**
+ * @return the result
+ */
+ var result: String? = null
+ private set
+
+ /**
+ * @return the memo
+ */
+ var memo: String? = null
+ private set
+
+ init {
+ if (rawResult == null) {
+
+ }
+
+ if (rawResult != null){
+ for (key in rawResult.keys) {
+ if (TextUtils.equals(key, "resultStatus")) {
+ resultStatus = rawResult.get(key)
+ } else if (TextUtils.equals(key, "result")) {
+ result = rawResult.get(key)
+ } else if (TextUtils.equals(key, "memo")) {
+ memo = rawResult.get(key)
+ }
+ }
+ }
+
+ }
+
+ override fun toString(): String {
+ return ("resultStatus={" + resultStatus + "};memo={" + memo
+ + "};result={" + result + "}")
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/model/PeopleCustomerMessageModel.kt b/app/src/main/java/com/ck/ckcollar/app/model/PeopleCustomerMessageModel.kt
new file mode 100644
index 0000000..213dbff
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/model/PeopleCustomerMessageModel.kt
@@ -0,0 +1,7 @@
+package com.ck.ckcollar.app.model
+
+class PeopleCustomerMessageModel {
+ var messages: List? = null
+
+
+}
diff --git a/app/src/main/java/com/ck/ckcollar/app/model/PointsModel.kt b/app/src/main/java/com/ck/ckcollar/app/model/PointsModel.kt
new file mode 100644
index 0000000..1e2e041
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/model/PointsModel.kt
@@ -0,0 +1,14 @@
+package com.ck.ckcollar.app.model
+
+class PointsModel : CkBaseModel(){
+
+ var memberPoints: Double = 0.0
+ var totalGained: Double = 0.0
+ var totalUsed: Double = 0.0
+
+ class PointsRecordModel : CkBaseModel(){
+ var title:String? = ""
+ var amount:Double = 0.0
+ var createTime:String? = ""
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/model/ProductTypeModel.kt b/app/src/main/java/com/ck/ckcollar/app/model/ProductTypeModel.kt
new file mode 100644
index 0000000..3ea2a02
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/model/ProductTypeModel.kt
@@ -0,0 +1,19 @@
+package com.ck.ckcollar.app.model
+
+class ProductTypeModel : CkBaseModel() {
+
+ var comId: Int = 0 // 商品ID
+ var comPrice: Double = 0.0 // 商品价格
+ var createBy: String? = "" // 创建人
+ var createTime: String? = "" // 创建时间
+ var id: Int = 0 // ID
+ var inventory: Int = 0 // 库存
+ var memPrice: Double = 0.0 // 会员价格
+ var profitRatio: Int = 0 // 利润比例
+ var remark: String? = "" // 备注
+ var salesVolume: Int = 0 // 销量
+ var specifyName: String? = "" // 规格名称
+ var updateBy: String? = "" // 更新人
+ var updateTime: String? = "" // 更新时间
+ var weight: Double = 0.0 // 重量
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/model/RechargeModel.kt b/app/src/main/java/com/ck/ckcollar/app/model/RechargeModel.kt
new file mode 100644
index 0000000..5ef16e9
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/model/RechargeModel.kt
@@ -0,0 +1,7 @@
+package com.ck.ckcollar.app.model
+
+class RechargeModel {
+ var orderStr :String? = null
+ var amount : Double? = null
+ var RC1782974779440000002 : String? = null
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/model/RecordDetailsModel.kt b/app/src/main/java/com/ck/ckcollar/app/model/RecordDetailsModel.kt
new file mode 100644
index 0000000..0aa333f
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/model/RecordDetailsModel.kt
@@ -0,0 +1,18 @@
+package com.ck.ckcollar.app.model
+
+class RecordDetailsModel {
+ var actualAmount: Double = 0.0 // 实际金额
+ var amount: Double = 0.0 // 金额
+ var applyTime: String? = "" // 申请时间
+ var arriveTime: String? = "" // 到账时间
+ var createTime: String? = "" // 创建时间
+ var id: Int = 0 // ID
+ var payMethod: String? = "" // 支付方式
+ var payeeAccount: String? = "" // 收款人账户
+ var processTime: String? = "" // 处理时间
+ var revenueType: String? = "" // 收支类型
+ var serialNo: String? = "" // 流水号
+ var serviceFee: Double = 0.0 // 服务费
+ var status: String? = "" // 状态
+ var title: String? = "" // 标题
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/model/RecordModel.kt b/app/src/main/java/com/ck/ckcollar/app/model/RecordModel.kt
new file mode 100644
index 0000000..cb865a3
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/model/RecordModel.kt
@@ -0,0 +1,9 @@
+package com.ck.ckcollar.app.model
+
+class RecordModel {
+ var amount: Double = 0.0 // 金额
+ var createTime: String? = "" // 创建时间
+ var id: Int = 0 // ID
+ var title: String? = "" // 标题
+ var revenueType : String? = "" //0充值1提现2订单支付3退款
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/model/ShopCarCoutTotalModel.kt b/app/src/main/java/com/ck/ckcollar/app/model/ShopCarCoutTotalModel.kt
new file mode 100644
index 0000000..f8ff352
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/model/ShopCarCoutTotalModel.kt
@@ -0,0 +1,7 @@
+package com.ck.ckcollar.app.model
+
+class ShopCarCoutTotalModel : CkBaseModel() {
+
+ var count : Int = 0
+ var totalMoney : Double? = 0.0
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/model/ShopCarModel.kt b/app/src/main/java/com/ck/ckcollar/app/model/ShopCarModel.kt
new file mode 100644
index 0000000..8a19af8
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/model/ShopCarModel.kt
@@ -0,0 +1,43 @@
+package com.ck.ckcollar.app.model
+
+import java.math.BigDecimal
+
+class ShopCarModel {
+
+ var comCover: String? = "" // 商品封面图
+ var comId: Int = 0 // 商品ID
+ var comName: String? = "" // 商品名称
+ var comNum: Long = 0L // 商品编号
+ var comPrice: Double = 0.0 // 商品价格
+ var createBy: String? = "" // 创建人
+ var createTime: String? = "" // 创建时间
+ var id: Int = 0 // ID
+ var memPrice: Double = 0.0 // 会员价格
+ var quantity: Int = 0 // 数量
+ var remark: String? = "" // 备注
+ var selected: String? = "" // 是否选中
+ var specId: Int = 0 // 规格ID
+ var specName: String? = "" // 规格名称
+ var updateBy: String? = "" // 更新人
+ var updateTime: String? = "" // 更新时间
+ var userId: Int = 0 // 用户ID
+
+ fun toOrderItem(): CreateOrderModel.OrderItem {
+ var model = CreateOrderModel.OrderItem()
+
+ model.comId = id
+ model.comNum = comNum
+ model.comName = comName
+ model.comCover = comCover
+ model.comPrice = comPrice
+ model.memPrice = memPrice
+ model.quantity = quantity
+
+ var countDecial = BigDecimal(quantity)
+
+ model.subtotal = BigDecimal(model.comPrice).multiply(countDecial).toDouble()
+ model.memSubtotal = BigDecimal(model.memPrice).multiply(countDecial).toDouble()
+
+ return model
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/model/ShopHotModel.kt b/app/src/main/java/com/ck/ckcollar/app/model/ShopHotModel.kt
new file mode 100644
index 0000000..e207408
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/model/ShopHotModel.kt
@@ -0,0 +1,4 @@
+package com.ck.ckcollar.app.model
+
+class ShopHotModel {
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/model/ShopItemModel.kt b/app/src/main/java/com/ck/ckcollar/app/model/ShopItemModel.kt
new file mode 100644
index 0000000..98cd996
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/model/ShopItemModel.kt
@@ -0,0 +1,8 @@
+package com.ck.ckcollar.app.model
+
+class ShopItemModel {
+ var id : Int? = -1
+ var imgUrl : String? = ""
+ var comType : String? = ""
+ var sort : Int? = 0
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/model/ShopProductModel.kt b/app/src/main/java/com/ck/ckcollar/app/model/ShopProductModel.kt
new file mode 100644
index 0000000..c5e7d8f
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/model/ShopProductModel.kt
@@ -0,0 +1,48 @@
+package com.ck.ckcollar.app.model
+
+class ShopProductModel : CkBaseModel() {
+
+ var total : Int = 0
+ var rows: List? = listOf()
+
+ class ProductModel : CkBaseModel() {
+ var colCommodityListCbs: List? = null // 集合类型
+ var comCarousel: String? = "" // 轮播图
+ var comCover: String? = "" // 封面图
+ var comDetail: String? = "" // 商品详情
+ var comName: String? = "" // 商品名称
+ var comNum: Long = 0L // 商品编号
+ var comPrice: Double = 0.0 // 商品价格
+ var comStatus: String? = "" // 商品状态
+ var comType: String? = "" // 商品类型
+ var comTypeName: String? = "" // 商品类型名称
+ var createBy: String? = "" // 创建人
+ var createTime: String? = "" // 创建时间
+ var createTimeScope: String? = "" // 创建时间范围
+ var id: Int = 0 // ID
+ var inventory: Int = 0 // 库存
+ var memPrice: Double = 0.0 // 会员价格
+ var recomSlot: String? = "" // 推荐位
+ var releaseTime: String? = "" // 发布时间
+ var releaseTimeArr: List? = null // 发布时间数组
+ var remark: String? = "" // 备注
+ var salesVolume: Int = 0 // 销量
+ var serialNum: Int = 0 // 序列号
+ var updateBy: String? = "" // 更新人
+ var updateTime: String? = "" // 更新时间
+
+
+ fun toOrderItem(): CreateOrderModel.OrderItem {
+ var model = CreateOrderModel.OrderItem()
+
+ model.comId = id
+ model.comNum = comNum
+ model.comName = comName
+ model.comCover = comCover
+ model.comPrice = comPrice
+ model.memPrice = memPrice
+ return model
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/model/TagModel.kt b/app/src/main/java/com/ck/ckcollar/app/model/TagModel.kt
new file mode 100644
index 0000000..6080615
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/model/TagModel.kt
@@ -0,0 +1,18 @@
+package com.ck.ckcollar.app.model
+
+class TagModel {
+ var isAdd : Boolean? = false
+ var isMore : Boolean? = false
+
+ var addressKey: String? = "" // 地址键值
+ var addressLabel: String? = "" // 地址标签名称
+ var createBy: String? = "" // 创建人
+ var createTime: String? = "" // 创建时间
+ var id: Int = 0 // ID
+ var isDefault: String? = "" // 是否默认标签
+ var remark: String? = "" // 备注
+ var updateBy: String? = "" // 更新人
+ var updateTime: String? = "" // 更新时间
+ var userId: Int = 0 // 用户ID
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/model/UnReadModel.kt b/app/src/main/java/com/ck/ckcollar/app/model/UnReadModel.kt
new file mode 100644
index 0000000..ae007e8
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/model/UnReadModel.kt
@@ -0,0 +1,8 @@
+package com.ck.ckcollar.app.model
+
+class UnReadModel : CkBaseModel(){
+
+ var unreadCount : Int = 0
+
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/model/UpdateModel.kt b/app/src/main/java/com/ck/ckcollar/app/model/UpdateModel.kt
new file mode 100644
index 0000000..2d2a53d
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/model/UpdateModel.kt
@@ -0,0 +1,11 @@
+package com.ck.ckcollar.app.model
+
+class UpdateModel : CkBaseModel(){
+ //{"androidVersion":1,"content":"","iosVersion":1,"isForce":false}
+
+ var androidVersion : Int = 0
+ var iosVersion : Int = 0
+ var isForce : Boolean = false
+ var content : String? = ""
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/model/UploadModel.kt b/app/src/main/java/com/ck/ckcollar/app/model/UploadModel.kt
new file mode 100644
index 0000000..f1611ca
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/model/UploadModel.kt
@@ -0,0 +1,9 @@
+package com.ck.ckcollar.app.model
+
+class UploadModel: CkBaseModel() {
+
+ var urls : String = ""
+ var newFileNames : String = ""
+ var fileNames : String = ""
+ var originalFilenames : String = ""
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/model/UserInfoModel.kt b/app/src/main/java/com/ck/ckcollar/app/model/UserInfoModel.kt
new file mode 100644
index 0000000..4fd6b2c
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/model/UserInfoModel.kt
@@ -0,0 +1,32 @@
+package com.ck.ckcollar.app.model
+
+class UserInfoModel : CkBaseModel(){
+ var avatar: String? = "" // 头像
+ var balance: Double = 0.0 // 余额
+ var custName: String? = "" // 客户名称
+ var deadlineTime: String? = "" // 截止时间
+ var depositAmount: Double = 0.03 // 押金金额
+ var depositStatus: String? = "" // 押金状态押金状态(0已免押 1待缴纳)
+ var depositType: String? = "" // 押金类型信用免押方式(1免押授权 2现金支付)
+
+
+ var id: Int = 0 // ID
+ var identityCard: String? = "" // 身份证号
+ var isMember: Boolean = false // 是否会员
+ var phonenumber: String? = "" // 手机号
+ var points: Double = 0.0 // 积分
+ var registrationTime: String? = "" // 注册时间
+ var wxBound: String? = "" // 微信绑定状态 微信绑定状态(0未绑定 1已绑定)
+
+
+ var wxName: String? = "" // 微信名称
+ var realName: String? = "" // 真实名称
+ var isLoginPwdSet: Boolean = false // 是否已设置登录密码(true=已设置,false=未设置,验证码/微信静默注册用户默认未设置)
+
+
+ var intoAmounts : String? = null//积分转金额比例
+ var intoPoints : String? = null//金额转积分比例
+
+
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/model/WithDrawModel.kt b/app/src/main/java/com/ck/ckcollar/app/model/WithDrawModel.kt
new file mode 100644
index 0000000..5471368
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/model/WithDrawModel.kt
@@ -0,0 +1,7 @@
+package com.ck.ckcollar.app.model
+
+class WithDrawModel {
+
+ var amount :String? = ""
+ var payMethod :String? = ""
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/ui/act/BlueToothActivity.kt b/app/src/main/java/com/ck/ckcollar/app/ui/act/BlueToothActivity.kt
new file mode 100644
index 0000000..db89379
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/ui/act/BlueToothActivity.kt
@@ -0,0 +1,218 @@
+package com.ck.ckcollar.app.ui.act
+
+import android.Manifest
+import android.app.ComponentCaller
+import android.bluetooth.BluetoothAdapter
+import android.bluetooth.BluetoothDevice
+import android.bluetooth.BluetoothManager
+import android.content.BroadcastReceiver
+import android.content.Context
+import android.content.Intent
+import android.content.IntentFilter
+import android.content.pm.PackageManager
+import android.net.wifi.WifiManager
+import android.os.Build
+import android.os.Bundle
+import android.view.ViewGroup
+import android.widget.Toast
+import androidx.annotation.RequiresPermission
+import androidx.core.app.ActivityCompat
+import androidx.recyclerview.widget.LinearLayoutManager
+import androidx.recyclerview.widget.RecyclerView
+import com.ck.ckcollar.app.databinding.ActivityBluetoothBinding
+import com.ck.ckcollar.app.databinding.LayoutItemBluetoothBinding
+import com.ck.ckcollar.app.ui.base.CKBaseActivity
+import pub.devrel.easypermissions.EasyPermissions
+import pub.devrel.easypermissions.EasyPermissions.PermissionCallbacks
+
+
+class BlueToothActivity : CKBaseActivity() , PermissionCallbacks{
+
+ lateinit var activityBluetoothBinding: ActivityBluetoothBinding
+ val permissions = listOf(Manifest.permission.BLUETOOTH,Manifest.permission.BLUETOOTH_ADMIN,Manifest.permission.BLUETOOTH_SCAN,Manifest.permission.BLUETOOTH_CONNECT)
+
+ lateinit var blueBoothAdapter: BlueBoothAdapter
+ var devices = mutableListOf()
+ lateinit var bluetoothManager: BluetoothManager
+
+ lateinit var bluetoothReceiver: BroadcastReceiver
+ lateinit var bluetoothAdapter: BluetoothAdapter
+ override fun onCreate(savedInstanceState: Bundle?) {
+ activityBluetoothBinding = ActivityBluetoothBinding.inflate(layoutInflater,null,false)
+ setContentView(activityBluetoothBinding.root)
+
+ if (!EasyPermissions.hasPermissions(this, *permissions.toTypedArray())) {
+ EasyPermissions.requestPermissions(
+ this,
+ "App需要发现权限",
+ 101,
+ *permissions.toTypedArray()
+ )
+ }
+
+ super.onCreate(savedInstanceState)
+
+ setTitle("BlueTooth")
+ }
+
+ override fun initView() {
+ activityBluetoothBinding.recyclerView.layoutManager = LinearLayoutManager(this, RecyclerView.VERTICAL,false)
+ activityBluetoothBinding.recyclerView.setHasFixedSize(true)
+
+ blueBoothAdapter = BlueBoothAdapter(this,devices);
+ activityBluetoothBinding.recyclerView.adapter = blueBoothAdapter
+ activityBluetoothBinding.btnScan.setOnClickListener {
+ startScan()
+ }
+ }
+ override fun initData() {
+
+ bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
+ registerBlueToothReceiver()
+
+
+ bluetoothAdapter.bondedDevices.forEach {
+ devices.add(it.name + "\n" + it.address)
+ }
+ blueBoothAdapter.scanResults = devices
+ blueBoothAdapter.notifyDataSetChanged()
+
+
+ if (ActivityCompat.checkSelfPermission(
+ this,
+ Manifest.permission.BLUETOOTH_SCAN
+ ) != PackageManager.PERMISSION_GRANTED
+ ) {
+ // TODO: Consider calling
+ // ActivityCompat#requestPermissions
+ // here to request the missing permissions, and then overriding
+ // public void onRequestPermissionsResult(int requestCode, String[] permissions,
+ // int[] grantResults)
+ // to handle the case where the user grants the permission. See the documentation
+ // for ActivityCompat#requestPermissions for more details.
+ return
+ }
+ startScan()
+
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+
+ unregisterReceiver(bluetoothReceiver)
+
+ if (bluetoothAdapter !=null){
+ bluetoothAdapter.cancelDiscovery()
+ }
+ }
+ fun startScan(){
+ if (bluetoothAdapter != null && bluetoothAdapter.isEnabled()) {
+ // 清空旧数据
+
+
+ // 开始扫描
+ bluetoothAdapter.startDiscovery()
+ Toast.makeText(this, "开始扫描...", Toast.LENGTH_SHORT).show()
+ } else {
+ // 提示用户开启蓝牙
+ val enableBtIntent = Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE)
+ startActivityForResult(enableBtIntent, 1001)
+ }
+ }
+
+
+ override fun onActivityResult(
+ requestCode: Int,
+ resultCode: Int,
+ data: Intent?,
+ caller: ComponentCaller
+ ) {
+ super.onActivityResult(requestCode, resultCode, data, caller)
+
+ if (resultCode == RESULT_OK && requestCode == 1001){
+ toast("蓝牙开启成功")
+ initData()
+ }
+ }
+ private fun registerBlueToothReceiver() {
+ bluetoothReceiver = object : BroadcastReceiver() {
+ @RequiresPermission(Manifest.permission.BLUETOOTH_CONNECT)
+ override fun onReceive(context: Context?, intent: Intent) {
+ // 扫描成功,获取并显示结果
+ val action = intent.getAction()
+ if (BluetoothDevice.ACTION_FOUND == action) {
+ val device: BluetoothDevice? =
+ intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE)
+ if (device != null) {
+ val deviceName = device.getName()
+ val deviceAddress = device.getAddress()
+
+
+ // 去重处理(避免重复添加同一个设备)
+ if (deviceName != null && !devices.contains(deviceName) && !deviceName.isEmpty()) {
+ devices.add(deviceName + "\n" + deviceAddress)
+ blueBoothAdapter.notifyDataSetChanged()
+ }
+ }
+ }
+ }
+ }
+ val intentFilter = IntentFilter(BluetoothDevice.ACTION_FOUND)
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ registerReceiver(bluetoothReceiver, intentFilter, RECEIVER_EXPORTED)
+ }else{
+ registerReceiver(bluetoothReceiver, intentFilter)
+ }
+ }
+
+
+ override fun onRequestPermissionsResult(
+ requestCode: Int,
+ permissions: Array,
+ grantResults: IntArray
+ ) {
+ super.onRequestPermissionsResult(requestCode, permissions, grantResults)
+ EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this)
+ }
+ override fun onPermissionsGranted(
+ requestCode: Int,
+ perms: List
+ ) {
+ initData()
+ }
+
+ override fun onPermissionsDenied(
+ requestCode: Int,
+ perms: List
+ ) {
+
+ }
+
+ class BlueBoothAdapter(var context: CKBaseActivity, var scanResults: List) : RecyclerView.Adapter() {
+ override fun onCreateViewHolder(
+ parent: ViewGroup,
+ viewType: Int
+ ): BlueBoothHolder {
+ return BlueBoothHolder(LayoutItemBluetoothBinding.inflate(context.layoutInflater,parent,false))
+ }
+
+ override fun onBindViewHolder(
+ holder: BlueBoothHolder,
+ position: Int
+ ) {
+
+ holder.itemBluetoothBinding.text.text = scanResults.get(position)
+
+ }
+
+ override fun getItemCount(): Int {
+ return scanResults.size
+ }
+
+ class BlueBoothHolder(var itemBluetoothBinding: LayoutItemBluetoothBinding) : RecyclerView.ViewHolder(itemBluetoothBinding.root){
+
+ }
+
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/ui/act/DemoActivity.kt b/app/src/main/java/com/ck/ckcollar/app/ui/act/DemoActivity.kt
new file mode 100644
index 0000000..6c5d95d
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/ui/act/DemoActivity.kt
@@ -0,0 +1,127 @@
+package com.ck.ckcollar.app.ui.act
+
+import android.content.Intent
+import android.graphics.Bitmap
+import android.os.Bundle
+import android.provider.MediaStore
+import com.alipay.sdk.app.PayTask
+import com.ck.ckcollar.app.databinding.ActivityDemoBinding
+import com.ck.ckcollar.app.ui.act.home.MainActivity
+import com.ck.ckcollar.app.ui.act.petmanager.MapLocationActivity
+import com.ck.ckcollar.app.ui.base.CKBaseActivity
+import com.huawei.hms.hmsscankit.ScanUtil
+import com.huawei.hms.ml.scan.HmsScan
+import com.tencent.mm.opensdk.modelmsg.SendAuth
+import com.tencent.mm.opensdk.openapi.IWXAPI
+import com.tt.kit.model.DataCollection
+import com.tt.kit.utils.TTUtils
+import com.tt.mnmlkitscanner.scan.MNScanManager
+import com.tt.mnmlkitscanner.scan.callback.act.MNScanCallback
+import com.tt.mnmlkitscanner.scan.model.MNScanConfig
+
+
+class DemoActivity : CKBaseActivity() {
+ lateinit var demoBinding: ActivityDemoBinding
+ lateinit var api: IWXAPI
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ lateinit var api: IWXAPI
+
+ super.onCreate(savedInstanceState)
+ demoBinding = ActivityDemoBinding.inflate(layoutInflater)
+ setContentView(demoBinding.root)
+
+// demoBinding.btnZhima.setOnClickListener {
+//
+// val alipay = PayTask(this@DemoActivity)
+// val result = alipay.payV2("orderInfo", true)
+// }
+
+ demoBinding.btnWifi.setOnClickListener {
+ toActivity(WifiListActivity::class.java, DataCollection())
+ }
+ demoBinding.btnBlueTooth.setOnClickListener {
+ toActivity(BlueToothActivity::class.java, DataCollection())
+ }
+ demoBinding.btnMap.setOnClickListener {
+ toActivity(MapLocationActivity::class.java, DataCollection())
+ }
+
+ demoBinding.btnWX.setOnClickListener {
+ val req = SendAuth.Req()
+ req.scope = "snsapi_userinfo" // 只能填 snsapi_userinfo
+ req.state = "wechat_sdk_demo_test"
+ api.sendReq(req)
+ }
+ demoBinding.btnScan.setOnClickListener {
+ // ScanUtil.startScan(this@LoginActivity, 1001, HmsScanAnalyzerOptions.Creator().create())
+
+ startScan()
+ }
+
+
+ demoBinding.btnHome.setOnClickListener {
+ toActivity(MainActivity::class.java, DataCollection())
+
+ }
+ demoBinding.btnCamera.setOnClickListener {
+ var cameraIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE);
+ if (cameraIntent.resolveActivity(getPackageManager()) != null) {
+ startActivityForResult(cameraIntent, 1002);
+ }
+
+ }
+ demoBinding.btnPhoto.setOnClickListener {
+ val intent = Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
+ startActivityForResult(intent, 1003)
+
+ }
+ }
+
+
+ private fun startScan() {
+ var scanConfig = MNScanConfig.Builder()
+ //显示相册功能
+ .isShowPhotoAlbum(false)
+ .builder()
+ MNScanManager.startScan(this, object: MNScanCallback {
+ override fun onActivityResult(resultCode: Int, data: Intent?) {
+ when (resultCode) {
+ MNScanManager.RESULT_SUCCESS -> {
+ val result = data?.getStringArrayListExtra(MNScanManager.INTENT_KEY_RESULT_SUCCESS)
+ if (!result.isNullOrEmpty()) {
+ toast("扫码成功: $result")
+ } else {
+ toast( "扫码结果为空")
+ }
+ }
+ MNScanManager.RESULT_FAIL -> {
+ val error = data?.getStringExtra(MNScanManager.INTENT_KEY_RESULT_ERROR)
+ toast( "扫码失败: $error")
+ }
+ MNScanManager.RESULT_CANCLE -> {
+ toast( "扫码取消")
+ }
+ }
+ }
+ })
+ }
+
+ override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
+ super.onActivityResult(requestCode, resultCode, data)
+ if (requestCode == 1001 && resultCode == RESULT_OK) {
+ val obj = data!!.getParcelableExtra(ScanUtil.RESULT)
+ toast(obj!!.originalValue)
+ }else if (requestCode == 1002 && resultCode == RESULT_OK) {
+ val imageBitmap = data?.extras?.get("data") as Bitmap
+ demoBinding.loginImage.setImageBitmap(imageBitmap)
+ }else if (requestCode == 1003 && resultCode == RESULT_OK) {
+ val selectedImage = data!!.getData() // 获取图片的Uri
+// demoBinding.loginImage.setImageURI(selectedImage)
+
+
+ val bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), selectedImage)
+ demoBinding.loginImage.setImageBitmap(bitmap) // 使用Bitmap显示图片到ImageView中
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/ui/act/WifiListActivity.kt b/app/src/main/java/com/ck/ckcollar/app/ui/act/WifiListActivity.kt
new file mode 100644
index 0000000..5aecb5a
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/ui/act/WifiListActivity.kt
@@ -0,0 +1,180 @@
+package com.ck.ckcollar.app.ui.act
+
+import android.Manifest
+import android.content.BroadcastReceiver
+import android.content.Context
+import android.content.Intent
+import android.content.IntentFilter
+import android.content.pm.PackageManager
+import android.net.wifi.ScanResult
+import android.net.wifi.WifiManager
+import android.os.Build
+import android.os.Bundle
+import android.text.TextUtils
+import android.view.ViewGroup
+import android.widget.Toast
+import androidx.core.app.ActivityCompat
+import androidx.recyclerview.widget.LinearLayoutManager
+import androidx.recyclerview.widget.RecyclerView
+import com.ck.ckcollar.app.databinding.ActivityWifiListBinding
+import com.ck.ckcollar.app.databinding.LayoutItemWifiBinding
+import com.ck.ckcollar.app.ui.base.CKBaseActivity
+import com.tt.kit.utils.TTLog
+import pub.devrel.easypermissions.EasyPermissions
+import pub.devrel.easypermissions.EasyPermissions.PermissionCallbacks
+
+
+class WifiListActivity : CKBaseActivity(), PermissionCallbacks {
+ val permissions = listOf(Manifest.permission.ACCESS_FINE_LOCATION)
+
+ lateinit var wifiListBinding: ActivityWifiListBinding
+ lateinit var wifiAdapter: WifiAdapter
+ var scanResults = mutableListOf()
+ lateinit var wifiManager : WifiManager
+ lateinit var wifiScanReceiver: BroadcastReceiver
+ override fun onCreate(savedInstanceState: Bundle?) {
+ wifiListBinding = ActivityWifiListBinding.inflate(layoutInflater)
+ setContentView(wifiListBinding.root)
+ if (!EasyPermissions.hasPermissions(this, *permissions.toTypedArray())) {
+ EasyPermissions.requestPermissions(
+ this,
+ "App需要发现权限",
+ 101,
+ *permissions.toTypedArray()
+ )
+ }
+ super.onCreate(savedInstanceState)
+ setTitle("WIFI")
+ }
+
+
+ override fun initView() {
+ wifiListBinding.recyclerView.layoutManager = LinearLayoutManager(this, RecyclerView.VERTICAL,false)
+ wifiListBinding.recyclerView.setHasFixedSize(true)
+
+ wifiAdapter = WifiAdapter(this,scanResults);
+ wifiListBinding.recyclerView.adapter = wifiAdapter
+
+ }
+
+ override fun initData() {
+
+ registerWifiScanReceiver()
+
+ wifiManager = getApplicationContext().getSystemService(WIFI_SERVICE) as WifiManager
+ // 检查并开启Wi-Fi
+ if (!wifiManager.isWifiEnabled()) {
+ wifiManager.setWifiEnabled(true)
+ }
+
+ // 获取Wi-Fi网络列表
+ if (ActivityCompat.checkSelfPermission(
+ this,
+ Manifest.permission.ACCESS_FINE_LOCATION
+ ) != PackageManager.PERMISSION_GRANTED
+ ) {
+ return
+ }
+ val scanStarted = wifiManager.startScan()
+ if (!scanStarted) {
+ toast("无法启动 Wi-Fi 扫描")
+ }else{
+ toast("启动 Wi-Fi 扫描")
+ }
+ }
+
+
+ private fun registerWifiScanReceiver() {
+ wifiScanReceiver = object : BroadcastReceiver() {
+ override fun onReceive(context: Context?, intent: Intent) {
+ val success = intent.getBooleanExtra(WifiManager.EXTRA_RESULTS_UPDATED, false)
+ if (success) {
+ // 扫描成功,获取并显示结果
+ displayScanResults()
+ } else {
+ // 扫描失败处理
+ toast("Wi-Fi 扫描失败,请重试")
+ }
+ }
+ }
+ val intentFilter = IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ registerReceiver(wifiScanReceiver, intentFilter, RECEIVER_NOT_EXPORTED)
+ }else{
+ registerReceiver(wifiScanReceiver, intentFilter)
+ }
+ }
+ fun displayScanResults(){
+ if (ActivityCompat.checkSelfPermission(
+ this,
+ Manifest.permission.ACCESS_FINE_LOCATION
+ ) != PackageManager.PERMISSION_GRANTED
+ ) {
+ return
+ }
+ var scanResults2 = wifiManager.getScanResults()
+
+ scanResults.clear()
+ scanResults2.forEach {
+ if (!TextUtils.isEmpty(it.SSID)){
+ scanResults.add(it)
+ }
+ }
+
+ wifiAdapter.scanResults = scanResults
+ wifiAdapter.notifyDataSetChanged()
+ }
+ override fun onRequestPermissionsResult(
+ requestCode: Int,
+ permissions: Array,
+ grantResults: IntArray
+ ) {
+ super.onRequestPermissionsResult(requestCode, permissions, grantResults)
+ EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this)
+ }
+ override fun onPermissionsGranted(
+ requestCode: Int,
+ perms: List
+ ) {
+ initData()
+ }
+
+ override fun onPermissionsDenied(
+ requestCode: Int,
+ perms: List
+ ) {
+
+ }
+
+ class WifiAdapter(var context: CKBaseActivity, var scanResults: List) : RecyclerView.Adapter() {
+ override fun onCreateViewHolder(
+ parent: ViewGroup,
+ viewType: Int
+ ): WifiiewHoldr {
+ return WifiiewHoldr(LayoutItemWifiBinding.inflate(context.layoutInflater,parent,false))
+ }
+
+ override fun onBindViewHolder(
+ holder: WifiiewHoldr,
+ position: Int
+ ) {
+
+ val string = scanResults.get(position).SSID
+ TTLog.e(string)
+ holder.itemWifiBinding.text.text = scanResults.get(position).SSID
+
+ }
+
+ override fun getItemCount(): Int {
+ return scanResults.size
+ }
+
+ class WifiiewHoldr(var itemWifiBinding: LayoutItemWifiBinding) : RecyclerView.ViewHolder(itemWifiBinding.root){
+
+ }
+
+ }
+
+
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/ui/act/balance/BalanceActivity.kt b/app/src/main/java/com/ck/ckcollar/app/ui/act/balance/BalanceActivity.kt
new file mode 100644
index 0000000..57b9a91
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/ui/act/balance/BalanceActivity.kt
@@ -0,0 +1,241 @@
+package com.ck.ckcollar.app.ui.act.balance
+
+import android.content.Context
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.TextView
+import androidx.recyclerview.widget.LinearLayoutManager
+import androidx.recyclerview.widget.RecyclerView
+import com.bumptech.glide.Glide
+import com.ck.ckcollar.app.CKApp
+import com.ck.ckcollar.app.R
+import com.ck.ckcollar.app.action.ActionCode
+import com.ck.ckcollar.app.databinding.ActivityBalanceBinding
+import com.ck.ckcollar.app.databinding.LayoutItemRecordsBinding
+import com.ck.ckcollar.app.listenner.OnItemClickListenner
+import com.ck.ckcollar.app.model.BalanceModle
+import com.ck.ckcollar.app.model.RecordModel
+import com.ck.ckcollar.app.model.UserInfoModel
+import com.ck.ckcollar.app.ui.base.CKLHBaseActionBarActivity
+import com.ck.ckcollar.app.ui.dialog.CKDateMonthDialog
+import com.ck.ckcollar.app.utils.CKUtils
+import com.ck.ckcollar.app.utils.Const
+import com.ck.ckcollar.app.utils.networkone.ICallback
+import com.ck.ckcollar.app.utils.networkone.TTHttpClient
+import com.ck.ckcollar.app.utils.networkone.model.TTRequestData
+import com.ck.ckcollar.app.utils.networkone.model.TTRequestParam
+import com.cyclone.shadowsocks.utils.PreferencesUtils
+import com.google.gson.Gson
+import com.google.gson.reflect.TypeToken
+import com.gyf.immersionbar.ImmersionBar
+import com.tt.kit.base.TTBaseActivity
+import com.tt.kit.model.Data
+import com.tt.kit.model.DataCollection
+import com.tt.kit.utils.TTUtils
+import com.tt.kit.utils.ViewUtils
+import java.text.SimpleDateFormat
+import java.util.Date
+
+class BalanceActivity : CKLHBaseActionBarActivity() , View.OnClickListener{
+ lateinit var binding: ActivityBalanceBinding
+ var data = listOf()
+ lateinit var adapter: RecordAdapter
+ var model : BalanceModle? = null
+ var date = ""
+ var type = "null"
+ override fun onCreate(savedInstanceState: Bundle?) {
+ binding = ActivityBalanceBinding.inflate(layoutInflater)
+ setContentView(binding.root)
+ ImmersionBar.with(this)
+ .statusBarDarkFont(true)
+ .init()
+ super.onCreate(savedInstanceState)
+
+ setTitleText(getString(R.string.my_balance))
+ }
+
+ override fun initView() {
+ var params = binding.contentTop.layoutParams as ViewGroup.MarginLayoutParams
+ params.topMargin = TTUtils.dpToPx(this@BalanceActivity,-220).toInt() + ViewUtils.getActionBarHeight(this)
+
+ binding.recyclerView.layoutManager = LinearLayoutManager(this@BalanceActivity, RecyclerView.VERTICAL,false)
+ binding.recyclerView.setHasFixedSize(true)
+ adapter = RecordAdapter(this@BalanceActivity,data,object : OnItemClickListenner{
+ override fun onClick(
+ pos: Int,
+ model: Any
+ ) {
+ if ("1".equals(data.get(pos).revenueType)){
+ toActivity(OutRecordDetailsActivity::class.java, DataCollection().apply { add(
+ Data("data",data.get(pos).id.toString())
+ ) })
+ }else{
+ toActivity(IncomeRecordDetailsActivity::class.java, DataCollection().apply { add(
+ Data("data",data.get(pos).id.toString())
+ ) })
+
+ }
+ }
+ })
+ binding.recyclerView.adapter = adapter
+
+ binding.btnAll.setOnClickListener(this)
+ binding.btnIncome.setOnClickListener(this)
+ binding.btnOut.setOnClickListener(this)
+
+ binding.btnDate.setOnClickListener {
+
+ CKDateMonthDialog(this@BalanceActivity, object : CKDateMonthDialog.ItemClickListener{
+ override fun onBack(date : Date, dataText: String) {
+ binding.textDate.text = dataText
+ this@BalanceActivity.date = SimpleDateFormat(CKUtils.YYYYMM).format(date)
+ getList()
+ }
+ }).show()
+ }
+
+ binding.btnRecharge.setOnClickListener {
+ toActivityForResult(RechargeActivity::class.java, DataCollection(),1001)
+ }
+ binding.btnWithdraw.setOnClickListener {
+ toActivity(WithDrawActivity::class.java, DataCollection())
+ }
+
+ }
+
+ override fun initData() {
+
+ binding.textDate.text = CKUtils.getDateForYYYYMM()
+ date = CKUtils.getDateFormat(CKUtils.YYYYMM)
+
+
+ }
+
+ override fun onStart() {
+ super.onStart()
+
+ getBalanceInfo()
+
+ getList()
+ }
+ override fun getResult(data: DataCollection, resultCode: Int) {
+ if (resultCode == 1001){
+ getBalanceInfo()
+
+ getList()
+ }
+ }
+ fun getBalanceInfo(){
+ TTHttpClient.get(this,"余额", TTRequestParam(),object : ICallback{
+ override fun onSuccess(data: String) {
+ model = Gson().fromJson(data, BalanceModle::class.java)
+
+ binding.textBalance.text = model?.balance.toString()
+
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ toast(msg)
+ }
+ })
+ }
+
+ fun getList(){
+ TTHttpClient.get(this,"余额明细列表", TTRequestParam().apply { add(TTRequestData("type",type))
+ add(TTRequestData("month",""))},object : ICallback{
+ override fun onSuccess(data: String) {
+ this@BalanceActivity.data = Gson().fromJson>(data, object : TypeToken>(){}.type)
+
+ adapter.data = this@BalanceActivity.data
+ adapter.notifyDataSetChanged()
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ toast(msg)
+ }
+ })
+ }
+
+ override fun onClick(v: View?) {
+ binding.btnAll.setTextSize(16f)
+ binding.btnAll.setTextColor(resources.getColor(R.color.textSecondColor))
+
+ binding.btnIncome.setTextSize(16f)
+ binding.btnIncome.setTextColor(resources.getColor(R.color.textSecondColor))
+
+ binding.btnOut.setTextSize(16f)
+ binding.btnOut.setTextColor(resources.getColor(R.color.textSecondColor))
+
+ binding.imageIntl1.visibility= View.GONE
+ binding.imageIntl2.visibility= View.GONE
+ binding.imageIntl3.visibility= View.GONE
+
+ var textView = v as TextView
+
+ textView.setTextSize(18f)
+ textView.setTextColor(resources.getColor(R.color.textColor))
+
+ when(v?.id){
+ R.id.btnAll->{
+ binding.imageIntl1.visibility= View.VISIBLE
+ type = "null"
+ }
+ R.id.btnIncome->{
+ binding.imageIntl2.visibility= View.VISIBLE
+ type = "income"
+ }
+ R.id.btnOut->{
+ binding.imageIntl3.visibility= View.VISIBLE
+ type = "expense"
+ }
+ }
+
+ getList()
+ }
+
+ class RecordAdapter(var context: Context, var data: List, var onItemClickListenner : OnItemClickListenner) : RecyclerView.Adapter() {
+
+ var selectPos = -1
+ override fun onCreateViewHolder(
+ parent: ViewGroup,
+ viewType: Int
+ ): RecordHolder {
+ return RecordHolder(LayoutItemRecordsBinding.inflate(LayoutInflater.from(context),parent,false))
+ }
+
+ override fun onBindViewHolder(
+ holder: RecordHolder,
+ position: Int
+ ) {
+ // holder.binding.text.text = data.get(position).name
+
+ var model = data.get(position)
+
+ holder.binding.text.text = model.title
+ holder.binding.textDate.text = model.createTime
+ var code = if (model.amount > 0){
+ "+"
+ }else{
+ ""
+ }
+ holder.binding.textAmount.text = code + model.amount.toString()
+
+ holder.binding.root.setTag(position)
+ holder.binding.root.setOnClickListener {
+ val position = it.tag as Int
+ onItemClickListenner.onClick(position,data.get(position))
+ }
+ }
+
+ override fun getItemCount(): Int {
+ return data.size
+ }
+
+ class RecordHolder(var binding: LayoutItemRecordsBinding) : RecyclerView.ViewHolder(binding.root){
+
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/ui/act/balance/IncomeRecordDetailsActivity.kt b/app/src/main/java/com/ck/ckcollar/app/ui/act/balance/IncomeRecordDetailsActivity.kt
new file mode 100644
index 0000000..2f9090d
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/ui/act/balance/IncomeRecordDetailsActivity.kt
@@ -0,0 +1,61 @@
+package com.ck.ckcollar.app.ui.act.balance
+
+import android.os.Bundle
+import com.ck.ckcollar.app.R
+import com.ck.ckcollar.app.databinding.ActivityIncomeRecordDetailsBinding
+import com.ck.ckcollar.app.databinding.ActivityOutRecordDetailsBinding
+import com.ck.ckcollar.app.model.BalanceModle
+import com.ck.ckcollar.app.model.RecordDetailsModel
+import com.ck.ckcollar.app.ui.base.CKBaseActivity
+import com.ck.ckcollar.app.utils.CKUtils
+import com.ck.ckcollar.app.utils.networkone.ICallback
+import com.ck.ckcollar.app.utils.networkone.TTHttpClient
+import com.ck.ckcollar.app.utils.networkone.model.TTRequestParam
+import com.google.gson.Gson
+
+class IncomeRecordDetailsActivity : CKBaseActivity() {
+
+ lateinit var binding: ActivityIncomeRecordDetailsBinding
+ var model : RecordDetailsModel? = null
+ override fun onCreate(savedInstanceState: Bundle?) {
+ binding = ActivityIncomeRecordDetailsBinding.inflate(layoutInflater)
+ setContentView(binding.root)
+ super.onCreate(savedInstanceState)
+ setTitleText(getString(R.string.income_expense_details))
+ }
+
+ override fun initView() {
+
+ }
+
+ override fun initData() {
+
+ getInfo()
+ }
+
+
+ fun getInfo(){
+ TTHttpClient.get(this,"余额明细",
+ getReceiveParam().get("data")!!.stringValue.toString(),object : ICallback{
+ override fun onSuccess(data: String) {
+ model = Gson().fromJson(data, RecordDetailsModel::class.java)
+ var code = if (model?.amount!! > 0){
+ "+"
+ }else{
+ ""
+ }
+ binding.textAmount.text = code + model?.amount.toString()
+ binding.textStatus.text = model?.status
+ binding.textArrivedType.text = model?.title
+ binding.textTitle.text = model?.title
+ binding.textArrivedDate.text = CKUtils.dataToFormat(model?.createTime, CKUtils.YYYYMMDD_HHMMSS,"yyyy年MM月dd HH:mm")
+ binding.textPayType.text = model?.payMethod
+ binding.textOrderNum.text = model?.serialNo
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ toast(msg)
+ }
+ })
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/ui/act/balance/OutRecordDetailsActivity.kt b/app/src/main/java/com/ck/ckcollar/app/ui/act/balance/OutRecordDetailsActivity.kt
new file mode 100644
index 0000000..d3b3550
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/ui/act/balance/OutRecordDetailsActivity.kt
@@ -0,0 +1,94 @@
+package com.ck.ckcollar.app.ui.act.balance
+
+import android.os.Bundle
+import androidx.compose.ui.graphics.Color
+import com.ck.ckcollar.app.R
+import com.ck.ckcollar.app.databinding.ActivityOutRecordDetailsBinding
+import com.ck.ckcollar.app.model.RecordDetailsModel
+import com.ck.ckcollar.app.ui.base.CKBaseActivity
+import com.ck.ckcollar.app.utils.CKUtils
+import com.ck.ckcollar.app.utils.networkone.ICallback
+import com.ck.ckcollar.app.utils.networkone.TTHttpClient
+import com.google.gson.Gson
+import java.math.BigDecimal
+
+class OutRecordDetailsActivity : CKBaseActivity() {
+
+ lateinit var binding: ActivityOutRecordDetailsBinding
+ var model : RecordDetailsModel? = null
+ override fun onCreate(savedInstanceState: Bundle?) {
+ binding = ActivityOutRecordDetailsBinding.inflate(layoutInflater)
+ setContentView(binding.root)
+ super.onCreate(savedInstanceState)
+
+ setTitleText(getString(R.string.income_expense_details))
+ }
+
+ override fun initView() {
+
+ }
+
+ override fun initData() {
+
+ getInfo()
+ getInfo2()
+ }
+
+ fun setStep3(){
+ binding.textBankProcess.setTextColor(resources.getColor(R.color.textSecondColor))
+ binding.textArrived.setTextColor(resources.getColor(R.color.textColor))
+ binding.textArrivedDate.setTextColor(resources.getColor(R.color.textColor))
+
+ binding.textStep3.setBackgroundResource(R.drawable.bg_number)
+ binding.textStep3.setTextColor(getColor(R.color.white))
+ }
+
+ fun getInfo(){
+ TTHttpClient.get(this,"余额明细",
+ getReceiveParam().get("data")!!.stringValue.toString(),object : ICallback{
+ override fun onSuccess(data: String) {
+ model = Gson().fromJson(data, RecordDetailsModel::class.java)
+
+ binding.amount.text = model?.amount.toString()
+ binding.textTitle.text = model?.title
+ model?.applyTime?.let {
+ binding.textDate.text = CKUtils.dataToFormat(model?.applyTime, CKUtils.YYYYMMDD_HHMMSS,"yyyy年MM月dd HH:mm")
+ }
+ if ("已到账".equals(model?.status)){
+ model?.arriveTime?.let {
+ binding.textArrivedDate.text = CKUtils.dataToFormat(model?.arriveTime, CKUtils.YYYYMMDD_HHMMSS,"yyyy年MM月dd HH:mm")
+ }
+ setStep3()
+ }
+
+ binding.textAmount.text = "¥" + BigDecimal(model?.amount.toString()).abs()
+ binding.textFreeAmount.text = "¥" + model?.serviceFee
+ model?.applyTime?.let {
+ binding.textApplyDate.text = CKUtils.dataToFormat(model?.applyTime, CKUtils.YYYYMMDD_HHMMSS,"yyyy年MM月dd HH:mm")
+ }
+ model?.arriveTime?.let {
+ binding.textReceiveDate.text = CKUtils.dataToFormat(model?.arriveTime, CKUtils.YYYYMMDD_HHMMSS,"yyyy年MM月dd HH:mm")
+ }
+ binding.textType.text = model?.payMethod
+ binding.textOrderNum.text = model?.serialNo
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ toast(msg)
+ }
+ })
+ }
+
+ fun getInfo2(){
+ TTHttpClient.get(this,"单条余额明细",
+ getReceiveParam().get("data")!!.stringValue.toString(),object : ICallback{
+ override fun onSuccess(data: String) {
+
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ toast(msg)
+ }
+ })
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/ui/act/balance/RechargeActivity.kt b/app/src/main/java/com/ck/ckcollar/app/ui/act/balance/RechargeActivity.kt
new file mode 100644
index 0000000..c0a5585
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/ui/act/balance/RechargeActivity.kt
@@ -0,0 +1,110 @@
+package com.ck.ckcollar.app.ui.act.balance
+
+import android.os.Bundle
+import android.text.TextUtils
+import com.alipay.sdk.app.PayTask
+import com.ck.ckcollar.app.R
+import com.ck.ckcollar.app.databinding.ActivityRechargeBinding
+import com.ck.ckcollar.app.model.PayResult
+import com.ck.ckcollar.app.model.RechargeModel
+import com.ck.ckcollar.app.ui.base.CKBaseActivity
+import com.ck.ckcollar.app.utils.networkone.ICallback
+import com.ck.ckcollar.app.utils.networkone.TTHttpClient
+import com.ck.ckcollar.app.utils.networkone.model.TTRequestData
+import com.ck.ckcollar.app.utils.networkone.model.TTRequestParam
+import com.ck.ckcollar.app.widget.CKEditView
+import com.google.gson.Gson
+import com.tt.kit.model.DataCollection
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.GlobalScope
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
+
+
+class RechargeActivity : CKBaseActivity() {
+ lateinit var binding: ActivityRechargeBinding
+ var payType = "1"
+ var model : RechargeModel? = null
+ override fun onCreate(savedInstanceState: Bundle?) {
+ binding = ActivityRechargeBinding.inflate(layoutInflater)
+ setContentView(binding.root)
+ super.onCreate(savedInstanceState)
+
+ setTitleText(getString(R.string.recharge))
+ }
+
+ override fun initView() {
+
+ binding.btnAli.setOnClickListener {
+ binding.image1.setImageResource(R.mipmap.image_address_check_select)
+ binding.image2.setImageResource(R.mipmap.image_address_check_narmal)
+ payType = "1"
+ }
+ binding.btnWX.setOnClickListener {
+ binding.image1.setImageResource(R.mipmap.image_address_check_narmal)
+ binding.image2.setImageResource(R.mipmap.image_address_check_select)
+ payType = "0"
+ }
+
+ binding.editAmount.filters = arrayOf(CKEditView.DecimalDigitsInputFilter(2))
+ binding.btnRecharge.setOnClickListener {
+
+ recharge()
+ }
+ }
+
+ fun recharge() {
+ if (TextUtils.isEmpty(binding.editAmount.text.toString())) {
+ toast(getString(R.string.recharge_amount_not_empty))
+ return
+ }
+ showProgeassDialog(getString(R.string.recharge))
+ TTHttpClient.postJson(this, "充值", TTRequestParam().apply {
+ add(TTRequestData("amount", binding.editAmount.text.toString()))
+ add(TTRequestData("payType", payType))
+ }, object : ICallback {
+ override fun onSuccess(data: String) {
+
+ model = Gson().fromJson(data,RechargeModel::class.java)
+
+ if ("1".equals(payType)){
+ aliPay()
+ }
+
+ }
+
+ override fun onFailed(code: String, msg: String) {
+
+ toast(msg)
+ }
+ })
+
+ }
+
+ override fun initData() {
+
+ }
+
+ fun aliPay(){
+ GlobalScope.launch(Dispatchers.IO){
+
+ val alipay = PayTask(this@RechargeActivity)
+ val result = alipay.payV2(model?.orderStr, true)
+
+ var payResult = PayResult(result)
+
+ val resultStatus: String? = payResult.resultStatus
+ withContext(Dispatchers.Main) {
+ // 判断resultStatus 为9000则代表支付成功
+ if (TextUtils.equals(resultStatus, "9000")) {
+ // 该笔订单是否真实支付成功,需要依赖服务端的异步通知。
+ toast(getString(R.string.recharge_success))
+ finish(DataCollection(),1001)
+ }else{
+ toast(getString(R.string.recharge_faild))
+ }
+ }
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/ui/act/balance/WithDrawActivity.kt b/app/src/main/java/com/ck/ckcollar/app/ui/act/balance/WithDrawActivity.kt
new file mode 100644
index 0000000..7edaf1b
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/ui/act/balance/WithDrawActivity.kt
@@ -0,0 +1,122 @@
+package com.ck.ckcollar.app.ui.act.balance
+
+import android.os.Bundle
+import android.text.Editable
+import android.text.TextUtils
+import android.text.TextWatcher
+import com.ck.ckcollar.app.R
+import com.ck.ckcollar.app.databinding.ActivityWithdrawBinding
+import com.ck.ckcollar.app.model.BalanceModle
+import com.ck.ckcollar.app.model.RechargeModel
+import com.ck.ckcollar.app.model.WithDrawModel
+import com.ck.ckcollar.app.ui.base.CKBaseActivity
+import com.ck.ckcollar.app.ui.base.CKLHBaseActionBarActivity
+import com.ck.ckcollar.app.utils.networkone.ICallback
+import com.ck.ckcollar.app.utils.networkone.TTHttpClient
+import com.ck.ckcollar.app.utils.networkone.model.TTRequestData
+import com.ck.ckcollar.app.utils.networkone.model.TTRequestParam
+import com.ck.ckcollar.app.widget.CKEditView
+import com.google.gson.Gson
+import com.gyf.immersionbar.ImmersionBar
+import com.tt.kit.model.Data
+import com.tt.kit.model.DataCollection
+import java.math.BigDecimal
+
+class WithDrawActivity : CKLHBaseActionBarActivity() {
+ lateinit var binding: ActivityWithdrawBinding
+ var model : BalanceModle? = null
+
+ var payType = "1"
+ override fun onCreate(savedInstanceState: Bundle?) {
+ binding = ActivityWithdrawBinding.inflate(layoutInflater)
+ setContentView(binding.root)
+ ImmersionBar.with(this)
+ .statusBarDarkFont(true)
+ .init()
+ super.onCreate(savedInstanceState)
+
+ setTitleText(getString(R.string.withdraw))
+ }
+
+ override fun initView() {
+
+ binding.btnAli.setOnClickListener {
+ binding.image1.setImageResource(R.mipmap.image_address_check_select)
+ binding.image2.setImageResource(R.mipmap.image_address_check_narmal)
+ payType = "1"
+
+ }
+ binding.btnWX.setOnClickListener {
+ binding.image1.setImageResource(R.mipmap.image_address_check_narmal)
+ binding.image2.setImageResource(R.mipmap.image_address_check_select)
+ payType = "0"
+ }
+
+ binding.btnAll.setOnClickListener {
+ binding.editAmount.setText(binding.textAmount.text.toString())
+ binding.editAmount.setSelection(binding.editAmount.text.toString().length)
+ }
+ binding.editAmount.filters = arrayOf(CKEditView.DecimalDigitsInputFilter(2))
+ binding.btnApply.setOnClickListener {
+ apply()
+ }
+ }
+
+ override fun initData() {
+ getBalanceInfo()
+ }
+ fun apply(){
+ if (model == null){
+ toast(getString(R.string.no_balance_data))
+ return
+ }
+ if (TextUtils.isEmpty(binding.editAmount.text.toString())){
+ toast(getString(R.string.withdraw_amount_not_empty))
+ return
+ }
+ if (binding.editAmount.text.toString().toDouble() > model!!.balance){
+ toast(getString(R.string.withdraw_amount_alert))
+ return
+ }
+
+ showProgeassDialog(getString(R.string.withdraw))
+ TTHttpClient.postJson(this, "提现", TTRequestParam().apply {
+ add(TTRequestData("amount", binding.editAmount.text.toString()))
+ add(TTRequestData("payType", payType))
+ }, object : ICallback {
+ override fun onSuccess(data: String) {
+
+ var model = Gson().fromJson(data, WithDrawModel::class.java)
+ toActivity(WithDrawSuccessActivity::class.java, DataCollection().apply {
+ add(Data("data", Gson().toJson(model)))
+
+ })
+
+ finish()
+
+ }
+
+ override fun onFailed(code: String, msg: String) {
+
+ toast(msg)
+ }
+ })
+
+ }
+
+
+ fun getBalanceInfo(){
+ TTHttpClient.get(this,"余额", TTRequestParam(),object : ICallback{
+ override fun onSuccess(data: String) {
+ model = Gson().fromJson(data, BalanceModle::class.java)
+
+ binding.textAmount.text = model?.balance.toString()
+
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ toast(msg)
+ }
+ })
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/ui/act/balance/WithDrawSuccessActivity.kt b/app/src/main/java/com/ck/ckcollar/app/ui/act/balance/WithDrawSuccessActivity.kt
new file mode 100644
index 0000000..759500c
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/ui/act/balance/WithDrawSuccessActivity.kt
@@ -0,0 +1,45 @@
+package com.ck.ckcollar.app.ui.act.balance
+
+import android.os.Bundle
+import android.text.Editable
+import android.text.TextUtils
+import android.text.TextWatcher
+import com.ck.ckcollar.app.R
+import com.ck.ckcollar.app.databinding.ActivityWithdrawBinding
+import com.ck.ckcollar.app.databinding.ActivityWithdrawSuccessBinding
+import com.ck.ckcollar.app.model.WithDrawModel
+import com.ck.ckcollar.app.ui.base.CKBaseActivity
+import com.ck.ckcollar.app.ui.base.CKLHBaseActionBarActivity
+import com.ck.ckcollar.app.widget.CKEditView
+import com.google.gson.Gson
+import com.gyf.immersionbar.ImmersionBar
+import java.math.BigDecimal
+
+class WithDrawSuccessActivity : CKBaseActivity() {
+ lateinit var binding: ActivityWithdrawSuccessBinding
+ override fun onCreate(savedInstanceState: Bundle?) {
+ binding = ActivityWithdrawSuccessBinding.inflate(layoutInflater)
+ setContentView(binding.root)
+
+ super.onCreate(savedInstanceState)
+
+ setTitleText(getString(R.string.withdraw_success))
+ }
+
+ override fun initView() {
+
+
+ binding.btnComplete.setOnClickListener {
+ finish()
+ }
+ }
+
+ override fun initData() {
+
+ var model = Gson().fromJson(getReceiveParam().get("data")!!.stringValue,
+ WithDrawModel::class.java)
+
+ binding.textAmount.text = model.amount
+ binding.textType.text = model.payMethod
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/ui/act/customer/CustomerActivity.kt b/app/src/main/java/com/ck/ckcollar/app/ui/act/customer/CustomerActivity.kt
new file mode 100644
index 0000000..de6e257
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/ui/act/customer/CustomerActivity.kt
@@ -0,0 +1,718 @@
+package com.ck.ckcollar.app.ui.act.customer
+
+import android.content.Context
+import android.content.Intent
+import android.net.Uri
+import android.os.Build
+import android.os.Bundle
+import android.os.Environment
+import android.os.Handler
+import android.os.Looper
+import android.provider.MediaStore
+import android.text.Editable
+import android.text.Spannable
+import android.text.SpannableString
+import android.text.TextUtils
+import android.text.TextWatcher
+import android.text.style.ImageSpan
+import android.view.KeyEvent
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.view.inputmethod.EditorInfo
+import android.widget.TextView
+import androidx.core.content.FileProvider
+import androidx.recyclerview.widget.LinearLayoutManager
+import androidx.recyclerview.widget.RecyclerView
+import com.bumptech.glide.Glide
+import com.ck.ckcollar.app.CKApp
+import com.ck.ckcollar.app.R
+import com.ck.ckcollar.app.action.ActionCode
+import com.ck.ckcollar.app.databinding.ActivityCustomerBinding
+import com.ck.ckcollar.app.databinding.LayoutItemAiCustomerMessageBinding
+import com.ck.ckcollar.app.databinding.LayoutItemCustomerMessageBinding
+import com.ck.ckcollar.app.listenner.OnItemClickListenner
+import com.ck.ckcollar.app.model.AIMessageModel
+import com.ck.ckcollar.app.model.CustomerMessageModel
+import com.ck.ckcollar.app.model.UploadModel
+import com.ck.ckcollar.app.ui.act.petmanager.ImageViewActivity
+import com.ck.ckcollar.app.ui.base.CKBaseActivity
+import com.ck.ckcollar.app.ui.dialog.CKAlertDialog
+import com.ck.ckcollar.app.utils.CKUtils
+import com.ck.ckcollar.app.utils.Const
+import com.ck.ckcollar.app.utils.networkone.ICallback
+import com.ck.ckcollar.app.utils.networkone.TTHttpClient
+import com.ck.ckcollar.app.utils.networkone.model.TTRequestData
+import com.ck.ckcollar.app.utils.networkone.model.TTRequestParam
+import com.cyclone.shadowsocks.utils.PreferencesUtils
+import com.google.gson.Gson
+import com.google.gson.reflect.TypeToken
+import com.tt.kit.base.TTBaseActivity
+import com.tt.kit.model.Data
+import com.tt.kit.model.DataCollection
+import com.tt.kit.utils.KeyboardUtils
+import com.tt.kit.utils.TTLog
+import com.tt.kit.utils.TTUtils
+import java.io.File
+import java.util.UUID
+import kotlin.math.min
+
+class CustomerActivity : CKBaseActivity() {
+
+ lateinit var binding: ActivityCustomerBinding
+ lateinit var customerMessageAdapter: CustomerMessageAdapter
+ var data = mutableListOf()
+
+ var path = ""
+ var url = ""
+
+ var lock = true
+ override fun onCreate(savedInstanceState: Bundle?) {
+ binding = ActivityCustomerBinding.inflate(layoutInflater)
+ setContentView(binding.root)
+ super.onCreate(savedInstanceState)
+ checkAppPermissions()
+
+ setTitleText(getString(R.string.customer_service4))
+
+ setRightText(getString(R.string.clear))
+ }
+
+ override fun initView() {
+ binding.recyclerView.layoutManager =
+ LinearLayoutManager(this@CustomerActivity, RecyclerView.VERTICAL, false)
+ binding.recyclerView.setHasFixedSize(true)
+ customerMessageAdapter =
+ CustomerMessageAdapter(this@CustomerActivity, data, object : OnItemClickListenner {
+ override fun onClick(
+ pos: Int,
+ model: Any
+ ) {
+
+ }
+ })
+ binding.recyclerView.adapter = customerMessageAdapter
+
+ binding.editMessage.setHorizontallyScrolling(false);
+
+ binding.editMessage.setOnEditorActionListener(object : TextView.OnEditorActionListener {
+ override fun onEditorAction(
+ p0: TextView?,
+ actionId: Int,
+ ketEvent: KeyEvent?
+ ): Boolean {
+ if (actionId == EditorInfo.IME_ACTION_UNSPECIFIED ||
+ actionId == EditorInfo.IME_ACTION_SEND ||
+ (ketEvent != null && ketEvent.keyCode == KeyEvent.KEYCODE_ENTER)
+ ) {
+ if (lock) {
+ var text = binding.editMessage.text.toString()
+ var index = text.indexOf("$$$$$") >= 0
+ if (!index) {
+ path = ""
+ }
+ text = text.replace("$$$$$", "")
+ if (!TextUtils.isEmpty(text) || !TextUtils.isEmpty(path)) {
+ lock = false
+ handler.post {
+ sendMessage(UUID.randomUUID().toString(),text,false)
+ }
+ }
+ }
+ }
+ return false
+ }
+ })
+ binding.editMessage.setOnClickListener {
+ binding.contentBottom.visibility = View.GONE
+ }
+ binding.editMessage.onFocusChangeListener = object : View.OnFocusChangeListener{
+ override fun onFocusChange(p0: View?, p1: Boolean) {
+ if (p1){
+ binding.contentBottom.visibility = View.GONE
+ }
+ }
+ }
+ binding.editMessage.addTextChangedListener(object : TextWatcher{
+ override fun afterTextChanged(p0: Editable?) {
+
+ }
+
+ override fun beforeTextChanged(
+ p0: CharSequence?,
+ p1: Int,
+ p2: Int,
+ p3: Int
+ ) {
+
+ }
+
+ override fun onTextChanged(
+ p0: CharSequence?,
+ p1: Int,
+ p2: Int,
+ p3: Int
+ ) {
+ try {
+ var text = binding.editMessage.text.toString()
+ var index = text.indexOf("$$$$$") >= 0
+// if (!index) {
+// path = ""
+// }
+
+
+ val lineCount: Int? = binding.editMessage.getLineCount()
+ val lineHeight: Int = binding.editMessage.getLineHeight()
+ val maxHeight: Int = lineCount!! * lineHeight
+ binding.editMessage.setHeight(min(maxHeight, maxHeight))
+ }catch (e : Exception){
+ e.toString()
+ }
+ }
+ })
+ binding.btnMore.setOnClickListener {
+ if (binding.contentBottom.visibility == View.GONE) {
+ KeyboardUtils.hideKeyboard(this@CustomerActivity)
+ binding.contentBottom.visibility = View.VISIBLE
+ } else {
+ binding.contentBottom.visibility = View.GONE
+ binding.editMessage.requestFocus()
+ KeyboardUtils.showKeyboard(binding.editMessage)
+ }
+ }
+ binding.btnSmile.setOnClickListener {
+ binding.contentBottom.visibility = View.GONE
+ binding.editMessage.requestFocus()
+ KeyboardUtils.showKeyboard(binding.editMessage)
+ }
+ binding.conetnt1.setOnClickListener {
+
+ if (TextUtils.isEmpty(path)) {
+ takePhoto()
+ } else {
+ toast(getString(R.string.only_one_photo))
+ }
+
+ }
+ binding.conetnt2.setOnClickListener {
+
+ if (TextUtils.isEmpty(path)) {
+ //相册
+ val i = Intent(
+ Intent.ACTION_PICK,
+ MediaStore.Images.Media.EXTERNAL_CONTENT_URI
+ )
+ i.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,"image/*");
+ startActivityForResult(i, 56)
+ } else {
+ toast(getString(R.string.only_one_photo))
+ }
+
+ }
+
+ Handler(Looper.getMainLooper()).post {
+ binding.recyclerView.scrollToPosition(this@CustomerActivity.data.size - 1)
+ binding.recyclerView.post {
+ if (customerMessageAdapter.itemCount > 0) {
+ val lastView = binding.recyclerView.layoutManager?.findViewByPosition(customerMessageAdapter.itemCount - 1)
+ lastView?.let {
+ val bottomOffset = it.bottom - binding.recyclerView.height
+ binding.recyclerView.scrollBy(0, bottomOffset)
+ }
+ }
+ }
+ }
+ handleMessage()
+
+ }
+
+ override fun initData() {
+
+ //getList()
+ var dataStr = PreferencesUtils.getString(this, Const.MESSAGE,"[]")
+
+ var models = Gson().fromJson>(dataStr,object : TypeToken>(){}.type)
+
+ var data2 = models.stream().filter { it-> !TextUtils.isEmpty(it.url) || !TextUtils.isEmpty(it.content) }.toList()
+ data.addAll(data2)
+
+ }
+
+ fun handleMessage(){
+ if (data.size > 0){
+ var model = data.last()
+ var isResend = false
+ var sendConetnt = ""
+ if (model.senderId == CKApp.app.userInfo?.id){
+ isResend = true
+ if (!TextUtils.isEmpty(model.url)){
+ url = model.url.toString()
+ }else{
+ sendConetnt = model.content.toString()
+ }
+ }else{
+ if (model.content!!.indexOf("不能替代兽医诊断") < 0){
+ isResend = true
+ if (data.size - 2 >= 0){
+ if (!TextUtils.isEmpty(model.url)){
+ url = data.get(data.size - 2).url.toString()
+ }else{
+ sendConetnt = data.get(data.size - 2).content.toString()
+ }
+ }
+ data.removeAt(data.size -1)
+ }
+ }
+
+ if (isResend){
+ customerMessageAdapter.data =data
+ customerMessageAdapter.notifyDataSetChanged()
+
+ if (!TextUtils.isEmpty(sendConetnt) || !TextUtils.isEmpty(url)){
+ handler.post {
+ sendMessage2(UUID.randomUUID().toString(),sendConetnt,true)
+ }
+ }
+ }
+ }
+ }
+
+ var handler = object : Handler(Looper.getMainLooper()){
+
+ }
+ override fun rightButton1OnClick() {
+ CKAlertDialog(this,getString(R.string.alert),getString(R.string.clear_alert),object : CKAlertDialog.AlertClickListener{
+
+ override fun onBack(isConfirm: Boolean) {
+
+ if (isConfirm){
+ lock = true
+ PreferencesUtils.putString(this@CustomerActivity, Const.MESSAGE,"[]")
+ data.clear()
+
+ customerMessageAdapter.data = data
+ customerMessageAdapter.notifyDataSetChanged()
+ }
+ }
+ }).show()
+ }
+
+ fun sendMessage(uuid :String ,content: String,isResend : Boolean) {
+
+ if (!TextUtils.isEmpty(url)) {
+ this@CustomerActivity.data.add(CustomerMessageModel.MessageItemModel().apply {
+ senderId = CKApp.app.userInfo?.id!!
+ this.content = content
+ this.senderAvatar = CKApp.app.userInfo?.avatar
+ this.senderName = CKApp.app.userInfo?.custName ?: "我"
+ this.url = this@CustomerActivity.url
+ })
+ }
+ if (!TextUtils.isEmpty(content) && !isResend) {
+ this@CustomerActivity.data.add(CustomerMessageModel.MessageItemModel().apply {
+ senderId = CKApp.app.userInfo?.id!!
+ this.content = content
+ this.senderAvatar = CKApp.app.userInfo?.avatar
+ this.senderName = CKApp.app.userInfo?.custName ?: "我"
+ })
+ }
+ this@CustomerActivity.data.add(CustomerMessageModel.MessageItemModel().apply {
+ senderId = -1
+ this.content = ""
+ this.senderName = getString(R.string.ai_doctor)
+ this.uuid = uuid
+ })
+
+
+ TTHttpClient.postJsonStream3(this, "发送会话消息stream", TTRequestParam().apply {
+ add(TTRequestData("imageUrl", url))
+
+ add(TTRequestData("question", content))
+ }, object : ICallback {
+ override fun onSuccess(data: String) {
+
+ lock = true
+
+ // var model = Gson().fromJson(data, AIMessageModel::class.java)
+
+ var flag = false
+ for (i in 0..this@CustomerActivity.data.size -1){
+ if (this@CustomerActivity.data.get(i).uuid.equals(uuid)){
+ flag = true
+ this@CustomerActivity.data.get(i).content = CKUtils.subMessage(this@CustomerActivity.data.get(i).content + data)
+
+ }
+ }
+ if (!flag){
+ this@CustomerActivity.data.add(CustomerMessageModel.MessageItemModel().apply {
+ senderId = -1
+ this.content =data
+ // this.senderAvatar = CKApp.app.userInfo?.avatar
+ this.senderName = getString(R.string.ai_doctor)
+ this.uuid = uuid
+ })
+ }
+
+
+ binding.editMessage.setText("")
+ path = ""
+ url = ""
+ customerMessageAdapter.data = this@CustomerActivity.data
+ customerMessageAdapter.notifyDataSetChanged()
+
+ if (this@CustomerActivity.data.last().content!!.indexOf("不能替代兽医诊断") > 0) {
+ binding.recyclerView.scrollToPosition(this@CustomerActivity.data.size - 1)
+ binding.recyclerView.post {
+ if (customerMessageAdapter.itemCount > 0) {
+ val lastView = binding.recyclerView.layoutManager?.findViewByPosition(customerMessageAdapter.itemCount - 1)
+ lastView?.let {
+ val bottomOffset = it.bottom - binding.recyclerView.height
+ binding.recyclerView.scrollBy(0, bottomOffset)
+ }
+ }
+ }
+ }
+
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ lock = true
+ // toast(msg)
+ //TTLog.e(msg)
+ }
+ })
+
+ binding.editMessage.setText("")
+
+ customerMessageAdapter.data = this@CustomerActivity.data
+ customerMessageAdapter.notifyDataSetChanged()
+
+ binding.recyclerView.scrollToPosition(this@CustomerActivity.data.size - 1)
+
+ }
+
+
+
+ fun sendMessage2(uuid :String ,content: String,isResend : Boolean) {
+ lock = false
+ if (!TextUtils.isEmpty(content) && !isResend) {
+ this@CustomerActivity.data.add(CustomerMessageModel.MessageItemModel().apply {
+ senderId = CKApp.app.userInfo?.id!!
+ this.content = content
+ this.senderAvatar = CKApp.app.userInfo?.avatar
+ this.senderName = CKApp.app.userInfo?.custName ?: "我"
+ })
+ }
+ this@CustomerActivity.data.add(CustomerMessageModel.MessageItemModel().apply {
+ senderId = -1
+ this.content = ""
+ this.senderName = getString(R.string.ai_doctor)
+ this.uuid = uuid
+ })
+
+
+ TTHttpClient.postJsonStream3(this, "发送会话消息stream", TTRequestParam().apply {
+ add(TTRequestData("imageUrl", url))
+
+ add(TTRequestData("question", content))
+ }, object : ICallback {
+ override fun onSuccess(data: String) {
+
+ lock = true
+
+ // var model = Gson().fromJson(data, AIMessageModel::class.java)
+
+ var flag = false
+ for (i in 0..this@CustomerActivity.data.size -1){
+ if (this@CustomerActivity.data.get(i).uuid.equals(uuid)){
+ flag = true
+ this@CustomerActivity.data.get(i).content = CKUtils.subMessage(this@CustomerActivity.data.get(i).content + data)
+
+ }
+ }
+ if (!flag){
+ this@CustomerActivity.data.add(CustomerMessageModel.MessageItemModel().apply {
+ senderId = -1
+ this.content =data
+ // this.senderAvatar = CKApp.app.userInfo?.avatar
+ this.senderName = getString(R.string.ai_doctor)
+ this.uuid = uuid
+ })
+ }
+
+
+ binding.editMessage.setText("")
+ path = ""
+ url = ""
+ customerMessageAdapter.data = this@CustomerActivity.data
+ customerMessageAdapter.notifyDataSetChanged()
+
+ if (this@CustomerActivity.data.last().content!!.indexOf("不能替代兽医诊断") > 0) {
+ binding.recyclerView.scrollToPosition(this@CustomerActivity.data.size - 1)
+ binding.recyclerView.post {
+ if (customerMessageAdapter.itemCount > 0) {
+ val lastView = binding.recyclerView.layoutManager?.findViewByPosition(customerMessageAdapter.itemCount - 1)
+ lastView?.let {
+ val bottomOffset = it.bottom - binding.recyclerView.height
+ binding.recyclerView.scrollBy(0, bottomOffset)
+ }
+ }
+ }
+ }
+
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ lock = true
+ // toast(msg)
+ //TTLog.e(msg)
+ }
+ })
+
+ binding.editMessage.setText("")
+
+ customerMessageAdapter.data = this@CustomerActivity.data
+ customerMessageAdapter.notifyDataSetChanged()
+
+ binding.recyclerView.scrollToPosition(this@CustomerActivity.data.size - 1)
+
+ }
+
+
+ fun uploadImage() {
+
+ var param = TTRequestParam()
+ param.files.add(File(path))
+
+ showProgeassDialog()
+ TTHttpClient.postFile(this, "上传照片s", param, object : ICallback {
+ override fun onSuccess(data: String) {
+ hiddenProgeassDialog()
+ var model = Gson().fromJson(data, UploadModel::class.java)
+
+ url = model.urls
+
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ hiddenProgeassDialog()
+ toast(msg)
+ }
+ })
+ }
+
+ fun addImage(path: String) {
+ try {
+ var bitmap = TTUtils.getBitmap(path, 300, 300)
+ var imageSpan = ImageSpan(bitmap!!);
+ var spannableString = SpannableString("$$$$$");
+ spannableString.setSpan(
+ imageSpan, 0, 5,
+ Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
+ );
+ binding.editMessage.text?.insert(0, spannableString);
+ } catch (e: Exception) {
+ e.printStackTrace();
+ }
+
+ }
+
+ fun getList() {
+ TTHttpClient.get(this, "会话消息列表", TTRequestParam(), object : ICallback {
+ override fun onSuccess(data: String) {
+// var model = Gson().fromJson(data,CustomerMessageModel::class.java)
+// model.rows?.let {
+// this@CustomerActivity.data.addAll(model.rows!!)
+// }
+ var model = Gson().fromJson>(
+ data,
+ object : TypeToken>() {}.type
+ )
+
+ this@CustomerActivity.data.addAll(model)
+ customerMessageAdapter.data = this@CustomerActivity.data
+ customerMessageAdapter.notifyDataSetChanged()
+ }
+
+ override fun onFailed(code: String, msg: String) {
+
+ }
+ })
+ }
+
+
+ override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
+ super.onActivityResult(requestCode, resultCode, data)
+
+ if (requestCode == 55 && resultCode == RESULT_OK) {
+ path = PreferencesUtils.getString(this@CustomerActivity, Const.IMAGE_PATH, "")!!
+
+ addImage(path!!)
+ uploadImage()
+ } else if (requestCode == 56 && resultCode == RESULT_OK) {
+ path = TTUtils.getImageUrl(this, data!!.getData());
+ addImage(path)
+ uploadImage()
+ }
+
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+
+ PreferencesUtils.putString(this, Const.MESSAGE,Gson().toJson(data))
+ }
+
+ fun takePhoto() {
+ try {
+ val openCameraIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
+
+ val vFile = File(
+ getExternalFilesDir(Environment.DIRECTORY_PICTURES),
+ "${System.currentTimeMillis()}.png"
+ )
+
+ val parentDir = vFile.parentFile
+ if (parentDir != null && !parentDir.exists()) {
+ parentDir.mkdirs()
+ }
+ TTLog.e(vFile.absolutePath)
+ PreferencesUtils.putString(getApplicationContext(), Const.IMAGE_PATH, vFile.absolutePath)
+
+ val cameraUri: Uri = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+ FileProvider.getUriForFile(
+ this@CustomerActivity,
+ packageName + ".fileprovider",
+ vFile
+ )
+ } else {
+ Uri.fromFile(vFile)
+ }
+
+ openCameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, cameraUri)
+ startActivityForResult(openCameraIntent, 55)
+ }catch (e: Exception){
+ e.printStackTrace()
+ }
+
+ }
+
+ class CustomerMessageAdapter(
+ var context: TTBaseActivity,
+ var data: List,
+ var onItemClickListenner: OnItemClickListenner
+ ) : RecyclerView.Adapter() {
+ override fun onCreateViewHolder(
+ parent: ViewGroup,
+ viewType: Int
+ ): CustomerMessageHolder {
+ return CustomerMessageHolder(
+ LayoutItemAiCustomerMessageBinding.inflate(
+ LayoutInflater.from(
+ context
+ ), parent, false
+ )
+ )
+ }
+
+ override fun onBindViewHolder(
+ holder: CustomerMessageHolder,
+ position: Int
+ ) {
+ // holder.binding.text.text = data.get(position).name
+
+ var model = data.get(position)
+ if (model.senderId != CKApp.app.userInfo?.id) {
+ holder.binding.contentTo.visibility = View.GONE
+ holder.binding.contentFrom.visibility = View.VISIBLE
+
+ holder.binding.textFrom.text = model.content
+ holder.binding.textFromNick.text = model.senderName
+
+ Glide.with(context)
+ .load(model.senderAvatar)
+ .placeholder(R.mipmap.image_ai_doctor)
+ .into(holder.binding.imageFrom)
+
+ holder.binding.imageContentTo.setOnClickListener(imageClick)
+
+ if (TextUtils.isEmpty(model.content)){
+ holder.binding.textFrom.visibility= View.GONE
+ holder.binding.progress.visibility= View.VISIBLE
+ }else{
+ holder.binding.textFrom.visibility= View.VISIBLE
+ holder.binding.progress.visibility= View.GONE
+ }
+
+ } else {
+ holder.binding.contentTo.visibility = View.VISIBLE
+ holder.binding.contentFrom.visibility = View.GONE
+
+ holder.binding.textTo.text = model.content
+ holder.binding.textToNick.text = model.senderName
+
+ Glide.with(context)
+ .load(model.senderAvatar)
+ .placeholder(R.mipmap.image_default)
+ .into(holder.binding.imageTo)
+ if (!TextUtils.isEmpty(model.url)) {
+ holder.binding.textTo.visibility = View.GONE
+ holder.binding.imageContentTo.visibility = View.VISIBLE
+
+ Glide.with(context)
+ .load( model.url)
+ .placeholder(R.mipmap.image_default)
+ .into(holder.binding.imageContentTo)
+
+ holder.binding.imageContentTo.setTag(model.url)
+ holder.binding.imageContentTo.setOnClickListener(imageClick)
+ } else {
+ holder.binding.textTo.visibility = View.VISIBLE
+ holder.binding.imageContentTo.visibility = View.GONE
+ }
+ }
+
+
+ holder.binding.root.setTag(position)
+ holder.binding.root.setOnClickListener {
+ val position = it.tag as Int
+ onItemClickListenner.onClick(position, data.get(position))
+ }
+ }
+
+ override fun getItemCount(): Int {
+ return data.size
+ }
+
+
+ class CustomerMessageHolder(var binding: LayoutItemAiCustomerMessageBinding) :
+ RecyclerView.ViewHolder(binding.root) {
+
+ }
+
+
+ var imageClick = object : View.OnClickListener{
+ override fun onClick(v: View?) {
+ var url = v?.tag as String
+
+ var urls = mutableListOf()
+ var n = 0
+ var pos = 0
+ for (m in data){
+ if (!TextUtils.isEmpty(m.url)){
+ urls.add(m.url!!)
+ if (url.equals(m.url)){
+ pos = n
+ }
+ n++
+ }
+ }
+ context.toActivity(ImageViewActivity::class.java, DataCollection().apply {
+ add(Data("data",Gson().toJson(urls)))
+ add(Data("pos",pos.toString()))
+ })
+ }
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/ui/act/customer/MineCustomerActivity.kt b/app/src/main/java/com/ck/ckcollar/app/ui/act/customer/MineCustomerActivity.kt
new file mode 100644
index 0000000..e40610a
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/ui/act/customer/MineCustomerActivity.kt
@@ -0,0 +1,559 @@
+package com.ck.ckcollar.app.ui.act.customer
+
+import android.content.Context
+import android.content.Intent
+import android.net.Uri
+import android.os.Build
+import android.os.Bundle
+import android.os.Environment
+import android.os.Handler
+import android.os.Looper
+import android.os.Message
+import android.provider.MediaStore
+import android.text.Editable
+import android.text.Spannable
+import android.text.SpannableString
+import android.text.TextUtils
+import android.text.TextWatcher
+import android.text.style.ImageSpan
+import android.view.KeyEvent
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.view.inputmethod.EditorInfo
+import android.widget.TextView
+import androidx.core.content.FileProvider
+import androidx.recyclerview.widget.LinearLayoutManager
+import androidx.recyclerview.widget.RecyclerView
+import com.bumptech.glide.Glide
+import com.ck.ckcollar.app.CKApp
+import com.ck.ckcollar.app.R
+import com.ck.ckcollar.app.action.ActionCode
+import com.ck.ckcollar.app.databinding.ActivityCustomerBinding
+import com.ck.ckcollar.app.databinding.LayoutItemCustomerMessageBinding
+import com.ck.ckcollar.app.listenner.OnItemClickListenner
+import com.ck.ckcollar.app.model.CustomerMessageModel
+import com.ck.ckcollar.app.model.UploadModel
+import com.ck.ckcollar.app.ui.base.CKBaseActivity
+import com.ck.ckcollar.app.utils.Const
+import com.ck.ckcollar.app.utils.networkone.ICallback
+import com.ck.ckcollar.app.utils.networkone.TTHttpClient
+import com.ck.ckcollar.app.utils.networkone.model.TTRequestData
+import com.ck.ckcollar.app.utils.networkone.model.TTRequestParam
+import com.ck.ckcollar.app.utils.websocket.MyWebSocketClient
+import com.cyclone.shadowsocks.utils.PreferencesUtils
+import com.google.gson.Gson
+import com.tt.kit.utils.KeyboardUtils
+import com.tt.kit.utils.TTLog
+import com.tt.kit.utils.TTUtils
+import okhttp3.OkHttpClient
+import okhttp3.Request
+import okhttp3.Response
+import okhttp3.WebSocket
+import okhttp3.WebSocketListener
+import okio.ByteString
+import java.io.File
+import java.net.URI
+import java.util.concurrent.TimeUnit
+
+class MineCustomerActivity : CKBaseActivity() {
+
+ lateinit var binding: ActivityCustomerBinding
+ lateinit var customerMessageAdapter: CustomerMessageAdapter
+ var data = mutableListOf()
+
+ var path = ""
+ var url = ""
+
+ var lock = true
+ var webSocket: WebSocket? = null
+ var lockWebscoket = true
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ binding = ActivityCustomerBinding.inflate(layoutInflater)
+ setContentView(binding.root)
+ super.onCreate(savedInstanceState)
+
+ setTitleText(getString(R.string.customer_service3))
+ }
+
+ override fun initView() {
+ binding.recyclerView.layoutManager =
+ LinearLayoutManager(this@MineCustomerActivity, RecyclerView.VERTICAL, false)
+ binding.recyclerView.setHasFixedSize(true)
+ customerMessageAdapter =
+ CustomerMessageAdapter(
+ this@MineCustomerActivity,
+ data,
+ object : OnItemClickListenner {
+ override fun onClick(
+ pos: Int,
+ model: Any
+ ) {
+
+ }
+ })
+ binding.recyclerView.adapter = customerMessageAdapter
+ binding.recyclerView.scrollToPosition(this@MineCustomerActivity.data.size - 1)
+
+ binding.editMessage.setHorizontallyScrolling(false);
+
+ binding.editMessage.setOnEditorActionListener(object : TextView.OnEditorActionListener {
+ override fun onEditorAction(
+ p0: TextView?,
+ actionId: Int,
+ ketEvent: KeyEvent?
+ ): Boolean {
+ if (actionId == EditorInfo.IME_ACTION_UNSPECIFIED ||
+ actionId == EditorInfo.IME_ACTION_SEND ||
+ (ketEvent != null && ketEvent.keyCode == KeyEvent.KEYCODE_ENTER)
+ ) {
+ if (lock) {
+ var text = binding.editMessage.text.toString()
+ var index = text.indexOf("$$$$$") >= 0
+ if (!index) {
+ path = ""
+ }
+ text = text.replace("$$$$$", "")
+ if (!TextUtils.isEmpty(text)) {
+ lock = false
+ sendMessage(text)
+ }
+ }
+ }
+ return false
+ }
+ })
+ binding.editMessage.addTextChangedListener(object : TextWatcher {
+ override fun afterTextChanged(p0: Editable?) {
+ try {
+ var text = binding.editMessage.text.toString()
+ var index = text.indexOf("$$$$$") >= 0
+ if (!index) {
+ path = ""
+ }
+ } catch (e: Exception) {
+ e.toString()
+ }
+ }
+
+ override fun beforeTextChanged(
+ p0: CharSequence?,
+ p1: Int,
+ p2: Int,
+ p3: Int
+ ) {
+
+ }
+
+ override fun onTextChanged(
+ p0: CharSequence?,
+ p1: Int,
+ p2: Int,
+ p3: Int
+ ) {
+
+ }
+ })
+ binding.btnMore.setOnClickListener {
+ if (binding.contentBottom.visibility == View.GONE) {
+ KeyboardUtils.hideKeyboard(this@MineCustomerActivity)
+ binding.contentBottom.visibility = View.VISIBLE
+ } else {
+ binding.contentBottom.visibility = View.GONE
+ binding.editMessage.requestFocus()
+ KeyboardUtils.showKeyboard(binding.editMessage)
+ }
+ }
+
+ binding.btnSmile.setOnClickListener {
+ binding.editMessage.requestFocus()
+ KeyboardUtils.showKeyboard(binding.editMessage)
+ }
+
+ binding.conetnt1.setOnClickListener {
+ if (TextUtils.isEmpty(path)) {
+ takePhoto()
+ } else {
+ toast(getString(R.string.only_one_photo))
+ }
+
+ }
+ binding.conetnt2.setOnClickListener {
+ if (TextUtils.isEmpty(path)) {
+ //相册
+ val i = Intent(
+ Intent.ACTION_PICK,
+ MediaStore.Images.Media.EXTERNAL_CONTENT_URI
+ )
+ startActivityForResult(i, 56)
+ } else {
+ toast(getString(R.string.only_one_photo))
+ }
+
+ }
+
+ }
+
+ override fun initData() {
+
+ //getList()
+ handler.sendEmptyMessage(0)
+
+
+ //initWebSocket()
+ }
+
+
+ fun initWebSocket() {
+ var url = ActionCode.CUSTOMER_URL + CKApp.app.userInfo?.id
+
+
+ var okHttpClient = OkHttpClient.Builder();
+ okHttpClient.pingInterval(30, TimeUnit.SECONDS)
+
+ var client = okHttpClient.build();
+ var request = Request.Builder().url(url)
+ .addHeader("Authorization", "Bearer " + CKApp.app.token).build();
+ webSocket = client.newWebSocket(request, object : WebSocketListener() {
+ override fun onClosed(
+ webSocket: WebSocket,
+ code: Int,
+ reason: String
+ ) {
+
+ TTLog.e("onClosed")
+ if (lockWebscoket) {
+ initWebSocket()
+ }
+ }
+
+ override fun onClosing(
+ webSocket: WebSocket,
+ code: Int,
+ reason: String
+ ) {
+ TTLog.e("onClosing")
+ }
+
+ override fun onFailure(
+ webSocket: WebSocket,
+ t: Throwable,
+ response: Response?
+ ) {
+ TTLog.e("onFailure")
+ if (lockWebscoket) {
+ initWebSocket()
+ }
+ }
+
+ override fun onMessage(webSocket: WebSocket, text: String) {
+
+ TTLog.e(text)
+
+ getList()
+ }
+
+ override fun onMessage(webSocket: WebSocket, bytes: ByteString) {
+ TTLog.e(bytes.string(Charsets.UTF_8))
+
+ }
+
+ override fun onOpen(webSocket: WebSocket, response: Response) {
+ TTLog.e("onOpen")
+ runOnUiThread {
+ toast(getString(R.string.connect_customer_success))
+ }
+ }
+ })
+
+// var uri: URI? = URI.create(url)
+// var client: MyWebSocketClient = object : MyWebSocketClient(uri){
+// override fun onMessage(message: String?) {
+// super.onMessage(message)
+// getList()
+// }
+// }
+// client.addHeader("Authorization", "Bearer " + CKApp.app.token)
+// client.connectBlocking()
+ }
+
+ fun sendMessage(content: String) {
+
+ showProgeassDialog(getString(R.string.send))
+ TTHttpClient.postJson(this, "发送人工会话消息", TTRequestParam().apply {
+ add(TTRequestData("content", content))
+ add(TTRequestData("chatType", 2))
+
+ }, object : ICallback {
+ override fun onSuccess(data: String) {
+
+ lock = true
+ if (!TextUtils.isEmpty(url)) {
+ this@MineCustomerActivity.data.add(
+ CustomerMessageModel.MessageItemModel().apply {
+ senderId = CKApp.app.userInfo?.id!!
+ this.content = content
+ this.senderAvatar = CKApp.app.userInfo?.avatar
+ this.senderName = CKApp.app.userInfo?.custName
+ this.url = this@MineCustomerActivity.url
+ })
+ }else{
+ this@MineCustomerActivity.data.add(CustomerMessageModel.MessageItemModel().apply {
+ senderId = CKApp.app.userInfo?.id!!
+ this.content = content
+ this.senderAvatar = CKApp.app.userInfo?.avatar
+ this.senderName = CKApp.app.userInfo?.custName
+ })
+ }
+
+
+
+ binding.editMessage.setText("")
+ path = ""
+ url = ""
+ customerMessageAdapter.data = this@MineCustomerActivity.data
+ customerMessageAdapter.notifyDataSetChanged()
+
+ binding.recyclerView.scrollToPosition(this@MineCustomerActivity.data.size - 1)
+
+
+ getMessage()
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ lock = true
+ toast(msg)
+ }
+ })
+ }
+
+
+ fun uploadImage() {
+
+ var param = TTRequestParam()
+ param.files.add(File(path))
+
+ showProgeassDialog(getString(R.string.submit))
+ TTHttpClient.postFile(this, "上传照片s", param, object : ICallback {
+ override fun onSuccess(data: String) {
+ hiddenProgeassDialog()
+ var model = Gson().fromJson(data, UploadModel::class.java)
+
+ url = model.urls
+
+ sendMessage(url)
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ hiddenProgeassDialog()
+ toast(msg)
+ }
+ })
+ }
+
+ fun addImage(path: String) {
+ try {
+ var bitmap = TTUtils.getBitmap(path, 300, 300)
+ var imageSpan = ImageSpan(bitmap!!);
+ var spannableString = SpannableString("$$$$$");
+ spannableString.setSpan(
+ imageSpan, 0, 5,
+ Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
+ );
+ binding.editMessage.text?.insert(0, spannableString);
+ } catch (e: Exception) {
+ e.printStackTrace();
+ }
+
+ }
+
+ fun getList() {
+ TTHttpClient.get(this, "会话消息列表", TTRequestParam().apply {
+ add(TTRequestData("chatType","2"))
+ }, object : ICallback {
+ override fun onSuccess(data: String) {
+ var model =
+ Gson().fromJson(data, CustomerMessageModel::class.java)
+ model.rows?.let {
+ this@MineCustomerActivity.data.clear()
+ this@MineCustomerActivity.data.addAll(model.rows!!)
+ }
+// var model = Gson().fromJson>(
+// data,
+// object : TypeToken>() {}.type
+// )
+
+ customerMessageAdapter.data = this@MineCustomerActivity.data
+ customerMessageAdapter.notifyDataSetChanged()
+
+ binding.recyclerView.scrollToPosition(this@MineCustomerActivity.data.size - 1)
+
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ toast(msg)
+ }
+ })
+ }
+
+ var handler = object : Handler(Looper.getMainLooper()) {
+
+ override fun handleMessage(msg: Message) {
+
+ getList()
+
+ sendEmptyMessageDelayed(0, 10 * 1000)
+ }
+ }
+
+ fun getMessage() {
+ TTHttpClient.get(this, "获取我的联系客服会话", TTRequestParam().apply {
+ add(TTRequestData("chatType","2"))
+ }, object : ICallback {
+ override fun onSuccess(data: String) {
+
+
+ }
+
+ override fun onFailed(code: String, msg: String) {
+
+ }
+ })
+ }
+
+
+ override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
+ super.onActivityResult(requestCode, resultCode, data)
+
+ if (requestCode == 55 && resultCode == RESULT_OK) {
+ path = PreferencesUtils.getString(this@MineCustomerActivity, Const.IMAGE_PATH, "")!!
+
+ //addImage(path!!)
+ uploadImage()
+ } else if (requestCode == 56 && resultCode == RESULT_OK) {
+ path = TTUtils.getImageUrl(this, data!!.getData());
+ // addImage(path)
+ uploadImage()
+ }
+
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+
+ handler.removeMessages(0)
+ lockWebscoket = false
+ webSocket?.cancel()
+ }
+
+ fun takePhoto() {
+ val openCameraIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
+
+ val vFile = File(
+ getExternalFilesDir(Environment.DIRECTORY_PICTURES),
+ "${System.currentTimeMillis()}.png"
+ )
+
+ val parentDir = vFile.parentFile
+ if (parentDir != null && !parentDir.exists()) {
+ parentDir.mkdirs()
+ }
+ TTLog.e(vFile.absolutePath)
+ PreferencesUtils.putString(getApplicationContext(), Const.IMAGE_PATH, vFile.absolutePath)
+
+ val cameraUri: Uri = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+ FileProvider.getUriForFile(
+ this@MineCustomerActivity,
+ packageName + ".fileprovider",
+ vFile
+ )
+ } else {
+ Uri.fromFile(vFile)
+ }
+
+ openCameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, cameraUri)
+ startActivityForResult(openCameraIntent, 55)
+ }
+
+ class CustomerMessageAdapter(
+ var context: Context,
+ var data: List,
+ var onItemClickListenner: OnItemClickListenner
+ ) : RecyclerView.Adapter() {
+ override fun onCreateViewHolder(
+ parent: ViewGroup,
+ viewType: Int
+ ): CustomerMessageHolder {
+ return CustomerMessageHolder(
+ LayoutItemCustomerMessageBinding.inflate(
+ LayoutInflater.from(
+ context
+ ), parent, false
+ )
+ )
+ }
+
+ override fun onBindViewHolder(
+ holder: CustomerMessageHolder,
+ position: Int
+ ) {
+ // holder.binding.text.text = data.get(position).name
+
+ var model = data.get(position)
+ if ("cs".equals(model.senderType)) {
+ holder.binding.contentTo.visibility = View.GONE
+ holder.binding.contentFrom.visibility = View.VISIBLE
+
+ holder.binding.textFrom.text = model.content
+ holder.binding.textFromNick.text = model.senderName
+
+ Glide.with(context)
+ .load( model.senderAvatar)
+ .placeholder(R.mipmap.image_default)
+ .into(holder.binding.imageFrom)
+
+ } else {
+ holder.binding.contentTo.visibility = View.VISIBLE
+ holder.binding.contentFrom.visibility = View.GONE
+
+ holder.binding.textTo.text = model.content
+ holder.binding.textToNick.text = model.senderName
+
+ Glide.with(context)
+ .load( model.senderAvatar)
+ .placeholder(R.mipmap.image_default)
+ .into(holder.binding.imageTo)
+ if (!TextUtils.isEmpty(model.url)) {
+ holder.binding.textTo.visibility = View.GONE
+ holder.binding.imageContentTo.visibility = View.VISIBLE
+
+ Glide.with(context)
+ .load(ActionCode.BASE_URL + model.url)
+ .placeholder(R.mipmap.image_default)
+ .into(holder.binding.imageContentTo)
+ } else {
+ holder.binding.textTo.visibility = View.VISIBLE
+ holder.binding.imageContentTo.visibility = View.GONE
+ }
+ }
+
+
+ holder.binding.root.setTag(position)
+ holder.binding.root.setOnClickListener {
+ val position = it.tag as Int
+ onItemClickListenner.onClick(position, data.get(position))
+ }
+ }
+
+ override fun getItemCount(): Int {
+ return data.size
+ }
+
+ class CustomerMessageHolder(var binding: LayoutItemCustomerMessageBinding) :
+ RecyclerView.ViewHolder(binding.root) {
+
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/ui/act/customer/PeopleCustomerActivity.kt b/app/src/main/java/com/ck/ckcollar/app/ui/act/customer/PeopleCustomerActivity.kt
new file mode 100644
index 0000000..762f65b
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/ui/act/customer/PeopleCustomerActivity.kt
@@ -0,0 +1,736 @@
+package com.ck.ckcollar.app.ui.act.customer
+
+import android.content.Context
+import android.content.Intent
+import android.graphics.Rect
+import android.net.Uri
+import android.os.Build
+import android.os.Bundle
+import android.os.Environment
+import android.os.Handler
+import android.os.Looper
+import android.os.Message
+import android.provider.MediaStore
+import android.text.Editable
+import android.text.Spannable
+import android.text.SpannableString
+import android.text.TextUtils
+import android.text.TextWatcher
+import android.text.style.ImageSpan
+import android.view.KeyEvent
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.view.ViewTreeObserver
+import android.view.inputmethod.EditorInfo
+import android.widget.TextView
+import androidx.compose.ui.unit.TextUnit
+import androidx.core.content.FileProvider
+import androidx.core.view.ViewCompat
+import androidx.core.view.WindowInsetsCompat
+import androidx.recyclerview.widget.LinearLayoutManager
+import androidx.recyclerview.widget.RecyclerView
+import com.bumptech.glide.Glide
+import com.ck.ckcollar.app.CKApp
+import com.ck.ckcollar.app.R
+import com.ck.ckcollar.app.action.ActionCode
+import com.ck.ckcollar.app.databinding.ActivityCustomerBinding
+import com.ck.ckcollar.app.databinding.LayoutItemCustomerMessageBinding
+import com.ck.ckcollar.app.listenner.OnItemClickListenner
+import com.ck.ckcollar.app.model.CustomerMessageModel
+import com.ck.ckcollar.app.model.CustomerStatusModel
+import com.ck.ckcollar.app.model.UploadModel
+import com.ck.ckcollar.app.ui.act.petmanager.ImageViewActivity
+import com.ck.ckcollar.app.ui.base.CKBaseActivity
+import com.ck.ckcollar.app.ui.dialog.CKAlertDialog
+import com.ck.ckcollar.app.utils.CKUtils
+import com.ck.ckcollar.app.utils.Const
+import com.ck.ckcollar.app.utils.networkone.ICallback
+import com.ck.ckcollar.app.utils.networkone.TTHttpClient
+import com.ck.ckcollar.app.utils.networkone.model.TTRequestData
+import com.ck.ckcollar.app.utils.networkone.model.TTRequestParam
+import com.ck.ckcollar.app.utils.websocket.MyWebSocketClient
+import com.cyclone.shadowsocks.utils.PreferencesUtils
+import com.google.gson.Gson
+import com.tt.kit.base.TTBaseActivity
+import com.tt.kit.model.Data
+import com.tt.kit.model.DataCollection
+import com.tt.kit.utils.KeyboardUtils
+import com.tt.kit.utils.TTLog
+import com.tt.kit.utils.TTUtils
+import okhttp3.OkHttpClient
+import okhttp3.Request
+import okhttp3.Response
+import okhttp3.WebSocket
+import okhttp3.WebSocketListener
+import okio.ByteString
+import java.io.File
+import java.net.URI
+import java.util.concurrent.TimeUnit
+
+class PeopleCustomerActivity : CKBaseActivity() {
+
+ lateinit var binding: ActivityCustomerBinding
+ lateinit var customerMessageAdapter: CustomerMessageAdapter
+ var data = mutableListOf()
+
+ var path = ""
+ var url = ""
+
+ var lock = true
+ var webSocket: WebSocket? = null
+ var lockWebscoket = true
+
+ var customerStatusModel : CustomerStatusModel ?= null
+ var chatType = 0
+
+ var isKeyboardVisible = false
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ binding = ActivityCustomerBinding.inflate(layoutInflater)
+ setContentView(binding.root)
+ super.onCreate(savedInstanceState)
+
+ setRightButton1Image(R.mipmap.image_call)
+ }
+
+ override fun initView() {
+ binding.recyclerView.layoutManager =
+ LinearLayoutManager(this@PeopleCustomerActivity, RecyclerView.VERTICAL, false)
+ binding.recyclerView.setHasFixedSize(true)
+ customerMessageAdapter =
+ CustomerMessageAdapter(
+ this@PeopleCustomerActivity,
+ data,
+ object : OnItemClickListenner {
+ override fun onClick(
+ pos: Int,
+ model: Any
+ ) {
+
+ }
+ })
+ binding.recyclerView.adapter = customerMessageAdapter
+ binding.recyclerView.scrollToPosition(this@PeopleCustomerActivity.data.size - 1)
+
+ binding.editMessage.setHorizontallyScrolling(false);
+
+ binding.editMessage.setOnClickListener {
+ binding.contentBottom.visibility = View.GONE
+
+ handler2.sendEmptyMessageDelayed(0,300)
+
+ }
+ binding.editMessage.onFocusChangeListener = object : View.OnFocusChangeListener{
+ override fun onFocusChange(p0: View?, p1: Boolean) {
+ if (p1){
+ binding.contentBottom.visibility = View.GONE
+
+ handler2.sendEmptyMessageDelayed(0,300)
+
+ }
+ }
+ }
+
+ binding.editMessage.setOnEditorActionListener(object : TextView.OnEditorActionListener {
+ override fun onEditorAction(
+ p0: TextView?,
+ actionId: Int,
+ ketEvent: KeyEvent?
+ ): Boolean {
+ if (actionId == EditorInfo.IME_ACTION_UNSPECIFIED ||
+ actionId == EditorInfo.IME_ACTION_SEND ||
+ (ketEvent != null && ketEvent.keyCode == KeyEvent.KEYCODE_ENTER)
+ ) {
+ if (lock) {
+ var text = binding.editMessage.text.toString()
+ var index = text.indexOf("$$$$$") >= 0
+ if (!index) {
+ path = ""
+ }
+ text = text.replace("$$$$$", "")
+ if (!TextUtils.isEmpty(text)) {
+ lock = false
+ sendMessage(text)
+ }
+ }
+ }
+ return false
+ }
+ })
+ binding.editMessage.addTextChangedListener(object : TextWatcher {
+ override fun afterTextChanged(p0: Editable?) {
+ try {
+ var text = binding.editMessage.text.toString()
+ var index = text.indexOf("$$$$$") >= 0
+ if (!index) {
+ path = ""
+ }
+ } catch (e: Exception) {
+ e.toString()
+ }
+ }
+
+ override fun beforeTextChanged(
+ p0: CharSequence?,
+ p1: Int,
+ p2: Int,
+ p3: Int
+ ) {
+
+ }
+
+ override fun onTextChanged(
+ p0: CharSequence?,
+ p1: Int,
+ p2: Int,
+ p3: Int
+ ) {
+
+ }
+ })
+ binding.btnMore.setOnClickListener {
+ if (binding.contentBottom.visibility == View.GONE) {
+ KeyboardUtils.hideKeyboard(this@PeopleCustomerActivity)
+ binding.contentBottom.visibility = View.VISIBLE
+ } else {
+ binding.contentBottom.visibility = View.GONE
+ binding.editMessage.requestFocus()
+ KeyboardUtils.showKeyboard(binding.editMessage)
+
+ handler2.sendEmptyMessageDelayed(0,300)
+ }
+ }
+
+ binding.btnSmile.setOnClickListener {
+ binding.editMessage.requestFocus()
+ KeyboardUtils.showKeyboard(binding.editMessage)
+ handler2.sendEmptyMessageDelayed(0,300)
+
+ }
+
+ binding.conetnt1.setOnClickListener {
+ if (TextUtils.isEmpty(path)) {
+ if (!checkCameraPermissions()){
+ CKAlertDialog(this@PeopleCustomerActivity,getString(R.string.alert),getString(R.string.camera_alert),object : CKAlertDialog.AlertClickListener{
+ override fun onBack(isConfirm: Boolean) {
+ TODO("Not yet implemented")
+ }
+
+ }).show()
+ return@setOnClickListener
+ }
+ takePhoto()
+ } else {
+ toast(getString(R.string.only_one_photo))
+ }
+
+ }
+ binding.conetnt2.setOnClickListener {
+ if (TextUtils.isEmpty(path)) {
+ //相册
+ val i = Intent(
+ Intent.ACTION_PICK,
+ MediaStore.Images.Media.EXTERNAL_CONTENT_URI
+ )
+ startActivityForResult(i, 56)
+ } else {
+ toast(getString(R.string.only_one_photo))
+ }
+
+ }
+
+
+ }
+
+ override fun initData() {
+
+
+ chatType = getReceiveParam().get("chatType")!!.stringValue.toString().toInt()
+
+ if (chatType == 0){
+ setTitleText(getString(R.string.customer_service2))
+ }else if (chatType == 1){
+ setTitleText(getString(R.string.customer_service5))
+ } else if (chatType == 2){
+ setTitleText(getString(R.string.customer_service3))
+ }
+ getList(true)
+ handler.sendEmptyMessage(0)
+
+
+ initWebSocket()
+ checkCustomerStatus()
+ }
+
+ override fun rightButton1OnClick() {
+ if (TextUtils.isEmpty(customerStatusModel?.servicePhone)){
+ toast(getString(R.string.no_setting_customer_phone))
+ }else{
+ CKUtils.callPhone(this,customerStatusModel?.servicePhone!!)
+ }
+
+ }
+
+ fun checkCustomerStatus(){
+
+ TTHttpClient.get(this,"客服在线状态", TTRequestParam(),object : ICallback{
+ override fun onSuccess(data: String) {
+ hiddenProgeassDialog()
+ customerStatusModel = Gson().fromJson(data,CustomerStatusModel::class.java)
+
+ if (customerStatusModel?.agentOnline == false){
+ CKAlertDialog(this@PeopleCustomerActivity,getString(R.string.alert),customerStatusModel?.tip!!,object : CKAlertDialog.AlertClickListener{
+ override fun onBack(isConfirm: Boolean) {
+ if (isConfirm){
+ }
+ }
+ }).show()
+ }
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ hiddenProgeassDialog()
+ toast(msg)
+ }
+ })
+ }
+
+ fun initWebSocket() {
+ var url = ActionCode.CUSTOMER_URL + CKApp.app.token
+
+
+ var okHttpClient = OkHttpClient.Builder();
+ okHttpClient.pingInterval(30, TimeUnit.SECONDS)
+
+ var client = okHttpClient.build();
+ var request = Request.Builder().url(url)
+ .addHeader("Authorization", "Bearer " + CKApp.app.token).build();
+ webSocket = client.newWebSocket(request, object : WebSocketListener() {
+ override fun onClosed(
+ webSocket: WebSocket,
+ code: Int,
+ reason: String
+ ) {
+
+ TTLog.e("onClosed")
+ if (lockWebscoket) {
+ initWebSocket()
+ }
+ }
+
+ override fun onClosing(
+ webSocket: WebSocket,
+ code: Int,
+ reason: String
+ ) {
+ TTLog.e("onClosing")
+ }
+
+ override fun onFailure(
+ webSocket: WebSocket,
+ t: Throwable,
+ response: Response?
+ ) {
+ TTLog.e("onFailure")
+ if (lockWebscoket) {
+ initWebSocket()
+ }
+ }
+
+ override fun onMessage(webSocket: WebSocket, text: String) {
+
+ TTLog.e(text)
+
+ getList(true)
+ }
+
+ override fun onMessage(webSocket: WebSocket, bytes: ByteString) {
+ TTLog.e(bytes.string(Charsets.UTF_8))
+
+ }
+
+ override fun onOpen(webSocket: WebSocket, response: Response) {
+ TTLog.e("onOpen")
+ runOnUiThread {
+ toast(getString(R.string.connect_customer_success))
+ }
+ }
+ })
+
+// var uri: URI? = URI.create(url)
+// var client: MyWebSocketClient = object : MyWebSocketClient(uri){
+// override fun onMessage(message: String?) {
+// super.onMessage(message)
+// getList()
+// }
+// }
+// client.addHeader("Authorization", "Bearer " + CKApp.app.token)
+// client.connectBlocking()
+ }
+
+ fun sendMessage(content: String) {
+
+// try {
+// webSocket!!.send(content)
+// binding.editMessage.setText("")
+// lock = true
+//
+// this@PeopleCustomerActivity.data.add(CustomerMessageModel.MessageItemModel().apply {
+// senderId = CKApp.app.userInfo?.id!!
+// this.content = content
+// this.senderAvatar = CKApp.app.userInfo?.avatar
+// this.senderName = CKApp.app.userInfo?.custName
+// })
+//
+// } catch (e: Exception) {
+// e.printStackTrace()
+// }
+
+
+ var sendContent = if (TextUtils.isEmpty(url)){
+ content
+ }else{
+ "
"
+ }
+
+ showProgeassDialog(getString(R.string.send))
+ TTHttpClient.postJson(this, "发送人工会话消息", TTRequestParam().apply {
+ add(TTRequestData("content", sendContent))
+ add(TTRequestData("chatType", chatType))
+ }, object : ICallback {
+ override fun onSuccess(data: String) {
+
+ lock = true
+ if (!TextUtils.isEmpty(url)) {
+ this@PeopleCustomerActivity.data.add(
+ CustomerMessageModel.MessageItemModel().apply {
+ senderId = CKApp.app.userInfo?.id!!
+ this.content = content
+ this.senderAvatar = CKApp.app.userInfo?.avatar
+ this.senderName = "客户"
+ this.url = this@PeopleCustomerActivity.url
+ })
+ }else{
+ this@PeopleCustomerActivity.data.add(CustomerMessageModel.MessageItemModel().apply {
+ senderId = CKApp.app.userInfo?.id!!
+ this.content = content
+ this.senderAvatar = CKApp.app.userInfo?.avatar
+ this.senderName = "客户"
+ })
+ }
+
+
+
+ binding.editMessage.setText("")
+ path = ""
+ url = ""
+ customerMessageAdapter.data = this@PeopleCustomerActivity.data
+ customerMessageAdapter.notifyDataSetChanged()
+
+ binding.recyclerView.scrollToPosition(this@PeopleCustomerActivity.data.size - 1)
+
+
+ getMessage()
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ lock = true
+ toast(msg)
+ }
+ })
+ }
+
+
+ fun uploadImage() {
+
+ var param = TTRequestParam()
+ param.files.add(File(path))
+
+ showProgeassDialog()
+ TTHttpClient.postFile(this, "上传照片s", param, object : ICallback {
+ override fun onSuccess(data: String) {
+ hiddenProgeassDialog()
+ var model = Gson().fromJson(data, UploadModel::class.java)
+
+ url = model.urls
+
+ sendMessage(url)
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ hiddenProgeassDialog()
+ toast(msg)
+ }
+ })
+ }
+
+ fun addImage(path: String) {
+ try {
+ var bitmap = TTUtils.getBitmap(path, 300, 300)
+ var imageSpan = ImageSpan(bitmap!!);
+ var spannableString = SpannableString("$$$$$");
+ spannableString.setSpan(
+ imageSpan, 0, 5,
+ Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
+ );
+ binding.editMessage.text?.insert(0, spannableString);
+ } catch (e: Exception) {
+ e.printStackTrace();
+ }
+
+ }
+
+ fun getList(isScrll : Boolean) {
+ TTHttpClient.get(this, "会话消息列表", TTRequestParam().apply {
+ add(TTRequestData("chatType",chatType))
+ }, object : ICallback {
+ override fun onSuccess(data: String) {
+ var model =
+ Gson().fromJson(data, CustomerMessageModel::class.java)
+ model.rows?.let {
+ this@PeopleCustomerActivity.data.clear()
+ this@PeopleCustomerActivity.data.addAll(model.rows!!)
+ }
+// var model = Gson().fromJson>(
+// data,
+// object : TypeToken>() {}.type
+// )
+
+ handlerData()
+ customerMessageAdapter.data = this@PeopleCustomerActivity.data
+ customerMessageAdapter.notifyDataSetChanged()
+
+ if (isScrll){
+ binding.recyclerView.scrollToPosition(this@PeopleCustomerActivity.data.size - 1)
+ }
+
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ toast(msg)
+ }
+ })
+ }
+
+ fun handlerData(){
+ for (model in data){
+ if (model.content!!.indexOf("
=0){
+ model.url = CKUtils.extractImgSrc(model.content!!)
+ }
+ }
+ }
+ var handler = object : Handler(Looper.getMainLooper()) {
+
+ override fun handleMessage(msg: Message) {
+
+ getList(false)
+
+ sendEmptyMessageDelayed(0, 10 * 1000)
+ }
+ }
+
+ var handler2 = object : Handler(Looper.getMainLooper()) {
+
+ override fun handleMessage(msg: Message) {
+ binding.recyclerView.scrollToPosition(this@PeopleCustomerActivity.data.size - 1)
+
+ }
+ }
+
+ fun getMessage() {
+ TTHttpClient.get(this, "获取我的联系客服会话", TTRequestParam().apply {
+ add(TTRequestData("chatType",chatType))
+ }, object : ICallback {
+ override fun onSuccess(data: String) {
+
+
+ }
+
+ override fun onFailed(code: String, msg: String) {
+
+ }
+ })
+ }
+
+
+ override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
+ super.onActivityResult(requestCode, resultCode, data)
+
+ if (requestCode == 55 && resultCode == RESULT_OK) {
+ path = PreferencesUtils.getString(this@PeopleCustomerActivity, Const.IMAGE_PATH, "")!!
+
+ //addImage(path!!)
+ uploadImage()
+ } else if (requestCode == 56 && resultCode == RESULT_OK) {
+ path = TTUtils.getImageUrl(this, data!!.getData());
+ //addImage(path)
+ uploadImage()
+ }
+
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+
+ handler.removeMessages(0)
+ lockWebscoket = false
+ webSocket?.cancel()
+ }
+
+ fun takePhoto() {
+ val openCameraIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
+
+ val vFile = File(
+ getExternalFilesDir(Environment.DIRECTORY_PICTURES),
+ "${System.currentTimeMillis()}.png"
+ )
+
+ val parentDir = vFile.parentFile
+ if (parentDir != null && !parentDir.exists()) {
+ parentDir.mkdirs()
+ }
+ TTLog.e(vFile.absolutePath)
+ PreferencesUtils.putString(getApplicationContext(), Const.IMAGE_PATH, vFile.absolutePath)
+
+ val cameraUri: Uri = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+ FileProvider.getUriForFile(
+ this@PeopleCustomerActivity,
+ packageName + ".fileprovider",
+ vFile
+ )
+ } else {
+ Uri.fromFile(vFile)
+ }
+
+ openCameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, cameraUri)
+ startActivityForResult(openCameraIntent, 55)
+ }
+
+ class CustomerMessageAdapter(
+ var context: TTBaseActivity,
+ var data: List,
+ var onItemClickListenner: OnItemClickListenner
+ ) : RecyclerView.Adapter() {
+ override fun onCreateViewHolder(
+ parent: ViewGroup,
+ viewType: Int
+ ): CustomerMessageHolder {
+ return CustomerMessageHolder(
+ LayoutItemCustomerMessageBinding.inflate(
+ LayoutInflater.from(
+ context
+ ), parent, false
+ )
+ )
+ }
+
+ override fun onBindViewHolder(
+ holder: CustomerMessageHolder,
+ position: Int
+ ) {
+ // holder.binding.text.text = data.get(position).name
+
+ var model = data.get(position)
+ if ("cs".equals(model.senderType)) {
+ holder.binding.contentTo.visibility = View.GONE
+ holder.binding.contentFrom.visibility = View.VISIBLE
+
+ holder.binding.textFrom.text = model.content
+ holder.binding.textFromNick.text = model.senderName
+
+ Glide.with(context)
+ .load( model.senderAvatar)
+ .placeholder(R.mipmap.image_default)
+ .into(holder.binding.imageFrom)
+
+ if (!TextUtils.isEmpty(model.url)) {
+ holder.binding.textFrom.visibility = View.GONE
+ holder.binding.imageContentFrom.visibility = View.VISIBLE
+
+ holder.binding.imageContentFrom.setTag(model.url)
+ Glide.with(context)
+ .load( model.url)
+ .placeholder(R.mipmap.image_default)
+ .into(holder.binding.imageContentFrom)
+ holder.binding.imageContentFrom.setTag(model.url)
+ holder.binding.imageContentFrom.setOnClickListener(imageClick)
+ } else {
+ holder.binding.textFrom.visibility = View.VISIBLE
+ holder.binding.imageContentFrom.visibility = View.GONE
+ }
+
+ } else {
+ holder.binding.contentTo.visibility = View.VISIBLE
+ holder.binding.contentFrom.visibility = View.GONE
+
+ holder.binding.textTo.text = model.content
+ holder.binding.textToNick.text = model.senderName
+
+ Glide.with(context)
+ .load( model.senderAvatar)
+ .placeholder(R.mipmap.image_default)
+ .into(holder.binding.imageTo)
+ if (!TextUtils.isEmpty(model.url)) {
+ holder.binding.textTo.visibility = View.GONE
+ holder.binding.imageContentTo.visibility = View.VISIBLE
+
+ Glide.with(context)
+ .load( model.url)
+ .placeholder(R.mipmap.image_default)
+ .into(holder.binding.imageContentTo)
+
+ holder.binding.imageContentTo.setTag(model.url)
+
+ holder.binding.imageContentTo.setOnClickListener(imageClick)
+
+ } else {
+ holder.binding.textTo.visibility = View.VISIBLE
+ holder.binding.imageContentTo.visibility = View.GONE
+ }
+ }
+
+
+ holder.binding.root.setTag(position)
+ holder.binding.root.setOnClickListener {
+ val position = it.tag as Int
+ onItemClickListenner.onClick(position, data.get(position))
+ }
+ }
+
+ override fun getItemCount(): Int {
+ return data.size
+ }
+
+ class CustomerMessageHolder(var binding: LayoutItemCustomerMessageBinding) :
+ RecyclerView.ViewHolder(binding.root) {
+
+ }
+
+ var imageClick = object : View.OnClickListener{
+ override fun onClick(v: View?) {
+ var url = v?.tag as String
+
+ var urls = mutableListOf()
+ var n = 0
+ var pos = 0
+ for (m in data){
+ if (!TextUtils.isEmpty(m.url)){
+ urls.add(m.url!!)
+ if (url.equals(m.url)){
+ pos = n
+ }
+ n++
+ }
+ }
+ context.toActivity(ImageViewActivity::class.java, DataCollection().apply {
+ add(Data("data",Gson().toJson(urls)))
+ add(Data("pos",pos.toString()))
+ })
+ }
+ }
+
+ }
+
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/ui/act/customer/ShopCustomerActivity.kt b/app/src/main/java/com/ck/ckcollar/app/ui/act/customer/ShopCustomerActivity.kt
new file mode 100644
index 0000000..d75021a
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/ui/act/customer/ShopCustomerActivity.kt
@@ -0,0 +1,572 @@
+package com.ck.ckcollar.app.ui.act.customer
+
+import android.content.Context
+import android.content.Intent
+import android.net.Uri
+import android.os.Build
+import android.os.Bundle
+import android.os.Environment
+import android.os.Handler
+import android.os.Looper
+import android.os.Message
+import android.provider.MediaStore
+import android.text.Editable
+import android.text.Spannable
+import android.text.SpannableString
+import android.text.TextUtils
+import android.text.TextWatcher
+import android.text.style.ImageSpan
+import android.view.KeyEvent
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.view.inputmethod.EditorInfo
+import android.widget.TextView
+import androidx.core.content.FileProvider
+import androidx.recyclerview.widget.LinearLayoutManager
+import androidx.recyclerview.widget.RecyclerView
+import com.bumptech.glide.Glide
+import com.ck.ckcollar.app.CKApp
+import com.ck.ckcollar.app.R
+import com.ck.ckcollar.app.action.ActionCode
+import com.ck.ckcollar.app.databinding.ActivityCustomerBinding
+import com.ck.ckcollar.app.databinding.LayoutItemCustomerMessageBinding
+import com.ck.ckcollar.app.listenner.OnItemClickListenner
+import com.ck.ckcollar.app.model.CustomerMessageModel
+import com.ck.ckcollar.app.model.UploadModel
+import com.ck.ckcollar.app.ui.base.CKBaseActivity
+import com.ck.ckcollar.app.utils.Const
+import com.ck.ckcollar.app.utils.networkone.ICallback
+import com.ck.ckcollar.app.utils.networkone.TTHttpClient
+import com.ck.ckcollar.app.utils.networkone.model.TTRequestData
+import com.ck.ckcollar.app.utils.networkone.model.TTRequestParam
+import com.ck.ckcollar.app.utils.websocket.MyWebSocketClient
+import com.cyclone.shadowsocks.utils.PreferencesUtils
+import com.google.gson.Gson
+import com.tt.kit.utils.KeyboardUtils
+import com.tt.kit.utils.TTLog
+import com.tt.kit.utils.TTUtils
+import okhttp3.OkHttpClient
+import okhttp3.Request
+import okhttp3.Response
+import okhttp3.WebSocket
+import okhttp3.WebSocketListener
+import okio.ByteString
+import java.io.File
+import java.net.URI
+import java.util.concurrent.TimeUnit
+
+class ShopCustomerActivity : CKBaseActivity() {
+
+ lateinit var binding: ActivityCustomerBinding
+ lateinit var customerMessageAdapter: CustomerMessageAdapter
+ var data = mutableListOf()
+
+ var path = ""
+ var url = ""
+
+ var lock = true
+ var webSocket: WebSocket? = null
+ var lockWebscoket = true
+ override fun onCreate(savedInstanceState: Bundle?) {
+ binding = ActivityCustomerBinding.inflate(layoutInflater)
+ setContentView(binding.root)
+ super.onCreate(savedInstanceState)
+
+ setTitleText(getString(R.string.customer_service5))
+ }
+
+ override fun initView() {
+ binding.recyclerView.layoutManager =
+ LinearLayoutManager(this@ShopCustomerActivity, RecyclerView.VERTICAL, false)
+ binding.recyclerView.setHasFixedSize(true)
+ customerMessageAdapter =
+ CustomerMessageAdapter(
+ this@ShopCustomerActivity,
+ data,
+ object : OnItemClickListenner {
+ override fun onClick(
+ pos: Int,
+ model: Any
+ ) {
+
+ }
+ })
+ binding.recyclerView.adapter = customerMessageAdapter
+ binding.recyclerView.scrollToPosition(this@ShopCustomerActivity.data.size - 1)
+
+ binding.editMessage.setHorizontallyScrolling(false);
+
+ binding.editMessage.setOnEditorActionListener(object : TextView.OnEditorActionListener {
+ override fun onEditorAction(
+ p0: TextView?,
+ actionId: Int,
+ ketEvent: KeyEvent?
+ ): Boolean {
+ if (actionId == EditorInfo.IME_ACTION_UNSPECIFIED ||
+ actionId == EditorInfo.IME_ACTION_SEND ||
+ (ketEvent != null && ketEvent.keyCode == KeyEvent.KEYCODE_ENTER)
+ ) {
+ if (lock) {
+ var text = binding.editMessage.text.toString()
+ var index = text.indexOf("$$$$$") >= 0
+ if (!index) {
+ path = ""
+ }
+ text = text.replace("$$$$$", "")
+ if (!TextUtils.isEmpty(text)) {
+ lock = false
+ sendMessage(text)
+ }
+ }
+ }
+ return false
+ }
+ })
+ binding.editMessage.addTextChangedListener(object : TextWatcher {
+ override fun afterTextChanged(p0: Editable?) {
+ try {
+ var text = binding.editMessage.text.toString()
+ var index = text.indexOf("$$$$$") >= 0
+ if (!index) {
+ path = ""
+ }
+ } catch (e: Exception) {
+ e.toString()
+ }
+ }
+
+ override fun beforeTextChanged(
+ p0: CharSequence?,
+ p1: Int,
+ p2: Int,
+ p3: Int
+ ) {
+
+ }
+
+ override fun onTextChanged(
+ p0: CharSequence?,
+ p1: Int,
+ p2: Int,
+ p3: Int
+ ) {
+
+ }
+ })
+ binding.btnMore.setOnClickListener {
+ if (binding.contentBottom.visibility == View.GONE) {
+ KeyboardUtils.hideKeyboard(this@ShopCustomerActivity)
+ binding.contentBottom.visibility = View.VISIBLE
+ } else {
+ binding.contentBottom.visibility = View.GONE
+ binding.editMessage.requestFocus()
+ KeyboardUtils.showKeyboard(binding.editMessage)
+ }
+ }
+
+ binding.btnSmile.setOnClickListener {
+ binding.editMessage.requestFocus()
+ KeyboardUtils.showKeyboard(binding.editMessage)
+ }
+
+ binding.conetnt1.setOnClickListener {
+ if (TextUtils.isEmpty(path)) {
+ takePhoto()
+ } else {
+ toast(getString(R.string.only_one_photo))
+ }
+
+ }
+ binding.conetnt2.setOnClickListener {
+ if (TextUtils.isEmpty(path)) {
+ //相册
+ val i = Intent(
+ Intent.ACTION_PICK,
+ MediaStore.Images.Media.EXTERNAL_CONTENT_URI
+ )
+ startActivityForResult(i, 56)
+ } else {
+ toast(getString(R.string.only_one_photo))
+ }
+
+ }
+
+ }
+
+ override fun initData() {
+
+ //getList()
+ handler.sendEmptyMessage(0)
+
+
+ //initWebSocket()
+ }
+
+
+ fun initWebSocket() {
+ var url = ActionCode.CUSTOMER_URL + CKApp.app.userInfo?.id
+
+
+ var okHttpClient = OkHttpClient.Builder();
+ okHttpClient.pingInterval(30, TimeUnit.SECONDS)
+
+ var client = okHttpClient.build();
+ var request = Request.Builder().url(url)
+ .addHeader("Authorization", "Bearer " + CKApp.app.token).build();
+ webSocket = client.newWebSocket(request, object : WebSocketListener() {
+ override fun onClosed(
+ webSocket: WebSocket,
+ code: Int,
+ reason: String
+ ) {
+
+ TTLog.e("onClosed")
+ if (lockWebscoket) {
+ initWebSocket()
+ }
+ }
+
+ override fun onClosing(
+ webSocket: WebSocket,
+ code: Int,
+ reason: String
+ ) {
+ TTLog.e("onClosing")
+ }
+
+ override fun onFailure(
+ webSocket: WebSocket,
+ t: Throwable,
+ response: Response?
+ ) {
+ TTLog.e("onFailure")
+ if (lockWebscoket) {
+ initWebSocket()
+ }
+ }
+
+ override fun onMessage(webSocket: WebSocket, text: String) {
+
+ TTLog.e(text)
+
+ getList()
+ }
+
+ override fun onMessage(webSocket: WebSocket, bytes: ByteString) {
+ TTLog.e(bytes.string(Charsets.UTF_8))
+
+ }
+
+ override fun onOpen(webSocket: WebSocket, response: Response) {
+ TTLog.e("onOpen")
+ runOnUiThread {
+ toast(getString(R.string.connect_customer_success))
+ }
+ }
+ })
+
+// var uri: URI? = URI.create(url)
+// var client: MyWebSocketClient = object : MyWebSocketClient(uri){
+// override fun onMessage(message: String?) {
+// super.onMessage(message)
+// getList()
+// }
+// }
+// client.addHeader("Authorization", "Bearer " + CKApp.app.token)
+// client.connectBlocking()
+ }
+
+ fun sendMessage(content: String) {
+
+// try {
+// webSocket!!.send(content)
+// binding.editMessage.setText("")
+// lock = true
+//
+// this@PeopleCustomerActivity.data.add(CustomerMessageModel.MessageItemModel().apply {
+// senderId = CKApp.app.userInfo?.id!!
+// this.content = content
+// this.senderAvatar = CKApp.app.userInfo?.avatar
+// this.senderName = CKApp.app.userInfo?.custName
+// })
+//
+// } catch (e: Exception) {
+// e.printStackTrace()
+// }
+
+ showProgeassDialog(getString(R.string.send))
+ TTHttpClient.postJson(this, "发送人工会话消息", TTRequestParam().apply {
+ add(TTRequestData("content", content))
+ add(TTRequestData("chatType", 1))
+ }, object : ICallback {
+ override fun onSuccess(data: String) {
+
+ lock = true
+ if (!TextUtils.isEmpty(url)) {
+ this@ShopCustomerActivity.data.add(
+ CustomerMessageModel.MessageItemModel().apply {
+ senderId = CKApp.app.userInfo?.id!!
+ this.content = content
+ this.senderAvatar = CKApp.app.userInfo?.avatar
+ this.senderName = CKApp.app.userInfo?.custName
+ this.url = this@ShopCustomerActivity.url
+ })
+ }else{
+ this@ShopCustomerActivity.data.add(CustomerMessageModel.MessageItemModel().apply {
+ senderId = CKApp.app.userInfo?.id!!
+ this.content = content
+ this.senderAvatar = CKApp.app.userInfo?.avatar
+ this.senderName = CKApp.app.userInfo?.custName
+ })
+ }
+
+
+
+ binding.editMessage.setText("")
+ path = ""
+ url = ""
+ customerMessageAdapter.data = this@ShopCustomerActivity.data
+ customerMessageAdapter.notifyDataSetChanged()
+
+ binding.recyclerView.scrollToPosition(this@ShopCustomerActivity.data.size - 1)
+
+
+ getMessage()
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ lock = true
+ toast(msg)
+ }
+ })
+ }
+
+
+ fun uploadImage() {
+
+ var param = TTRequestParam()
+ param.files.add(File(path))
+
+ showProgeassDialog()
+ TTHttpClient.postFile(this, "上传照片s", param, object : ICallback {
+ override fun onSuccess(data: String) {
+ hiddenProgeassDialog()
+ var model = Gson().fromJson(data, UploadModel::class.java)
+
+ url = model.urls
+ sendMessage(url)
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ hiddenProgeassDialog()
+ toast(msg)
+ }
+ })
+ }
+
+ fun addImage(path: String) {
+ try {
+ var bitmap = TTUtils.getBitmap(path, 300, 300)
+ var imageSpan = ImageSpan(bitmap!!);
+ var spannableString = SpannableString("$$$$$");
+ spannableString.setSpan(
+ imageSpan, 0, 5,
+ Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
+ );
+ binding.editMessage.text?.insert(0, spannableString);
+ } catch (e: Exception) {
+ e.printStackTrace();
+ }
+
+ }
+
+ fun getList() {
+ TTHttpClient.get(this, "会话消息列表", TTRequestParam().apply {
+ add(TTRequestData("chatType","1"))
+ }, object : ICallback {
+ override fun onSuccess(data: String) {
+ var model =
+ Gson().fromJson(data, CustomerMessageModel::class.java)
+ model.rows?.let {
+ this@ShopCustomerActivity.data.clear()
+ this@ShopCustomerActivity.data.addAll(model.rows!!)
+ }
+// var model = Gson().fromJson>(
+// data,
+// object : TypeToken>() {}.type
+// )
+
+ customerMessageAdapter.data = this@ShopCustomerActivity.data
+ customerMessageAdapter.notifyDataSetChanged()
+
+ binding.recyclerView.scrollToPosition(this@ShopCustomerActivity.data.size - 1)
+
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ toast(msg)
+ }
+ })
+ }
+
+ var handler = object : Handler(Looper.getMainLooper()) {
+
+ override fun handleMessage(msg: Message) {
+
+ getList()
+
+ sendEmptyMessageDelayed(0, 10 * 1000)
+ }
+ }
+
+ fun getMessage() {
+ TTHttpClient.get(this, "获取我的联系客服会话", TTRequestParam().apply {
+ add(TTRequestData("chatType",1))
+ }, object : ICallback {
+ override fun onSuccess(data: String) {
+
+
+ }
+
+ override fun onFailed(code: String, msg: String) {
+
+ }
+ })
+ }
+
+
+ override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
+ super.onActivityResult(requestCode, resultCode, data)
+
+ if (requestCode == 55 && resultCode == RESULT_OK) {
+ path = PreferencesUtils.getString(this@ShopCustomerActivity, Const.IMAGE_PATH, "")!!
+
+ //addImage(path!!)
+ uploadImage()
+ } else if (requestCode == 56 && resultCode == RESULT_OK) {
+ path = TTUtils.getImageUrl(this, data!!.getData());
+ //addImage(path)
+ uploadImage()
+ }
+
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+
+ handler.removeMessages(0)
+ lockWebscoket = false
+ webSocket?.cancel()
+ }
+
+ fun takePhoto() {
+ val openCameraIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
+
+ val vFile = File(
+ getExternalFilesDir(Environment.DIRECTORY_PICTURES),
+ "${System.currentTimeMillis()}.png"
+ )
+
+ val parentDir = vFile.parentFile
+ if (parentDir != null && !parentDir.exists()) {
+ parentDir.mkdirs()
+ }
+ TTLog.e(vFile.absolutePath)
+ PreferencesUtils.putString(getApplicationContext(), Const.IMAGE_PATH, vFile.absolutePath)
+
+ val cameraUri: Uri = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+ FileProvider.getUriForFile(
+ this@ShopCustomerActivity,
+ packageName + ".fileprovider",
+ vFile
+ )
+ } else {
+ Uri.fromFile(vFile)
+ }
+
+ openCameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, cameraUri)
+ startActivityForResult(openCameraIntent, 55)
+ }
+
+ class CustomerMessageAdapter(
+ var context: Context,
+ var data: List,
+ var onItemClickListenner: OnItemClickListenner
+ ) : RecyclerView.Adapter() {
+ override fun onCreateViewHolder(
+ parent: ViewGroup,
+ viewType: Int
+ ): CustomerMessageHolder {
+ return CustomerMessageHolder(
+ LayoutItemCustomerMessageBinding.inflate(
+ LayoutInflater.from(
+ context
+ ), parent, false
+ )
+ )
+ }
+
+ override fun onBindViewHolder(
+ holder: CustomerMessageHolder,
+ position: Int
+ ) {
+ // holder.binding.text.text = data.get(position).name
+
+ var model = data.get(position)
+ if ("cs".equals(model.senderType)) {
+ holder.binding.contentTo.visibility = View.GONE
+ holder.binding.contentFrom.visibility = View.VISIBLE
+
+ holder.binding.textFrom.text = model.content
+ holder.binding.textFromNick.text = model.senderName
+
+ Glide.with(context)
+ .load( model.senderAvatar)
+ .placeholder(R.mipmap.image_default)
+ .into(holder.binding.imageFrom)
+
+ } else {
+ holder.binding.contentTo.visibility = View.VISIBLE
+ holder.binding.contentFrom.visibility = View.GONE
+
+ holder.binding.textTo.text = model.content
+ holder.binding.textToNick.text = model.senderName
+
+ Glide.with(context)
+ .load( model.senderAvatar)
+ .placeholder(R.mipmap.image_default)
+ .into(holder.binding.imageTo)
+ if (!TextUtils.isEmpty(model.url)) {
+ holder.binding.textTo.visibility = View.GONE
+ holder.binding.imageContentTo.visibility = View.VISIBLE
+
+ Glide.with(context)
+ .load( model.url)
+ .placeholder(R.mipmap.image_default)
+ .into(holder.binding.imageContentTo)
+ } else {
+ holder.binding.textTo.visibility = View.VISIBLE
+ holder.binding.imageContentTo.visibility = View.GONE
+ }
+ }
+
+
+ holder.binding.root.setTag(position)
+ holder.binding.root.setOnClickListener {
+ val position = it.tag as Int
+ onItemClickListenner.onClick(position, data.get(position))
+ }
+ }
+
+ override fun getItemCount(): Int {
+ return data.size
+ }
+
+ class CustomerMessageHolder(var binding: LayoutItemCustomerMessageBinding) :
+ RecyclerView.ViewHolder(binding.root) {
+
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/ui/act/deposit/DepositActivity.kt b/app/src/main/java/com/ck/ckcollar/app/ui/act/deposit/DepositActivity.kt
new file mode 100644
index 0000000..6c76d15
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/ui/act/deposit/DepositActivity.kt
@@ -0,0 +1,111 @@
+package com.ck.ckcollar.app.ui.act.deposit
+
+import android.os.Bundle
+import com.alipay.sdk.app.PayTask
+import com.ck.ckcollar.app.R
+import com.ck.ckcollar.app.databinding.ActivityDepositBinding
+import com.ck.ckcollar.app.model.DepositModel
+import com.ck.ckcollar.app.model.MemberModel
+import com.ck.ckcollar.app.model.PayResult
+import com.ck.ckcollar.app.model.UserInfoModel
+import com.ck.ckcollar.app.ui.base.CKBaseActivity
+import com.ck.ckcollar.app.ui.dialog.CKAlertDialog
+import com.ck.ckcollar.app.utils.networkone.ICallback
+import com.ck.ckcollar.app.utils.networkone.TTHttpClient
+import com.ck.ckcollar.app.utils.networkone.model.TTRequestParam
+import com.google.gson.Gson
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.GlobalScope
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
+
+class DepositActivity : CKBaseActivity() {
+
+ lateinit var binding: ActivityDepositBinding
+ override fun onCreate(savedInstanceState: Bundle?) {
+ binding = ActivityDepositBinding.inflate(layoutInflater)
+ setContentView(binding.root)
+ super.onCreate(savedInstanceState)
+
+ setTitleText(getString(R.string.deposit))
+ }
+
+ override fun initView() {
+
+ binding.btnReturn.setOnClickListener {
+
+ CKAlertDialog(this@DepositActivity,getString(R.string.bound_alert),getString(R.string.bound_alert_tip),object : CKAlertDialog.AlertClickListener{
+ override fun onBack(isConfirm: Boolean) {
+ if (isConfirm){
+ returnMoney()
+
+ }
+ }
+ }).show()
+ }
+ }
+ override fun initData() {
+
+ getInfo()
+
+ startZM()
+ }
+
+
+ fun getInfo() {
+ TTHttpClient.get(this, "个人资料", TTRequestParam(), object : ICallback {
+ override fun onSuccess(data: String) {
+
+ var model = Gson().fromJson(data, UserInfoModel::class.java)
+ binding.textAmount.text = model.depositAmount.toString()
+
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ toast(msg)
+ finish()
+ }
+ })
+ }
+ fun startZM() {
+ TTHttpClient.post(this, "芝麻授权", TTRequestParam(), object : ICallback {
+ override fun onSuccess(data: String) {
+ var model = Gson().fromJson(data,DepositModel::class.java)
+
+ GlobalScope.launch(Dispatchers.IO){
+ val alipay = PayTask(this@DepositActivity)
+ val result = alipay.payV2(model.orderStr, true)
+
+ var payResult = PayResult(result)
+ withContext(Dispatchers.Main){
+ if ("9000".equals(payResult.resultStatus)){
+
+ }
+ }
+
+ }
+
+
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ toast(msg)
+ finish()
+ }
+ })
+ }
+ fun returnMoney() {
+ TTHttpClient.post(this, "退还押金", TTRequestParam(), object : ICallback {
+ override fun onSuccess(data: String) {
+
+ toast(getString(R.string.return_success))
+
+ finish()
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ toast(msg)
+ }
+ })
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/ui/act/deposit/StartDepositActivity.kt b/app/src/main/java/com/ck/ckcollar/app/ui/act/deposit/StartDepositActivity.kt
new file mode 100644
index 0000000..0c83be7
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/ui/act/deposit/StartDepositActivity.kt
@@ -0,0 +1,145 @@
+package com.ck.ckcollar.app.ui.act.deposit
+
+import android.os.Bundle
+import android.text.SpannableStringBuilder
+import android.text.Spanned
+import android.text.TextPaint
+import android.text.method.LinkMovementMethod
+import android.text.style.ClickableSpan
+import android.view.View
+import com.alipay.sdk.app.PayTask
+import com.ck.ckcollar.app.R
+import com.ck.ckcollar.app.databinding.ActivityDepositBinding
+import com.ck.ckcollar.app.databinding.ActivityStartDepositBinding
+import com.ck.ckcollar.app.model.DepositModel
+import com.ck.ckcollar.app.model.MemberModel
+import com.ck.ckcollar.app.model.PayResult
+import com.ck.ckcollar.app.model.UserInfoModel
+import com.ck.ckcollar.app.ui.act.login.AgreementActivity
+import com.ck.ckcollar.app.ui.base.CKBaseActivity
+import com.ck.ckcollar.app.ui.dialog.CKAlertDialog
+import com.ck.ckcollar.app.utils.networkone.ICallback
+import com.ck.ckcollar.app.utils.networkone.TTHttpClient
+import com.ck.ckcollar.app.utils.networkone.model.TTRequestParam
+import com.google.gson.Gson
+import com.tt.kit.model.Data
+import com.tt.kit.model.DataCollection
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.GlobalScope
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
+
+class StartDepositActivity : CKBaseActivity() {
+
+ lateinit var binding: ActivityStartDepositBinding
+ var isCheck = false
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ binding = ActivityStartDepositBinding.inflate(layoutInflater)
+ setContentView(binding.root)
+ super.onCreate(savedInstanceState)
+
+ setStatusBarColor2(resources.getColor(R.color.white))
+ setActionBarColor(resources.getColor(R.color.white))
+ }
+
+ override fun initView() {
+
+ val text = "我已阅读并同意《芝麻信用协议及授权条款》";
+ val spannable = SpannableStringBuilder(text)
+ // 获取需要应用样式的文本的开始和结束索引
+ val start1 = text.indexOf("《芝麻信用协议及授权条款》")
+ val end1 = start1 + "《芝麻信用协议及授权条款》".length
+
+ var clickableSpan = object : ClickableSpan() {
+ override fun onClick(v: View) {
+ toActivity(AgreementActivity::class.java, DataCollection().apply { add(Data("title","芝麻信用协议及授权条款")) })
+ }
+ override fun updateDrawState(ds: TextPaint) {
+ ds.setColor(getColor2(R.attr.appTextColor))
+ }
+ };
+
+
+ binding.textAgreement.setMovementMethod(LinkMovementMethod.getInstance());
+ binding.textAgreement.setHighlightColor(resources.getColor(R.color.transparent))
+ // 应用样式
+ spannable.setSpan(clickableSpan, start1, end1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
+
+ binding.textAgreement.setText(spannable)
+
+
+ setCheckUI()
+ binding.btnCheck.setOnClickListener {
+ isCheck = !isCheck
+ setCheckUI()
+ }
+
+
+ binding.btnStart.setOnClickListener {
+ startZM()
+ }
+ }
+ override fun initData() {
+
+ getInfo()
+
+ // startZM()
+ }
+
+ fun setCheckUI(){
+ if (isCheck){
+ binding.check.setImageResource(R.mipmap.image_check_select)
+ }else{
+ binding.check.setImageResource(R.mipmap.image_check_unselect)
+ }
+ }
+ fun getInfo() {
+ TTHttpClient.get(this, "个人资料", TTRequestParam(), object : ICallback {
+ override fun onSuccess(data: String) {
+
+ var model = Gson().fromJson(data, UserInfoModel::class.java)
+ binding.textAmount.text = model.depositAmount.toString()
+
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ toast(msg)
+ finish()
+ }
+ })
+ }
+ fun startZM() {
+ if (!isCheck){
+ toast(getString(R.string.alert_agreement))
+ return
+ }
+
+ TTHttpClient.post(this, "芝麻授权", TTRequestParam(), object : ICallback {
+ override fun onSuccess(data: String) {
+ var model = Gson().fromJson(data,DepositModel::class.java)
+
+ GlobalScope.launch(Dispatchers.IO){
+ val alipay = PayTask(this@StartDepositActivity)
+ val result = alipay.payV2(model.orderStr, true)
+
+ var payResult = PayResult(result)
+ withContext(Dispatchers.Main){
+ if ("9000".equals(payResult.resultStatus)){
+
+ }
+ }
+
+ }
+
+
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ toast(msg)
+ finish()
+ }
+ })
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/ui/act/home/MainActivity.kt b/app/src/main/java/com/ck/ckcollar/app/ui/act/home/MainActivity.kt
new file mode 100644
index 0000000..8a35d7b
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/ui/act/home/MainActivity.kt
@@ -0,0 +1,195 @@
+package com.ck.ckcollar.app.ui.act.home
+
+import android.graphics.Color
+import android.os.Build
+import android.os.Bundle
+import android.view.MenuItem
+import android.view.View
+import android.view.WindowInsets
+import android.widget.TextView
+import androidx.viewpager2.widget.ViewPager2
+import androidx.viewpager2.widget.ViewPager2.OnPageChangeCallback
+import com.ck.ckcollar.app.R
+import com.ck.ckcollar.app.databinding.ActivityMainBinding
+import com.ck.ckcollar.app.databinding.FragmentHomeBinding
+import com.ck.ckcollar.app.model.CustomerStatusModel
+import com.ck.ckcollar.app.model.UpdateModel
+import com.ck.ckcollar.app.ui.act.home.adapter.MainFragmentAdapter
+import com.ck.ckcollar.app.ui.act.home.fragment.HealthFragment
+import com.ck.ckcollar.app.ui.act.home.fragment.HomeFragment
+import com.ck.ckcollar.app.ui.act.home.fragment.MineFragment
+import com.ck.ckcollar.app.ui.act.home.fragment.ShopFragment
+import com.ck.ckcollar.app.ui.base.CKBaseActivity
+import com.ck.ckcollar.app.ui.base.CKBaseFragment
+import com.ck.ckcollar.app.ui.base.CKLHBaseActivity
+import com.ck.ckcollar.app.ui.dialog.CKUpdateAlertDialog
+import com.ck.ckcollar.app.utils.networkone.ICallback
+import com.ck.ckcollar.app.utils.networkone.TTHttpClient
+import com.ck.ckcollar.app.utils.networkone.model.TTRequestParam
+import com.cyclone.shadowsocks.ui.frg.TTBaseFragment
+import com.google.android.material.navigation.NavigationBarView
+import com.google.gson.Gson
+
+import com.tt.kit.base.TTBaseActivity
+import com.tt.kit.utils.TTUtils
+
+
+class MainActivity : CKLHBaseActivity(),View.OnClickListener {
+ lateinit var mainBinding: ActivityMainBinding
+ override fun onCreate(savedInstanceState: Bundle?) {
+
+
+ mainBinding = ActivityMainBinding.inflate(layoutInflater)
+ setContentView(mainBinding.root)
+ super.onCreate(savedInstanceState)
+
+
+// if (Build.VERSION.SDK_INT >= 36){
+//
+// mainBinding.root.setOnApplyWindowInsetsListener { v, insets ->
+//
+// val bottom = insets.getInsets(WindowInsets.Type.navigationBars()).bottom
+// v.setPadding(0,0,0,16 + bottom)
+// insets
+//
+// }
+// }
+
+
+ var list =
+ listOf(HomeFragment(), HealthFragment(), ShopFragment(), MineFragment())
+ mainBinding.viewPager.adapter = MainFragmentAdapter(this, list)
+
+
+// mainBinding.bottomNav.setOnItemSelectedListener(object :
+// NavigationBarView.OnItemSelectedListener {
+// override fun onNavigationItemSelected(item: MenuItem): Boolean {
+// resetItemIcon()
+// when (item.itemId) {
+// R.id.fragmnt1 -> {
+// mainBinding.viewPager.currentItem = 0
+// item.setIcon(R.mipmap.image_nav_item1_select)
+// }
+//
+// R.id.fragmnt2 -> {
+// mainBinding.viewPager.currentItem = 1
+// item.setIcon(R.mipmap.image_nav_item2_select)
+// }
+//
+// R.id.fragmnt3 -> {
+// mainBinding.viewPager.currentItem = 2
+// item.setIcon(R.mipmap.image_nav_item1_select)
+// }
+//
+// R.id.fragmnt4 -> {
+// mainBinding.viewPager.currentItem = 3
+// item.setIcon(R.mipmap.image_nav_item4_select)
+// }
+// }
+// return true
+// }
+// })
+// //禁止用户滑动
+// mainBinding.viewPager.setPagingEnabled(false)
+// mainBinding.bottomNav.itemIconTintList = null
+
+ mainBinding.content1.setOnClickListener(this)
+ mainBinding.content2.setOnClickListener(this)
+ mainBinding.content3.setOnClickListener(this)
+ mainBinding.content4.setOnClickListener(this)
+
+ mainBinding.viewPager.setPagingEnabled(false)
+
+ }
+
+ fun resetItemIcon() {
+// var item1 = mainBinding.bottomNav.menu.findItem(R.id.fragmnt1)
+// var item2 = mainBinding.bottomNav.menu.findItem(R.id.fragmnt2)
+// var item3 = mainBinding.bottomNav.menu.findItem(R.id.fragmnt3)
+// var item4 = mainBinding.bottomNav.menu.findItem(R.id.fragmnt4)
+//
+// item1.setIcon(R.mipmap.image_nav_item1_normal)
+// item2.setIcon(R.mipmap.image_nav_item2_normal)
+// item3.setIcon(R.mipmap.image_nav_item3_normal)
+// item4.setIcon(R.mipmap.image_nav_item4_normal)
+
+ }
+
+
+ override fun initData() {
+// CKUpdateAlertDialog(this,"更新内容",object : CKUpdateAlertDialog.AlertClickListener{
+// override fun onBack(isConfirm: Boolean) {
+//
+// }
+// }).show()
+
+ checkUpdate()
+
+ }
+
+
+ override fun onClick(v: View?) {
+
+ mainBinding.image1.setImageResource(R.mipmap.image_nav_item1_normal)
+ mainBinding.image2.setImageResource(R.mipmap.image_nav_item2_normal)
+ mainBinding.image3.setImageResource(R.mipmap.image_nav_item3_normal)
+ mainBinding.image4.setImageResource(R.mipmap.image_nav_item4_normal)
+
+ mainBinding.text1.setTextColor(getColor(R.color.textSecondColor))
+ mainBinding.text2.setTextColor(getColor(R.color.textSecondColor))
+ mainBinding.text3.setTextColor(getColor(R.color.textSecondColor))
+ mainBinding.text4.setTextColor(getColor(R.color.textSecondColor))
+
+ when(v?.id){
+ R.id.content1->{
+ mainBinding.image1.setImageResource(R.mipmap.image_nav_item1_select)
+ mainBinding.text1.setTextColor(getColor(R.color.textColor))
+ mainBinding.viewPager.currentItem = 0
+ }
+ R.id.content2->{
+ mainBinding.image2.setImageResource(R.mipmap.image_nav_item2_select)
+ mainBinding.text2.setTextColor(getColor(R.color.textColor))
+ mainBinding.viewPager.currentItem = 1
+ }
+ R.id.content3->{
+ mainBinding.image3.setImageResource(R.mipmap.image_nav_item3_select)
+ mainBinding.text3.setTextColor(getColor(R.color.textColor))
+ mainBinding.viewPager.currentItem = 2
+ }
+ R.id.content4->{
+ mainBinding.image4.setImageResource(R.mipmap.image_nav_item4_select)
+ mainBinding.text4.setTextColor(getColor(R.color.textColor))
+ mainBinding.viewPager.currentItem = 3
+ }
+ }
+ }
+
+
+ override fun onStart() {
+ super.onStart()
+ }
+
+ fun checkUpdate(){
+
+ TTHttpClient.get(this,"更新", TTRequestParam(),object : ICallback{
+ override fun onSuccess(data: String) {
+
+ var mode = Gson().fromJson(data,UpdateModel::class.java)
+
+ if (mode.androidVersion != TTUtils.getVersionCode(this@MainActivity)){
+ CKUpdateAlertDialog(this@MainActivity,mode
+ .content!!,mode.isForce,object : CKUpdateAlertDialog.AlertClickListener{
+ override fun onBack(isConfirm: Boolean) {
+
+ }
+ }).show()
+ }
+
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ toast(msg)
+ }
+ })
+ }
+}
diff --git a/app/src/main/java/com/ck/ckcollar/app/ui/act/home/adapter/MainFragmentAdapter.kt b/app/src/main/java/com/ck/ckcollar/app/ui/act/home/adapter/MainFragmentAdapter.kt
new file mode 100644
index 0000000..364bd1f
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/ui/act/home/adapter/MainFragmentAdapter.kt
@@ -0,0 +1,23 @@
+package com.ck.ckcollar.app.ui.act.home.adapter
+
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+import androidx.fragment.app.FragmentActivity
+import androidx.fragment.app.FragmentPagerAdapter
+import androidx.viewpager2.adapter.FragmentStateAdapter
+import com.cyclone.shadowsocks.ui.frg.TTBaseFragment
+
+class MainFragmentAdapter(var fragmentActivity: FragmentActivity,var list : List) : FragmentPagerAdapter(fragmentActivity.supportFragmentManager) {
+
+ override fun getItem(position: Int): Fragment {
+ return list.get(position)
+ }
+
+ override fun getCount(): Int {
+ return list.size
+ }
+
+ override fun destroyItem(container: ViewGroup, position: Int, `object`: Any) {
+
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/ui/act/home/fragment/HealthFragment.kt b/app/src/main/java/com/ck/ckcollar/app/ui/act/home/fragment/HealthFragment.kt
new file mode 100644
index 0000000..fb8094a
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/ui/act/home/fragment/HealthFragment.kt
@@ -0,0 +1,192 @@
+package com.ck.ckcollar.app.ui.act.home.fragment
+
+import android.content.Context
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.recyclerview.widget.LinearLayoutManager
+import androidx.recyclerview.widget.RecyclerView
+import com.bumptech.glide.Glide
+import com.ck.ckcollar.app.R
+import com.ck.ckcollar.app.databinding.FragmentHealthBinding
+import com.ck.ckcollar.app.databinding.LayoutItemNoteBinding
+import com.ck.ckcollar.app.listenner.OnItemClickListenner
+import com.ck.ckcollar.app.model.CustomerStatusModel
+import com.ck.ckcollar.app.model.HealthNoteModel
+import com.ck.ckcollar.app.ui.act.customer.CustomerActivity
+import com.ck.ckcollar.app.ui.act.customer.PeopleCustomerActivity
+import com.ck.ckcollar.app.ui.act.note.NoteDetailsActivity
+import com.ck.ckcollar.app.ui.base.CKBaseFragment
+import com.ck.ckcollar.app.ui.dialog.CKAlertDialog
+import com.ck.ckcollar.app.utils.networkone.ICallback
+import com.ck.ckcollar.app.utils.networkone.TTHttpClient
+import com.ck.ckcollar.app.utils.networkone.model.TTRequestData
+import com.ck.ckcollar.app.utils.networkone.model.TTRequestParam
+import com.google.gson.Gson
+import com.scwang.smartrefresh.layout.api.RefreshLayout
+import com.scwang.smartrefresh.layout.listener.OnLoadMoreListener
+import com.scwang.smartrefresh.layout.listener.OnRefreshLoadMoreListener
+import com.tt.kit.base.TTBaseActivity
+import com.tt.kit.model.Data
+import com.tt.kit.model.DataCollection
+
+class HealthFragment: CKBaseFragment() {
+
+ lateinit var binding: FragmentHealthBinding
+ var data = mutableListOf()
+ lateinit var noteAdapter: NoteAdapter
+ var page = 1
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ binding = FragmentHealthBinding.inflate(inflater)
+ return binding.root
+ }
+
+ override fun initView() {
+
+ binding.recyclerView.layoutManager = LinearLayoutManager(context, RecyclerView.VERTICAL,false)
+ binding.recyclerView.setHasFixedSize(true)
+ noteAdapter = NoteAdapter(activity!!,data,object : OnItemClickListenner{
+ override fun onClick(
+ pos: Int,
+ model: Any
+ ) {
+ toActivity(NoteDetailsActivity::class.java, DataCollection().apply { add(Data("id",data.get(pos).id.toString()))
+ add(Data("title",data.get(pos).pageName))
+ })
+
+ }
+ })
+ binding.recyclerView.adapter = noteAdapter
+
+ binding.btnAIText.setOnClickListener {
+
+ toActivity(CustomerActivity::class.java, DataCollection())
+ }
+ binding.btnAIPhoto.setOnClickListener {
+ toActivity(CustomerActivity::class.java, DataCollection())
+ }
+ binding.contentCustomer.setOnClickListener {
+ checkCustomerStatus()
+ }
+ binding.refreshLayout.setEnableLoadMore(false)
+ binding.refreshLayout.setOnRefreshListener {
+ page = 1
+ getData()
+ getCustomerTime()
+ }
+
+
+
+ }
+
+ override fun initData() {
+
+
+ getData()
+ getCustomerTime()
+ }
+
+
+ fun getCustomerTime(){
+
+ TTHttpClient.get(activity as TTBaseActivity,"客服在线状态", TTRequestParam(),object : ICallback{
+ override fun onSuccess(data: String) {
+ hiddenProgeassDialog()
+ var customerStatusModel = Gson().fromJson(data,CustomerStatusModel::class.java)
+
+
+ binding.textDate.text = getString(R.string.pet_advisor2)
+ binding.textDate2.text = "("+customerStatusModel.serviceStartTime +","+customerStatusModel.serviceEndTime+")"
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ hiddenProgeassDialog()
+ toast(msg)
+ }
+ })
+ }
+ fun checkCustomerStatus(){
+
+ toActivity(PeopleCustomerActivity::class.java, DataCollection().apply { add(Data("chatType","0")) })
+
+ }
+ fun getData(){
+ TTHttpClient.get(activity as TTBaseActivity,"宠物知识列表", TTRequestParam().apply {
+ add(
+ TTRequestData("pageNum", page)
+ )
+ add (
+ TTRequestData("pageSize", 100)
+ )
+ },object : ICallback{
+ override fun onSuccess(data: String) {
+ var model = Gson().fromJson(data, HealthNoteModel::class.java)
+
+ if (page == 1){
+ this@HealthFragment.data.clear()
+ }
+ if (this@HealthFragment.data.size != model.total){
+ this@HealthFragment.data.addAll(model.rows)
+ }
+
+ noteAdapter.data = this@HealthFragment.data
+ noteAdapter.notifyDataSetChanged()
+ binding.refreshLayout.finishLoadMore(true)
+ binding.refreshLayout.finishRefresh()
+
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ try {
+ toast(msg)
+ binding.refreshLayout.finishLoadMore(true)
+
+ }catch (e : Exception){
+ e.printStackTrace()
+ }
+
+ }
+ })
+ }
+
+ class NoteAdapter(var context: Context, var data: List, var onItemClickListenner : OnItemClickListenner) : RecyclerView.Adapter() {
+ override fun onCreateViewHolder(
+ parent: ViewGroup,
+ viewType: Int
+ ): NoteHolder {
+ return NoteHolder(LayoutItemNoteBinding.inflate(LayoutInflater.from(context),parent,false))
+ }
+
+ override fun onBindViewHolder(
+ holder: NoteHolder,
+ position: Int
+ ) {
+ holder.binding.text.text = data.get(position).pageName
+ holder.binding.textDate.text = data.get(position).createTime
+ Glide.with(context)
+ .load(data.get(position).imageUrl)
+ .placeholder(R.mipmap.image_default)
+ .into(holder.binding.image)
+
+ holder.binding.root.setTag(position)
+ holder.binding.root.setOnClickListener {
+ val position = it.tag as Int
+ onItemClickListenner.onClick(position,data.get(position))
+ }
+ }
+
+ override fun getItemCount(): Int {
+ return data.size
+ }
+
+ class NoteHolder(var binding: LayoutItemNoteBinding) : RecyclerView.ViewHolder(binding.root){
+
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/ui/act/home/fragment/HomeFragment.kt b/app/src/main/java/com/ck/ckcollar/app/ui/act/home/fragment/HomeFragment.kt
new file mode 100644
index 0000000..df572ac
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/ui/act/home/fragment/HomeFragment.kt
@@ -0,0 +1,771 @@
+package com.ck.ckcollar.app.ui.act.home.fragment
+
+import android.app.Activity.RESULT_OK
+import android.content.Context
+import android.content.Intent
+import android.graphics.drawable.GradientDrawable.Orientation
+import android.net.Uri
+import android.os.Build
+import android.os.Bundle
+import android.os.Environment
+import android.provider.MediaStore
+import android.text.TextUtils
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.ImageView
+import android.widget.PopupWindow
+import androidx.core.content.FileProvider
+import androidx.lifecycle.Observer
+import androidx.recyclerview.widget.RecyclerView
+import com.bumptech.glide.Glide
+import com.bumptech.glide.load.resource.bitmap.RoundedCorners
+import com.bumptech.glide.request.RequestOptions
+import com.ck.ckcollar.app.R
+import com.ck.ckcollar.app.databinding.FragmentHomeBinding
+import com.ck.ckcollar.app.listenner.OnItemClickListenner
+import com.ck.ckcollar.app.model.AIPhotoModel
+import com.ck.ckcollar.app.model.BannarModel
+import com.ck.ckcollar.app.model.CollarTypeModel
+import com.ck.ckcollar.app.model.HomeModel
+import com.ck.ckcollar.app.model.ImageModel
+import com.ck.ckcollar.app.model.UploadModel
+import com.ck.ckcollar.app.ui.act.petmanager.AddPetActivity
+import com.ck.ckcollar.app.ui.act.petmanager.InputInviteCodeActivity
+import com.ck.ckcollar.app.ui.act.petmanager.MapLocationActivity
+import com.ck.ckcollar.app.ui.act.petmanager.PetManagerActivity
+import com.ck.ckcollar.app.ui.act.petmanager.ViewPetFileActivity
+import com.ck.ckcollar.app.ui.base.CKBaseFragment
+import com.ck.ckcollar.app.ui.dialog.CKAlertDialog
+import com.ck.ckcollar.app.ui.popview.CKCollarTypePopView
+import com.ck.ckcollar.app.ui.popview.CKPowerAlertView
+import com.ck.ckcollar.app.utils.CKUtils
+import com.ck.ckcollar.app.utils.Const
+import com.ck.ckcollar.app.utils.networkone.ICallback
+import com.ck.ckcollar.app.utils.networkone.TTHttpClient
+import com.ck.ckcollar.app.utils.networkone.model.TTRequestData
+import com.ck.ckcollar.app.utils.networkone.model.TTRequestParam
+import com.ck.ckcollar.app.widget.CKRoundImageView
+import com.cyclone.shadowsocks.utils.PreferencesUtils
+import com.google.gson.Gson
+import com.gyf.immersionbar.ImmersionBar
+import com.tt.kit.base.TTBaseActivity
+import com.tt.kit.model.Data
+import com.tt.kit.model.DataCollection
+import com.tt.kit.utils.LiveDataBus
+import com.tt.kit.utils.TTLog
+import com.tt.kit.utils.TTUtils
+import com.tt.kit.utils.ViewUtils
+import com.tt.mnmlkitscanner.scan.MNScanManager
+import com.tt.mnmlkitscanner.scan.callback.act.MNScanCallback
+import com.youth.banner.adapter.BannerAdapter
+import com.youth.banner.indicator.CircleIndicator
+import org.json.JSONObject
+import java.io.File
+import kotlin.random.Random
+
+
+class HomeFragment : CKBaseFragment() {
+
+ lateinit var homeBinding: FragmentHomeBinding
+ var collarDatas = listOf()
+
+ lateinit var imageAdapter: ImageAdapter
+ var bannarData = listOf()
+ var dataModel: CollarTypeModel.TypeDataModel? = null
+ var homeModel: HomeModel? = null
+ var isFirstShow = false
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ homeBinding = FragmentHomeBinding.inflate(layoutInflater)
+ ImmersionBar.with(this)
+ .statusBarDarkFont(true)
+ // .titleBar(binding.main)
+ .init()
+ homeBinding.contentView.setPadding(0, TTUtils.getStatusBarHeight(activity!!), 0, 0)
+ return homeBinding.root
+ }
+
+ override fun initView() {
+ ViewUtils.setGradientBackground(
+ homeBinding.contentView,
+ resources.getColor(R.color.color_FFF5D5),
+ resources.getColor(R.color.color_D8D8D8),
+ Orientation.TOP_BOTTOM
+ )
+
+
+ homeBinding.textName?.setOnClickListener {
+ getPetList()
+ }
+ //扫一扫
+ homeBinding.btnScan?.setOnClickListener {
+ if (dataModel == null) {
+ toast(getString(R.string.choose_pet_alert))
+ return@setOnClickListener
+ }
+
+ if (!checkCameraPermissions()){
+ CKAlertDialog(activity!!,getString(R.string.alert),getString(R.string.camera_alert),object : CKAlertDialog.AlertClickListener{
+ override fun onBack(isConfirm: Boolean) {
+ }
+
+ }).show()
+ return@setOnClickListener
+ }
+
+ startScan()
+ }
+ homeBinding.btnCamera?.setOnClickListener {
+ try {
+
+ if (!checkCameraPermissions()){
+ CKAlertDialog(activity!!,getString(R.string.alert),getString(R.string.camera_alert),object : CKAlertDialog.AlertClickListener{
+
+ override fun onBack(isConfirm: Boolean) {
+
+ }
+ }).show()
+ return@setOnClickListener
+ }
+
+ takePhoto()
+
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ }
+ homeBinding.btnManager?.setOnClickListener {
+ toActivity(PetManagerActivity::class.java, DataCollection())
+ }
+ homeBinding.btnAddPet?.setOnClickListener {
+ toActivity(AddPetActivity::class.java, DataCollection())
+ }
+
+ homeBinding.contentPower?.setOnClickListener {
+ CKPowerAlertView(
+ activity!!, homeBinding.contentPower!!, getString(
+ R.string.power_tip, homeModel?.equipment?.powerLevel + "%",
+ CKUtils.dataToFormat(
+ homeModel?.equipment?.equUpdatetime, CKUtils.YYYYMMDD_HHMMSS,
+ CKUtils.YYYYMMDD_HHMM
+ )
+ ), object : PopupWindow.OnDismissListener {
+ override fun onDismiss() {
+
+ }
+ }).show()
+ }
+
+ homeBinding.btnAdreessDetails?.setOnClickListener {
+
+ getPetInfo(dataModel?.id.toString())
+
+
+ }
+ homeBinding.btnViewPostion?.setOnClickListener {
+ getData(dataModel?.id.toString())
+
+// toActivity(MapLocationActivity::class.java, DataCollection().apply {
+// add(Data("latitude", "40.909"))
+// add(Data("longitude", "118.39742"))
+// add(Data("url", ""))
+// })
+
+ }
+
+ homeBinding.btnDetails?.setOnClickListener {
+ toActivity(ViewPetFileActivity::class.java, DataCollection().apply {
+ add(
+ Data("data", Gson().toJson(dataModel))
+ )
+ })
+ }
+ homeBinding.refreshLayout?.setOnRefreshListener {
+
+ if (dataModel == null) {
+ getData("")
+ } else {
+ getData(dataModel?.id.toString())
+ }
+
+ }
+ homeBinding.btnConsignment?.setOnClickListener {
+ toast(getString(R.string.waitting_open_area))
+ }
+ homeBinding.btnTraining?.setOnClickListener {
+ toast(getString(R.string.waitting_open_area))
+ }
+ }
+
+ override fun initData() {
+
+ var data = PreferencesUtils.getString(activity!!, Const.PET_DATA, "")
+
+ if (!TextUtils.isEmpty(data)) {
+ dataModel = Gson().fromJson(
+ data,
+ CollarTypeModel.TypeDataModel::class.java
+ )
+ homeBinding.textName?.text = dataModel?.patName
+ getData(dataModel!!.id.toString())
+
+ switchPet()
+
+ } else {
+ isFirstShow = true
+ getData("")
+
+ }
+
+
+ if (isFirstShow) {
+ getPetList()
+ }
+
+
+ LiveDataBus.get().with("FIRST", Int::class.java)
+ .observe(viewLifecycleOwner, object : Observer {
+ override fun onChanged(result: Int?) {
+ getPetList2()
+ }
+ })
+
+ }
+
+ fun takePhoto() {
+ try {
+ val openCameraIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
+
+ val vFile = File(
+ activity!!.getExternalFilesDir(Environment.DIRECTORY_PICTURES),
+ "${System.currentTimeMillis()}.png"
+ )
+
+ val parentDir = vFile.parentFile
+ if (parentDir != null && !parentDir.exists()) {
+ parentDir.mkdirs()
+ }
+ TTLog.e(vFile.absolutePath)
+ PreferencesUtils.putString(
+ activity!!.getApplicationContext(),
+ Const.IMAGE_PATH,
+ vFile.absolutePath
+ )
+
+ val cameraUri: Uri = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+ FileProvider.getUriForFile(
+ activity!!,
+ activity!!.packageName + ".fileprovider",
+ vFile
+ )
+ } else {
+ Uri.fromFile(vFile)
+ }
+
+ openCameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, cameraUri)
+ startActivityForResult(openCameraIntent, 55)
+ }catch (e : Exception){
+ e.printStackTrace()
+ }
+
+ }
+
+ fun getData(id: String) {
+ TTHttpClient.get(activity as TTBaseActivity, "首页", TTRequestParam().apply {
+ add(TTRequestData("patId", id))
+ }, object : ICallback {
+ override fun onSuccess(data: String) {
+ homeModel = Gson().fromJson(data, HomeModel::class.java)
+
+ bannarData = homeModel?.banners!!
+
+ imageAdapter = ImageAdapter(activity!!, bannarData, object : OnItemClickListenner {
+ override fun onClick(pos: Int, model: Any) {
+
+ }
+ })
+ homeBinding.banner.addBannerLifecycleObserver(this@HomeFragment)//添加生命周期观察者
+ .setAdapter(imageAdapter)
+ .setIndicator(CircleIndicator(activity));
+
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ toast(msg)
+ }
+ })
+
+
+ TTHttpClient.get(activity as TTBaseActivity, "设备信息", TTRequestParam().apply { add(TTRequestData("patId",id)) },object : ICallback{
+ override fun onSuccess(data: String) {
+ var model = Gson().fromJson(data, HomeModel.EquipmentModel::class.java)
+
+ homeModel?.equipment = model
+
+
+ try {
+ if (!TextUtils.isEmpty(homeModel?.equipment?.collNum)) {
+ homeBinding.btnBound!!.text = homeModel?.equipment?.collNum
+ homeBinding.textHealthPoints!!.text = homeModel?.equipment?.healthVitality
+ homeBinding.textStep!!.text = homeModel?.equipment?.steps
+ homeBinding.textDistance!!.text = homeModel?.equipment?.mileage.toString()
+ homeBinding.textPowerValue!!.text = homeModel?.equipment?.powerLevel + "%"
+
+
+ homeModel?.equipment?.powerLevel?.let {
+ if (it.toDouble() == 0.0){
+ homeBinding.imagePower?.setImageResource(R.mipmap.image_power_0)
+ }else if (it.toDouble() > 0 && it.toDouble() <= 10){
+ homeBinding.imagePower?.setImageResource(R.mipmap.image_power_1)
+ }else if (it.toDouble() > 10 && it.toDouble() <= 20){
+ homeBinding.imagePower?.setImageResource(R.mipmap.image_power_2)
+ }else if (it.toDouble() > 20 && it.toDouble() <= 30){
+ homeBinding.imagePower?.setImageResource(R.mipmap.image_power_3)
+ }else if (it.toDouble() > 30 && it.toDouble() <= 40){
+ homeBinding.imagePower?.setImageResource(R.mipmap.image_power_4)
+ }else if (it.toDouble() > 40 && it.toDouble() <= 50){
+ homeBinding.imagePower?.setImageResource(R.mipmap.image_power_5)
+ }else if (it.toDouble() > 50 && it.toDouble() <= 60){
+ homeBinding.imagePower?.setImageResource(R.mipmap.image_power_6)
+ }else if (it.toDouble() > 60 && it.toDouble() <= 70){
+ homeBinding.imagePower?.setImageResource(R.mipmap.image_power_7)
+ }else if (it.toDouble() > 70 && it.toDouble() <= 80){
+ homeBinding.imagePower?.setImageResource(R.mipmap.image_power_8)
+ }else if (it.toDouble() > 80 && it.toDouble() <= 90){
+ homeBinding.imagePower?.setImageResource(R.mipmap.image_power_9)
+ }else if (it.toDouble() > 90 && it.toDouble() <= 100){
+ homeBinding.imagePower?.setImageResource(R.mipmap.image_power_10)
+ }
+ }
+
+ homeBinding.contentPower?.visibility = View.VISIBLE
+
+ homeBinding.btnScan?.visibility = View.GONE
+ homeBinding.btnDetails?.visibility = View.VISIBLE
+
+ homeBinding.btnAdreessDetails?.visibility = View.VISIBLE
+ homeBinding.btnViewPostion?.visibility = View.GONE
+
+ if (homeModel?.equipment!!.noSignal) {
+ if (TextUtils.isEmpty(homeModel?.equipment?.lastLocation)){
+ homeBinding.textAddress!!.text = getString(R.string.no_position)
+ }else{
+ homeBinding.textAddress!!.text =
+ "当前位置无法接收信号,最后一次定位是:" + (homeModel?.equipment?.lastLocation
+ ?: "")
+
+ }
+
+ } else {
+ homeBinding.textAddress!!.text = homeModel?.equipment?.lastLocation
+
+ }
+
+ } else {
+ homeBinding.btnBound!!.text = getString(R.string.unbound)
+ homeBinding.textHealthPoints!!.text = "--"
+ homeBinding.textStep!!.text = "-"
+ homeBinding.textAddress!!.text = getString(R.string.no_position)
+ homeBinding.textDistance!!.text = "-"
+ homeBinding.textPowerValue!!.text = "%"
+
+ homeBinding.contentPower?.visibility = View.GONE
+
+ homeBinding.btnScan?.visibility = View.VISIBLE
+ homeBinding.btnDetails?.visibility = View.GONE
+
+ homeBinding.btnAdreessDetails?.visibility = View.GONE
+ homeBinding.btnViewPostion?.visibility = View.VISIBLE
+ }
+ homeBinding.refreshLayout?.finishRefresh()
+ }catch (e : Exception ){
+
+ }
+
+
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ toast(msg)
+ }
+ })
+ }
+
+ fun switchPet() {
+
+
+ LiveDataBus.get().with("BOUND" + dataModel!!.id, Int::class.java)
+ .observe(viewLifecycleOwner, object : Observer {
+ override fun onChanged(result: Int?) {
+ getData(dataModel?.id.toString())
+ }
+ })
+
+ LiveDataBus.get().with("DELETE" + dataModel!!.id, Int::class.java)
+ .observe(viewLifecycleOwner, object : Observer {
+ override fun onChanged(result: Int?) {
+ homeBinding.textName?.text = getString(R.string.choost_pet)
+ dataModel = null
+ getData("")
+ }
+ });
+
+
+ TTHttpClient.post(activity as TTBaseActivity, "切换设备", TTRequestParam().apply {
+ add(
+ TTRequestData("newPatId", dataModel!!.id)
+ )
+ }, object : ICallback {
+ override fun onSuccess(data: String) {
+ getData(dataModel?.id.toString())
+ }
+
+ override fun onFailed(code: String, msg: String) {
+
+ }
+ })
+ }
+
+ fun getPetInfo(id: String) {
+ TTHttpClient.get(activity as TTBaseActivity, "宠物档案", id, object : ICallback {
+ override fun onSuccess(data: String) {
+ var model = Gson().fromJson(
+ data,
+ CollarTypeModel.TypeDataModel::class.java
+ )
+
+
+ var urls = model.patPhoto?.split(",")
+ var url = ""
+ urls?.let {
+ if (urls!!.size > 0) {
+ url = urls.get(0)
+ } else {
+ url = ""
+ }
+ }
+
+
+ if (!TextUtils.isEmpty(homeModel?.equipment?.collNum)) {
+
+ if (homeModel?.equipment?.latitude == 0.0 || homeModel?.equipment?.longitude == 0.0) {
+ toast(getString(R.string.no_position2))
+ return
+ }
+
+ toActivity(MapLocationActivity::class.java, DataCollection().apply {
+ add(Data("latitude", homeModel?.equipment?.latitude))
+ add(Data("longitude", homeModel?.equipment?.longitude))
+ add(Data("url", url))
+ })
+ } else {
+ toast(getString(R.string.no_device_data))
+ }
+
+
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ toast(msg)
+ }
+ })
+ }
+
+ private fun startScan() {
+ MNScanManager.startScan(activity!!, object : MNScanCallback {
+ override fun onActivityResult(resultCode: Int, data: Intent?) {
+ when (resultCode) {
+ MNScanManager.RESULT_SUCCESS -> {
+ val result =
+ data?.getStringArrayListExtra(MNScanManager.INTENT_KEY_RESULT_SUCCESS)
+ if (!result.isNullOrEmpty()) {
+ try {
+ //{"deviceNo":"862323085947268","mac":"dc:da:0c:fa:28:9e","transport":"ble","name":"Water_0001"}
+ var json = JSONObject(result[0])
+ toActivity(
+ InputInviteCodeActivity::class.java,
+ DataCollection().apply {
+ add(Data("id", dataModel!!.id.toString()))
+ add(Data("num", json.getString("collNum")))
+ })
+ } catch (e: Exception) {
+ e.printStackTrace()
+ toast(getString(R.string.data_alert))
+ }
+
+ } else {
+ toast("扫码结果为空")
+ }
+ }
+
+ MNScanManager.RESULT_FAIL -> {
+ val error = data?.getStringExtra(MNScanManager.INTENT_KEY_RESULT_ERROR)
+ toast("扫码失败: $error")
+ }
+
+ MNScanManager.RESULT_CANCLE -> {
+ toast("扫码取消")
+ }
+ }
+ }
+ })
+ }
+
+
+ fun getPetList() {
+ showProgeassDialog(getString(R.string.search))
+ TTHttpClient.get(activity as TTBaseActivity, "宠物列表", TTRequestParam().apply {
+ add(
+ TTRequestData("pageNum", 1)
+ )
+ add(
+ TTRequestData("pageSize", 100)
+ )
+ }, object : ICallback {
+ override fun onSuccess(data: String) {
+
+ hiddenProgeassDialog()
+ var model = Gson().fromJson(data, CollarTypeModel::class.java)
+
+ if (!isFirstShow) {
+ collarDatas = model.rows
+
+ homeBinding.btnRotate?.rotateDownward()
+ CKCollarTypePopView(
+ activity!!,
+ homeBinding.textName!!,
+ collarDatas,
+ object : PopupWindow.OnDismissListener {
+ override fun onDismiss() {
+ homeBinding.btnRotate?.rotateUpwards()
+ }
+ }).show(object : CKCollarTypePopView.OnItemDataClickListenner {
+ override fun onClick(
+ pos: Int,
+ model: CollarTypeModel.TypeDataModel
+ ) {
+ dataModel = model
+ homeBinding.textName?.setText(model.patName)
+
+ switchPet()
+ dataModel?.let {
+ PreferencesUtils.putString(
+ activity!!,
+ Const.PET_DATA,
+ Gson().toJson(dataModel)
+ )
+ }
+ }
+ })
+ } else {
+ isFirstShow = false
+ if (model.rows.size > 0) {
+ dataModel = model.rows.get(0)
+ homeBinding.textName?.setText(dataModel?.patName)
+ switchPet()
+ }
+ }
+
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ hiddenProgeassDialog()
+ toast(msg)
+ }
+ })
+ }
+
+
+ fun getPetList2() {
+ showProgeassDialog(getString(R.string.search))
+ TTHttpClient.get(activity as TTBaseActivity, "宠物列表", TTRequestParam().apply {
+ add(
+ TTRequestData("pageNum", 1)
+ )
+ add(
+ TTRequestData("pageSize", 100)
+ )
+ }, object : ICallback {
+ override fun onSuccess(data: String) {
+
+ hiddenProgeassDialog()
+ var model = Gson().fromJson(data, CollarTypeModel::class.java)
+
+ if (model.rows.size == 1) {
+ dataModel = model.rows.get(0)
+ homeBinding.textName?.setText(dataModel?.patName)
+ switchPet()
+ }
+
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ hiddenProgeassDialog()
+ toast(msg)
+ }
+ })
+ }
+
+
+ override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
+ super.onActivityResult(requestCode, resultCode, data)
+
+ if (requestCode == 55 && resultCode == RESULT_OK) {
+ var path = PreferencesUtils.getString(activity!!, Const.IMAGE_PATH, "")
+ uploadImage(path!!)
+ }
+ }
+
+ fun uploadImage(path: String) {
+
+ var param = TTRequestParam()
+ param.files.add(File(path))
+
+ showProgeassDialog(getString(R.string.see))
+ TTHttpClient.postFile(activity as TTBaseActivity, "上传照片s", param, object : ICallback {
+ override fun onSuccess(data: String) {
+ var model = Gson().fromJson(data, UploadModel::class.java)
+
+ //aiPhoto(ActionCode.BASE_URL + "/" + model.fileNames)
+ aiPhoto(model.urls)
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ hiddenProgeassDialog()
+ toast(msg)
+ }
+ })
+ }
+
+ fun aiPhoto(imageUrl: String) {
+
+ TTHttpClient.postJson(activity as TTBaseActivity, "AI拍照识别", TTRequestParam().apply {
+ add(TTRequestData("imageUrl", imageUrl))
+ }, object : ICallback {
+ override fun onSuccess(data: String) {
+ hiddenProgeassDialog()
+
+ var model = Gson().fromJson(data, AIPhotoModel::class.java)
+ if ("狗".equals(model.species) || "猫".equals(model.species)) {
+ toActivity(AddPetActivity::class.java, DataCollection().apply {
+ add(
+ Data("data", model.species.toString())
+ )
+ add(
+ Data("variety", model.variety.toString())
+ )
+ })
+ } else {
+ toast(getString(R.string.no_data_see))
+ }
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ hiddenProgeassDialog()
+ toast(msg)
+ }
+ })
+ }
+
+ fun setNoDeviceUI() {
+
+ homeBinding.btnBound?.setText(R.string.unbound)
+ homeBinding.btnScan?.visibility = View.VISIBLE
+ homeBinding.btnDetails?.visibility = View.GONE
+
+ homeBinding.btnViewPostion?.visibility = View.VISIBLE
+ homeBinding.btnAdreessDetails?.visibility = View.GONE
+ }
+
+ fun setDeviceUI() {
+
+ homeBinding.btnBound?.setText(R.string.unbound)
+ homeBinding.btnScan?.visibility = View.GONE
+ homeBinding.btnDetails?.visibility = View.VISIBLE
+
+ homeBinding.btnViewPostion?.visibility = View.GONE
+ homeBinding.btnAdreessDetails?.visibility = View.VISIBLE
+ }
+
+ fun setEmptyHealthValueUI() {
+ homeBinding.textHealthPoints?.setText("--")
+ homeBinding.points?.visibility = View.GONE
+ }
+
+ fun setHealthValueUI(points: String) {
+ homeBinding.textHealthPoints?.setText(points)
+ homeBinding.points?.visibility = View.VISIBLE
+ }
+
+
+ override fun onStart() {
+ super.onStart()
+ homeBinding.banner.start();
+ dataModel?.let {
+ getData(dataModel!!.id.toString())
+ }
+ }
+
+ override fun onStop() {
+ super.onStop()
+ homeBinding.banner.stop();
+ }
+
+
+ override fun onDestroy() {
+ super.onDestroy()
+ homeBinding.banner.destroy();
+
+ }
+
+ class ImageAdapter(
+ var context: Context,
+ var mDatas: List?,
+ var itemClickListenner: OnItemClickListenner
+ ) :
+ BannerAdapter(mDatas) {
+ //创建ViewHolder,可以用viewType这个字段来区分不同的ViewHolder
+ override fun onCreateHolder(parent: ViewGroup, viewType: Int): BannerViewHolder {
+ val imageView = CKRoundImageView(parent.getContext())
+ //注意,必须设置为match_parent,这个是viewpager2强制要求的
+ imageView.setLayoutParams(
+ ViewGroup.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.MATCH_PARENT
+ )
+ )
+ imageView.setRoundRadius(12f)
+ imageView.setScaleType(ImageView.ScaleType.CENTER_CROP)
+ return BannerViewHolder(imageView)
+ }
+
+ override fun onBindView(
+ holder: BannerViewHolder?,
+ data: BannarModel?,
+ position: Int,
+ size: Int
+ ) {
+ Glide.with(context)
+ .load(data?.bannerUrl)
+ .apply(RequestOptions.bitmapTransform(RoundedCorners(12)))
+ .placeholder(R.mipmap.image_bannar_item)
+ .into(holder!!.imageView)
+
+ holder!!.imageView.setRoundRadius(20f)
+
+ holder!!.imageView.setTag(position)
+ holder!!.imageView.setOnClickListener {
+ var tag = it.tag as Int
+ itemClickListenner.onClick(tag, mDatas!!.get(tag)!!)
+ }
+ }
+
+ class BannerViewHolder(var imageView: CKRoundImageView) : RecyclerView.ViewHolder(
+ imageView
+ )
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/ui/act/home/fragment/MineFragment.kt b/app/src/main/java/com/ck/ckcollar/app/ui/act/home/fragment/MineFragment.kt
new file mode 100644
index 0000000..fdb89a2
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/ui/act/home/fragment/MineFragment.kt
@@ -0,0 +1,190 @@
+package com.ck.ckcollar.app.ui.act.home.fragment
+
+import android.os.Bundle
+import android.text.TextUtils
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import com.bumptech.glide.Glide
+import com.ck.ckcollar.app.CKApp
+import com.ck.ckcollar.app.R
+import com.ck.ckcollar.app.databinding.FragmentMineBinding
+import com.ck.ckcollar.app.model.UnReadModel
+import com.ck.ckcollar.app.model.UserInfoModel
+import com.ck.ckcollar.app.ui.act.balance.BalanceActivity
+import com.ck.ckcollar.app.ui.act.customer.PeopleCustomerActivity
+import com.ck.ckcollar.app.ui.act.deposit.DepositActivity
+import com.ck.ckcollar.app.ui.act.deposit.StartDepositActivity
+import com.ck.ckcollar.app.ui.act.member.MemberActivity
+import com.ck.ckcollar.app.ui.act.message.MessageCenterActivity
+import com.ck.ckcollar.app.ui.act.mine.FeedBackActivity
+import com.ck.ckcollar.app.ui.act.mine.ReturnDeviceActivity
+import com.ck.ckcollar.app.ui.act.points.PointsActivity
+import com.ck.ckcollar.app.ui.act.setting.SettingActivity
+import com.ck.ckcollar.app.ui.act.order.MyOrderActivity
+import com.ck.ckcollar.app.ui.act.user.UserInfoActivity
+import com.ck.ckcollar.app.ui.base.CKBaseFragment
+import com.ck.ckcollar.app.utils.CKUtils
+import com.ck.ckcollar.app.utils.Const
+import com.ck.ckcollar.app.utils.networkone.ICallback
+import com.ck.ckcollar.app.utils.networkone.TTHttpClient
+import com.ck.ckcollar.app.utils.networkone.model.TTRequestData
+import com.ck.ckcollar.app.utils.networkone.model.TTRequestParam
+import com.cyclone.shadowsocks.utils.PreferencesUtils
+import com.google.gson.Gson
+import com.tt.kit.base.TTBaseActivity
+import com.tt.kit.model.Data
+import com.tt.kit.model.DataCollection
+
+class MineFragment : CKBaseFragment() {
+
+ lateinit var binding: FragmentMineBinding
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ binding = FragmentMineBinding.inflate(layoutInflater)
+ return binding.root
+ }
+
+ override fun initView() {
+
+ binding.contentBalance.setOnClickListener {
+ toActivity(BalanceActivity::class.java, DataCollection())
+ }
+ binding.conetntPoints.setOnClickListener {
+ toActivity(PointsActivity::class.java, DataCollection())
+ }
+ binding.imageUser.setOnClickListener {
+ toActivity(UserInfoActivity::class.java, DataCollection())
+ }
+ binding.btnUserInfo.setOnClickListener {
+ toActivity(UserInfoActivity::class.java, DataCollection())
+ }
+
+ binding.btnMessage.setOnClickListener {
+ toActivity(MessageCenterActivity::class.java, DataCollection())
+ }
+
+ binding.btnSetting.setOnClickListener {
+ toActivity(SettingActivity::class.java, DataCollection())
+ }
+ binding.btnOpen.setOnClickListener {
+ toActivity(MemberActivity::class.java, DataCollection())
+ }
+
+ binding.btnReturnDevice.setOnClickListener {
+ toActivity(ReturnDeviceActivity::class.java, DataCollection())
+ }
+ binding.btnFeedback.setOnClickListener {
+ toActivity(FeedBackActivity::class.java, DataCollection())
+ }
+ binding.btnCustomerService.setOnClickListener {
+ toActivity(PeopleCustomerActivity::class.java, DataCollection().apply { add(Data("chatType","2")) })
+ }
+ binding.textDeposit.setOnClickListener {
+ if ("0".equals(CKApp.app.userInfo!!.depositStatus)){
+ toActivity(DepositActivity::class.java, DataCollection())
+ }else{
+ toActivity(StartDepositActivity::class.java, DataCollection())
+ }
+ }
+
+ binding.btnAllOrder.setOnClickListener {
+ toActivity(MyOrderActivity::class.java, DataCollection().apply { add(Data("pos","0")) })
+ }
+ binding.btnOrderPayment.setOnClickListener {
+ toActivity(MyOrderActivity::class.java, DataCollection().apply { add(Data("pos","1")) })
+ }
+ binding.btnOrderDelivery.setOnClickListener {
+ toActivity(MyOrderActivity::class.java, DataCollection().apply { add(Data("pos","2")) })
+ }
+ binding.btnOrderReceipt.setOnClickListener {
+ toActivity(MyOrderActivity::class.java, DataCollection().apply { add(Data("pos","3")) })
+ }
+ binding.btnOrderAfterSales.setOnClickListener {
+ toActivity(MyOrderActivity::class.java, DataCollection().apply { add(Data("pos","4")) })
+ }
+
+
+
+ }
+
+ override fun initData() {
+
+ binding.textNick.text = CKApp.app.userInfo?.custName
+ binding.textPhone.text = CKApp.app.userInfo?.phonenumber
+
+ if (!TextUtils.isEmpty(CKApp.app.userInfo?.avatar)){
+ Glide.with(this@MineFragment)
+ .load( CKApp.app.userInfo?.avatar)
+ .placeholder(R.mipmap.image_user_default)
+ .into(binding.imageUser)
+ }
+
+ binding.textBalance.text = CKApp.app.userInfo?.balance.toString()
+ binding.textPoints.text = CKApp.app.userInfo?.points.toString()
+
+ if (CKApp.app.userInfo?.isMember == true){
+ binding.btnOpen.setText(getString(R.string.auto_renewal2))
+ binding.textMemberDate.text = getString(R.string.deadline_date, CKUtils.dataToFormat(CKApp.app.userInfo?.deadlineTime,
+ CKUtils.YYYYMMDD_HHMMSS, CKUtils.YYYYMMDD))
+ binding.textMemberTitle.text = getString(R.string.pet_member2)
+
+ }else{
+ binding.btnOpen.setText(getString(R.string.open_member))
+ binding.textMemberTitle.text = getString(R.string.pet_member)
+ }
+
+
+ }
+
+ override fun onStart() {
+ super.onStart()
+
+ }
+
+ override fun onResume() {
+ super.onResume()
+ getUserInfo()
+ }
+ fun getUserInfo(){
+ TTHttpClient.get(activity as TTBaseActivity,"个人资料", TTRequestParam(),object : ICallback{
+ override fun onSuccess(data: String) {
+ CKApp.app.userInfo = Gson().fromJson(data, UserInfoModel::class.java)
+ PreferencesUtils.putString(activity!!, Const.USER_DATA,data)
+
+ initData()
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ toast(msg)
+ }
+ })
+
+
+ TTHttpClient.get(activity as TTBaseActivity,"未读消息数量", TTRequestParam().apply {
+ add(TTRequestData("accept","true"))
+ },object : ICallback{
+ override fun onSuccess(data: String) {
+ var model = Gson().fromJson(data, UnReadModel::class.java)
+
+ binding.textCount.text = model.unreadCount.toString()
+ if (model.unreadCount == 0){
+ binding.textCount.visibility = View.INVISIBLE
+ }else{
+ binding.textCount.visibility = View.VISIBLE
+ }
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ toast(msg)
+ }
+ })
+
+ }
+
+
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/ui/act/home/fragment/ShopFragment.kt b/app/src/main/java/com/ck/ckcollar/app/ui/act/home/fragment/ShopFragment.kt
new file mode 100644
index 0000000..26f618c
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/ui/act/home/fragment/ShopFragment.kt
@@ -0,0 +1,549 @@
+package com.ck.ckcollar.app.ui.act.home.fragment
+
+import JsonBean
+import android.content.Context
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.AdapterView
+import android.widget.BaseAdapter
+import android.widget.ImageView
+import androidx.recyclerview.widget.GridLayoutManager
+import androidx.recyclerview.widget.LinearLayoutManager
+import androidx.recyclerview.widget.RecyclerView
+import com.bumptech.glide.Glide
+import com.bumptech.glide.load.resource.bitmap.RoundedCorners
+import com.bumptech.glide.request.RequestOptions
+import com.ck.ckcollar.app.R
+import com.ck.ckcollar.app.action.ActionCode
+import com.ck.ckcollar.app.databinding.FragmentShopBinding
+import com.ck.ckcollar.app.databinding.LayoutItemImageBinding
+import com.ck.ckcollar.app.databinding.LayoutItemPetManagerBinding
+import com.ck.ckcollar.app.databinding.LayoutItemShopBinding
+import com.ck.ckcollar.app.databinding.LayoutItemShopHotBinding
+import com.ck.ckcollar.app.databinding.LayoutItemShopItemBinding
+import com.ck.ckcollar.app.listenner.OnItemClickListenner
+import com.ck.ckcollar.app.model.BannarModel
+import com.ck.ckcollar.app.model.CollarModel
+import com.ck.ckcollar.app.model.ImageModel
+import com.ck.ckcollar.app.model.ShopCarCoutTotalModel
+import com.ck.ckcollar.app.model.ShopHotModel
+import com.ck.ckcollar.app.model.ShopItemModel
+import com.ck.ckcollar.app.model.ShopProductModel
+import com.ck.ckcollar.app.ui.act.home.fragment.HomeFragment.ImageAdapter
+import com.ck.ckcollar.app.ui.act.order.MyOrderActivity
+import com.ck.ckcollar.app.ui.act.petmanager.EditPetActivity
+import com.ck.ckcollar.app.ui.act.petmanager.PetManagerActivity.PetAdapter
+import com.ck.ckcollar.app.ui.act.petmanager.ViewPetFileActivity
+import com.ck.ckcollar.app.ui.act.shop.ProductDetailsActivity
+import com.ck.ckcollar.app.ui.act.shop.SearchActivity
+import com.ck.ckcollar.app.ui.act.shop.ShopCarActivity
+import com.ck.ckcollar.app.ui.act.shop.TypeActivity
+import com.ck.ckcollar.app.ui.base.CKBaseActivity
+import com.ck.ckcollar.app.ui.base.CKBaseFragment
+import com.ck.ckcollar.app.utils.networkone.ICallback
+import com.ck.ckcollar.app.utils.networkone.TTHttpClient
+import com.ck.ckcollar.app.utils.networkone.model.TTRequestData
+import com.ck.ckcollar.app.utils.networkone.model.TTRequestParam
+import com.ck.ckcollar.app.widget.CKRoundImageView
+import com.google.gson.Gson
+import com.google.gson.reflect.TypeToken
+import com.scwang.smartrefresh.layout.api.RefreshLayout
+import com.scwang.smartrefresh.layout.listener.OnRefreshLoadMoreListener
+import com.tt.kit.base.TTBaseActivity
+import com.tt.kit.model.Data
+import com.tt.kit.model.DataCollection
+import com.tt.kit.utils.TTUtils
+import com.youth.banner.adapter.BannerAdapter
+import com.youth.banner.indicator.CircleIndicator
+
+class ShopFragment : CKBaseFragment() {
+
+ lateinit var binding: FragmentShopBinding
+ var bannarData = mutableListOf()
+ var itemDatas = mutableListOf()
+ var hotDatas = mutableListOf()
+ var productDatas = mutableListOf()
+
+ lateinit var bannerAdapter: ImageAdapter
+ lateinit var shopItemAdapter: ShopItemAdapter
+ lateinit var hotAdapter: HotAdapter
+ lateinit var productAdapter: ProductAdapter
+
+ var page = 1
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ binding = FragmentShopBinding.inflate(inflater)
+ return binding.root
+ }
+
+ override fun initView() {
+
+ shopItemAdapter = ShopItemAdapter(activity!!, itemDatas)
+ binding.girdView.adapter = shopItemAdapter
+ binding.girdView.onItemClickListener = object : AdapterView.OnItemClickListener {
+ override fun onItemClick(
+ p0: AdapterView<*>?,
+ p1: View?,
+ p2: Int,
+ p3: Long
+ ) {
+
+ toActivity(
+ TypeActivity::class.java,
+ DataCollection().apply {
+ add(
+ Data(
+ "title",
+ itemDatas.get(p2).comType!!
+ )
+ )
+ add(Data("data",itemDatas.get(p2).id.toString()))
+ })
+ }
+ }
+
+ hotAdapter = HotAdapter(this, hotDatas)
+ binding.recyclerView1.layoutManager =
+ LinearLayoutManager(activity!!, RecyclerView.VERTICAL, false)
+ binding.recyclerView1.setHasFixedSize(true)
+ binding.recyclerView1.adapter = hotAdapter
+
+
+ productAdapter = ProductAdapter(activity!!, productDatas, object : OnItemClickListenner {
+ override fun onClick(pos: Int, model: Any) {
+
+ toActivity(ProductDetailsActivity::class.java, DataCollection().apply {
+ add(
+ Data("data", Gson().toJson(model))
+ )
+ })
+ }
+ })
+ binding.recyclerView2.layoutManager =
+ GridLayoutManager(activity!!, 2)
+ binding.recyclerView2.setHasFixedSize(true)
+ binding.recyclerView2.adapter = productAdapter
+
+ binding.textSearch.setOnClickListener {
+ toActivity(SearchActivity::class.java, DataCollection())
+ }
+
+ binding.btnShopCar.setOnClickListener {
+ toActivity(ShopCarActivity::class.java, DataCollection())
+ }
+
+ binding.btnShopOrder.setOnClickListener {
+ toActivity(MyOrderActivity::class.java, DataCollection().apply { add(Data("pos","0")) })
+ }
+
+ binding.refreshLayout.setEnableRefresh(false)
+ binding.refreshLayout.setOnLoadMoreListener {
+ page++
+ getData()
+ }
+
+ binding.refreshLayout2.setEnableLoadMore(false)
+ binding.refreshLayout2.setOnRefreshLoadMoreListener(object : OnRefreshLoadMoreListener{
+ override fun onRefresh(refreshLayout: RefreshLayout) {
+
+ getHot()
+ page = 1
+ getData()
+ getBannar()
+ }
+
+ override fun onLoadMore(refreshLayout: RefreshLayout) {
+
+ }
+ })
+ }
+
+ override fun initData() {
+
+// itemDatas.add(ShopItemModel().apply {
+// icon = R.mipmap.image_shop_item_1
+// text = R.string.shop_item_1
+// })
+// itemDatas.add(ShopItemModel().apply {
+// icon = R.mipmap.image_shop_item_2
+// text = R.string.shop_item_2
+// })
+// itemDatas.add(ShopItemModel().apply {
+// icon = R.mipmap.image_shop_item_3
+// text = R.string.shop_item_3
+// })
+// itemDatas.add(ShopItemModel().apply {
+// icon = R.mipmap.image_shop_item_4
+// text = R.string.shop_item_4
+// })
+// itemDatas.add(ShopItemModel().apply {
+// icon = R.mipmap.image_shop_item_5
+// text = R.string.shop_item_5
+// })
+// itemDatas.add(ShopItemModel().apply {
+// icon = R.mipmap.image_shop_item_6
+// text = R.string.shop_item_6
+// })
+// itemDatas.add(ShopItemModel().apply {
+// icon = R.mipmap.image_shop_item_7
+// text = R.string.shop_item_7
+// })
+// itemDatas.add(ShopItemModel().apply {
+// icon = R.mipmap.image_shop_item_8
+// text = R.string.shop_item_8
+// })
+// itemDatas.add(ShopItemModel().apply {
+// icon = R.mipmap.image_shop_item_9
+// text = R.string.shop_item_9
+// })
+// itemDatas.add(ShopItemModel().apply {
+// icon = R.mipmap.image_shop_item_10
+// text = R.string.shop_item_10
+// })
+
+ getBannar()
+ getType()
+ getHot()
+
+ getData()
+ }
+
+ fun getType() {
+
+ TTHttpClient.get(
+ activity as TTBaseActivity,
+ "商品种类",
+ TTRequestParam(),
+ object : ICallback {
+ override fun onSuccess(data: String) {
+ var mode = Gson().fromJson>(
+ data,
+ object : TypeToken>() {}.type
+ )
+ itemDatas.clear()
+ mode?.let { itemDatas.addAll(it) }
+
+ shopItemAdapter.data = itemDatas
+ shopItemAdapter.notifyDataSetChanged()
+ }
+
+ override fun onFailed(code: String, msg: String) {
+
+ }
+ })
+ }
+
+ fun getHot() {
+ TTHttpClient.get(
+ activity as TTBaseActivity,
+ "精选好物",
+ TTRequestParam(),
+ object : ICallback {
+ override fun onSuccess(data: String) {
+ var mode = Gson().fromJson(data, ShopProductModel::class.java)
+ mode.rows?.let {
+ hotDatas.clear()
+ hotDatas.addAll(it)
+ }
+
+ hotAdapter.data = hotDatas
+ hotAdapter.notifyDataSetChanged()
+
+ binding.refreshLayout2.finishRefresh(true)
+ }
+
+ override fun onFailed(code: String, msg: String) {
+
+ }
+ })
+ }
+
+ fun getData() {
+ TTHttpClient.get(activity as TTBaseActivity, "商品列表", TTRequestParam().apply {
+ add(
+ TTRequestData("pageNum", page)
+ )
+ add(
+ TTRequestData("pageSize", 30)
+ )
+ }, object : ICallback {
+ override fun onSuccess(data: String) {
+ var mode = Gson().fromJson(data, ShopProductModel::class.java)
+ if (page == 1) {
+ productDatas.clear()
+ }
+ if (productDatas.size != mode.total){
+ mode.rows?.let { productDatas.addAll(it) }
+ }
+ productAdapter.data = productDatas
+ productAdapter.notifyDataSetChanged()
+
+ binding.refreshLayout.finishLoadMore(true)
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ binding.refreshLayout.finishLoadMore(true)
+
+ }
+ })
+ }
+
+ override fun onStart() {
+ super.onStart()
+ getCarCount()
+ }
+
+ fun getCarCount() {
+ TTHttpClient.get(
+ activity as TTBaseActivity,
+ "购物车数量和合计",
+ TTRequestParam(),
+ object : ICallback {
+ override fun onSuccess(data: String) {
+ var model = Gson().fromJson(
+ data,
+ ShopCarCoutTotalModel::class.java
+ )
+
+ if (model.count > 0){
+ binding.textCount.text = model.count.toString()
+ binding.textCount.visibility = View.VISIBLE
+ }else{
+ binding.textCount.visibility = View.GONE
+ }
+ }
+
+ override fun onFailed(code: String, msg: String) {
+
+ }
+ })
+ }
+ fun getBannar() {
+ TTHttpClient.get(
+ activity as TTBaseActivity,
+ "商城轮训图",
+ TTRequestParam(),
+ object : ICallback {
+ override fun onSuccess(data: String) {
+ var model = Gson().fromJson>(
+ data,
+ object : TypeToken>(){}.type
+ )
+
+ model?.let {
+ bannarData.clear()
+ bannarData.addAll(model)
+ }
+
+ bannerAdapter = ImageAdapter(activity!!, bannarData, object : OnItemClickListenner {
+ override fun onClick(pos: Int, model: Any) {
+
+ }
+ })
+ binding.banner.addBannerLifecycleObserver(this@ShopFragment)//添加生命周期观察者
+ .setAdapter(bannerAdapter)
+ .setIndicator(CircleIndicator(activity));
+
+ }
+
+ override fun onFailed(code: String, msg: String) {
+
+ }
+ })
+ }
+
+ class ImageAdapter(
+ var context: Context,
+ mDatas: List?,
+ var itemClickListenner: OnItemClickListenner
+ ) :
+ BannerAdapter(mDatas) {
+ //创建ViewHolder,可以用viewType这个字段来区分不同的ViewHolder
+ override fun onCreateHolder(parent: ViewGroup, viewType: Int): BannerViewHolder {
+ val imageView = CKRoundImageView(parent.getContext())
+ //注意,必须设置为match_parent,这个是viewpager2强制要求的
+ imageView.setLayoutParams(
+ ViewGroup.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.MATCH_PARENT
+ )
+ )
+ imageView.setRoundRadius(12f)
+ imageView.setScaleType(ImageView.ScaleType.CENTER_CROP)
+ return BannerViewHolder(imageView)
+ }
+
+ override fun onBindView(
+ holder: BannerViewHolder?,
+ data: BannarModel?,
+ position: Int,
+ size: Int
+ ) {
+ Glide.with(context)
+ .load(data?.bannerUrl)
+ .apply(RequestOptions.bitmapTransform(RoundedCorners(12)))
+ .placeholder(R.mipmap.image_shop_bannar)
+ .into(holder!!.imageView)
+
+ holder!!.imageView.setRoundRadius(20f)
+
+ holder!!.imageView.setTag(position)
+ holder!!.imageView.setOnClickListener {
+ var tag = it.tag as Int
+ itemClickListenner.onClick(tag, mDatas!!.get(tag)!!)
+ }
+ }
+
+ class BannerViewHolder(var imageView: CKRoundImageView) : RecyclerView.ViewHolder(
+ imageView
+ )
+ }
+
+ class ShopItemAdapter(var context: Context, var data: List) : BaseAdapter() {
+
+ override fun getCount(): Int {
+ return data.size
+ }
+
+ override fun getItem(p0: Int): Any? {
+ TODO("Not yet implemented")
+ }
+
+ override fun getItemId(p: Int): Long {
+ return p.toLong()
+ }
+
+ override fun getView(
+ p0: Int,
+ p1: View?,
+ p2: ViewGroup?
+ ): View? {
+ var binding =
+ LayoutItemShopItemBinding.inflate(LayoutInflater.from(context))
+
+ var model = data.get(p0)
+
+
+ binding.text.text = model.comType
+ Glide.with(context)
+ .load( model.imgUrl)
+ .placeholder(R.mipmap.image_default)
+ .into(binding.image)
+ return binding.root
+ }
+ }
+
+ class HotAdapter(var context: CKBaseFragment, var data: List) :
+ RecyclerView.Adapter() {
+ override fun onCreateViewHolder(
+ parent: ViewGroup,
+ viewType: Int
+ ): HotHolder {
+ return HotHolder(
+ LayoutItemShopHotBinding.inflate(
+ LayoutInflater.from(context.activity),
+ parent,
+ false
+ )
+ )
+ }
+
+ override fun onBindViewHolder(
+ holder: HotHolder,
+ position: Int
+ ) {
+
+
+ var model = data.get(position)
+
+ holder.binding.textDesc.text = model.comName
+ holder.binding.textPriec.text = "¥" + model.comPrice
+ holder.binding.textMemberPriec.text =
+ context.getString(R.string.member_price, model.memPrice.toString())
+
+ Glide.with(context)
+ .load( model.comCover)
+ .placeholder(R.mipmap.image_default)
+ .into(holder.binding.image)
+
+ holder.binding.btnView.setTag(position)
+ holder.binding.btnView.setOnClickListener {
+ var tag = it.tag as Int
+ context.toActivity(ProductDetailsActivity::class.java, DataCollection().apply {
+ add(
+ Data("data", Gson().toJson(model))
+ )
+ })
+ }
+ }
+
+ override fun getItemCount(): Int {
+ return data.size
+ }
+
+ class HotHolder(var binding: LayoutItemShopHotBinding) :
+ RecyclerView.ViewHolder(binding.root) {
+
+ }
+
+ }
+
+ class ProductAdapter(
+ var context: Context,
+ var data: List,
+ var itemClickListenner: OnItemClickListenner
+ ) : RecyclerView.Adapter() {
+ override fun onCreateViewHolder(
+ parent: ViewGroup,
+ viewType: Int
+ ): ProductHolder {
+ return ProductHolder(
+ LayoutItemShopBinding.inflate(
+ LayoutInflater.from(context),
+ parent,
+ false
+ )
+ )
+ }
+
+ override fun onBindViewHolder(
+ holder: ProductHolder,
+ position: Int
+ ) {
+
+ var model = data.get(position)
+
+ holder.binding.textDesc.text = model.comName
+ holder.binding.textPriec.text =
+ context.getString(R.string.price_start, model.comPrice.toString())
+ holder.binding.textMemberPriec.text =
+ context.getString(R.string.member_price, model.memPrice.toString())
+
+ Glide.with(context)
+ .load( model.comCover)
+ .placeholder(R.mipmap.image_default)
+ .into(holder.binding.image)
+
+ holder.binding.root.setTag(position)
+ holder.binding.root.setOnClickListener {
+ var tag = it.tag as Int
+ itemClickListenner.onClick(tag, data.get(tag))
+ }
+ }
+
+ override fun getItemCount(): Int {
+ return data.size
+ }
+
+ class ProductHolder(var binding: LayoutItemShopBinding) :
+ RecyclerView.ViewHolder(binding.root) {
+
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/ui/act/login/AgreementActivity.kt b/app/src/main/java/com/ck/ckcollar/app/ui/act/login/AgreementActivity.kt
new file mode 100644
index 0000000..8727635
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/ui/act/login/AgreementActivity.kt
@@ -0,0 +1,71 @@
+package com.ck.ckcollar.app.ui.act.login
+
+import android.os.Bundle
+import android.text.Html
+import android.text.TextUtils
+import android.webkit.WebChromeClient
+import android.webkit.WebViewClient
+import com.ck.ckcollar.app.databinding.ActivityAgreementBinding
+import com.ck.ckcollar.app.model.AgreementModel
+import com.ck.ckcollar.app.ui.base.CKBaseActivity
+import com.ck.ckcollar.app.utils.networkone.ICallback
+import com.ck.ckcollar.app.utils.networkone.TTHttpClient
+import com.ck.ckcollar.app.utils.networkone.model.TTRequestData
+import com.ck.ckcollar.app.utils.networkone.model.TTRequestParam
+import com.google.gson.Gson
+import com.tt.kit.model.Data
+
+class AgreementActivity : CKBaseActivity() {
+ lateinit var binding: ActivityAgreementBinding
+ override fun onCreate(savedInstanceState: Bundle?) {
+ binding = ActivityAgreementBinding.inflate(layoutInflater)
+ setContentView(binding.root)
+ super.onCreate(savedInstanceState)
+ }
+
+ override fun initView() {
+// var webSettings = binding.webView.getSettings();
+// webSettings.setJavaScriptEnabled(true); // 启用JavaScript支持
+// binding.webView.setWebViewClient(WebViewClient()); // 设置WebViewClient处理网页中的链接点击等行为
+// binding.webView.setWebChromeClient(WebChromeClient()); // 可选,用于处理JavaScript的对话框、网站图标等
+// binding.webView.loadUrl("http://baidu.com")
+ }
+
+ override fun initData() {
+ var actionCode = getReceiveParam().get("title")!!.stringValue.toString()
+ setTitleText(actionCode)
+ var type = 0;
+ when(actionCode){
+ "关于我们" ->
+ type = 0
+ "用户协议" ->
+ type = 1
+ "隐私政策" ->
+ type = 2
+ "隐私协议" ->
+ type = 2
+ "芝麻信用协议及授权条款" ->
+ type = 3
+ "用户注销协议" ->
+ type = 4
+
+ }
+ getData(type.toString())
+ }
+
+ fun getData(type : String){
+ TTHttpClient.get(this,"协议", TTRequestParam().apply { add(TTRequestData("type",type)) },object : ICallback{
+ override fun onSuccess(data: String) {
+ var model = Gson().fromJson(data, AgreementModel::class.java)
+
+ if (model != null && !TextUtils.isEmpty(model.pageMsg)){
+ binding.webView.setText(Html.fromHtml(model.pageMsg))
+ }
+ }
+
+ override fun onFailed(code: String, msg: String) {
+
+ }
+ })
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/ui/act/login/BoundPhoneActivity.kt b/app/src/main/java/com/ck/ckcollar/app/ui/act/login/BoundPhoneActivity.kt
new file mode 100644
index 0000000..a83df32
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/ui/act/login/BoundPhoneActivity.kt
@@ -0,0 +1,143 @@
+package com.ck.ckcollar.app.ui.act.login
+
+import android.content.Intent
+import android.os.Bundle
+import android.view.View
+import android.widget.ImageButton
+import com.ck.ckcollar.app.CKApp
+import com.ck.ckcollar.app.R
+import com.ck.ckcollar.app.databinding.ActivitySetingPasswordBinding
+import com.ck.ckcollar.app.model.LoginModel
+import com.ck.ckcollar.app.model.UserInfoModel
+import com.ck.ckcollar.app.ui.base.CKBaseActivity
+import com.ck.ckcollar.app.utils.Const
+import com.ck.ckcollar.app.utils.networkone.ICallback
+import com.ck.ckcollar.app.utils.networkone.TTHttpClient
+import com.ck.ckcollar.app.utils.networkone.model.TTRequestData
+import com.ck.ckcollar.app.utils.networkone.model.TTRequestParam
+import com.cyclone.shadowsocks.utils.PreferencesUtils
+import com.google.gson.Gson
+import com.tt.kit.model.DataCollection
+import org.json.JSONObject
+
+
+class BoundPhoneActivity : CKBaseActivity() {
+
+ private lateinit var binding: ActivitySetingPasswordBinding
+ lateinit var model :LoginModel
+ override fun onCreate(savedInstanceState: Bundle?) {
+ binding = ActivitySetingPasswordBinding.inflate(layoutInflater)
+ setContentView(binding.root)
+ super.onCreate(savedInstanceState)
+
+ setStatusBarColor(R.attr.mainBackground)
+ setTitleText(getString(R.string.bound_phone))
+
+ }
+
+ override fun initView() {
+ findViewById(R.id.btnLeft).visibility = View.GONE
+ binding.btnCode.setOnClickListener {
+ sendCode()
+ }
+ binding.btnComplete.setOnClickListener {
+ submit()
+ }
+
+ }
+
+
+ fun sendCode(){
+ if (binding.editLoginName.isEmpty()){
+ toast(getString(R.string.phone_not_empty))
+ return
+ }
+
+ showProgeassDialog(resources.getString(R.string.send))
+ var param = TTRequestParam().apply {
+ add(TTRequestData("phonenumber",binding.editLoginName.text.toString()))
+ add(TTRequestData("scene","changePhone"))
+ }
+ TTHttpClient.postJson(this,"发送验证码",param,object : ICallback{
+ override fun onSuccess(data: String) {
+ toast(getString(R.string.send_success))
+ binding.btnCode.startCountDown()
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ toast(msg)
+ }
+ })
+
+ }
+ fun submit(){
+ if (binding.editLoginName.isEmpty()){
+ toast(getString(R.string.phone_not_empty))
+ return
+ }
+ if (binding.editCode.isEmpty()){
+ toast(getString(R.string.code_not_empty))
+ return
+ }
+ showProgeassDialog(getString(R.string.bound))
+ TTHttpClient.postJson(this,"微信绑定手机", TTRequestParam().apply {
+ add(TTRequestData("phonenumber",binding.editLoginName.text.toString()))
+ add(TTRequestData("smsCode",binding.editCode.text.toString()))
+ add(TTRequestData("openid",model.openid!!))
+ add(TTRequestData("wxNickname",model.wxNickname!!))
+ add(TTRequestData("wxAvatar",model.wxAvatar!!))
+
+ },object : ICallback{
+ override fun onSuccess(data: String) {
+
+ var token = JSONObject(data).getString("token")
+ PreferencesUtils.putString(
+ this@BoundPhoneActivity,
+ Const.TOKEN, token
+ )
+ CKApp.app.token = token
+
+
+
+ getUserInfo()
+ }
+
+ override fun onFailed(code: String, msg: String) {
+
+ toast(msg)
+ }
+ })
+ }
+
+ fun getUserInfo(){
+ TTHttpClient.get(this,"个人资料", TTRequestParam(),object : ICallback{
+ override fun onSuccess(data: String) {
+ CKApp.app.userInfo = Gson().fromJson(data, UserInfoModel::class.java)
+ PreferencesUtils.putString(this@BoundPhoneActivity, Const.USER_DATA,data)
+ toActivity(RegisterSuccessActivity::class.java, DataCollection())
+ finish()
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ toast(msg)
+ }
+ })
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ binding.btnCode.stopCountDown()
+ }
+ override fun initData() {
+
+ model = Gson().fromJson(getReceiveParam().get("data")!!.stringValue,LoginModel::class.java)
+ }
+
+ override fun onNewIntent(intent: Intent) {
+ super.onNewIntent(intent)
+
+ setIntent(intent)
+ }
+
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/ui/act/login/LoginActivity.kt b/app/src/main/java/com/ck/ckcollar/app/ui/act/login/LoginActivity.kt
new file mode 100644
index 0000000..b7d8268
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/ui/act/login/LoginActivity.kt
@@ -0,0 +1,361 @@
+package com.ck.ckcollar.app.ui.act.login
+
+import android.content.Intent
+import android.os.Bundle
+import android.text.InputType
+import android.text.SpannableStringBuilder
+import android.text.Spanned
+import android.text.TextPaint
+import android.text.TextUtils
+import android.text.method.LinkMovementMethod
+import android.text.style.ClickableSpan
+import android.view.View
+import com.ck.ckcollar.app.CKApp
+import com.ck.ckcollar.app.R
+import com.ck.ckcollar.app.databinding.ActivityLoginBinding
+import com.ck.ckcollar.app.model.LoginModel
+import com.ck.ckcollar.app.model.UserInfoModel
+import com.ck.ckcollar.app.ui.act.home.MainActivity
+import com.ck.ckcollar.app.ui.base.CKBaseActivity
+import com.ck.ckcollar.app.utils.Const
+import com.ck.ckcollar.app.utils.networkone.ICallback
+import com.ck.ckcollar.app.utils.networkone.TTHttpClient
+import com.ck.ckcollar.app.utils.networkone.model.TTRequestData
+import com.ck.ckcollar.app.utils.networkone.model.TTRequestParam
+import com.cyclone.shadowsocks.utils.PreferencesUtils
+import com.google.gson.Gson
+import com.tencent.mm.opensdk.modelmsg.SendAuth
+import com.tencent.mm.opensdk.openapi.IWXAPI
+import com.tencent.mm.opensdk.openapi.WXAPIFactory
+import com.tt.kit.model.Data
+import com.tt.kit.model.DataCollection
+import com.tt.kit.utils.TTUtils
+
+
+class LoginActivity : CKBaseActivity() {
+
+ private lateinit var binding: ActivityLoginBinding
+ var isCheck = false
+ lateinit var api: IWXAPI
+
+ var flag = 0
+ override fun onCreate(savedInstanceState: Bundle?) {
+ binding = ActivityLoginBinding.inflate(layoutInflater)
+ setContentView(binding.root)
+
+ api = WXAPIFactory.createWXAPI(this, Const.WX_APP_ID)
+ CKApp.app.wxJump = 0
+ super.onCreate(savedInstanceState)
+ // api = WXAPIFactory.createWXAPI(this, Const.WX_APP_ID, false);
+ setStatusBarColor(R.attr.mainBackground)
+ //检测权限
+ checkAppPermissions()
+
+ }
+
+ override fun initView() {
+
+ binding.btnRegister.setOnClickListener {
+ toActivity(RegisterActivity::class.java, DataCollection())
+ }
+ binding.btnLost.setOnClickListener {
+ toActivity(LostActivity::class.java, DataCollection())
+ }
+
+ binding.btnLogin.setOnClickListener {
+ login()
+ }
+
+ binding.btnCodeLogin.setOnClickListener {
+ binding.btnCodeLogin.setTextColor(getColor2(R.attr.appTextColor))
+ binding.btnPasswordLogin.setTextColor(getColor2(R.attr.appTextSecondColor))
+
+ binding.imageCode.setImageResource(R.mipmap.image_login_code)
+ binding.editLoginPwd.setHint(R.string.input_code)
+ binding.editLoginPwd.inputType = InputType.TYPE_CLASS_TEXT
+
+ binding.editLoginPwd.setText("")
+
+ binding.btnSendCode.visibility = View.VISIBLE
+ binding.view.visibility = View.GONE
+ binding.btnLost.visibility = View.GONE
+ binding.btnRegister.setText(R.string.register_now)
+
+ flag = 0
+ }
+ binding.btnPasswordLogin.setOnClickListener {
+ binding.btnPasswordLogin.setTextColor(getColor2(R.attr.appTextColor))
+ binding.btnCodeLogin.setTextColor(getColor2(R.attr.appTextSecondColor))
+
+ binding.imageCode.setImageResource(R.mipmap.image_login_password)
+ binding.editLoginPwd.setHint(R.string.input_login_password)
+ binding.editLoginPwd.inputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_PASSWORD
+
+ binding.editLoginPwd.setText("")
+
+ binding.btnSendCode.visibility = View.GONE
+ binding.view.visibility = View.VISIBLE
+ binding.btnLost.visibility = View.VISIBLE
+ binding.btnRegister.setText(R.string.register)
+
+ flag = 1
+ }
+
+ val text = "我已阅读并同意《用户服务协议》和《隐私政策》";
+ val spannable = SpannableStringBuilder(text)
+ // 获取需要应用样式的文本的开始和结束索引
+ val start1 = text.indexOf("《用户服务协议》")
+ val end1 = start1 + "《用户服务协议》".length
+ val start2 = text.indexOf("《隐私政策》")
+ val end2 = start2 + "《隐私政策》".length
+ var clickableSpan = object : ClickableSpan() {
+ override fun onClick(v: View) {
+ toActivity(
+ AgreementActivity::class.java,
+ DataCollection().apply { add(Data("title", "用户协议")) })
+ }
+
+ override fun updateDrawState(ds: TextPaint) {
+ ds.setColor(getColor2(R.attr.appTextColor))
+ }
+ };
+ var clickableSpan2 = object : ClickableSpan() {
+ override fun onClick(v: View) {
+ toActivity(
+ AgreementActivity::class.java,
+ DataCollection().apply { add(Data("title", "隐私政策")) })
+ }
+
+ override fun updateDrawState(ds: TextPaint) {
+ ds.setColor(getColor2(R.attr.appTextColor))
+ }
+ };
+
+ binding.textAgreement.setMovementMethod(LinkMovementMethod.getInstance());
+ binding.textAgreement.setHighlightColor(resources.getColor(R.color.transparent))
+ // 应用样式
+ spannable.setSpan(clickableSpan, start1, end1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
+ spannable.setSpan(clickableSpan2, start2, end2, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
+
+
+ binding.textAgreement.setText(spannable)
+
+ setCheckUI()
+ binding.btnCheck.setOnClickListener {
+ isCheck = !isCheck
+ setCheckUI()
+ PreferencesUtils.putBoolean(this@LoginActivity, Const.AGREEMENT_CHECK, isCheck)
+ }
+
+ binding.btnSendCode.setOnClickListener {
+
+ sendCode()
+ }
+ binding.btnWX.setOnClickListener {
+ val req = SendAuth.Req()
+ req.scope = "snsapi_userinfo" // 只能填 snsapi_userinfo
+ req.state = "wechat_sdk_demo_test"
+ api.sendReq(req)
+ }
+ }
+
+ fun sendCode() {
+ if (binding.editLoginName.isEmpty()) {
+ toast(getString(R.string.phone_not_empty))
+ return
+ }
+
+ showProgeassDialog(getString(R.string.send))
+ TTHttpClient.postJson(this,"发送验证码", TTRequestParam().apply {
+ add(TTRequestData("phonenumber",binding.editLoginName.text.toString()))
+ add(TTRequestData("scene","login"))
+ },object : ICallback{
+ override fun onSuccess(data: String) {
+ binding.btnSendCode.startCountDown()
+ toast(getString(R.string.send_success))
+
+
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ toast(msg)
+ }
+ })
+ }
+
+ fun setCheckUI() {
+ if (isCheck) {
+ binding.check.setImageResource(R.mipmap.image_check_select)
+ } else {
+ binding.check.setImageResource(R.mipmap.image_check_unselect)
+ }
+ }
+
+ fun login() {
+ if (!isCheck) {
+ toast(getString(R.string.alert_agreement))
+ return
+ }
+ if (binding.editLoginName.isEmpty()) {
+ toast(getString(R.string.phone_not_empty))
+ return
+ }
+ if (binding.editLoginPwd.isEmpty()) {
+ if (flag == 1) {
+ toast(getString(R.string.password_not_empty))
+ } else {
+ toast(getString(R.string.code_not_empty))
+ }
+ return
+ }
+
+ var passWord = if (binding.btnSendCode.visibility == View.GONE) {
+ binding.editLoginPwd.text.toString()
+ } else {
+ ""
+ }
+
+ var code = if (binding.btnSendCode.visibility == View.GONE) {
+ ""
+ } else {
+ binding.editLoginPwd.text.toString()
+ }
+
+ if (binding.btnSendCode.visibility != View.GONE){
+ TTHttpClient.postJson(this, "验证码登录", TTRequestParam().apply {
+ add(TTRequestData("phonenumber", binding.editLoginName.text.toString()))
+ add(TTRequestData("smsCode", code))
+ }, object : ICallback {
+ override fun onSuccess(data: String) {
+
+ try {
+ var model = Gson().fromJson(data, LoginModel::class.java)
+ PreferencesUtils.putString(
+ this@LoginActivity,
+ Const.TOKEN, model.token.toString()
+ )
+ CKApp.app.token = model.token.toString()
+
+ getUserInfo()
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+
+
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ toast(msg)
+ }
+ })
+ }else{
+ TTHttpClient.postJson(this, "登录", TTRequestParam().apply {
+ add(TTRequestData("username", binding.editLoginName.text.toString()))
+ add(TTRequestData("password", passWord))
+ add(TTRequestData("code", code))
+ add(TTRequestData("uuid", TTUtils.getDeviceId(this@LoginActivity).toString()))
+
+ }, object : ICallback {
+ override fun onSuccess(data: String) {
+
+ try {
+ var model = Gson().fromJson(data, LoginModel::class.java)
+ PreferencesUtils.putString(
+ this@LoginActivity,
+ Const.TOKEN, model.token.toString()
+ )
+ CKApp.app.token = model.token.toString()
+
+ getUserInfo()
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+
+
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ toast(msg)
+ }
+ })
+ }
+
+
+ }
+
+ fun getUserInfo(){
+ TTHttpClient.get(this,"个人资料", TTRequestParam(),object : ICallback{
+ override fun onSuccess(data: String) {
+ CKApp.app.userInfo = Gson().fromJson(data, UserInfoModel::class.java)
+ PreferencesUtils.putString(this@LoginActivity, Const.USER_DATA,data)
+
+ toActivity(MainActivity::class.java, DataCollection())
+
+
+ finish()
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ toast(msg)
+ }
+ })
+ }
+
+ override fun initData() {
+
+
+ binding.editLoginName.setText(PreferencesUtils.getString(this, Const.LOGIN_NAME, ""))
+
+ isCheck = PreferencesUtils.getBolean(this, Const.AGREEMENT_CHECK, false) as Boolean
+
+ }
+
+ override fun onNewIntent(intent: Intent) {
+ super.onNewIntent(intent)
+
+ setIntent(intent)
+
+ var code = intent.extras?.getString("code")
+ if (!TextUtils.isEmpty(code)){
+ wxLogin(code!!)
+ }
+ }
+
+ fun wxLogin(code : String){
+ showProgeassDialog(getString(R.string.login))
+ TTHttpClient.postJson(this,"微信登录", TTRequestParam().apply { add(TTRequestData("code",code)) },object : ICallback{
+ override fun onSuccess(data: String) {
+ try {
+ var model = Gson().fromJson(data, LoginModel::class.java)
+
+ if (model.needBindPhone){
+
+ toActivity(BoundPhoneActivity::class.java, DataCollection().apply {
+ add(Data("data",Gson().toJson(model)))
+ })
+ finish()
+
+ }else{
+ PreferencesUtils.putString(
+ this@LoginActivity,
+ Const.TOKEN, model.token.toString()
+ )
+ CKApp.app.token = model.token.toString()
+
+ getUserInfo()
+ }
+
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ toast(msg)
+ }
+ })
+ }
+
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/ui/act/login/LostActivity.kt b/app/src/main/java/com/ck/ckcollar/app/ui/act/login/LostActivity.kt
new file mode 100644
index 0000000..9b37188
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/ui/act/login/LostActivity.kt
@@ -0,0 +1,120 @@
+package com.ck.ckcollar.app.ui.act.login
+
+import android.content.Intent
+import android.os.Bundle
+import com.bumptech.glide.Glide
+import com.ck.ckcollar.app.R
+import com.ck.ckcollar.app.databinding.ActivityLoginBinding
+import com.ck.ckcollar.app.databinding.ActivityLostBinding
+import com.ck.ckcollar.app.databinding.ActivityRegisterBinding
+import com.ck.ckcollar.app.ui.act.BlueToothActivity
+import com.ck.ckcollar.app.ui.act.DemoActivity
+import com.ck.ckcollar.app.ui.act.petmanager.MapLocationActivity
+import com.ck.ckcollar.app.ui.act.WifiListActivity
+import com.ck.ckcollar.app.ui.act.home.MainActivity
+import com.ck.ckcollar.app.ui.base.CKBaseActivity
+import com.ck.ckcollar.app.utils.Const
+import com.ck.ckcollar.app.utils.networkone.ICallback
+import com.ck.ckcollar.app.utils.networkone.TTHttpClient
+import com.ck.ckcollar.app.utils.networkone.model.TTRequestData
+import com.ck.ckcollar.app.utils.networkone.model.TTRequestParam
+
+
+class LostActivity : CKBaseActivity() {
+
+ private lateinit var binding: ActivityLostBinding
+ override fun onCreate(savedInstanceState: Bundle?) {
+ binding = ActivityLostBinding.inflate(layoutInflater)
+ setContentView(binding.root)
+ super.onCreate(savedInstanceState)
+
+ setTitleText(getString(R.string.lost))
+ }
+
+ override fun initView() {
+ binding.btnCode.setOnClickListener {
+ sendCode()
+
+ }
+ binding.btnRegister.setOnClickListener {
+ lost()
+ }
+
+ }
+
+
+ fun sendCode(){
+ if (binding.editLoginName.isEmpty()){
+ toast(getString(R.string.phone_not_empty))
+ return
+ }
+
+ showProgeassDialog(resources.getString(R.string.send))
+ var param = TTRequestParam().apply {
+ add(TTRequestData("phonenumber",binding.editLoginName.text.toString()))
+ add(TTRequestData("scene","forgot"))
+ }
+ TTHttpClient.postJson(this,"发送验证码",param,object : ICallback{
+ override fun onSuccess(data: String) {
+ toast(getString(R.string.send_success))
+ binding.btnCode.startCountDown()
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ toast(msg)
+ }
+ })
+
+ }
+
+ fun lost(){
+ if (binding.editLoginName.isEmpty()){
+ toast(getString(R.string.phone_not_empty))
+ return
+ }
+ if (binding.editCode.isEmpty()){
+ toast(getString(R.string.code_not_empty))
+ return
+ }
+ if (binding.editLoginPwd.isEmpty()){
+ toast(getString(R.string.password_not_empty))
+ return
+ }
+ if (!binding.editLoginPwd.text.toString().equals(binding.editLoginPwdConfirm.text.toString())){
+ toast(getString(R.string.confirm_password_not_both))
+ return
+ }
+ showProgeassDialog(getString(R.string.submit))
+ TTHttpClient.postJson(this,"找回密码", TTRequestParam().apply {
+ add(TTRequestData("phonenumber",binding.editLoginName.text.toString()))
+ add(TTRequestData("smsCode",binding.editCode.text.toString()))
+ add(TTRequestData("newPassword",binding.editLoginPwd.text.toString()))
+ add(TTRequestData("confirmPassword",binding.editLoginPwdConfirm.text.toString()))
+ },object : ICallback{
+ override fun onSuccess(data: String) {
+ toast(getString(R.string.lost_success))
+ finish()
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ toast(msg)
+ }
+ })
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ binding.btnCode.stopCountDown()
+ }
+ override fun initData() {
+
+ }
+
+ override fun onNewIntent(intent: Intent) {
+ super.onNewIntent(intent)
+
+ setIntent(intent)
+ }
+
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/ui/act/login/RegisterActivity.kt b/app/src/main/java/com/ck/ckcollar/app/ui/act/login/RegisterActivity.kt
new file mode 100644
index 0000000..4e8daa7
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/ui/act/login/RegisterActivity.kt
@@ -0,0 +1,174 @@
+package com.ck.ckcollar.app.ui.act.login
+
+import android.content.Intent
+import android.os.Build
+import android.os.Bundle
+import android.view.WindowManager
+import androidx.core.view.WindowCompat
+import com.bumptech.glide.Glide
+import com.ck.ckcollar.app.CKApp
+import com.ck.ckcollar.app.R
+import com.ck.ckcollar.app.databinding.ActivityLoginBinding
+import com.ck.ckcollar.app.databinding.ActivityRegisterBinding
+import com.ck.ckcollar.app.model.LoginModel
+import com.ck.ckcollar.app.model.UserInfoModel
+import com.ck.ckcollar.app.ui.act.BlueToothActivity
+import com.ck.ckcollar.app.ui.act.DemoActivity
+import com.ck.ckcollar.app.ui.act.petmanager.MapLocationActivity
+import com.ck.ckcollar.app.ui.act.WifiListActivity
+import com.ck.ckcollar.app.ui.act.home.MainActivity
+import com.ck.ckcollar.app.ui.base.CKBaseActivity
+import com.ck.ckcollar.app.utils.Const
+import com.ck.ckcollar.app.utils.networkone.ICallback
+import com.ck.ckcollar.app.utils.networkone.TTHttpClient
+import com.ck.ckcollar.app.utils.networkone.model.TTRequestData
+import com.ck.ckcollar.app.utils.networkone.model.TTRequestParam
+import com.cyclone.shadowsocks.utils.PreferencesUtils
+import com.google.gson.Gson
+import com.tt.kit.model.DataCollection
+import com.tt.kit.utils.TTUtils
+
+
+class RegisterActivity : CKBaseActivity() {
+
+ private lateinit var binding: ActivityRegisterBinding
+ override fun onCreate(savedInstanceState: Bundle?) {
+ binding = ActivityRegisterBinding.inflate(layoutInflater)
+ setContentView(binding.root)
+ super.onCreate(savedInstanceState)
+
+ setStatusBarColor(R.attr.mainBackground)
+ setTitleText(getString(R.string.register))
+ }
+
+ override fun initView() {
+ binding.btnCode.setOnClickListener {
+ sendCode()
+ }
+ binding.btnRegister.setOnClickListener {
+ register()
+ }
+
+ }
+
+ fun sendCode(){
+ if (binding.editLoginName.isEmpty()){
+ toast(getString(R.string.phone_not_empty))
+ return
+ }
+
+ showProgeassDialog(resources.getString(R.string.send))
+ var param = TTRequestParam().apply {
+ add(TTRequestData("phonenumber",binding.editLoginName.text.toString()))
+ add(TTRequestData("scene","register"))
+ }
+ TTHttpClient.postJson(this,"发送验证码",param,object : ICallback{
+ override fun onSuccess(data: String) {
+ toast(getString(R.string.send_success))
+ binding.btnCode.startCountDown()
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ toast(msg)
+ }
+ })
+
+ }
+ fun register(){
+ if (binding.editLoginName.isEmpty()){
+ toast(getString(R.string.phone_not_empty))
+ return
+ }
+ if (binding.editCode.isEmpty()){
+ toast(getString(R.string.code_not_empty))
+ return
+ }
+ if (binding.editLoginPwd.isEmpty()){
+ toast(getString(R.string.password_not_empty))
+ return
+ }
+ if (!binding.editLoginPwd.text.toString().equals(binding.editLoginPwdConfirm.text.toString())){
+ toast(getString(R.string.confirm_password_not_both))
+ return
+ }
+ showProgeassDialog(getString(R.string.register))
+ TTHttpClient.postJson(this,"注册", TTRequestParam().apply {
+ add(TTRequestData("phonenumber",binding.editLoginName.text.toString()))
+ add(TTRequestData("smsCode",binding.editCode.text.toString()))
+ add(TTRequestData("password",binding.editLoginPwd.text.toString()))
+ add(TTRequestData("confirmPassword",binding.editLoginPwdConfirm.text.toString()))
+ },object : ICallback{
+ override fun onSuccess(data: String) {
+ toast(getString(R.string.register_success))
+ login()
+ }
+
+ override fun onFailed(code: String, msg: String) {
+
+ toast(msg)
+ }
+ })
+ }
+
+
+ fun login(){
+ TTHttpClient.postJson(this, "登录",TTRequestParam().apply {
+ add(TTRequestData("username", binding.editLoginName.text.toString()))
+ add(TTRequestData("password", binding.editLoginPwdConfirm.text.toString()))
+ add(TTRequestData("code", ""))
+ add(TTRequestData("uuid", TTUtils.getDeviceId(this@RegisterActivity).toString()))
+ }, object : ICallback {
+ override fun onSuccess(data: String) {
+
+ try {
+ var model = Gson().fromJson(data, LoginModel::class.java)
+ PreferencesUtils.putString(
+ this@RegisterActivity,
+ Const.TOKEN, model.token.toString()
+ )
+ CKApp.app.token = model.token.toString()
+
+ getUserInfo()
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+
+
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ toast(msg)
+ }
+ })
+ }
+
+ fun getUserInfo(){
+ TTHttpClient.get(this,"个人资料", TTRequestParam(),object : ICallback{
+ override fun onSuccess(data: String) {
+ CKApp.app.userInfo = Gson().fromJson(data, UserInfoModel::class.java)
+ PreferencesUtils.putString(this@RegisterActivity, Const.USER_DATA,data)
+ toActivity(RegisterSuccessActivity::class.java, DataCollection())
+ finish()
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ toast(msg)
+ }
+ })
+ }
+ override fun onDestroy() {
+ super.onDestroy()
+ binding.btnCode.stopCountDown()
+ }
+ override fun initData() {
+
+ }
+
+ override fun onNewIntent(intent: Intent) {
+ super.onNewIntent(intent)
+
+ setIntent(intent)
+ }
+
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/ui/act/login/RegisterSuccessActivity.kt b/app/src/main/java/com/ck/ckcollar/app/ui/act/login/RegisterSuccessActivity.kt
new file mode 100644
index 0000000..f29feb4
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/ui/act/login/RegisterSuccessActivity.kt
@@ -0,0 +1,37 @@
+package com.ck.ckcollar.app.ui.act.login
+
+import android.os.Bundle
+import com.ck.ckcollar.app.databinding.ActivityRegisterSuccessBinding
+import com.ck.ckcollar.app.ui.act.home.MainActivity
+import com.ck.ckcollar.app.ui.base.CKBaseActivity
+import com.tt.kit.model.DataCollection
+import com.ck.ckcollar.app.widget.CKCountDownButton
+
+class RegisterSuccessActivity : CKBaseActivity() {
+
+ lateinit var binding: ActivityRegisterSuccessBinding
+ override fun onCreate(savedInstanceState: Bundle?) {
+ binding = ActivityRegisterSuccessBinding.inflate(layoutInflater)
+ setContentView(binding.root)
+ super.onCreate(savedInstanceState)
+
+ }
+
+
+ override fun initView() {
+ binding.btnGoHome.onCountDownListenner = object : CKCountDownButton.OnCountDownListenner{
+ override fun onClick() {
+ toActivity(MainActivity::class.java, DataCollection())
+ }
+ }
+ binding.btnGoHome.startCountDown()
+ binding.btnGoHome.setOnClickListener {
+ toActivity(MainActivity::class.java, DataCollection())
+ }
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ binding.btnGoHome.stopCountDown()
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/ui/act/member/MemberActivity.kt b/app/src/main/java/com/ck/ckcollar/app/ui/act/member/MemberActivity.kt
new file mode 100644
index 0000000..c8a0f94
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/ui/act/member/MemberActivity.kt
@@ -0,0 +1,109 @@
+package com.ck.ckcollar.app.ui.act.member
+
+import android.content.res.ColorStateList
+import android.graphics.Color
+import android.os.Bundle
+import android.view.View
+import android.widget.ImageButton
+import com.ck.ckcollar.app.CKApp
+import com.ck.ckcollar.app.R
+import com.ck.ckcollar.app.databinding.ActivityMemberBinding
+import com.ck.ckcollar.app.model.MemberModel
+import com.ck.ckcollar.app.model.MemberPriceModel
+import com.ck.ckcollar.app.model.PointsModel
+import com.ck.ckcollar.app.model.RecordModel
+import com.ck.ckcollar.app.model.UserInfoModel
+import com.ck.ckcollar.app.ui.base.CKBaseActivity
+import com.ck.ckcollar.app.utils.CKUtils
+import com.ck.ckcollar.app.utils.networkone.ICallback
+import com.ck.ckcollar.app.utils.networkone.TTHttpClient
+import com.ck.ckcollar.app.utils.networkone.model.TTRequestParam
+import com.google.gson.Gson
+import com.google.gson.reflect.TypeToken
+import com.gyf.immersionbar.ImmersionBar
+import com.tt.kit.base.TTBaseActivity
+import com.tt.kit.model.DataCollection
+
+class MemberActivity : CKBaseActivity() {
+
+ lateinit var binding: ActivityMemberBinding
+ override fun onCreate(savedInstanceState: Bundle?) {
+ binding = ActivityMemberBinding.inflate(layoutInflater)
+ setContentView(binding.root)
+// ImmersionBar.with(this)
+// .statusBarDarkFont(true)
+// .init()
+ super.onCreate(savedInstanceState)
+
+
+ setActionBarColor(resources.getColor(R.color.color_252132))
+ setStatusBarColor2(resources.getColor(R.color.color_252132))
+
+ findViewById(R.id.btnLeft).imageTintList = ColorStateList.valueOf(Color.WHITE)
+ setTitleTextColor(resources.getColor(R.color.white))
+
+ setTitleText(getString(R.string.member))
+ }
+
+ override fun initView() {
+
+ binding.btnOpen.setOnClickListener {
+ toActivity(OpenMemberActivity::class.java, DataCollection())
+ }
+ binding.btnOpen2.setOnClickListener {
+ toActivity(OpenMemberActivity::class.java, DataCollection())
+ }
+ }
+
+ override fun initData() {
+
+
+ }
+
+ override fun onStart() {
+ super.onStart()
+ getMemberInfo()
+ }
+
+ fun getInfo() {
+ TTHttpClient.get(this, "会员套餐列表", TTRequestParam(), object : ICallback {
+ override fun onSuccess(data: String) {
+ var model = Gson().fromJson>(data, object : TypeToken>(){}.type)
+
+ if (model.size > 0){
+ binding.textMoney.text = model.get(0).actualPrice.toString()
+ }
+
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ toast(msg)
+ }
+ })
+ }
+
+ fun getMemberInfo(){
+ TTHttpClient.get(this,"个人资料", TTRequestParam(),object : ICallback{
+ override fun onSuccess(data: String) {
+ var model = Gson().fromJson(data, UserInfoModel::class.java)
+
+
+ if (model.isMember == true){
+ binding.textMemberDate.text = getString(R.string.deadline_date, CKUtils.dataToFormat(model.deadlineTime,
+ CKUtils.YYYYMMDD_HHMMSS, CKUtils.YYYYMMDD))
+ binding.conetnt1.visibility = View.GONE
+ binding.conetnt2.visibility = View.VISIBLE
+ }else{
+ binding.conetnt1.visibility = View.VISIBLE
+ binding.conetnt2.visibility = View.GONE
+
+ getInfo()
+ }
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ toast(msg)
+ }
+ })
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/ui/act/member/OpenMemberActivity.kt b/app/src/main/java/com/ck/ckcollar/app/ui/act/member/OpenMemberActivity.kt
new file mode 100644
index 0000000..7891857
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/ui/act/member/OpenMemberActivity.kt
@@ -0,0 +1,242 @@
+package com.ck.ckcollar.app.ui.act.member
+
+import android.content.res.ColorStateList
+import android.graphics.Color
+import android.os.Bundle
+import android.text.TextUtils
+import android.view.View
+import android.view.ViewGroup
+import android.widget.LinearLayout
+import android.widget.TextView
+import com.alipay.sdk.app.PayTask
+import com.ck.ckcollar.app.R
+import com.ck.ckcollar.app.databinding.ActivityMemberBinding
+import com.ck.ckcollar.app.databinding.ActivityOpenMemberBinding
+import com.ck.ckcollar.app.databinding.LayoutItemMemberBinding
+import com.ck.ckcollar.app.model.MemberModel
+import com.ck.ckcollar.app.model.MemberPriceModel
+import com.ck.ckcollar.app.model.PayResult
+import com.ck.ckcollar.app.ui.act.shop.PayPasswordBottomFragment
+import com.ck.ckcollar.app.ui.base.CKBaseActivity
+import com.ck.ckcollar.app.ui.base.CKLHBaseActionBarActivity
+import com.ck.ckcollar.app.utils.networkone.ICallback
+import com.ck.ckcollar.app.utils.networkone.TTHttpClient
+import com.ck.ckcollar.app.utils.networkone.model.TTRequestData
+import com.ck.ckcollar.app.utils.networkone.model.TTRequestParam
+import com.google.gson.Gson
+import com.google.gson.reflect.TypeToken
+import com.gyf.immersionbar.ImmersionBar
+import com.tt.kit.utils.TTUtils
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.GlobalScope
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
+
+class OpenMemberActivity : CKLHBaseActionBarActivity() {
+
+ lateinit var binding: ActivityOpenMemberBinding
+ var data = listOf()
+ var pos = -1
+ var isAuto = false
+ var payType = "1"
+ override fun onCreate(savedInstanceState: Bundle?) {
+ binding = ActivityOpenMemberBinding.inflate(layoutInflater)
+ setContentView(binding.root)
+ ImmersionBar.with(this)
+ .statusBarDarkFont(true)
+ .init()
+ super.onCreate(savedInstanceState)
+
+
+ setTitleText(getString(R.string.open_member))
+ }
+
+ override fun initView() {
+
+ //setPriceUI()
+
+ binding.btnAli.setOnClickListener {
+ binding.image1.setImageResource(R.mipmap.image_address_check_select)
+ binding.image2.setImageResource(R.mipmap.image_address_check_narmal)
+ binding.image3.setImageResource(R.mipmap.image_address_check_narmal)
+ payType = "1"
+ }
+ binding.btnWX.setOnClickListener {
+ binding.image1.setImageResource(R.mipmap.image_address_check_narmal)
+ binding.image2.setImageResource(R.mipmap.image_address_check_select)
+ binding.image3.setImageResource(R.mipmap.image_address_check_narmal)
+ payType = "0"
+ }
+ binding.btnBalance.setOnClickListener {
+ binding.image1.setImageResource(R.mipmap.image_address_check_narmal)
+ binding.image2.setImageResource(R.mipmap.image_address_check_narmal)
+ binding.image3.setImageResource(R.mipmap.image_address_check_select)
+
+ payType = "2"
+ }
+
+ binding.btnAuto.setOnClickListener {
+ isAuto = !isAuto
+ if (isAuto){
+ binding.check.setImageResource(R.mipmap.image_address_check_select)
+ }else{
+ binding.check.setImageResource(R.mipmap.image_address_check_narmal)
+ }
+ }
+
+ binding.btnPay.setOnClickListener {
+
+ if ("2".equals(payType)){
+ if (pos == -1){
+ toast(getString(R.string.no_pack_data))
+ return@setOnClickListener
+ }
+ var passwordBottomFragment = PayPasswordBottomFragment(data.get(pos).actualPrice.toString(), "余额",object : PayPasswordBottomFragment.PasswordCallBack{
+ override fun callBack(password: String) {
+
+ limit(password)
+ }
+ })
+
+ passwordBottomFragment.show(supportFragmentManager, "PayPasswordBottomFragment")
+ }else{
+ limit("")
+ }
+
+
+ }
+ }
+
+ override fun initData() {
+
+ getList()
+
+ }
+
+ fun limit(payPassword:String){
+
+ if (pos == -1){
+ toast(getString(R.string.no_pack_data))
+ return
+ }
+
+ var param = TTRequestParam().apply {
+ add(TTRequestData("packageId",data.get(pos).id))
+ add(TTRequestData("packageName",data.get(pos).packageName!!))
+ add(TTRequestData("durationMonths",data.get(pos).durationMonths))
+ add(TTRequestData("payAmount",data.get(pos).actualPrice))
+ add(TTRequestData("payType",payType))
+ add(TTRequestData("payPassword",payPassword))
+ }
+ showProgeassDialog(getString(R.string.order))
+ TTHttpClient.postJson(this,"开通会员",param,object : ICallback{
+ override fun onSuccess(data: String) {
+ var model = Gson().fromJson(data, MemberModel::class.java)
+ if ("1".equals(payType)){
+ aliPay(model.orderStr!!)
+ }else{
+ toast(getString(R.string.payment_success))
+ finish()
+ }
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ toast(msg)
+ }
+ })
+ }
+
+ fun getList() {
+ showProgeassDialog(getString(R.string.search))
+ TTHttpClient.get(this, "会员套餐列表", TTRequestParam(), object : ICallback {
+ override fun onSuccess(data: String) {
+ this@OpenMemberActivity.data = Gson().fromJson>(data, object : TypeToken>(){}.type)
+
+ setPriceUI()
+
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ toast(msg)
+ }
+ })
+ }
+
+ fun setPriceUI(){
+ binding.content.removeAllViews()
+ var tag = 0;
+ for (model in data){
+ var itemMemberBinding = LayoutItemMemberBinding.inflate(layoutInflater)
+ itemMemberBinding.root.tag = tag
+ itemMemberBinding.root.layoutParams = LinearLayout.LayoutParams(TTUtils.dpToPx(this,135).toInt(),
+ TTUtils.dpToPx(this,172).toInt())
+
+ itemMemberBinding.textMonth.text = getString(R.string.month_vip,model.durationMonths.toString())
+ itemMemberBinding.textMoney.text = model.actualPrice.toString()
+ itemMemberBinding.textGoNoMoney.text = getString(R.string.go_on_month_vip,model.actualPrice.toString())
+
+ itemMemberBinding.root.setOnClickListener {
+ var tag = it.tag as Int
+
+ it.setBackgroundResource(R.drawable.bg_item_member_radius_16)
+
+ setTextColor(it,resources.getColor(R.color.color_7B4B12))
+ if (pos >= 0){
+ binding.content.getChildAt(pos).setBackgroundResource(R.drawable.bg_item_member_normal)
+ setTextColor(binding.content.getChildAt(pos),resources.getColor(R.color.textColor))
+
+ }
+ if (pos == tag){
+ pos = -1
+ }else{
+ pos = tag
+ }
+
+ }
+ tag++
+ binding.content.addView(itemMemberBinding.root)
+
+ }
+
+ for (i in 0..binding.content.childCount - 1){
+ var params = binding.content.getChildAt(i).layoutParams as ViewGroup.MarginLayoutParams
+ params.rightMargin = TTUtils.dpToPx(this,10).toInt()
+
+ }
+ }
+
+ fun setTextColor(view : View, color :Int) {
+ var textAmount = view.findViewById(R.id.textMoney)
+ var textMonth = view.findViewById(R.id.textMonth)
+ var textGoNoMoney = view.findViewById(R.id.textGoNoMoney)
+ var textUnit = view.findViewById(R.id.textUnit)
+
+
+ textAmount.setTextColor(color)
+ textMonth.setTextColor(color)
+ textGoNoMoney.setTextColor(color)
+ textUnit.setTextColor(color)
+ }
+
+ fun aliPay(orderStr : String){
+ GlobalScope.launch(Dispatchers.IO){
+
+ val alipay = PayTask(this@OpenMemberActivity)
+ val result = alipay.payV2(orderStr, true)
+
+ var payResult = PayResult(result)
+
+ val resultStatus: String? = payResult.resultStatus
+ withContext(Dispatchers.Main) {
+ // 判断resultStatus 为9000则代表支付成功
+ if (TextUtils.equals(resultStatus, "9000")) {
+ // 该笔订单是否真实支付成功,需要依赖服务端的异步通知。
+ toast(getString(R.string.payment_success))
+ finish()
+ }else{
+ toast(getString(R.string.payment_faild))
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/ui/act/message/MessageCenterActivity.kt b/app/src/main/java/com/ck/ckcollar/app/ui/act/message/MessageCenterActivity.kt
new file mode 100644
index 0000000..629bd31
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/ui/act/message/MessageCenterActivity.kt
@@ -0,0 +1,152 @@
+package com.ck.ckcollar.app.ui.act.message
+
+import android.content.Context
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.recyclerview.widget.LinearLayoutManager
+import androidx.recyclerview.widget.RecyclerView
+import com.ck.ckcollar.app.R
+import com.ck.ckcollar.app.databinding.ActivityMessageCenterBinding
+import com.ck.ckcollar.app.databinding.LayoutItemMessageBinding
+import com.ck.ckcollar.app.databinding.LayoutItemRecordsBinding
+import com.ck.ckcollar.app.listenner.OnItemClickListenner
+import com.ck.ckcollar.app.model.MemberModel
+import com.ck.ckcollar.app.model.MessageModel
+import com.ck.ckcollar.app.model.RecordModel
+import com.ck.ckcollar.app.ui.act.balance.BalanceActivity.RecordAdapter
+import com.ck.ckcollar.app.ui.act.balance.IncomeRecordDetailsActivity
+import com.ck.ckcollar.app.ui.act.balance.OutRecordDetailsActivity
+import com.ck.ckcollar.app.ui.base.CKBaseActivity
+import com.ck.ckcollar.app.utils.networkone.ICallback
+import com.ck.ckcollar.app.utils.networkone.TTHttpClient
+import com.ck.ckcollar.app.utils.networkone.model.TTRequestParam
+import com.google.gson.Gson
+import com.google.gson.reflect.TypeToken
+import com.tt.kit.model.Data
+import com.tt.kit.model.DataCollection
+import java.lang.reflect.Type
+
+class MessageCenterActivity : CKBaseActivity() {
+ lateinit var binding: ActivityMessageCenterBinding
+ var data = listOf()
+ lateinit var adapter: MessageAdapter
+ override fun onCreate(savedInstanceState: Bundle?) {
+ binding = ActivityMessageCenterBinding.inflate(layoutInflater)
+ setContentView(binding.root)
+ super.onCreate(savedInstanceState)
+
+
+ setStatusBarColor(resources.getColor(R.color.white))
+ setActionBarColor(resources.getColor(R.color.white))
+
+ setTitleText(getString(R.string.message_center))
+ setRightButton1Image(R.mipmap.image_read_all)
+ }
+
+ override fun initView() {
+
+ binding.recyclerView.layoutManager = LinearLayoutManager(this@MessageCenterActivity, RecyclerView.VERTICAL,false)
+ binding.recyclerView.setHasFixedSize(true)
+ adapter = MessageAdapter(this@MessageCenterActivity,data,object : OnItemClickListenner{
+ override fun onClick(
+ pos: Int,
+ model: Any
+ ) {
+ toActivity(MessageDetailsActivity::class.java, DataCollection().apply {
+ add(Data("data",Gson().toJson(model)))
+ })
+ }
+ })
+ binding.recyclerView.adapter = adapter
+ }
+
+ override fun initData() {
+
+ }
+
+ override fun rightButton1OnClick() {
+ readAll()
+ }
+
+ override fun onStart() {
+ super.onStart()
+ getData()
+ }
+
+ fun getData(){
+ TTHttpClient.get(this,"消息通知列表", TTRequestParam(),object : ICallback{
+ override fun onSuccess(data: String) {
+
+ this@MessageCenterActivity.data = Gson().fromJson>(data,object : TypeToken>(){}.type)
+
+ adapter.data= this@MessageCenterActivity.data
+ adapter.notifyDataSetChanged()
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ toast(msg)
+ finish()
+ }
+ })
+ }
+ fun readAll(){
+ TTHttpClient.post(this,"读取全部消息", TTRequestParam(),object : ICallback{
+ override fun onSuccess(data: String) {
+
+ getData()
+ toast(getString(R.string.option_success))
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ toast(msg)
+ }
+ })
+ }
+
+
+ class MessageAdapter(var context: Context, var data: List, var onItemClickListenner : OnItemClickListenner) : RecyclerView.Adapter() {
+
+ var selectPos = -1
+ override fun onCreateViewHolder(
+ parent: ViewGroup,
+ viewType: Int
+ ): MessageHolder {
+ return MessageHolder(LayoutItemMessageBinding.inflate(LayoutInflater.from(context),parent,false))
+ }
+
+ override fun onBindViewHolder(
+ holder: MessageHolder,
+ position: Int
+ ) {
+ // holder.binding.text.text = data.get(position).name
+
+ var model = data.get(position)
+
+ holder.binding.textTitle.text = model.noticeTitle
+ holder.binding.textDate.text = model.createTime
+
+ if (model.isRead == 0){
+ holder.binding.viewRead.visibility = View.VISIBLE
+ }else{
+ holder.binding.viewRead.visibility = View.GONE
+ }
+
+ holder.binding.root.setTag(position)
+ holder.binding.root.setOnClickListener {
+ val position = it.tag as Int
+ onItemClickListenner.onClick(position,data.get(position))
+ }
+ }
+
+ override fun getItemCount(): Int {
+ return data.size
+ }
+
+ class MessageHolder(var binding: LayoutItemMessageBinding) : RecyclerView.ViewHolder(binding.root){
+
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/ui/act/message/MessageDetailsActivity.kt b/app/src/main/java/com/ck/ckcollar/app/ui/act/message/MessageDetailsActivity.kt
new file mode 100644
index 0000000..8708c5a
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/ui/act/message/MessageDetailsActivity.kt
@@ -0,0 +1,109 @@
+package com.ck.ckcollar.app.ui.act.message
+
+import android.content.Context
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.LinearLayoutManager
+import androidx.recyclerview.widget.RecyclerView
+import com.ck.ckcollar.app.R
+import com.ck.ckcollar.app.databinding.ActivityMessageCenterBinding
+import com.ck.ckcollar.app.databinding.ActivityMessageDetailsBinding
+import com.ck.ckcollar.app.databinding.LayoutItemMessageBinding
+import com.ck.ckcollar.app.databinding.LayoutItemRecordsBinding
+import com.ck.ckcollar.app.listenner.OnItemClickListenner
+import com.ck.ckcollar.app.model.MemberModel
+import com.ck.ckcollar.app.model.MessageModel
+import com.ck.ckcollar.app.model.RecordModel
+import com.ck.ckcollar.app.ui.act.balance.BalanceActivity.RecordAdapter
+import com.ck.ckcollar.app.ui.act.balance.IncomeRecordDetailsActivity
+import com.ck.ckcollar.app.ui.act.balance.OutRecordDetailsActivity
+import com.ck.ckcollar.app.ui.base.CKBaseActivity
+import com.ck.ckcollar.app.utils.networkone.ICallback
+import com.ck.ckcollar.app.utils.networkone.TTHttpClient
+import com.ck.ckcollar.app.utils.networkone.model.TTRequestParam
+import com.google.gson.Gson
+import com.google.gson.reflect.TypeToken
+import com.tt.kit.model.Data
+import com.tt.kit.model.DataCollection
+import java.lang.reflect.Type
+
+class MessageDetailsActivity : CKBaseActivity() {
+ lateinit var binding: ActivityMessageDetailsBinding
+ lateinit var model : MessageModel
+ override fun onCreate(savedInstanceState: Bundle?) {
+ binding = ActivityMessageDetailsBinding.inflate(layoutInflater)
+ setContentView(binding.root)
+ super.onCreate(savedInstanceState)
+
+ setTitleText(getString(R.string.message))
+ }
+
+ override fun initView() {
+
+
+ }
+
+ override fun initData() {
+
+ model = Gson().fromJson(getReceiveParam().get("data")!!.stringValue,
+ MessageModel::class.java)
+
+ binding.text.text= model.noticeContent
+
+ readMessage()
+ }
+
+
+
+ fun readMessage(){
+ TTHttpClient.post(this,"读取消息", model.id.toString(),object : ICallback{
+ override fun onSuccess(data: String) {
+
+
+ }
+
+ override fun onFailed(code: String, msg: String) {
+
+ }
+ })
+ }
+
+ class MessageAdapter(var context: Context, var data: List, var onItemClickListenner : OnItemClickListenner) : RecyclerView.Adapter() {
+
+ var selectPos = -1
+ override fun onCreateViewHolder(
+ parent: ViewGroup,
+ viewType: Int
+ ): MessageHolder {
+ return MessageHolder(LayoutItemMessageBinding.inflate(LayoutInflater.from(context),parent,false))
+ }
+
+ override fun onBindViewHolder(
+ holder: MessageHolder,
+ position: Int
+ ) {
+ // holder.binding.text.text = data.get(position).name
+
+ var model = data.get(position)
+
+ holder.binding.textTitle.text = model.noticeTitle
+ holder.binding.textDate.text = model.createTime
+
+ holder.binding.root.setTag(position)
+ holder.binding.root.setOnClickListener {
+ val position = it.tag as Int
+ onItemClickListenner.onClick(position,data.get(position))
+ }
+ }
+
+ override fun getItemCount(): Int {
+ return data.size
+ }
+
+ class MessageHolder(var binding: LayoutItemMessageBinding) : RecyclerView.ViewHolder(binding.root){
+
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/ui/act/mine/FeedBackActivity.kt b/app/src/main/java/com/ck/ckcollar/app/ui/act/mine/FeedBackActivity.kt
new file mode 100644
index 0000000..4a9e132
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/ui/act/mine/FeedBackActivity.kt
@@ -0,0 +1,237 @@
+package com.ck.ckcollar.app.ui.act.mine
+
+import android.content.Intent
+import android.net.Uri
+import android.os.Build
+import android.os.Bundle
+import android.os.Environment
+import android.provider.MediaStore
+import android.text.TextUtils
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.AdapterView
+import android.widget.BaseAdapter
+import android.widget.ImageView
+import androidx.core.content.FileProvider
+import com.ck.ckcollar.app.R
+import com.ck.ckcollar.app.databinding.ActivityFeedBackBinding
+import com.ck.ckcollar.app.databinding.LayoutItemImage2Binding
+import com.ck.ckcollar.app.databinding.LayoutItemImageBinding
+import com.ck.ckcollar.app.model.ImageModel
+import com.ck.ckcollar.app.model.UploadModel
+import com.ck.ckcollar.app.ui.act.petmanager.AddPetActivity
+import com.ck.ckcollar.app.ui.act.petmanager.AddPetActivity.ImageAdapter
+import com.ck.ckcollar.app.ui.act.petmanager.ImageViewActivity
+import com.ck.ckcollar.app.ui.base.CKBaseActivity
+import com.ck.ckcollar.app.ui.dialog.CKAlertDialog
+import com.ck.ckcollar.app.ui.dialog.CKPhotoDialog
+import com.ck.ckcollar.app.utils.CKUtils
+import com.ck.ckcollar.app.utils.Const
+import com.ck.ckcollar.app.utils.networkone.ICallback
+import com.ck.ckcollar.app.utils.networkone.TTHttpClient
+import com.ck.ckcollar.app.utils.networkone.model.TTRequestData
+import com.ck.ckcollar.app.utils.networkone.model.TTRequestParam
+import com.cyclone.shadowsocks.utils.PreferencesUtils
+import com.google.gson.Gson
+import com.tt.kit.model.Data
+import com.tt.kit.model.DataCollection
+import com.tt.kit.utils.TTLog
+import com.tt.kit.utils.TTUtils
+import java.io.File
+
+class FeedBackActivity : CKBaseActivity() {
+
+ lateinit var binding: ActivityFeedBackBinding
+ lateinit var imageAdapter: ImageAdapter
+ var data = mutableListOf()
+ override fun onCreate(savedInstanceState: Bundle?) {
+
+ binding = ActivityFeedBackBinding.inflate(layoutInflater)
+ setContentView(binding.root)
+ super.onCreate(savedInstanceState)
+ checkAppPermissions()
+ setTitleText(getString(R.string.feedback))
+ }
+
+ override fun initView() {
+ data.add(ImageModel().apply { isAdd = true })
+ imageAdapter = ImageAdapter(this,data)
+ binding.girdView.adapter = imageAdapter
+ binding.girdView.onItemClickListener = object :
+ AdapterView.OnItemClickListener {
+ override fun onItemClick(
+ p0: AdapterView<*>?,
+ p1: View?,
+ p2: Int,
+ p3: Long
+ ) {
+ if (!data.get(p2).isAdd){
+ var urls = mutableListOf()
+ for (d in data){
+ if (d.isAdd){
+ continue
+ }
+ if(TextUtils.isEmpty(d.url)){
+ urls.add(d.path!!)
+ }else{
+ urls.add(d.url!!)
+ }
+ }
+ toActivity(ImageViewActivity::class.java, DataCollection().apply {
+ add(Data("data",Gson().toJson(urls)))
+ add(Data("pos",p2.toString()))
+ })
+ return
+ }
+ //相册
+ val i = Intent(
+ Intent.ACTION_PICK,
+ MediaStore.Images.Media.EXTERNAL_CONTENT_URI
+ )
+ i.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,"image/*");
+ startActivityForResult(i, 56)
+ }
+
+ }
+
+
+ binding.btnComplete.setOnClickListener {
+ upload()
+ }
+ }
+
+ override fun initData() {
+
+ }
+
+ fun upload(){
+
+ if (binding.editConten.isEmpty()){
+ toast(getString(R.string.please_input_complaint))
+ return
+ }
+
+ if (data.size > 1){
+ var param = TTRequestParam()
+ for (model in data){
+ if (model.isAdd == false){
+ param.files.add(File(model.path))
+ }
+ }
+
+ showProgeassDialog()
+ TTHttpClient.postFile(this,"上传照片s", param,object : ICallback{
+ override fun onSuccess(data: String) {
+ var model = Gson().fromJson(data,UploadModel::class.java)
+
+ submit(model.urls)
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ hiddenProgeassDialog()
+ toast(msg)
+ }
+ })
+ }else{
+ submit("")
+ }
+
+
+ }
+
+ fun submit(patPhoto : String){
+
+
+ var param = TTRequestParam().apply {
+ add(TTRequestData("feedbackMsg",binding.editConten.text.toString()))
+
+ add(TTRequestData("feedbackVoucher",patPhoto))
+ }
+ TTHttpClient.postJson(this,"意见反馈",param ,object : ICallback{
+ override fun onSuccess(data: String) {
+ toast(getString(R.string.submit_success))
+ finish()
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ toast(msg)
+ }
+ })
+ }
+ override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
+ super.onActivityResult(requestCode, resultCode, data)
+
+ if (requestCode == 56 && resultCode == RESULT_OK) {
+ var path = TTUtils.getImageUrl(this, data!!.getData());
+ this.data.add(this.data.size - 1,ImageModel().apply { this.path = path })
+ imageAdapter.data = this.data
+ imageAdapter.notifyDataSetChanged()
+ }
+ }
+
+
+ class ImageAdapter(var context: FeedBackActivity, var data: List) : BaseAdapter() {
+
+ override fun getCount(): Int {
+ var count = if (data.size > 3){
+ 3
+ }else{
+ data.size
+ }
+ return count
+ }
+
+ override fun getItem(p0: Int): Any? {
+ TODO("Not yet implemented")
+ }
+
+ override fun getItemId(p: Int): Long {
+ return p.toLong()
+ }
+
+ override fun getView(
+ p0: Int,
+ p1: View?,
+ p2: ViewGroup?
+ ): View? {
+ var layoutItemImageBinding =
+ LayoutItemImage2Binding.inflate(LayoutInflater.from(context))
+ layoutItemImageBinding.root.layoutParams = ViewGroup.LayoutParams(TTUtils.dpToPx(context,80).toInt(),
+ TTUtils.dpToPx(context,80).toInt())
+ var model = data.get(p0)
+ if (model.isAdd) {
+ layoutItemImageBinding.image.setImageResource(R.mipmap.image_photo_add)
+ layoutItemImageBinding.image.scaleType = ImageView.ScaleType.CENTER_INSIDE
+ layoutItemImageBinding.imageDelete.visibility = View.GONE
+ } else {
+ layoutItemImageBinding.image.scaleType = ImageView.ScaleType.CENTER_CROP
+ layoutItemImageBinding.image.setImageBitmap(
+ TTUtils.getBitmap(
+ model.path,
+ 200,
+ 200
+ )
+ )
+ layoutItemImageBinding.imageDelete.visibility = View.VISIBLE
+ layoutItemImageBinding.imageDelete.setOnClickListener {
+
+
+
+ CKAlertDialog(context,context.getString(R.string.alert),context.getString(R.string.alert_delete_photo),object : CKAlertDialog.AlertClickListener{
+ override fun onBack(isConfirm: Boolean) {
+ if (isConfirm){
+ context.data.removeAt(p0)
+ this@ImageAdapter.data = context.data
+ notifyDataSetChanged()
+ }
+ }
+ }).show()
+
+ }
+ }
+ return layoutItemImageBinding.root
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/ui/act/mine/ReturnDeviceActivity.kt b/app/src/main/java/com/ck/ckcollar/app/ui/act/mine/ReturnDeviceActivity.kt
new file mode 100644
index 0000000..b354c75
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/ui/act/mine/ReturnDeviceActivity.kt
@@ -0,0 +1,127 @@
+package com.ck.ckcollar.app.ui.act.mine
+
+import android.content.Intent
+import android.os.Bundle
+import com.ck.ckcollar.app.R
+import com.ck.ckcollar.app.databinding.ActivityReturnDeviceBinding
+import com.ck.ckcollar.app.ui.act.petmanager.InputInviteCodeActivity
+import com.ck.ckcollar.app.ui.base.CKBaseActivity
+import com.ck.ckcollar.app.ui.dialog.CKAlertDialog
+import com.ck.ckcollar.app.utils.networkone.ICallback
+import com.ck.ckcollar.app.utils.networkone.TTHttpClient
+import com.ck.ckcollar.app.utils.networkone.model.TTRequestData
+import com.ck.ckcollar.app.utils.networkone.model.TTRequestParam
+import com.tt.kit.model.Data
+import com.tt.kit.model.DataCollection
+import com.tt.mnmlkitscanner.scan.MNScanManager
+import com.tt.mnmlkitscanner.scan.callback.act.MNScanCallback
+import org.json.JSONObject
+
+class ReturnDeviceActivity : CKBaseActivity() {
+ lateinit var binding: ActivityReturnDeviceBinding
+ override fun onCreate(savedInstanceState: Bundle?) {
+ binding = ActivityReturnDeviceBinding.inflate(layoutInflater)
+ setContentView(binding.root)
+ super.onCreate(savedInstanceState)
+ checkAppPermissions()
+ setTitleText(getString(R.string.device_return))
+
+ setActionBarColor(getColor(R.color.white))
+ setStatusBarColor2(getColor(R.color.white))
+ }
+
+ override fun initView() {
+
+ binding.textNum.setOnClickListener {
+ if (!checkCameraPermissions()){
+ CKAlertDialog(this@ReturnDeviceActivity,getString(R.string.alert),getString(R.string.camera_alert),object : CKAlertDialog.AlertClickListener{
+ override fun onBack(isConfirm: Boolean) {
+ }
+
+ }).show()
+ return@setOnClickListener
+ }
+ startScan()
+ }
+ binding.btnComplete.setOnClickListener {
+ complete()
+ }
+ }
+
+ override fun initData() {
+
+ }
+
+ private fun startScan() {
+ MNScanManager.startScan(this, object : MNScanCallback {
+ override fun onActivityResult(resultCode: Int, data: Intent?) {
+ when (resultCode) {
+ MNScanManager.RESULT_SUCCESS -> {
+ val result =
+ data?.getStringArrayListExtra(MNScanManager.INTENT_KEY_RESULT_SUCCESS)
+ if (!result.isNullOrEmpty()) {
+ try {
+ //{"deviceNo":"862323085947268","mac":"dc:da:0c:fa:28:9e","transport":"ble","name":"Water_0001"}
+ var json = JSONObject(result[0])
+ binding.textNum.text = json.getString("collNum")
+
+ }catch (e : Exception){
+ e.printStackTrace()
+ toast(getString(R.string.data_alert))
+ }
+ } else {
+ toast("扫码结果为空")
+ }
+ }
+
+ MNScanManager.RESULT_FAIL -> {
+ val error = data?.getStringExtra(MNScanManager.INTENT_KEY_RESULT_ERROR)
+ toast("扫码失败: $error")
+ }
+
+ MNScanManager.RESULT_CANCLE -> {
+ toast("扫码取消")
+ }
+ }
+ }
+ })
+ }
+ fun complete(){
+ if (binding.textName.isEmpty()){
+ toast(getString(R.string.input_name))
+ return
+ }
+
+ if (binding.textPhone.isEmpty()){
+ toast(getString(R.string.input_contact_info))
+ return
+ }
+
+ if (binding.textReason.isEmpty()){
+ toast(getString(R.string.input_return_reason))
+ return
+ }
+ if (binding.textNum.isEmpty()){
+ toast(getString(R.string.input_coll_num))
+ return
+ }
+
+ showProgeassDialog(getString(R.string.submit))
+ var param = TTRequestParam().apply {
+ add(TTRequestData("customerName",binding.textName.text.toString()))
+ add(TTRequestData("contactInfo",binding.textPhone.text.toString()))
+ add(TTRequestData("returnReason",binding.textReason.text.toString()))
+ add(TTRequestData("collNum",binding.textNum.text.toString()))
+ }
+ TTHttpClient.postJson(this,"设备退回",param ,object : ICallback{
+ override fun onSuccess(data: String) {
+ toast(getString(R.string.submit_success))
+ finish()
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ toast(msg)
+ }
+ })
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/ui/act/note/NoteDetailsActivity.kt b/app/src/main/java/com/ck/ckcollar/app/ui/act/note/NoteDetailsActivity.kt
new file mode 100644
index 0000000..efd1c19
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/ui/act/note/NoteDetailsActivity.kt
@@ -0,0 +1,205 @@
+package com.ck.ckcollar.app.ui.act.note
+
+import android.os.Bundle
+import android.text.Html
+import android.text.TextUtils
+import android.webkit.WebChromeClient
+import android.webkit.WebSettings
+import android.webkit.WebView
+import android.webkit.WebViewClient
+import com.ck.ckcollar.app.R
+import com.ck.ckcollar.app.databinding.ActivityAgreementBinding
+import com.ck.ckcollar.app.databinding.ActivityNoteDetailsBinding
+import com.ck.ckcollar.app.model.AgreementModel
+import com.ck.ckcollar.app.model.HealthNoteModel
+import com.ck.ckcollar.app.ui.base.CKBaseActivity
+import com.ck.ckcollar.app.utils.networkone.ICallback
+import com.ck.ckcollar.app.utils.networkone.TTHttpClient
+import com.ck.ckcollar.app.utils.networkone.model.TTRequestParam
+import com.google.gson.Gson
+
+class NoteDetailsActivity : CKBaseActivity() {
+ lateinit var binding: ActivityNoteDetailsBinding
+ override fun onCreate(savedInstanceState: Bundle?) {
+ binding = ActivityNoteDetailsBinding.inflate(layoutInflater)
+ setContentView(binding.root)
+ super.onCreate(savedInstanceState)
+ setActionBarColor(getColor(R.color.white))
+ setStatusBarColor(getColor2(R.color.white))
+ }
+
+ override fun initView() {
+
+ setupWebView(binding.webView)
+ }
+
+ fun setupWebView(webView: WebView) {
+ webView.apply {
+ settings.apply {
+ // 启用 JavaScript(如果需要)
+ javaScriptEnabled = true
+
+ // 自适应屏幕 - 关键设置
+ useWideViewPort = true // 支持 viewport
+ loadWithOverviewMode = true // 缩放至屏幕宽度
+
+ // 缩放控制
+ builtInZoomControls = true // 启用缩放
+ displayZoomControls = false // 隐藏缩放按钮
+
+ // 布局适配
+ layoutAlgorithm = WebSettings.LayoutAlgorithm.NARROW_COLUMNS
+
+ // 其他设置
+ domStorageEnabled = true
+ setSupportZoom(true)
+ }
+
+ // 设置 WebViewClient
+ webViewClient = object : WebViewClient() {
+ override fun onPageFinished(view: WebView?, url: String?) {
+ super.onPageFinished(view, url)
+ // 页面加载完成后,确保内容宽度适配屏幕
+ // view?.loadUrl("javascript:document.body.style.width='100%'")
+ }
+ }
+ }
+ }
+
+
+ fun loadRichText(webView: WebView, htmlContent: String, title: String) {
+ val styledHtml = """
+
+
+
+
+
+
+
+
+ $title
+ $htmlContent
+
+
+ """.trimIndent()
+
+ // 使用 loadDataWithBaseURL 加载
+ webView.loadDataWithBaseURL(null, styledHtml, "text/html", "UTF-8", null)
+ }
+
+ override fun initData() {
+ setTitleText(getString(R.string.pet_note))
+
+ getData(getReceiveParam().get("id")!!.stringValue!!)
+ }
+
+ fun getData(id: String) {
+ TTHttpClient.get(this, "宠物知识明细", id, object : ICallback {
+ override fun onSuccess(data: String) {
+ var model = Gson().fromJson(
+ data,
+ HealthNoteModel.NoteModel::class.java
+ )
+
+ if (model != null && !TextUtils.isEmpty(model.knowledgeMsg)) {
+
+ // binding.webView.loadData(" "+ model.knowledgeMsg + "", "text/html", "UTF-8");
+ loadRichText(
+ binding.webView,
+ model.knowledgeMsg.toString(),
+ getReceiveParam().get("title")!!.stringValue.toString()
+ )
+ }
+ }
+
+ override fun onFailed(code: String, msg: String) {
+
+ }
+ })
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/ui/act/order/AfterSalesActivity.kt b/app/src/main/java/com/ck/ckcollar/app/ui/act/order/AfterSalesActivity.kt
new file mode 100644
index 0000000..1461648
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/ui/act/order/AfterSalesActivity.kt
@@ -0,0 +1,78 @@
+package com.ck.ckcollar.app.ui.act.order
+
+import android.os.Bundle
+import com.bumptech.glide.Glide
+import com.ck.ckcollar.app.R
+import com.ck.ckcollar.app.action.ActionCode
+import com.ck.ckcollar.app.databinding.ActivityAfterSalesBinding
+import com.ck.ckcollar.app.model.OrderModel
+import com.ck.ckcollar.app.ui.base.CKBaseActivity
+import com.ck.ckcollar.app.utils.CKUtils
+import com.google.gson.Gson
+import com.tt.kit.model.Data
+import com.tt.kit.model.DataCollection
+
+class AfterSalesActivity : CKBaseActivity() {
+
+ lateinit var binding: ActivityAfterSalesBinding
+ lateinit var model : OrderModel.Order
+ override fun onCreate(savedInstanceState: Bundle?) {
+ binding = ActivityAfterSalesBinding.inflate(layoutInflater)
+ setContentView(binding.root)
+ super.onCreate(savedInstanceState)
+
+ setTitleText(getString(R.string.choose_after_sales_type))
+ }
+
+ override fun initView() {
+
+ binding.contentRefund.setOnClickListener {
+ toActivityForResult(RefundActivity::class.java, DataCollection().apply { add(Data("data",Gson().toJson(model)))
+ add(Data("refundType","0"))
+ },2001)
+ }
+ binding.contentRefundAmount.setOnClickListener {
+ toActivityForResult(RefundActivity::class.java, DataCollection().apply { add(Data("data",Gson().toJson(model)))
+ add(Data("refundType","1"))
+ },2001)
+ }
+ binding.contentExchange.setOnClickListener {
+
+ }
+ }
+
+ override fun initData() {
+
+ model = Gson().fromJson(getReceiveParam().get("data")!!.stringValue.toString(),
+ OrderModel.Order::class.java)
+
+ binding.textStatus.text= CKUtils.getOrderStatus(model.orderStatus)
+ binding.textShopName.text = model.shopName
+ if (model.orderStatus == 5){
+ binding.textMoney.text = "¥" + 0
+ }else{
+ binding.textMoney.text = "¥" + model.payAmount.toString()
+ }
+
+ if (model.colOrderItems != null && model.colOrderItems!!.size > 0){
+ Glide.with(this)
+ .load( model.colOrderItems!!.get(0).goodsImg)
+ .placeholder(R.mipmap.image_default)
+ .into(binding.image)
+
+ binding.textDesc.text = getString(R.string.desc_text,model.colOrderItems!!.get(0).specInfo)
+ binding.textName.text = model.colOrderItems!!.get(0).goodsName
+
+ binding.textPrice.text = "¥" + model.colOrderItems!!.get(0).unitPrice
+ binding.textCount.text = "x" + model.colOrderItems!!.get(0).quantity
+ }
+
+ }
+
+
+ override fun getResult(data: DataCollection, resultCode: Int) {
+ if (resultCode == 2001){
+ finish(DataCollection(),2001)
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/ui/act/order/AfterSalesProgressActivity.kt b/app/src/main/java/com/ck/ckcollar/app/ui/act/order/AfterSalesProgressActivity.kt
new file mode 100644
index 0000000..6fdc2ab
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/ui/act/order/AfterSalesProgressActivity.kt
@@ -0,0 +1,132 @@
+package com.ck.ckcollar.app.ui.act.order
+
+import android.graphics.Color
+import android.os.Bundle
+import android.text.TextUtils
+import android.view.View
+import com.ck.ckcollar.app.R
+import com.ck.ckcollar.app.databinding.ActivityAfterSalesProgressBinding
+import com.ck.ckcollar.app.model.AfterSalesPrograss
+import com.ck.ckcollar.app.model.OrderModel
+import com.ck.ckcollar.app.ui.base.CKBaseActivity
+import com.ck.ckcollar.app.utils.CKUtils
+import com.ck.ckcollar.app.utils.networkone.ICallback
+import com.ck.ckcollar.app.utils.networkone.TTHttpClient
+import com.ck.ckcollar.app.utils.networkone.model.TTRequestData
+import com.ck.ckcollar.app.utils.networkone.model.TTRequestParam
+import com.google.gson.Gson
+
+class AfterSalesProgressActivity : CKBaseActivity() {
+
+ lateinit var binding: ActivityAfterSalesProgressBinding
+ lateinit var model : OrderModel.Order
+
+ var data = mutableListOf()
+ override fun onCreate(savedInstanceState: Bundle?) {
+ binding = ActivityAfterSalesProgressBinding.inflate(layoutInflater)
+ setContentView(binding.root)
+ super.onCreate(savedInstanceState)
+
+ setTitleText(getString(R.string.after_sales_progress))
+ }
+
+ override fun initView() {
+
+
+
+ }
+
+ override fun initData() {
+ model = Gson().fromJson(getReceiveParam().get("data")!!.stringValue.toString(),
+ OrderModel.Order::class.java)
+
+ data.add(getString(R.string.reason_1))
+ data.add(getString(R.string.reason_2))
+ data.add(getString(R.string.reason_3))
+ data.add(getString(R.string.reason_4))
+ data.add(getString(R.string.reason_5))
+ data.add(getString(R.string.reason_6))
+ data.add(getString(R.string.reason_7))
+ data.add(getString(R.string.reason_8))
+ data.add(getString(R.string.reason_9))
+
+ binding.textOrderNum.text = model.orderNo
+ getData()
+ }
+
+
+ fun getData(){
+ TTHttpClient.get(this@AfterSalesProgressActivity,"售后进度", TTRequestParam().apply { add(
+ TTRequestData("id",model.id)) },object : ICallback{
+ override fun onSuccess(data: String) {
+ try {
+ var model = Gson().fromJson(data, AfterSalesPrograss::class.java)
+
+ setStep(model.currentStage)
+ binding.textDate.text = model.applyTime
+ binding.textReason.text = this@AfterSalesProgressActivity.data.get(model.refundReason!!.toInt())
+
+ var refundType = if ("0".equals(model.refundType)){
+ "退款"
+ }else{
+ "退货退款"
+ }
+ binding.textType.text = refundType
+ binding.textMark.text = model.supplementInfo
+ binding.textMoney.text = model.refundAmount.toString()
+ binding.textAmount.text = "¥" + model.refundAmount.toString()
+ binding.textApplyStatus.text = CKUtils.getApplyStatusLab(model.applyStatus.toString())
+ binding.textNote.text = model.auditResult
+ if (TextUtils.isEmpty(model.auditResult)){
+ binding.contentNote.visibility = View.GONE
+ }else{
+ binding.contentNote.visibility = View.VISIBLE
+ }
+ }catch (e : Exception){
+ e.printStackTrace()
+ }
+
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ toast(msg)
+ finish()
+ }
+ })
+ }
+
+ fun setStep(step : Int){
+ if (step >=1){
+ binding.textStep1.setTextColor(Color.WHITE)
+ binding.textStep1.setBackgroundResource(R.drawable.bg_after_sales_step_select)
+ binding.line1.setBackgroundColor(resources.getColor(R.color.appStyle))
+ binding.line2.setBackgroundColor(resources.getColor(R.color.appStyle))
+ binding.textLab1.setTextColor(resources.getColor(R.color.appStyle))
+ }
+
+ if (step >= 2){
+ binding.textStep2.setTextColor(Color.WHITE)
+ binding.textStep2.setBackgroundResource(R.drawable.bg_after_sales_step_select)
+ binding.line2.setBackgroundColor(resources.getColor(R.color.appStyle))
+ binding.textLab2.setTextColor(resources.getColor(R.color.appStyle))
+
+ }
+
+ if (step >= 3){
+ binding.textStep3.setTextColor(Color.WHITE)
+ binding.textStep3.setBackgroundResource(R.drawable.bg_after_sales_step_select)
+ binding.line3.setBackgroundColor(resources.getColor(R.color.appStyle))
+ binding.line4.setBackgroundColor(resources.getColor(R.color.appStyle))
+ binding.textLab3.setTextColor(resources.getColor(R.color.appStyle))
+
+ }
+ if (step >= 4){
+ binding.textStep4.setTextColor(Color.WHITE)
+ binding.textStep4.setBackgroundResource(R.drawable.bg_after_sales_step_select)
+ binding.line5.setBackgroundColor(resources.getColor(R.color.appStyle))
+ binding.line6.setBackgroundColor(resources.getColor(R.color.appStyle))
+ binding.textLab4.setTextColor(resources.getColor(R.color.appStyle))
+
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/ui/act/order/InputLogisticsNumActivity.kt b/app/src/main/java/com/ck/ckcollar/app/ui/act/order/InputLogisticsNumActivity.kt
new file mode 100644
index 0000000..d86935e
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/ui/act/order/InputLogisticsNumActivity.kt
@@ -0,0 +1,126 @@
+package com.ck.ckcollar.app.ui.act.order
+
+import android.os.Bundle
+import com.ck.ckcollar.app.R
+import com.ck.ckcollar.app.databinding.ActivityInputLogisticsNumBinding
+import com.ck.ckcollar.app.model.AfterSalesPrograss
+import com.ck.ckcollar.app.model.LogisticsModel
+import com.ck.ckcollar.app.model.OrderModel
+import com.ck.ckcollar.app.ui.base.CKBaseActivity
+import com.ck.ckcollar.app.utils.networkone.ICallback
+import com.ck.ckcollar.app.utils.networkone.TTHttpClient
+import com.ck.ckcollar.app.utils.networkone.model.TTRequestData
+import com.ck.ckcollar.app.utils.networkone.model.TTRequestParam
+import com.ck.ckcollar.app.widget.CKEditView
+import com.google.gson.Gson
+
+class InputLogisticsNumActivity : CKBaseActivity() {
+
+ lateinit var binding: ActivityInputLogisticsNumBinding
+ var logModel : LogisticsModel? = null
+ lateinit var model : OrderModel.Order
+ var data = mutableListOf()
+
+ var afterSalesPrograss : AfterSalesPrograss? = null
+ override fun onCreate(savedInstanceState: Bundle?) {
+ binding = ActivityInputLogisticsNumBinding.inflate(layoutInflater)
+ setContentView(binding.root)
+ super.onCreate(savedInstanceState)
+
+ setTitleText(getString(R.string.input_order_num))
+ }
+
+ override fun initView() {
+
+ binding.textLogisticsCompany.setOnClickListener {
+ var logisticsBottomFragment = LogisticsBottomFragment(object : LogisticsBottomFragment.OnItemChooseLisnner{
+ override fun onItemChoose(pos: Int, model: Any) {
+ this@InputLogisticsNumActivity.logModel = model as LogisticsModel
+
+ binding.textLogisticsCompany.text = model.name
+ }
+ })
+ logisticsBottomFragment.show(supportFragmentManager,"LogisticsBottomFragment")
+ }
+
+ binding.btnSubmitRefund.setOnClickListener {
+ submit()
+ }
+
+ binding.etLogisticsNum2.filters = arrayOf(CKEditView.AlphanumericInputFilter())
+
+ }
+
+ override fun initData() {
+ model = Gson().fromJson(getReceiveParam().get("data")!!.stringValue.toString(),
+ OrderModel.Order::class.java)
+
+ data.add(getString(R.string.reason_1))
+ data.add(getString(R.string.reason_2))
+ data.add(getString(R.string.reason_3))
+ data.add(getString(R.string.reason_4))
+ data.add(getString(R.string.reason_5))
+ data.add(getString(R.string.reason_6))
+ data.add(getString(R.string.reason_7))
+ data.add(getString(R.string.reason_8))
+ data.add(getString(R.string.reason_9))
+
+ getData()
+ }
+
+ fun getData(){
+ TTHttpClient.get(this@InputLogisticsNumActivity,"售后进度", TTRequestParam().apply { add(
+ TTRequestData("id",model.id)) },object : ICallback{
+ override fun onSuccess(data: String) {
+ try {
+ afterSalesPrograss = Gson().fromJson(data, AfterSalesPrograss::class.java)
+
+
+ binding.textReason.text = this@InputLogisticsNumActivity.data.get(afterSalesPrograss?.refundReason!!.toInt())
+ binding.textAmount.text = "¥" + afterSalesPrograss?.refundAmount
+ binding.textCantAmount.text = getString(R.string.cannot_modify_amount,afterSalesPrograss?.refundAmount.toString())
+ }catch (e : Exception){
+ e.printStackTrace()
+ }
+
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ toast(msg)
+ finish()
+ }
+ })
+ }
+
+ fun submit(){
+ if (logModel == null){
+ toast(getString(R.string.please_select_logistics_company))
+ return
+ }
+ if (binding.etLogisticsNum2.isEmpty()){
+ toast(getString(R.string.please_input_logistics_number))
+ return
+ }
+
+ showProgeassDialog(getString(R.string.submit))
+
+ TTHttpClient.put(this,"填写快递单号", TTRequestParam().apply {
+ add(TTRequestData("id",model!!.colRefundApply!!.id))
+ add(TTRequestData("logisticsCode",logModel!!.code!!))
+ add(TTRequestData("logisticsNo",binding.etLogisticsNum2.text.toString()))
+
+ },object : ICallback{
+
+ override fun onSuccess(data: String) {
+ toast(getString(R.string.submit_success))
+ finish()
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ toast(msg)
+ }
+ })
+
+
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/ui/act/order/LogisticsBottomFragment.kt b/app/src/main/java/com/ck/ckcollar/app/ui/act/order/LogisticsBottomFragment.kt
new file mode 100644
index 0000000..eb2b268
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/ui/act/order/LogisticsBottomFragment.kt
@@ -0,0 +1,127 @@
+package com.ck.ckcollar.app.ui.act.order
+
+import android.net.wifi.ScanResult
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.recyclerview.widget.GridLayoutManager
+import androidx.recyclerview.widget.LinearLayoutManager
+import androidx.recyclerview.widget.RecyclerView
+import com.ck.ckcollar.app.R
+import com.ck.ckcollar.app.databinding.FragmentLogisticsBinding
+import com.ck.ckcollar.app.databinding.FragmentRefundReasonBinding
+import com.ck.ckcollar.app.databinding.LayoutItemRecordsBinding
+import com.ck.ckcollar.app.databinding.LayoutItemRefundReasonBinding
+import com.ck.ckcollar.app.databinding.LayoutItemWifiBinding
+import com.ck.ckcollar.app.listenner.OnItemClickListenner
+import com.ck.ckcollar.app.model.LogisticsModel
+import com.ck.ckcollar.app.model.MemberPriceModel
+import com.ck.ckcollar.app.ui.act.shop.ProductDetailsActivity
+import com.ck.ckcollar.app.ui.act.shop.TypeActivity.ProductAdapter
+import com.ck.ckcollar.app.ui.base.CKBaseActivity
+import com.ck.ckcollar.app.utils.networkone.ICallback
+import com.ck.ckcollar.app.utils.networkone.TTHttpClient
+import com.ck.ckcollar.app.utils.networkone.model.TTRequestParam
+import com.google.gson.Gson
+import com.google.gson.reflect.TypeToken
+import com.tt.kit.base.TTBaseActivity
+import com.tt.kit.dialog.TTBottomSheetDialogFragment
+import com.tt.kit.model.DataCollection
+import com.tt.kit.utils.TTLog
+
+class LogisticsBottomFragment(var onItemChooseLisnner : OnItemChooseLisnner?): TTBottomSheetDialogFragment() {
+
+ lateinit var binding: FragmentLogisticsBinding
+ var data = listOf()
+ lateinit var reasonAdapter: Adapter
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ binding = FragmentLogisticsBinding.inflate(layoutInflater)
+ return binding.root
+ }
+
+ override fun initView() {
+
+ reasonAdapter = Adapter( activity as CKBaseActivity, data, object : OnItemClickListenner {
+ override fun onClick(pos: Int, model: Any) {
+
+ reasonAdapter.selectPos = pos
+ reasonAdapter.notifyDataSetChanged()
+
+ onItemChooseLisnner?.onItemChoose(pos,model)
+
+ dismiss()
+ }
+ })
+ binding.recyclerView.layoutManager =
+ LinearLayoutManager(activity!!, RecyclerView.VERTICAL,false)
+ binding.recyclerView.setHasFixedSize(true)
+ binding.recyclerView.adapter = reasonAdapter
+
+ }
+
+ override fun initData() {
+
+ getData()
+
+ }
+ fun getData() {
+ TTHttpClient.get(activity as TTBaseActivity, "物流公司", TTRequestParam(), object : ICallback {
+ override fun onSuccess(data: String) {
+ this@LogisticsBottomFragment.data = Gson().fromJson>(data, object : TypeToken>(){}.type)
+
+
+ reasonAdapter.data = this@LogisticsBottomFragment.data
+ reasonAdapter.notifyDataSetChanged()
+
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ toast(msg)
+ }
+ })
+ }
+
+ class Adapter(var context: CKBaseActivity, var data: List, var itemClickListenner: OnItemClickListenner) : RecyclerView.Adapter() {
+
+ var selectPos = -1
+ override fun onCreateViewHolder(
+ parent: ViewGroup,
+ viewType: Int
+ ): ReasonwHolder {
+ return ReasonwHolder(LayoutItemRefundReasonBinding.inflate(context.layoutInflater,parent,false))
+ }
+
+ override fun onBindViewHolder(
+ holder: ReasonwHolder,
+ position: Int
+ ) {
+
+ holder.binding.image.visibility = View.GONE
+ holder.binding.text.text = data.get(position).name
+ holder.binding.root.setTag(position)
+ holder.binding.root.setOnClickListener {
+ var tag = it.tag as Int
+ itemClickListenner.onClick(tag, data.get(tag))
+ }
+
+ }
+
+ override fun getItemCount(): Int {
+ return data.size
+ }
+
+ class ReasonwHolder(var binding: LayoutItemRefundReasonBinding) : RecyclerView.ViewHolder(binding.root){
+
+ }
+
+ }
+
+ interface OnItemChooseLisnner{
+ fun onItemChoose(pos :Int,text : Any)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/ui/act/order/LogisticsInfoActivity.kt b/app/src/main/java/com/ck/ckcollar/app/ui/act/order/LogisticsInfoActivity.kt
new file mode 100644
index 0000000..06fdc03
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/ui/act/order/LogisticsInfoActivity.kt
@@ -0,0 +1,213 @@
+package com.ck.ckcollar.app.ui.act.order
+
+import android.content.Intent
+import android.net.Uri
+import android.net.http.SslError
+import android.os.Build
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.MotionEvent
+import android.view.ViewGroup
+import android.webkit.SslErrorHandler
+import android.webkit.WebChromeClient
+import android.webkit.WebResourceRequest
+import android.webkit.WebSettings
+import android.webkit.WebView
+import android.webkit.WebViewClient
+import androidx.recyclerview.widget.LinearLayoutManager
+import androidx.recyclerview.widget.RecyclerView
+import com.ck.ckcollar.app.R
+import com.ck.ckcollar.app.config.Config
+import com.ck.ckcollar.app.databinding.ActivityLogisticsInfoBinding
+import com.ck.ckcollar.app.databinding.LayoutItemAddressBinding
+import com.ck.ckcollar.app.databinding.LayoutItemExpressBinding
+import com.ck.ckcollar.app.listenner.OnItemClickListenner
+import com.ck.ckcollar.app.model.AddressModel
+import com.ck.ckcollar.app.model.ExpressModel
+import com.ck.ckcollar.app.model.ExpressModel.ColLogisticsInfo
+import com.ck.ckcollar.app.model.MemberPriceModel
+import com.ck.ckcollar.app.model.OrderModel
+import com.ck.ckcollar.app.ui.act.setting.AddressActivity.AddressAdapter
+import com.ck.ckcollar.app.ui.base.CKBaseActivity
+import com.ck.ckcollar.app.utils.CKUtils
+import com.ck.ckcollar.app.utils.networkone.ICallback
+import com.ck.ckcollar.app.utils.networkone.TTHttpClient
+import com.ck.ckcollar.app.utils.networkone.model.TTRequestData
+import com.ck.ckcollar.app.utils.networkone.model.TTRequestParam
+import com.google.gson.Gson
+import com.google.gson.reflect.TypeToken
+import com.tt.kit.model.Data
+import com.tt.kit.model.DataCollection
+import com.tt.kit.utils.TTLog
+import com.tt.kit.utils.TTUtils
+import org.osmdroid.util.GeoPoint
+import org.osmdroid.views.CustomZoomButtonsController
+import org.osmdroid.views.MapView
+import org.osmdroid.views.overlay.Overlay
+import org.osmdroid.views.overlay.ScaleBarOverlay
+import org.osmdroid.views.overlay.compass.CompassOverlay
+import org.osmdroid.views.overlay.gestures.RotationGestureOverlay
+
+class LogisticsInfoActivity : CKBaseActivity() {
+
+ lateinit var binding: ActivityLogisticsInfoBinding
+ lateinit var expressAdapter: ExpressAdapter
+ var data = listOf()
+ var expressModel : ExpressModel?= null
+ lateinit var model : OrderModel.Order
+ override fun onCreate(savedInstanceState: Bundle?) {
+ binding = ActivityLogisticsInfoBinding.inflate(layoutInflater)
+ setContentView(binding.root)
+ super.onCreate(savedInstanceState)
+
+ setTitleText(getString(R.string.view_express))
+ setActionBarColor(getColor(R.color.white))
+ setStatusBarColor2(getColor(R.color.white))
+ }
+
+ override fun initView() {
+ var webSettings = binding.webView.getSettings();
+ webSettings.setJavaScriptEnabled(true); // 启用JavaScript支持
+ binding.webView.setWebViewClient(object : WebViewClient(){
+
+ override fun onReceivedSslError(
+ view: WebView?,
+ handler: SslErrorHandler?,
+ error: SslError?
+ ) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+ binding.webView.getSettings()
+ .setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
+ }
+ }
+
+ override fun shouldOverrideUrlLoading(
+ view: WebView?,
+ request: WebResourceRequest?
+ ): Boolean {
+ binding.webView.loadUrl(request?.getUrl().toString())
+ return super.shouldOverrideUrlLoading(view, request)
+ }
+ }); // 设置WebViewClient处理网页中的链接点击等行为
+ binding.webView.setWebChromeClient(object :WebChromeClient(){
+
+
+ }); // 可选,用于处理JavaScript的对话框、网站图标等
+
+ webSettings.setDomStorageEnabled(true);
+ webSettings.supportMultipleWindows();
+ webSettings.setAllowContentAccess(true);
+ webSettings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NARROW_COLUMNS);
+ webSettings.setUseWideViewPort(true);
+ webSettings.setLoadWithOverviewMode(true);
+ webSettings.setSavePassword(true);
+ webSettings.setSaveFormData(true);
+ webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
+ webSettings.setLoadsImagesAutomatically(true);
+
+
+ binding.recyclerView.layoutManager = LinearLayoutManager(this@LogisticsInfoActivity, RecyclerView.VERTICAL,false)
+ binding.recyclerView.setHasFixedSize(true)
+ expressAdapter = ExpressAdapter(this@LogisticsInfoActivity,data,object : OnItemClickListenner{
+ override fun onClick(
+ pos: Int,
+ model: Any
+ ) {
+
+ }
+ })
+ binding.recyclerView.adapter = expressAdapter
+
+
+ binding.btnCopy.setOnClickListener {
+ expressModel?.let {
+ TTUtils.copyTextToClipboard(this@LogisticsInfoActivity, it.logisticsNo ?: "")
+ toast(getString(R.string.copy_success))
+ }
+
+ }
+ binding.btnPhone.setOnClickListener {
+
+ CKUtils.callPhone(this,expressModel?.logisticsPhone!!)
+ }
+ }
+
+ override fun initData() {
+
+ model = Gson().fromJson(getReceiveParam().get("data")!!.stringValue.toString(),
+ OrderModel.Order::class.java)
+
+ binding.textReceiveName.text = model.receiverName + " " + model.receiverPhone
+ getData()
+ }
+
+
+ fun getData() {
+ TTHttpClient.get(this, "查看物流信息", TTRequestParam().apply {
+ add(TTRequestData("id",model.id.toString()))
+ }, object : ICallback {
+ override fun onSuccess(data: String) {
+ expressModel = Gson().fromJson(data, ExpressModel::class.java)
+
+ expressModel?.colLogisticsInfos?.let {
+ this@LogisticsInfoActivity.data = expressModel!!.colLogisticsInfos!!
+
+ expressAdapter.data = this@LogisticsInfoActivity.data
+ expressAdapter.notifyDataSetChanged()
+ }
+
+ binding.textExpress.text = expressModel?.logisticsCompanyName + " " + expressModel?.logisticsNo
+
+ binding.textStatus.text = CKUtils.logisticsStatusText(expressModel?.logisticsStatus ?: "")
+ expressModel?.routeMapUrl?.let {
+ binding.webView.loadUrl(it)
+ TTLog.e(it)
+
+ }
+
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ toast(msg)
+ }
+ })
+ }
+
+
+
+
+ class ExpressAdapter(var context: CKBaseActivity, var data: List, var onItemClickListenner : OnItemClickListenner) : RecyclerView.Adapter() {
+
+ override fun onCreateViewHolder(
+ parent: ViewGroup,
+ viewType: Int
+ ): ExpressHolder {
+ return ExpressHolder(LayoutItemExpressBinding.inflate(LayoutInflater.from(context),parent,false))
+ }
+
+ override fun onBindViewHolder(
+ holder: ExpressHolder,
+ position: Int
+ ) {
+ // holder.binding.text.text = data.get(position).name
+
+ var model = data.get(position)
+ holder.binding.text.text = model.logisticsDesc
+
+ holder.binding.root.setTag(position)
+ holder.binding.root.setOnClickListener {
+ val position = it.tag as Int
+ onItemClickListenner.onClick(position,data.get(position))
+ }
+ }
+
+ override fun getItemCount(): Int {
+ return data.size
+ }
+
+ class ExpressHolder(var binding: LayoutItemExpressBinding) : RecyclerView.ViewHolder(binding.root){
+
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/ui/act/order/ModifyAddressActivity.kt b/app/src/main/java/com/ck/ckcollar/app/ui/act/order/ModifyAddressActivity.kt
new file mode 100644
index 0000000..fc9c8c8
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/ui/act/order/ModifyAddressActivity.kt
@@ -0,0 +1,104 @@
+package com.ck.ckcollar.app.ui.act.order
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.LinearLayoutManager
+import androidx.recyclerview.widget.RecyclerView
+import com.ck.ckcollar.app.R
+import com.ck.ckcollar.app.databinding.ActivityModifyAddressBinding
+import com.ck.ckcollar.app.databinding.LayoutItemAddressBinding
+import com.ck.ckcollar.app.databinding.LayoutItemModifyAddressBinding
+import com.ck.ckcollar.app.listenner.OnItemClickListenner
+import com.ck.ckcollar.app.model.AddressModel
+import com.ck.ckcollar.app.ui.act.setting.AddressActivity
+import com.ck.ckcollar.app.ui.act.setting.AddressActivity.AddressAdapter
+import com.ck.ckcollar.app.ui.base.CKBaseActivity
+import com.tt.kit.model.DataCollection
+
+class ModifyAddressActivity : CKBaseActivity() {
+
+
+ lateinit var binding: ActivityModifyAddressBinding
+
+ lateinit var addressAdapter: AddressAdapter
+ var data = mutableListOf()
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ binding = ActivityModifyAddressBinding.inflate(layoutInflater)
+
+ setContentView(binding.root)
+ super.onCreate(savedInstanceState)
+
+ setTitleText(getString(R.string.change_address))
+ }
+
+ override fun initView() {
+
+ binding.recyclerView.layoutManager = LinearLayoutManager(this@ModifyAddressActivity, RecyclerView.VERTICAL,false)
+ binding.recyclerView.setHasFixedSize(true)
+ addressAdapter = AddressAdapter(this@ModifyAddressActivity,data,object : OnItemClickListenner{
+ override fun onClick(
+ pos: Int,
+ model: Any
+ ) {
+ addressAdapter.selectPos = pos
+ addressAdapter.notifyDataSetChanged()
+ }
+ })
+ binding.recyclerView.adapter = addressAdapter
+
+ binding.btnSubmit.setOnClickListener {
+
+ }
+ }
+
+ override fun initData() {
+
+ data.add(AddressModel())
+ data.add(AddressModel())
+ data.add(AddressModel())
+
+ }
+
+
+ class AddressAdapter(var context: CKBaseActivity, var data: List, var onItemClickListenner : OnItemClickListenner) : RecyclerView.Adapter() {
+
+ var selectPos = -1
+ override fun onCreateViewHolder(
+ parent: ViewGroup,
+ viewType: Int
+ ): AddressHolder {
+ return AddressHolder(LayoutItemModifyAddressBinding.inflate(LayoutInflater.from(context),parent,false))
+ }
+
+ override fun onBindViewHolder(
+ holder: AddressHolder,
+ position: Int
+ ) {
+ // holder.binding.text.text = data.get(position).name
+
+ if (selectPos == position){
+ holder.binding.check.setImageResource(R.mipmap.image_address_check_select)
+ }else{
+ holder.binding.check.setImageResource(R.mipmap.image_address_check_narmal)
+ }
+
+
+ holder.binding.root.setTag(position)
+ holder.binding.root.setOnClickListener {
+ val position = it.tag as Int
+ onItemClickListenner.onClick(position,data.get(position))
+ }
+ }
+
+ override fun getItemCount(): Int {
+ return data.size
+ }
+
+ class AddressHolder(var binding: LayoutItemModifyAddressBinding) : RecyclerView.ViewHolder(binding.root){
+
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/ui/act/order/MyOrderActivity.kt b/app/src/main/java/com/ck/ckcollar/app/ui/act/order/MyOrderActivity.kt
new file mode 100644
index 0000000..c24a56c
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/ui/act/order/MyOrderActivity.kt
@@ -0,0 +1,448 @@
+package com.ck.ckcollar.app.ui.act.order
+
+import android.graphics.Typeface
+import android.os.Bundle
+import android.text.TextUtils
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.recyclerview.widget.LinearLayoutManager
+import androidx.recyclerview.widget.RecyclerView
+import com.bumptech.glide.Glide
+import com.ck.ckcollar.app.R
+import com.ck.ckcollar.app.action.ActionCode
+import com.ck.ckcollar.app.databinding.ActivityMyOrderBinding
+import com.ck.ckcollar.app.databinding.LayoutItemOrderBinding
+import com.ck.ckcollar.app.listenner.OnItemClickListenner
+import com.ck.ckcollar.app.model.MemberPriceModel
+import com.ck.ckcollar.app.model.OrderModel
+import com.ck.ckcollar.app.model.ShopProductModel
+import com.ck.ckcollar.app.ui.act.order.OrderDetailsActivity
+import com.ck.ckcollar.app.ui.act.setting.AddressActivity
+import com.ck.ckcollar.app.ui.act.shop.ProductDetailsActivity
+import com.ck.ckcollar.app.ui.base.CKBaseActivity
+import com.ck.ckcollar.app.ui.dialog.CKAlertDialog
+import com.ck.ckcollar.app.utils.CKUtils
+import com.ck.ckcollar.app.utils.networkone.ICallback
+import com.ck.ckcollar.app.utils.networkone.TTHttpClient
+import com.ck.ckcollar.app.utils.networkone.model.TTRequestData
+import com.ck.ckcollar.app.utils.networkone.model.TTRequestParam
+import com.ck.ckcollar.app.widget.CKTextView
+import com.google.gson.Gson
+import com.google.gson.reflect.TypeToken
+import com.scwang.smartrefresh.layout.api.RefreshLayout
+import com.scwang.smartrefresh.layout.listener.OnRefreshLoadMoreListener
+import com.tt.kit.model.Data
+import com.tt.kit.model.DataCollection
+
+class MyOrderActivity : CKBaseActivity() , View.OnClickListener{
+
+ lateinit var binding: ActivityMyOrderBinding
+ var pos = -1
+ lateinit var selectView : CKTextView
+ var data = mutableListOf()
+ lateinit var orderAdapter: OrderAdapter
+
+ var page = 1
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ binding = ActivityMyOrderBinding.inflate(layoutInflater)
+ setContentView(binding.root)
+ super.onCreate(savedInstanceState)
+
+ setStatusBarColor2(resources.getColor(R.color.white))
+ setActionBarColor(resources.getColor(R.color.white))
+
+ setTitleText(getString(R.string.my_orders))
+ }
+
+ override fun initView() {
+
+
+ binding.textAllOrder.setOnClickListener(this)
+ binding.textPendingPayment.setOnClickListener(this)
+ binding.textPendingDelivery.setOnClickListener(this)
+ binding.textPendingReceipt.setOnClickListener(this)
+ binding.textAfterSale.setOnClickListener(this)
+
+
+ orderAdapter = OrderAdapter(this@MyOrderActivity, data, object : OnItemClickListenner {
+ override fun onClick(postion: Int, model: Any) {
+ toActivity(OrderDetailsActivity::class.java, DataCollection().apply { add(Data("data",Gson().toJson(data.get(postion)))) })
+ }
+ })
+ binding.recyclerView.layoutManager =
+ LinearLayoutManager(this@MyOrderActivity, RecyclerView.VERTICAL, false)
+ binding.recyclerView.setHasFixedSize(true)
+ binding.recyclerView.adapter = orderAdapter
+
+
+ binding.refreshLayout.setOnRefreshLoadMoreListener(object : OnRefreshLoadMoreListener{
+ override fun onRefresh(refreshLayout: RefreshLayout) {
+ page = 1
+ getData()
+ }
+
+ override fun onLoadMore(refreshLayout: RefreshLayout) {
+ page++
+ getData()
+ }
+ })
+ }
+
+ override fun initData() {
+ selectView = binding.textAllOrder
+
+ pos = getReceiveParam().get("pos")!!.intValue
+ when(pos){
+ 0->{
+ onClick(binding.textAllOrder)
+ }
+ 1->{
+ onClick(binding.textPendingPayment)
+ }
+ 2->{
+ onClick(binding.textPendingDelivery)
+ }
+ 3->{
+ onClick(binding.textPendingReceipt)
+ }
+ 4->{
+ onClick(binding.textAfterSale)
+ }
+ }
+
+ getData()
+ }
+
+ override fun onStart() {
+ super.onStart()
+
+ page = 1
+ getData()
+ }
+
+ override fun getResult(data: DataCollection, resultCode: Int) {
+ if (resultCode == 1001 || resultCode == 1002|| resultCode == 2001){
+ page = 1
+ getData()
+ }
+ }
+
+ override fun onClick(v: View?) {
+
+ selectView.typeface = Typeface.DEFAULT
+ selectView.setTextColor(resources.getColor(R.color.textThirdColor))
+ selectView = v as CKTextView
+ selectView.typeface = Typeface.DEFAULT_BOLD
+ selectView.setTextColor(resources.getColor(R.color.textColor))
+
+ when(v?.id){
+ R.id.textAllOrder->{
+ pos = -1
+ }
+ R.id.textPendingPayment->{
+ pos = 0
+ }
+ R.id.textPendingDelivery->{
+ pos = 1
+ }
+ R.id.textPendingReceipt->{
+ pos = 2
+ }
+ R.id.textAfterSale->{
+ pos = -2
+ }
+ }
+ page=1
+ getData()
+ }
+
+
+ fun getData() {
+ TTHttpClient.get(this, "我的订单", TTRequestParam().apply {
+ add(
+ TTRequestData("pageNum", page)
+ )
+ add(
+ TTRequestData("pageSize", 30)
+ )
+ add(TTRequestData("orderStatus",pos))
+ }, object : ICallback {
+ override fun onSuccess(data: String) {
+ var model = Gson().fromJson(data, OrderModel::class.java)
+
+ model.rows?.let{
+ if (page ==1){
+ this@MyOrderActivity.data.clear()
+ }
+ if (this@MyOrderActivity.data.size != model.total){
+ this@MyOrderActivity.data.addAll(model.rows!!)
+ }
+ }
+
+ orderAdapter.data = this@MyOrderActivity.data
+ orderAdapter.notifyDataSetChanged()
+
+ binding.refreshLayout.finishRefresh()
+ binding.refreshLayout.finishLoadMore(true)
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ toast(msg)
+ }
+ })
+ }
+
+
+
+ class OrderAdapter(
+ var context: MyOrderActivity,
+ var data: List,
+ var itemClickListenner: OnItemClickListenner
+ ) : RecyclerView.Adapter() {
+ override fun onCreateViewHolder(
+ parent: ViewGroup,
+ viewType: Int
+ ): OrderHolder {
+ return OrderHolder(
+ LayoutItemOrderBinding.inflate(
+ LayoutInflater.from(context),
+ parent,
+ false
+ )
+ )
+ }
+
+ override fun onBindViewHolder(
+ holder: OrderHolder,
+ position: Int
+ ) {
+
+
+ var model = data.get(position)
+
+ holder.binding.textStatus.text = CKUtils.getOrderStatus(model.orderStatus)
+
+ if (model.colOrderItems != null && model.colOrderItems!!.size > 0){
+ Glide.with(context)
+ .load( model.colOrderItems!!.get(0).goodsImg)
+ .placeholder(R.mipmap.image_default)
+ .into(holder.binding.image)
+
+ holder.binding.textDesc.text = context.getString(R.string.desc_text,model.colOrderItems!!.get(0).specInfo)
+ holder.binding.textName.text = model.colOrderItems!!.get(0).goodsName
+
+ holder.binding.textPrice.text = "¥" + model.colOrderItems!!.get(0).unitPrice
+ holder.binding.textCount.text = "x" + model.colOrderItems!!.get(0).quantity
+ }
+
+
+ if (model.orderStatus == 5){
+ holder.binding.textMoney.text = "¥0.00"
+ }else{
+ holder.binding.textMoney.text = "¥" + model.payAmount.toString()
+ }
+ holder.binding.textShopName.text = model.shopName
+ /**
+ * 0待付款 1待发货 2已发货 3已收货 4已完成 5已关闭 6已取消 7待审核 8已退款 9退款中 10拒绝退款
+ */
+ for (i in 0..holder.binding.contentBtn.childCount - 1){
+ holder.binding.contentBtn.getChildAt(i).visibility = View.GONE
+ }
+ //holder.binding.btnMore.visibility = View.VISIBLE
+ holder.binding.line.visibility = View.VISIBLE
+ holder.binding.textPayment.text = context.getString(R.string.pending_payment3)
+ if (model.orderStatus == 0){
+ holder.binding.textPayment.text = context.getString(R.string.pending_payment2)
+ holder.binding.btnCancel.visibility = View.VISIBLE
+ holder.binding.btnPayment.visibility = View.VISIBLE
+ holder.binding.btnChangeAddress.visibility = View.VISIBLE
+ }else if (model.orderStatus == 1){
+ holder.binding.btnCancel.visibility = View.VISIBLE
+ }else if (model.orderStatus == 2){
+ holder.binding.btnConfirmReceive.visibility = View.VISIBLE
+ holder.binding.btnViewWL.visibility = View.VISIBLE
+ holder.binding.btnAfterSale.visibility = View.VISIBLE
+ }else if (model.orderStatus == 3 || model.orderStatus == 4 || model.orderStatus == 5 || model.orderStatus == 6){
+ holder.binding.btnAgain.visibility = View.VISIBLE
+ holder.binding.btnDelete.visibility = View.VISIBLE
+
+ }else if (model.orderStatus == 9 ){
+ if ("0".equals(model.islogisticsNo)){
+ holder.binding.btnInputOrder.visibility = View.VISIBLE
+ }
+ holder.binding.btnViewPrograss.visibility = View.VISIBLE
+ holder.binding.btnAgain.visibility = View.VISIBLE
+ }else if ( model.orderStatus == 7 ){
+ if ("0".equals(model.colRefundApply?.applyStatus)){
+ holder.binding.btnCancelRefund.visibility = View.VISIBLE
+ }
+ holder.binding.btnViewPrograss.visibility = View.VISIBLE
+ holder.binding.btnAgain.visibility = View.VISIBLE
+ }else if ( model.orderStatus == 8 || model.orderStatus == 10){
+ holder.binding.btnViewPrograss.visibility = View.VISIBLE
+ holder.binding.btnAgain.visibility = View.VISIBLE
+ holder.binding.btnDelete.visibility = View.VISIBLE
+ }
+
+ holder.binding.btnPayment.setOnClickListener {
+ context.toActivityForResult(PayOrderActivity::class.java, DataCollection().apply { add(Data("data",
+ Gson().toJson(model))) },1002)
+ }
+ holder.binding.btnAgain.setOnClickListener {
+ context.toActivity(ProductDetailsActivity::class.java, DataCollection().apply { add(Data("data",
+ Gson().toJson(ShopProductModel.ProductModel().apply { id = model.colOrderItems?.get(0)!!.goodsId }))) })
+ }
+ holder.binding.btnAfterSale.setOnClickListener {
+ context.toActivityForResult(AfterSalesActivity::class.java, DataCollection().apply { add(Data("data",
+ Gson().toJson(model))) },2001)
+ }
+ holder.binding.btnViewPrograss.setOnClickListener {
+ context.toActivity(AfterSalesProgressActivity::class.java, DataCollection().apply { add(Data("data",
+ Gson().toJson(model))) })
+ }
+
+ holder.binding.btnChangeAddress.setOnClickListener {
+ context.toActivityForResult(AddressActivity::class.java, DataCollection().apply {
+ add(Data("flag","2"))
+ add(Data("data",
+ model.id.toString())) },1001)
+ }
+
+ holder.binding.btnViewWL.setOnClickListener {
+ context.toActivity(LogisticsInfoActivity::class.java, DataCollection().apply { add(Data("data",
+ Gson().toJson(model))) })
+ }
+ holder.binding.btnInputOrder.setOnClickListener {
+ context.toActivity(InputLogisticsNumActivity::class.java, DataCollection().apply { add(Data("data",
+ Gson().toJson(model))) })
+ }
+
+ holder.binding.btnCancel.setOnClickListener {
+ cancel(model.id.toString())
+ }
+
+ holder.binding.btnDelete.setOnClickListener {
+ delete(model.id.toString())
+ }
+ holder.binding.btnConfirmReceive.setOnClickListener {
+ confrimReceive(model.id.toString())
+ }
+ holder.binding.btnCancelRefund.setOnClickListener {
+ cancelRefund(model.colRefundApply?.id.toString())
+ }
+
+
+
+ holder.binding.root.setTag(position)
+ holder.binding.root.setOnClickListener {
+ var tag = it.tag as Int
+ itemClickListenner.onClick(tag, data.get(tag))
+ }
+ }
+
+ override fun getItemCount(): Int {
+ return data.size
+ }
+
+ class OrderHolder(var binding: LayoutItemOrderBinding) :
+ RecyclerView.ViewHolder(binding.root) {
+
+ }
+
+ fun cancel(id:String){
+ CKAlertDialog(context,context.getString(R.string.alert),context.getString(R.string.alert_cancel_order),object : CKAlertDialog.AlertClickListener{
+ override fun onBack(isConfirm: Boolean) {
+ if (isConfirm){
+
+ context.showProgeassDialog(context.getString(R.string.cancel))
+ TTHttpClient.put(context,"取消订单", TTRequestParam().apply { add(
+ TTRequestData("id",id)) },object : ICallback{
+ override fun onSuccess(data: String) {
+ context.toast(context.getString(R.string.cancel_cussess))
+ context.page = 1
+ context.getData()
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ context.toast(msg)
+ }
+ })
+ }
+ }
+ }).show()
+ }
+
+ fun delete(id:String){
+ CKAlertDialog(context,context.getString(R.string.alert),context.getString(R.string.alert_delete_order),object : CKAlertDialog.AlertClickListener{
+ override fun onBack(isConfirm: Boolean) {
+ if (isConfirm){
+
+ context.showProgeassDialog(context.getString(R.string.delete))
+ TTHttpClient.delete(context,"删除订单", TTRequestParam().apply { add(
+ TTRequestData("id",id)) },object : ICallback{
+ override fun onSuccess(data: String) {
+ context.toast(context.getString(R.string.delete_success))
+ context.page = 1
+ context.getData()
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ context.toast(msg)
+ }
+ })
+ }
+ }
+ }).show()
+ }
+ fun confrimReceive(id:String){
+ CKAlertDialog(context,context.getString(R.string.alert),context.getString(R.string.alert_option_receive_order),object : CKAlertDialog.AlertClickListener{
+ override fun onBack(isConfirm: Boolean) {
+ if (isConfirm){
+
+ context.showProgeassDialog(context.getString(R.string.receive))
+ TTHttpClient.put(context,"确认收货", TTRequestParam().apply { add(
+ TTRequestData("orderId",id)) },object : ICallback{
+ override fun onSuccess(data: String) {
+ context.toast(context.getString(R.string.receive_cussess))
+ context.page = 1
+ context.getData()
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ context.toast(msg)
+ }
+ })
+ }
+ }
+ }).show()
+ }
+
+ fun cancelRefund(id:String){
+ CKAlertDialog(context,context.getString(R.string.alert),context.getString(R.string.alert_option_cancel_refund),object : CKAlertDialog.AlertClickListener{
+ override fun onBack(isConfirm: Boolean) {
+ if (isConfirm){
+
+ context.showProgeassDialog(context.getString(R.string.cancel))
+ TTHttpClient.put(context,"取消退款", TTRequestParam().apply { add(
+ TTRequestData("refundId",id)) },object : ICallback{
+ override fun onSuccess(data: String) {
+ context.toast(context.getString(R.string.cancel_cussess))
+ context.page = 1
+ context.getData()
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ context.toast(msg)
+ }
+ })
+ }
+ }
+ }).show()
+ }
+
+ }
+
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/ui/act/order/OrderDetailsActivity.kt b/app/src/main/java/com/ck/ckcollar/app/ui/act/order/OrderDetailsActivity.kt
new file mode 100644
index 0000000..6595dda
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/ui/act/order/OrderDetailsActivity.kt
@@ -0,0 +1,404 @@
+package com.ck.ckcollar.app.ui.act.order
+
+import android.os.Bundle
+import android.text.TextUtils
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.recyclerview.widget.GridLayoutManager
+import androidx.recyclerview.widget.LinearLayoutManager
+import androidx.recyclerview.widget.RecyclerView
+import com.bumptech.glide.Glide
+import com.ck.ckcollar.app.R
+import com.ck.ckcollar.app.action.ActionCode
+import com.ck.ckcollar.app.databinding.ActivityOrderDetailsBinding
+import com.ck.ckcollar.app.databinding.LayoutItemOrderBinding
+import com.ck.ckcollar.app.databinding.LayoutItemOrderDetailsBinding
+import com.ck.ckcollar.app.listenner.OnItemClickListenner
+import com.ck.ckcollar.app.model.MemberPriceModel
+import com.ck.ckcollar.app.model.OrderModel
+import com.ck.ckcollar.app.model.ShopProductModel
+import com.ck.ckcollar.app.ui.act.customer.CustomerActivity
+import com.ck.ckcollar.app.ui.act.customer.PeopleCustomerActivity
+import com.ck.ckcollar.app.ui.act.customer.ShopCustomerActivity
+import com.ck.ckcollar.app.ui.act.order.MyOrderActivity.OrderAdapter
+import com.ck.ckcollar.app.ui.act.setting.AddressActivity
+import com.ck.ckcollar.app.ui.act.shop.ProductDetailsActivity
+import com.ck.ckcollar.app.ui.act.shop.SearchActivity
+import com.ck.ckcollar.app.ui.base.CKBaseActivity
+import com.ck.ckcollar.app.ui.dialog.CKAlertDialog
+import com.ck.ckcollar.app.utils.CKUtils
+import com.ck.ckcollar.app.utils.networkone.ICallback
+import com.ck.ckcollar.app.utils.networkone.TTHttpClient
+import com.ck.ckcollar.app.utils.networkone.model.TTRequestData
+import com.ck.ckcollar.app.utils.networkone.model.TTRequestParam
+import com.google.gson.Gson
+import com.google.gson.reflect.TypeToken
+import com.tt.kit.model.Data
+import com.tt.kit.model.DataCollection
+import com.tt.kit.utils.TTLog
+import com.tt.kit.utils.TTUtils
+import org.json.JSONObject
+import kotlin.toString
+
+class OrderDetailsActivity : CKBaseActivity() {
+
+ lateinit var binding: ActivityOrderDetailsBinding
+
+ lateinit var adapter: OrderAdapter
+ var productDatas = listOf()
+ lateinit var model : OrderModel.Order
+ override fun onCreate(savedInstanceState: Bundle?) {
+ binding = ActivityOrderDetailsBinding.inflate(layoutInflater)
+ setContentView(binding.root)
+ super.onCreate(savedInstanceState)
+ }
+
+ override fun initView() {
+
+
+ adapter = OrderAdapter(this@OrderDetailsActivity, productDatas, object : OnItemClickListenner {
+ override fun onClick(postion: Int, model: Any) {
+
+
+ }
+ })
+ binding.recyclerView.layoutManager =
+ LinearLayoutManager(this@OrderDetailsActivity, RecyclerView.VERTICAL, false)
+ binding.recyclerView.setHasFixedSize(true)
+ binding.recyclerView.adapter = adapter
+
+
+ binding.textCopy.setOnClickListener {
+ TTUtils.copyTextToClipboard(this@OrderDetailsActivity,binding.textOrderNum.text.toString())
+ toast(getString(R.string.copy_success))
+ }
+ binding.btnAddCar.setOnClickListener {
+
+ }
+
+ binding.btnPayment.setOnClickListener {
+ toActivityForResult(PayOrderActivity::class.java, DataCollection().apply { add(Data("data",
+ Gson().toJson(model))) },1002)
+ }
+
+ binding.btnAgain.setOnClickListener {
+ toActivity(ProductDetailsActivity::class.java, DataCollection().apply { add(Data("data",
+ Gson().toJson(ShopProductModel.ProductModel().apply { id = model.colOrderItems!!.get(0).goodsId }))) })
+ }
+
+
+ binding.btnAfterSale.setOnClickListener {
+ toActivityForResult(AfterSalesActivity::class.java, DataCollection().apply { add(Data("data",
+ Gson().toJson(model))) },2001)
+ }
+ binding.btnViewPrograss.setOnClickListener {
+ toActivity(AfterSalesProgressActivity::class.java, DataCollection().apply { add(Data("data",
+ Gson().toJson(model))) })
+ }
+
+ binding.btnChangeAddress.setOnClickListener {
+ toActivityForResult(AddressActivity::class.java, DataCollection().apply {
+ add(Data("flag","2"))
+ add(Data("data",
+ model.id.toString())) },1001)
+ }
+
+ binding.btnViewWL.setOnClickListener {
+ toActivity(LogisticsInfoActivity::class.java, DataCollection().apply { add(Data("data",
+ Gson().toJson(model))) })
+ }
+ binding.btnInputOrder.setOnClickListener {
+ toActivity(InputLogisticsNumActivity::class.java, DataCollection().apply { add(Data("data",
+ Gson().toJson(model))) })
+ }
+
+ binding.btnCancel.setOnClickListener {
+ cancel(model.id.toString())
+ }
+
+ binding.btnDelete.setOnClickListener {
+ delete(model.id.toString())
+ }
+ binding.btnConfirmReceive.setOnClickListener {
+ confrimReceive(model.id.toString())
+ }
+ binding.btnCancelRefund.setOnClickListener {
+ cancelRefund(model.colRefundApply?.id.toString())
+ }
+ binding.contentCustomer.setOnClickListener {
+ toActivity(PeopleCustomerActivity::class.java, DataCollection().apply { add(Data("chatType","1")) })
+ }
+
+
+ }
+
+
+ override fun initData() {
+ model = Gson().fromJson(getReceiveParam().get("data")!!.stringValue.toString(),
+ OrderModel.Order::class.java)
+
+
+ setView()
+
+ productDatas = model.colOrderItems!!
+
+ getInfo()
+
+ }
+
+ fun setView(){
+ setTitleText(CKUtils.getOrderStatus(model.orderStatus))
+ binding.textShopName.text = model.shopName
+ binding.textStatus.text = CKUtils.getOrderStatus(model.orderStatus)
+ binding.textTotal.text = "¥" + model.goodsTotalAmount
+ binding.textShipFee.text = "¥" + model.freightAmount
+
+ binding.textAddress.text = model.receiverName + model.receiverPhone + "\n" + model.receiverAddress
+ binding.textOrderNum.text = model.orderNo
+ binding.textOrderPayNum.text = model.orderNo
+ binding.textCreateDate.text = model.createTime
+ if (TextUtils.isEmpty(model.payTime)){
+ binding.contentPayDate.visibility = View.GONE
+ }else{
+ binding.contentPayDate.visibility = View.VISIBLE
+ binding.textPayDate.text = model.payTime
+ }
+
+ if (TextUtils.isEmpty(model.shipTime)){
+ binding.contentDeliveryDate.visibility = View.GONE
+ }else{
+ binding.contentDeliveryDate.visibility = View.VISIBLE
+ binding.textDeliveryDate.text = model.shipTime
+ }
+
+ if (TextUtils.isEmpty(model.finishTime)){
+ binding.contentOverDate.visibility = View.GONE
+ }else{
+ binding.contentOverDate.visibility = View.VISIBLE
+ binding.textOverDate.text = model.finishTime
+ }
+
+ if (model.orderStatus == 5){
+ binding.textMoney.text = "¥" + 0.00
+ binding.textMoney2.text = "¥" + 0.00
+ }else{
+ binding.textMoney.text = "¥" + model.payAmount.toString()
+ binding.textMoney2.text = "¥" + model.payAmount
+
+ }
+
+ model?.let {
+ for (i in 0..binding.contentBtn.childCount - 1){
+ binding.contentBtn.getChildAt(i).visibility = View.GONE
+ }
+ binding.contentCustomer.visibility = View.VISIBLE
+ binding.line.visibility = View.VISIBLE
+
+ binding.textPayment.text = getString(R.string.pending_payment3)
+
+ if (model.orderStatus == 0){
+ binding.textPayment.text = getString(R.string.pending_payment2)
+ binding.btnCancel.visibility = View.VISIBLE
+ binding.btnPayment.visibility = View.VISIBLE
+ binding.btnChangeAddress.visibility = View.VISIBLE
+ }else if (model.orderStatus == 1){
+ binding.btnCancel.visibility = View.VISIBLE
+ }else if (model.orderStatus == 2){
+ binding.btnConfirmReceive.visibility = View.VISIBLE
+ binding.btnViewWL.visibility = View.VISIBLE
+ binding.btnAfterSale.visibility = View.VISIBLE
+ }else if (model.orderStatus == 3 || model.orderStatus == 4 || model.orderStatus == 5 || model.orderStatus == 6){
+ binding.btnAgain.visibility = View.VISIBLE
+ binding.btnDelete.visibility = View.VISIBLE
+ }else if ( model.orderStatus == 9){
+ if ("0".equals(model.islogisticsNo)){
+ binding.btnInputOrder.visibility = View.VISIBLE
+ }
+ binding.btnViewPrograss.visibility = View.VISIBLE
+ binding.btnAgain.visibility = View.VISIBLE
+ }else if (model.orderStatus == 7){
+ if ("0".equals(model.colRefundApply?.applyStatus)){
+ binding.btnCancelRefund.visibility = View.VISIBLE
+ }
+ binding.btnViewPrograss.visibility = View.VISIBLE
+ binding.btnAgain.visibility = View.VISIBLE
+ }else if ( model.orderStatus == 8 || model.orderStatus == 10){
+ binding.btnViewPrograss.visibility = View.VISIBLE
+ binding.btnAgain.visibility = View.VISIBLE
+ binding.btnDelete.visibility = View.VISIBLE
+ }
+ }
+ }
+
+ fun getInfo() {
+ TTHttpClient.get(this, "我的订单明细", TTRequestParam().apply { add(TTRequestData("id",model.id.toString())) }, object : ICallback {
+ override fun onSuccess(data: String) {
+ model = Gson().fromJson(data,
+ OrderModel.Order::class.java)
+
+ setView()
+
+ var json = JSONObject(data)
+ TTLog.e(json.get("colRefundApply").toString())
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ toast(msg)
+ }
+ })
+ }
+
+ override fun getResult(data: DataCollection, resultCode: Int) {
+ if (resultCode == 1001 || resultCode == 1002|| resultCode == 2001){
+ getInfo()
+ }
+ }
+
+
+ fun cancelRefund(id:String){
+ CKAlertDialog(this,getString(R.string.alert),getString(R.string.alert_option_cancel_refund),object : CKAlertDialog.AlertClickListener{
+ override fun onBack(isConfirm: Boolean) {
+ if (isConfirm){
+ showProgeassDialog(getString(R.string.cancel))
+ TTHttpClient.put(this@OrderDetailsActivity,"取消退款", TTRequestParam().apply { add(
+ TTRequestData("refundId",id)) },object : ICallback{
+ override fun onSuccess(data: String) {
+ toast(getString(R.string.cancel_cussess))
+ getInfo()
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ toast(msg)
+ }
+ })
+ }
+ }
+ }).show()
+ }
+
+
+ fun cancel(id:String){
+ CKAlertDialog(this,getString(R.string.alert),getString(R.string.alert_cancel_order),object : CKAlertDialog.AlertClickListener{
+ override fun onBack(isConfirm: Boolean) {
+ if (isConfirm){
+
+ showProgeassDialog(getString(R.string.cancel))
+ TTHttpClient.put(this@OrderDetailsActivity,"取消订单", TTRequestParam().apply { add(
+ TTRequestData("id",id)) },object : ICallback{
+ override fun onSuccess(data: String) {
+ toast(getString(R.string.cancel_cussess))
+ finish()
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ toast(msg)
+ }
+ })
+ }
+ }
+ }).show()
+ }
+
+ fun delete(id:String){
+ CKAlertDialog(this,getString(R.string.alert),getString(R.string.alert_delete_order),object : CKAlertDialog.AlertClickListener{
+ override fun onBack(isConfirm: Boolean) {
+ if (isConfirm){
+
+ showProgeassDialog(getString(R.string.delete))
+ TTHttpClient.delete(this@OrderDetailsActivity,"删除订单", TTRequestParam().apply { add(
+ TTRequestData("id",id)) },object : ICallback{
+ override fun onSuccess(data: String) {
+ toast(getString(R.string.delete_success))
+ finish()
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ toast(msg)
+ }
+ })
+ }
+ }
+ }).show()
+ }
+ fun confrimReceive(id:String){
+ CKAlertDialog(this,getString(R.string.alert),getString(R.string.alert_option_receive_order),object : CKAlertDialog.AlertClickListener{
+ override fun onBack(isConfirm: Boolean) {
+ if (isConfirm){
+
+ showProgeassDialog(getString(R.string.receive))
+ TTHttpClient.put(this@OrderDetailsActivity,"确认收货", TTRequestParam().apply { add(
+ TTRequestData("orderId",id)) },object : ICallback{
+ override fun onSuccess(data: String) {
+ toast(getString(R.string.receive_cussess))
+ finish()
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ toast(msg)
+ }
+ })
+ }
+ }
+ }).show()
+ }
+
+ class OrderAdapter(
+ var context: CKBaseActivity,
+ var data: List,
+ var itemClickListenner: OnItemClickListenner
+ ) : RecyclerView.Adapter() {
+ override fun onCreateViewHolder(
+ parent: ViewGroup,
+ viewType: Int
+ ): OrderHolder {
+ return OrderHolder(
+ LayoutItemOrderDetailsBinding.inflate(
+ LayoutInflater.from(context),
+ parent,
+ false
+ )
+ )
+ }
+
+ override fun onBindViewHolder(
+ holder: OrderHolder,
+ position: Int
+ ) {
+
+
+ var model = data.get(position)
+
+
+
+ Glide.with(context)
+ .load( model.goodsImg)
+ .placeholder(R.mipmap.image_default)
+ .into(holder.binding.image)
+
+ holder.binding.textDesc.text = context.getString(R.string.desc_text,model.specInfo)
+ holder.binding.textName.text = model.goodsName
+
+ holder.binding.textPrice.text = "¥" + model.unitPrice
+ holder.binding.textCount.text = "x" + model.quantity
+
+
+
+ holder.binding.root.setTag(position)
+ holder.binding.root.setOnClickListener {
+ var tag = it.tag as Int
+ itemClickListenner.onClick(tag, data.get(tag))
+ }
+ }
+
+ override fun getItemCount(): Int {
+ return data.size
+ }
+
+ class OrderHolder(var binding: LayoutItemOrderDetailsBinding) :
+ RecyclerView.ViewHolder(binding.root) {
+
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/ui/act/order/PayOrderActivity.kt b/app/src/main/java/com/ck/ckcollar/app/ui/act/order/PayOrderActivity.kt
new file mode 100644
index 0000000..efa4d48
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/ui/act/order/PayOrderActivity.kt
@@ -0,0 +1,435 @@
+package com.ck.ckcollar.app.ui.act.order
+
+import android.content.Context
+import android.os.Bundle
+import android.text.TextUtils
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.recyclerview.widget.LinearLayoutManager
+import androidx.recyclerview.widget.RecyclerView
+import com.alipay.sdk.app.PayTask
+import com.bumptech.glide.Glide
+import com.ck.ckcollar.app.CKApp
+import com.ck.ckcollar.app.R
+import com.ck.ckcollar.app.action.ActionCode
+import com.ck.ckcollar.app.databinding.ActivityPayOrderBinding
+import com.ck.ckcollar.app.databinding.LayoutItemShopOrderProductBinding
+import com.ck.ckcollar.app.listenner.OnItemClickListenner
+import com.ck.ckcollar.app.model.AddressModel
+import com.ck.ckcollar.app.model.ConfirmOrderModel
+import com.ck.ckcollar.app.model.MemberModel
+import com.ck.ckcollar.app.model.OrderModel
+import com.ck.ckcollar.app.model.PayOrderModel
+import com.ck.ckcollar.app.model.PayPasswordStatus
+import com.ck.ckcollar.app.model.PayResult
+import com.ck.ckcollar.app.model.UserInfoModel
+import com.ck.ckcollar.app.ui.act.setting.PayPsswordActivity
+import com.ck.ckcollar.app.ui.act.shop.OrderSuccessActivity
+import com.ck.ckcollar.app.ui.act.shop.PayPasswordBottomFragment
+import com.ck.ckcollar.app.ui.base.CKBaseActivity
+import com.ck.ckcollar.app.utils.CKUtils
+import com.ck.ckcollar.app.utils.networkone.ICallback
+import com.ck.ckcollar.app.utils.networkone.TTHttpClient
+import com.ck.ckcollar.app.utils.networkone.model.TTRequestData
+import com.ck.ckcollar.app.utils.networkone.model.TTRequestParam
+import com.google.gson.Gson
+import com.tt.kit.model.Data
+import com.tt.kit.model.DataCollection
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.GlobalScope
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
+import java.math.BigDecimal
+
+class PayOrderActivity : CKBaseActivity() {
+
+ lateinit var binding: ActivityPayOrderBinding
+
+ lateinit var productAdapter: ProductAdapter
+
+ var productDatas = listOf()
+
+ lateinit var model: OrderModel.Order
+
+ var memberModel: UserInfoModel? = null
+
+ var payType = "1"
+
+ var selectBalance = false
+ var selectPoints = false
+ var confirmOrderModel : ConfirmOrderModel? = null
+ lateinit var orderSource: String
+ override fun onCreate(savedInstanceState: Bundle?) {
+ binding = ActivityPayOrderBinding.inflate(layoutInflater)
+ setContentView(binding.root)
+ super.onCreate(savedInstanceState)
+
+ }
+
+ override fun initView() {
+ productAdapter =
+ ProductAdapter(this@PayOrderActivity, productDatas, object : OnItemClickListenner {
+ override fun onClick(pos: Int, model: Any) {
+ // toActivity(ProductDetailsActivity::class.java, DataCollection())
+ }
+ })
+ binding.recyclerView.layoutManager =
+ LinearLayoutManager(this@PayOrderActivity, RecyclerView.VERTICAL, false)
+ binding.recyclerView.setHasFixedSize(true)
+ binding.recyclerView.adapter = productAdapter
+
+
+ binding.btnAli.setOnClickListener(payClick)
+ binding.btnWX.setOnClickListener(payClick)
+ binding.btnBalance.setOnClickListener(payClick)
+ binding.btnPoints.setOnClickListener(payClick)
+
+
+ binding.btnBalance.setOnClickListener {
+
+ if (memberModel?.balance == 0.0){
+ toast(getString(R.string.balance_over))
+ return@setOnClickListener
+ }
+
+ selectBalance = !selectBalance
+ if (selectBalance){
+ binding.image3.setImageResource(R.mipmap.image_address_check_select)
+ }else{
+ binding.image3.setImageResource(R.mipmap.image_address_check_narmal)
+ }
+ }
+ binding.btnPoints.setOnClickListener {
+ selectPoints = !selectPoints
+ if (selectPoints){
+ binding.image4.setImageResource(R.mipmap.image_address_check_select)
+ }else{
+ binding.image4.setImageResource(R.mipmap.image_address_check_narmal)
+ }
+ }
+
+
+ binding.btnBuyNow.setOnClickListener {
+
+
+ if (selectBalance){
+ getPayPassword()
+ }else{
+ order("")
+ }
+ }
+
+ }
+
+ override fun initData() {
+
+ model =
+ Gson().fromJson(
+ getReceiveParam().get("data")!!.stringValue,
+ OrderModel.Order::class.java
+ )
+
+ setTitleText(CKUtils.getOrderStatus(model.orderStatus))
+
+ binding.textGoodTotal.text = "¥" + model.goodsTotalAmount
+
+ binding.textTotal.text = "¥" + model.payAmount
+ binding.textShipFeeTotal.text = "¥" + model.freightAmount
+
+ binding.textName.text= model.receiverName + " " + model.receiverPhone
+ binding.textAddress.text = model.receiverAddress
+
+ productDatas = model.colOrderItems!!
+
+ getMemberInfo()
+ getInfo()
+ }
+
+
+ fun getInfo(){
+ TTHttpClient.get(this, "订单ID获取确认信息", TTRequestParam().apply {
+ add(TTRequestData("orderId",model.id))
+ }, object : ICallback {
+ override fun onSuccess(data: String) {
+ confirmOrderModel = Gson().fromJson(data, ConfirmOrderModel::class.java)
+ confirmOrderModel?.let {
+ if ("1".equals(confirmOrderModel?.isPoint.toString())){
+ binding.textPointsAlert.visibility = View.VISIBLE
+ }
+ }
+
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ toast(msg)
+ }
+ })
+ }
+ fun getPayPassword(){
+
+
+ if (TextUtils.isEmpty(payType) && memberModel?.balance == 0.0){
+ if (!selectPoints || "1".equals(confirmOrderModel?.isPoint)){
+ toast(getString(R.string.balance_over))
+ return
+ }
+ }
+
+ checkPasswordStatus()
+
+ }
+
+
+ fun checkPasswordStatus(){
+ TTHttpClient.get(this,"查询支付密码状态", TTRequestParam().apply {
+
+ },object : ICallback{
+ override fun onSuccess(data: String) {
+
+ var model = Gson().fromJson(data,PayPasswordStatus::class.java)
+ if (!model.isSet){
+ toActivityForResult(PayPsswordActivity::class.java, DataCollection(),10001)
+ }else{
+ showPayBottomView()
+ }
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ toast(msg)
+ }
+ })
+ }
+
+
+ fun showPayBottomView(){
+
+ var showBalance = model.payAmount
+ if (selectPoints){
+ CKApp.app.userInfo?.intoAmounts?.let {
+ showBalance = showBalance - BigDecimal(memberModel?.points!!).multiply(
+ BigDecimal(memberModel!!.intoAmounts!!)).setScale(2).toDouble()
+ if (showBalance < 0.0){
+ showBalance = 0.00
+ }
+ }
+ }
+
+ var passwordBottomFragment = PayPasswordBottomFragment(showBalance.toString(), "余额",object : PayPasswordBottomFragment.PasswordCallBack{
+ override fun callBack(password: String) {
+
+ order(password)
+ }
+ })
+
+ passwordBottomFragment.show(supportFragmentManager, "PayPasswordBottomFragment")
+ }
+
+ fun order(payPassword : String) {
+
+ var payType = payType
+ if(selectBalance){
+ if (TextUtils.isEmpty(payType)){
+ payType = "2"
+ }else{
+ payType = payType + ",2"
+ }
+ }
+ if(selectPoints){
+ if (TextUtils.isEmpty(payType)){
+ payType = "3"
+ }else{
+ payType = payType + ",3"
+ }
+ }
+ if (TextUtils.isEmpty(payType)){
+ toast(getString(R.string.please_select_payment_method))
+ return
+ }
+
+ showProgeassDialog(getString(R.string.submit))
+
+
+ TTHttpClient.postJson(this, "订单支付", TTRequestParam().apply {
+ add(
+ TTRequestData(
+ "orderId",
+ model.id
+ )
+ )
+ add(
+ TTRequestData(
+ "payType",
+ payType
+ )
+ )
+ add(
+ TTRequestData(
+ "payPassword",
+ payPassword
+ )
+ )
+ }, object : ICallback {
+ override fun onSuccess(data: String) {
+ var model = Gson().fromJson(data, PayOrderModel::class.java)
+
+ if ("0".equals(this@PayOrderActivity.payType)) {
+ //微信
+ }else if ("1".equals(this@PayOrderActivity.payType)) {
+ if (TextUtils.isEmpty(model.orderStr)){
+ toActivity(OrderSuccessActivity::class.java, DataCollection())
+ finish(DataCollection(),1002)
+ }else{
+ aliPay(model.orderStr!!)
+ }
+ }else{
+ toast(getString(R.string.order_success))
+
+ toActivity(OrderSuccessActivity::class.java, DataCollection())
+ finish(DataCollection(),1002)
+ }
+
+ }
+
+ override fun onFailed(code: String, msg: String) {
+
+ toast(msg)
+
+ }
+ })
+ }
+
+ fun aliPay(orderStr: String) {
+ GlobalScope.launch(Dispatchers.IO) {
+
+ val alipay = PayTask(this@PayOrderActivity)
+ val result = alipay.payV2(orderStr, true)
+
+ var payResult = PayResult(result)
+
+ val resultStatus: String? = payResult.resultStatus
+ withContext(Dispatchers.Main) {
+ // 判断resultStatus 为9000则代表支付成功
+ if (TextUtils.equals(resultStatus, "9000")) {
+ // 该笔订单是否真实支付成功,需要依赖服务端的异步通知。
+ toast(getString(R.string.payment_success))
+ finish(DataCollection(),1002)
+ } else {
+ toast(getString(R.string.payment_faild))
+ }
+ }
+ }
+ }
+
+ fun getMemberInfo() {
+ TTHttpClient.get(this, "个人资料", TTRequestParam(), object : ICallback {
+ override fun onSuccess(data: String) {
+ memberModel = Gson().fromJson(data, UserInfoModel::class.java)
+
+ binding.textBalance.text =
+ getString(R.string.balance2, memberModel!!.balance.toString())
+ binding.textPoints.text =
+ getString(R.string.points3, memberModel!!.points.toString())
+
+
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ toast(msg)
+ finish()
+ }
+ })
+ }
+
+ override fun getResult(data: DataCollection, resultCode: Int) {
+ if (resultCode == 10001){
+ showPayBottomView()
+ }
+ }
+
+ var payClick = object : View.OnClickListener {
+ override fun onClick(v: View?) {
+ binding.image1.setImageResource(R.mipmap.image_address_check_narmal)
+ binding.image2.setImageResource(R.mipmap.image_address_check_narmal)
+ when (v?.id) {
+ R.id.btnAli -> {
+ if (!"1".equals(payType)){
+ binding.image1.setImageResource(R.mipmap.image_address_check_select)
+ payType = "1"
+ }else{
+ payType = ""
+ }
+
+ }
+
+ R.id.btnWX -> {
+ if (!"0".equals(payType)){
+ binding.image2.setImageResource(R.mipmap.image_address_check_select)
+ payType = "0"
+ }else{
+ payType = ""
+ }
+ }
+
+ }
+ }
+ }
+
+
+ class ProductAdapter(
+ var context: Context,
+ var data: List,
+ var itemClickListenner: OnItemClickListenner
+ ) : RecyclerView.Adapter() {
+ override fun onCreateViewHolder(
+ parent: ViewGroup,
+ viewType: Int
+ ): ProductHolder {
+ return ProductHolder(
+ LayoutItemShopOrderProductBinding.inflate(
+ LayoutInflater.from(context),
+ parent,
+ false
+ )
+ )
+ }
+
+ override fun onBindViewHolder(
+ holder: ProductHolder,
+ position: Int
+ ) {
+
+ var model = data.get(position)
+
+ holder.binding.textDesc.text = model.goodsName
+ holder.binding.textType.text = model.specInfo
+ var price = if (CKApp.app.userInfo!!.isMember == true) {
+ model.unitPrice.toString()
+ } else {
+ model.unitPrice.toString()
+ }
+ holder.binding.textPriec.text = "¥" + price
+ holder.binding.textCount.text = "x" + model.quantity
+
+ Glide.with(context)
+ .load( model.goodsImg)
+ .placeholder(R.mipmap.image_default)
+ .into(holder.binding.image)
+ holder.binding.root.setTag(position)
+ holder.binding.root.setOnClickListener {
+ var tag = it.tag as Int
+ itemClickListenner.onClick(tag, data.get(tag))
+ }
+ }
+
+ override fun getItemCount(): Int {
+ return data.size
+ }
+
+ class ProductHolder(var binding: LayoutItemShopOrderProductBinding) :
+ RecyclerView.ViewHolder(binding.root) {
+
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/ui/act/order/RefundActivity.kt b/app/src/main/java/com/ck/ckcollar/app/ui/act/order/RefundActivity.kt
new file mode 100644
index 0000000..6c008bb
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/ui/act/order/RefundActivity.kt
@@ -0,0 +1,397 @@
+package com.ck.ckcollar.app.ui.act.order
+
+import android.content.Intent
+import android.net.Uri
+import android.os.Build
+import android.os.Bundle
+import android.os.Environment
+import android.provider.MediaStore
+import android.text.Editable
+import android.text.TextUtils
+import android.text.TextWatcher
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.AdapterView
+import android.widget.BaseAdapter
+import android.widget.ImageView
+import androidx.core.content.FileProvider
+import com.bumptech.glide.Glide
+import com.ck.ckcollar.app.R
+import com.ck.ckcollar.app.action.ActionCode
+import com.ck.ckcollar.app.databinding.ActivityRefundBinding
+import com.ck.ckcollar.app.databinding.LayoutItemImage2Binding
+import com.ck.ckcollar.app.model.ImageModel
+import com.ck.ckcollar.app.model.OrderModel
+import com.ck.ckcollar.app.model.UploadModel
+import com.ck.ckcollar.app.ui.act.mine.FeedBackActivity
+import com.ck.ckcollar.app.ui.act.petmanager.AddPetActivity.ImageAdapter
+import com.ck.ckcollar.app.ui.act.petmanager.ImageViewActivity
+import com.ck.ckcollar.app.ui.base.CKBaseActivity
+import com.ck.ckcollar.app.ui.dialog.CKAlertDialog
+import com.ck.ckcollar.app.ui.dialog.CKPhotoDialog
+import com.ck.ckcollar.app.utils.CKUtils
+import com.ck.ckcollar.app.utils.Const
+import com.ck.ckcollar.app.utils.networkone.ICallback
+import com.ck.ckcollar.app.utils.networkone.TTHttpClient
+import com.ck.ckcollar.app.utils.networkone.model.TTRequestData
+import com.ck.ckcollar.app.utils.networkone.model.TTRequestParam
+import com.cyclone.shadowsocks.utils.PreferencesUtils
+import com.google.gson.Gson
+import com.tt.kit.model.Data
+import com.tt.kit.model.DataCollection
+import com.tt.kit.utils.TTLog
+import com.tt.kit.utils.TTUtils
+import java.io.File
+
+class RefundActivity: CKBaseActivity() {
+
+ lateinit var binding: ActivityRefundBinding
+ lateinit var imageAdapter: ImageAdapter
+ var data = mutableListOf()
+ lateinit var model : OrderModel.Order
+
+ lateinit var refundType: String
+ var refundReason = ""
+ override fun onCreate(savedInstanceState: Bundle?) {
+ binding = ActivityRefundBinding.inflate(layoutInflater)
+ setContentView(binding.root)
+ super.onCreate(savedInstanceState)
+
+
+ }
+
+ override fun initView() {
+ binding.tvCharCount.text = getString(R.string.char_count_0_200,binding.editSupplementary.text.toString().length.toString())
+
+ binding.editSupplementary.addTextChangedListener(object : TextWatcher{
+ override fun afterTextChanged(p0: Editable?) {
+ }
+
+ override fun beforeTextChanged(
+ p0: CharSequence?,
+ p1: Int,
+ p2: Int,
+ p3: Int
+ ) {
+
+ }
+
+ override fun onTextChanged(
+ p0: CharSequence?,
+ p1: Int,
+ p2: Int,
+ p3: Int
+ ) {
+ binding.tvCharCount.text = getString(R.string.char_count_0_200,binding.editSupplementary.text.toString().length.toString())
+ }
+ })
+
+
+
+ data.add(ImageModel().apply { isAdd = true })
+ imageAdapter = ImageAdapter(this@RefundActivity,data)
+ binding.girdView.adapter = imageAdapter
+ binding.girdView.onItemClickListener = object :
+ AdapterView.OnItemClickListener {
+ override fun onItemClick(
+ p0: AdapterView<*>?,
+ p1: View?,
+ p2: Int,
+ p3: Long
+ ) {
+ if (!data.get(p2).isAdd){
+ return
+ }
+ CKPhotoDialog(this@RefundActivity,object : CKPhotoDialog.PhotoClickListener{
+ override fun onBack(mark: Int, position: Int) {
+ try {
+ if (mark == 0){
+ takePhoto()
+ }else{
+ //相册
+ val i = Intent(
+ Intent.ACTION_PICK,
+ MediaStore.Images.Media.EXTERNAL_CONTENT_URI
+ )
+ i.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,"image/*");
+ startActivityForResult(i, 56)
+ }
+ }catch (e: Exception){
+ e.printStackTrace()
+ }
+
+ }
+ }).show()
+ }
+
+ }
+ binding.girdView.onItemLongClickListener = object :
+ AdapterView.OnItemLongClickListener {
+
+ override fun onItemLongClick(
+ p0: AdapterView<*>?,
+ p1: View?,
+ p2: Int,
+ p3: Long
+ ): Boolean {
+
+ if (data.get(p2).isAdd){
+
+ var urls = mutableListOf()
+ for (d in data){
+ if (d.isAdd){
+ continue
+ }
+ if(TextUtils.isEmpty(d.url)){
+ urls.add(d.path!!)
+ }else{
+ urls.add(d.url!!)
+ }
+ }
+ toActivity(ImageViewActivity::class.java, DataCollection().apply {
+ add(Data("data",Gson().toJson(urls)))
+ add(Data("pos",p2.toString()))
+ })
+
+ return false
+ }
+
+ CKAlertDialog(this@RefundActivity,getString(R.string.alert),getString(R.string.alert_delete_photo),object : CKAlertDialog.AlertClickListener{
+ override fun onBack(isConfirm: Boolean) {
+ if (isConfirm){
+ data.removeAt(p2)
+ imageAdapter.data = data
+ imageAdapter.notifyDataSetChanged()
+ }
+ }
+ }).show()
+
+
+ return false
+ }
+ }
+
+ binding.btnReason.setOnClickListener {
+ var fragment = RefundReasonBottomFragment(object : RefundReasonBottomFragment.OnItemChooseLisnner{
+ override fun onItemChoose(pos: Int,text: String) {
+ binding.textReason.text = text
+ refundReason = pos.toString()
+ }
+ })
+ fragment.show(supportFragmentManager,"RefundReasonBottomFragment")
+ }
+
+ binding.btnSubmitRefund.setOnClickListener {
+ uploadImage()
+ }
+ }
+
+ override fun initData() {
+ model = Gson().fromJson(getReceiveParam().get("data")!!.stringValue.toString(),
+ OrderModel.Order::class.java)
+
+
+ refundType = getReceiveParam().get("refundType")!!.stringValue.toString()
+
+
+ binding.textAmount.text= "¥" + model.payAmount.toString()
+ binding.textCantAmount.text = getString(R.string.cannot_modify_amount,model.payAmount.toString())
+
+ if ("0".equals(refundType)){
+ binding.textRefundType.text = getString(R.string.not_received_or_refused)
+ setTitleText(getString(R.string.apply_refund))
+
+ }else{
+ binding.textRefundType.text = getString(R.string.received_or_refused)
+ binding.content.visibility = View.GONE
+
+ setTitleText(getString(R.string.apply_return_refund))
+ }
+
+
+
+ }
+
+
+
+ fun uploadImage(){
+
+ if (TextUtils.isEmpty(refundReason)){
+ toast(getString(R.string.select_reason))
+ return
+ }
+ if (data.size == 1){
+ apply("")
+ }else{
+ var param = TTRequestParam()
+ for (model in data){
+ if (model.isAdd == false){
+ param.files.add(File(model.path))
+ }
+ }
+ showProgeassDialog()
+ TTHttpClient.postFile(this,"上传照片s", param,object : ICallback{
+ override fun onSuccess(data: String) {
+ var model = Gson().fromJson(data,UploadModel::class.java)
+
+ apply(model.urls)
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ hiddenProgeassDialog()
+ toast(msg)
+ }
+ })
+ }
+
+
+ }
+ fun apply(photo : String){
+
+
+ showProgeassDialog(getString(R.string.submit))
+ var commodityState = if(model.orderStatus >= 3){
+ "1"
+ }else{
+ "0"
+ }
+ var param = TTRequestParam().apply {
+ add(TTRequestData("orderId",model.id))
+ add(TTRequestData("commodityState",commodityState))
+ add(TTRequestData("refundType",refundType))
+ add(TTRequestData("refundReason",refundReason))
+ add(TTRequestData("refundAmount",model.payAmount))
+ add(TTRequestData("orderNo",model.orderNo!!))
+ add(TTRequestData("supplementInfo",binding.editSupplementary.text.toString()))
+ add(TTRequestData("attachmentUrls",photo))
+
+ }
+ TTHttpClient.postJson(this,"申请售后",param ,object : ICallback{
+ override fun onSuccess(data: String) {
+ toast(getString(R.string.submit_success))
+ finish(DataCollection(),2001)
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ toast(msg)
+ }
+ })
+ }
+
+
+
+ fun takePhoto() {
+ try {
+ val openCameraIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
+
+ val vFile = File(
+ getExternalFilesDir(Environment.DIRECTORY_PICTURES),
+ "${System.currentTimeMillis()}.png"
+ )
+
+ val parentDir = vFile.parentFile
+ if (parentDir != null && !parentDir.exists()) {
+ parentDir.mkdirs()
+ }
+ TTLog.e(vFile.absolutePath)
+ PreferencesUtils.putString(getApplicationContext(), Const.IMAGE_PATH, vFile.absolutePath)
+
+ val cameraUri: Uri = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+ FileProvider.getUriForFile(
+ this@RefundActivity,
+ packageName + ".fileprovider",
+ vFile
+ )
+ } else {
+ Uri.fromFile(vFile)
+ }
+
+ openCameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, cameraUri)
+ startActivityForResult(openCameraIntent, 55)
+ }catch (e: Exception){
+ e.printStackTrace()
+ }
+
+ }
+
+ override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
+ super.onActivityResult(requestCode, resultCode, data)
+
+ if (requestCode == 55 && resultCode == RESULT_OK) {
+ var path = PreferencesUtils.getString(this@RefundActivity, Const.IMAGE_PATH,"")
+ this.data.add(this.data.size - 1,ImageModel().apply { this.path = path })
+ imageAdapter.data = this.data
+ imageAdapter.notifyDataSetChanged()
+ }else if (requestCode == 56 && resultCode == RESULT_OK) {
+ var path = TTUtils.getImageUrl(this, data!!.getData());
+ this.data.add(this.data.size - 1,ImageModel().apply { this.path = path })
+ imageAdapter.data = this.data
+ imageAdapter.notifyDataSetChanged()
+ }
+ }
+
+
+ class ImageAdapter(var context: RefundActivity, var data: List) : BaseAdapter() {
+
+ override fun getCount(): Int {
+ var count = if (data.size > 4){
+ 4
+ }else{
+ data.size
+ }
+ return count
+ }
+
+ override fun getItem(p0: Int): Any? {
+ TODO("Not yet implemented")
+ }
+
+ override fun getItemId(p: Int): Long {
+ return p.toLong()
+ }
+
+ override fun getView(
+ p0: Int,
+ p1: View?,
+ p2: ViewGroup?
+ ): View? {
+ var layoutItemImageBinding =
+ LayoutItemImage2Binding.inflate(LayoutInflater.from(context))
+ layoutItemImageBinding.root.layoutParams = ViewGroup.LayoutParams(TTUtils.dpToPx(context,72).toInt(),
+ TTUtils.dpToPx(context,72).toInt())
+ var model = data.get(p0)
+ if (model.isAdd) {
+ layoutItemImageBinding.image.setImageResource(R.mipmap.image_add3)
+ layoutItemImageBinding.image.scaleType = ImageView.ScaleType.CENTER_CROP
+ layoutItemImageBinding.imageDelete.visibility = View.GONE
+ } else {
+ layoutItemImageBinding.image.scaleType = ImageView.ScaleType.CENTER_CROP
+ layoutItemImageBinding.image.setImageBitmap(
+ TTUtils.getBitmap(
+ model.path,
+ 200,
+ 200
+ )
+ )
+ layoutItemImageBinding.imageDelete.visibility = View.VISIBLE
+ layoutItemImageBinding.imageDelete.setOnClickListener {
+
+
+
+ CKAlertDialog(context,context.getString(R.string.alert),context.getString(R.string.alert_delete_photo),object : CKAlertDialog.AlertClickListener{
+ override fun onBack(isConfirm: Boolean) {
+ if (isConfirm){
+ context.data.removeAt(p0)
+ this@ImageAdapter.data = context.data
+ notifyDataSetChanged()
+ }
+ }
+ }).show()
+
+ }
+ }
+ return layoutItemImageBinding.root
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/ui/act/order/RefundReasonBottomFragment.kt b/app/src/main/java/com/ck/ckcollar/app/ui/act/order/RefundReasonBottomFragment.kt
new file mode 100644
index 0000000..9a6d674
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/ui/act/order/RefundReasonBottomFragment.kt
@@ -0,0 +1,118 @@
+package com.ck.ckcollar.app.ui.act.order
+
+import android.content.Context
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.recyclerview.widget.LinearLayoutManager
+import androidx.recyclerview.widget.RecyclerView
+import com.ck.ckcollar.app.R
+import com.ck.ckcollar.app.databinding.FragmentRefundReasonBinding
+import com.ck.ckcollar.app.databinding.LayoutItemRefundReasonBinding
+import com.ck.ckcollar.app.listenner.OnItemClickListenner
+import com.tt.kit.dialog.TTBottomSheetDialogFragment
+
+class RefundReasonBottomFragment(var onItemChooseLisnner : OnItemChooseLisnner?): TTBottomSheetDialogFragment() {
+
+ lateinit var binding: FragmentRefundReasonBinding
+ var data = mutableListOf()
+ lateinit var reasonAdapter: ReasonAdapter
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setStyle(STYLE_NORMAL, R.style.BottomSheetDialog_Rounded)
+
+ }
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ binding = FragmentRefundReasonBinding.inflate(layoutInflater)
+ return binding.root
+ }
+
+ override fun initView() {
+
+ reasonAdapter = ReasonAdapter( activity!! , data, object : OnItemClickListenner {
+ override fun onClick(pos: Int, model: Any) {
+
+ reasonAdapter.selectPos = pos
+ reasonAdapter.notifyDataSetChanged()
+
+ }
+ })
+ binding.recyclerView.layoutManager =
+ LinearLayoutManager(activity!!, RecyclerView.VERTICAL,false)
+ binding.recyclerView.setHasFixedSize(true)
+ binding.recyclerView.adapter = reasonAdapter
+
+ binding.btnSubmit.setOnClickListener {
+
+ if (reasonAdapter.selectPos == -1){
+ toast(getString(R.string.please_choose_data))
+ return@setOnClickListener
+ }
+ onItemChooseLisnner?.onItemChoose(reasonAdapter.selectPos,data.get(reasonAdapter.selectPos))
+
+ dismiss()
+ }
+ }
+
+ override fun initData() {
+ data.add(getString(R.string.reason_1))
+ data.add(getString(R.string.reason_2))
+ data.add(getString(R.string.reason_3))
+ data.add(getString(R.string.reason_4))
+ data.add(getString(R.string.reason_5))
+ data.add(getString(R.string.reason_6))
+ data.add(getString(R.string.reason_7))
+ data.add(getString(R.string.reason_8))
+ data.add(getString(R.string.reason_9))
+
+ }
+
+
+ class ReasonAdapter(var context: Context, var data: List, var itemClickListenner: OnItemClickListenner) : RecyclerView.Adapter() {
+
+ var selectPos = -1
+ override fun onCreateViewHolder(
+ parent: ViewGroup,
+ viewType: Int
+ ): ReasonwHolder {
+ return ReasonwHolder(LayoutItemRefundReasonBinding.inflate(LayoutInflater.from(context),parent,false))
+ }
+
+ override fun onBindViewHolder(
+ holder: ReasonwHolder,
+ position: Int
+ ) {
+
+ if (selectPos == position){
+ holder.binding.image.setImageResource(R.mipmap.image_address_check_select)
+ }else{
+ holder.binding.image.setImageResource(R.mipmap.image_address_check_narmal)
+ }
+ holder.binding.text.text = data.get(position)
+ holder.binding.root.setTag(position)
+ holder.binding.root.setOnClickListener {
+ var tag = it.tag as Int
+ itemClickListenner.onClick(tag, data.get(tag))
+ }
+
+ }
+
+ override fun getItemCount(): Int {
+ return data.size
+ }
+
+ class ReasonwHolder(var binding: LayoutItemRefundReasonBinding) : RecyclerView.ViewHolder(binding.root){
+
+ }
+
+ }
+
+ interface OnItemChooseLisnner{
+ fun onItemChoose(pos :Int,text : String)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/ui/act/petmanager/AddPetActivity.kt b/app/src/main/java/com/ck/ckcollar/app/ui/act/petmanager/AddPetActivity.kt
new file mode 100644
index 0000000..cfd0878
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/ui/act/petmanager/AddPetActivity.kt
@@ -0,0 +1,524 @@
+package com.ck.ckcollar.app.ui.act.petmanager
+
+import android.content.Intent
+import android.graphics.Bitmap
+import android.net.Uri
+import android.os.Build
+import android.os.Bundle
+import android.os.Environment
+import android.provider.MediaStore
+import android.text.TextUtils
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.AdapterView
+import android.widget.BaseAdapter
+import android.widget.ImageView
+import androidx.core.content.FileProvider
+import com.bumptech.glide.Glide
+import com.ck.ckcollar.app.R
+import com.ck.ckcollar.app.databinding.ActivityAddPetBinding
+import com.ck.ckcollar.app.databinding.LayoutItemImageBinding
+import com.ck.ckcollar.app.model.AIPhotoModel
+import com.ck.ckcollar.app.model.ImageModel
+import com.ck.ckcollar.app.model.UploadModel
+import com.ck.ckcollar.app.ui.base.CKBaseActivity
+import com.ck.ckcollar.app.ui.dialog.CKAlertDialog
+import com.ck.ckcollar.app.ui.dialog.CKPhotoDialog
+import com.ck.ckcollar.app.ui.dialog.CKPickViewDialog
+import com.ck.ckcollar.app.utils.CKUtils
+import com.ck.ckcollar.app.utils.Const
+import com.ck.ckcollar.app.utils.networkone.ICallback
+import com.ck.ckcollar.app.utils.networkone.TTHttpClient
+import com.ck.ckcollar.app.utils.networkone.model.TTRequestData
+import com.ck.ckcollar.app.utils.networkone.model.TTRequestParam
+import com.cyclone.shadowsocks.utils.PreferencesUtils
+import com.google.gson.Gson
+import com.tt.kit.base.TTBaseActivity
+import com.tt.kit.model.Data
+import com.tt.kit.model.DataCollection
+import com.tt.kit.utils.LiveDataBus
+import com.tt.kit.utils.TTLog
+import com.tt.kit.utils.TTUtils
+import java.io.File
+
+class AddPetActivity : CKBaseActivity() {
+
+ lateinit var binding: ActivityAddPetBinding
+ lateinit var imageAdapter: ImageAdapter
+ var data = mutableListOf()
+ override fun onCreate(savedInstanceState: Bundle?) {
+ binding = ActivityAddPetBinding.inflate(layoutInflater)
+ setContentView(binding.root)
+ super.onCreate(savedInstanceState)
+
+ setTitleText(getString(R.string.add_pet))
+ setStatusBarColor(resources.getColor(R.color.white))
+
+ setActionBarColor(resources.getColor(R.color.white))
+ setRightTextColor(resources.getColor(R.color.color_F83B3B))
+
+ }
+
+
+ override fun initView() {
+ data.add(ImageModel().apply { isAdd = true })
+ imageAdapter = ImageAdapter(this,data)
+ binding.girdView.adapter = imageAdapter
+ binding.girdView.onItemClickListener = object :
+ AdapterView.OnItemClickListener {
+ override fun onItemClick(
+ p0: AdapterView<*>?,
+ p1: View?,
+ p2: Int,
+ p3: Long
+ ) {
+ if (!data.get(p2).isAdd){
+ var urls = mutableListOf()
+ for (d in data){
+ if (d.isAdd){
+ continue
+ }
+ if(TextUtils.isEmpty(d.url)){
+ urls.add(d.path!!)
+ }else{
+ urls.add(d.url!!)
+ }
+ }
+ toActivity(ImageViewActivity::class.java, DataCollection().apply {
+ add(Data("data",Gson().toJson(urls)))
+ add(Data("pos",p2.toString()))
+ })
+ return
+ }
+ CKPhotoDialog(this@AddPetActivity,object : CKPhotoDialog.PhotoClickListener{
+ override fun onBack(mark: Int, position: Int) {
+
+ try {
+ if (mark == 0){
+ if (!checkCameraPermissions()){
+ CKAlertDialog(this@AddPetActivity,getString(R.string.alert),getString(R.string.camera_alert),object : CKAlertDialog.AlertClickListener{
+ override fun onBack(isConfirm: Boolean) {
+ TODO("Not yet implemented")
+ }
+
+ }).show()
+ return
+ }
+ takePhoto()
+ }else{
+ //相册
+ val i = Intent(
+ Intent.ACTION_PICK,
+ MediaStore.Images.Media.EXTERNAL_CONTENT_URI
+ )
+ i.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,"image/*");
+ startActivityForResult(i, 56)
+ }
+ }catch (e : Exception){
+ e.printStackTrace()
+ }
+
+ }
+ }).show()
+ }
+
+ }
+
+ binding.tvSpecies.setOnClickListener {
+ CKPickViewDialog(this@AddPetActivity,listOf("狗","猫"),object : CKPickViewDialog.ItemClickListener{
+ override fun onBack(pos: Int, data: String) {
+ binding.tvSpecies.text = data
+ }
+ }).show()
+ }
+ binding.tvBodyType.setOnClickListener {
+ CKPickViewDialog(this@AddPetActivity,listOf("小型","中型","大型"),object : CKPickViewDialog.ItemClickListener{
+ override fun onBack(pos: Int, data: String) {
+ binding.tvBodyType.text = data
+ }
+ }).show()
+ }
+ binding.tvColor.setOnClickListener {
+ CKPickViewDialog(this@AddPetActivity,listOf("白色","黑色","棕色","米色","灰色","红色","咖啡色","奶油色","其他"
+ ),object : CKPickViewDialog.ItemClickListener{
+ override fun onBack(pos: Int, data: String) {
+ binding.tvColor.text = data
+ }
+ }).show()
+ }
+ binding.tvVaccination.setOnClickListener {
+ CKPickViewDialog(this@AddPetActivity,listOf("是","否"),object : CKPickViewDialog.ItemClickListener{
+ override fun onBack(pos: Int, data: String) {
+ binding.tvVaccination.text = data
+ }
+ }).show()
+ }
+
+ binding.btnItem1.setOnClickListener {
+ CKPickViewDialog(this@AddPetActivity,listOf("狗","猫"),object : CKPickViewDialog.ItemClickListener{
+ override fun onBack(pos: Int, data: String) {
+ binding.tvSpecies.text = data
+ }
+ }).show()
+ }
+ binding.btnItem2.setOnClickListener {
+ CKPickViewDialog(this@AddPetActivity,listOf("小型","中型","大型"),object : CKPickViewDialog.ItemClickListener{
+ override fun onBack(pos: Int, data: String) {
+ binding.tvBodyType.text = data
+ }
+ }).show()
+ }
+ binding.btnItem3.setOnClickListener {
+ CKPickViewDialog(this@AddPetActivity,listOf("白色","黑色","棕色","米色","灰色","红色","咖啡色","奶油色","其他"
+ ),object : CKPickViewDialog.ItemClickListener{
+ override fun onBack(pos: Int, data: String) {
+ binding.tvColor.text = data
+ }
+ }).show()
+ }
+ binding.btnItem4.setOnClickListener {
+ CKPickViewDialog(this@AddPetActivity,listOf("是","否"),object : CKPickViewDialog.ItemClickListener{
+ override fun onBack(pos: Int, data: String) {
+ binding.tvVaccination.text = data
+ }
+ }).show()
+ }
+ binding.btnSubmit.setOnClickListener {
+ uploadImage()
+ }
+
+ binding.tvAiRecognize.setOnClickListener {
+ takePhoto2()
+ }
+
+ }
+
+ override fun initData() {
+ var data = getReceiveParam().get("data")
+ data?.let {
+ binding.tvSpecies.text = data.stringValue
+ }
+ var variety = getReceiveParam().get("variety")
+ variety?.let {
+ binding.etBreed.setText(variety.stringValue)
+ }
+
+ }
+ fun uploadImage(){
+ if (binding.etName.isEmpty()){
+ toast(getString(R.string.input_name))
+ return
+ }
+ if (binding.tvSpecies.isEmpty()){
+ toast(getString(R.string.select_species))
+ return
+ }
+
+ if (binding.etBreed.isEmpty()){
+ toast(getString(R.string.input_breed))
+ return
+ }
+ if (binding.etAge.isEmpty()){
+ toast(getString(R.string.input_age))
+ return
+ }
+ if (binding.etAge.text.toString().toFloat() > 100){
+ toast(getString(R.string.input_age_over))
+ return
+ }
+
+ if (binding.etHeight.isEmpty()){
+ toast(getString(R.string.input_height))
+ return
+ }
+ if (binding.etHeight.text.toString().toFloat() > 200){
+ toast(getString(R.string.input_height_over))
+ return
+ }
+
+ if (binding.etWeight.isEmpty()){
+ toast(getString(R.string.input_weight))
+ return
+ }
+ if (binding.etWeight.text.toString().toFloat() > 1000){
+ toast(getString(R.string.input_weight_over))
+ return
+ }
+
+ if (binding.tvBodyType.isEmpty()){
+ toast(getString(R.string.select_body_type))
+ return
+ }
+
+ if (binding.tvColor.isEmpty()){
+ toast(getString(R.string.select_color))
+ return
+ }
+ if (binding.tvVaccination.isEmpty()){
+ toast(getString(R.string.select_vaccination))
+ return
+ }
+ if (data.size == 1){
+ toast(getString(R.string.please_dupload_photos))
+ return
+ }
+
+ var param = TTRequestParam()
+ for (model in data){
+ if (model.isAdd == false){
+ param.files.add(File(model.path))
+ }
+ }
+ showProgeassDialog()
+ TTHttpClient.postFile(this,"上传照片s", param,object : ICallback{
+ override fun onSuccess(data: String) {
+ var model = Gson().fromJson(data,UploadModel::class.java)
+
+ add(model.urls)
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ hiddenProgeassDialog()
+ toast(msg)
+ }
+ })
+ }
+ fun add(patPhoto : String){
+
+
+ var param = TTRequestParam().apply {
+ add(TTRequestData("patName",binding.etName.text.toString()))
+ add(TTRequestData("patSpecies", CKUtils.getPetSpecValue(binding.tvSpecies.text.toString())))
+ add(TTRequestData("patVariety",binding.etBreed.text.toString()))
+ add(TTRequestData("patAge",binding.etAge.text.toString()))
+ add(TTRequestData("patHeight",binding.etHeight.text.toString()))
+ add(TTRequestData("patWeight",binding.etWeight.text.toString()))
+ add(TTRequestData("patBodytype",binding.tvBodyType.text.toString()))
+ add(TTRequestData("patColor",binding.tvColor.text.toString()))
+ add(TTRequestData("patProphylactic",binding.tvVaccination.text.toString()))
+ add(TTRequestData("patPhoto",patPhoto))
+ }
+ TTHttpClient.postJson(this,"添加宠物",param ,object : ICallback{
+ override fun onSuccess(data: String) {
+ toast(getString(R.string.add_success))
+
+ LiveDataBus.get().with("FIRST").value = 1
+
+ finish()
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ toast(msg)
+ }
+ })
+ }
+ override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
+ super.onActivityResult(requestCode, resultCode, data)
+
+ if (requestCode == 55 && resultCode == RESULT_OK) {
+ var path = PreferencesUtils.getString(this@AddPetActivity, Const.IMAGE_PATH,"")
+ this.data.add(this.data.size - 1,ImageModel().apply { this.path = path })
+ imageAdapter.data = this.data
+ imageAdapter.notifyDataSetChanged()
+ }else if (requestCode == 56 && resultCode == RESULT_OK) {
+ var path = TTUtils.getImageUrl(this, data!!.getData());
+ this.data.add(this.data.size - 1,ImageModel().apply { this.path = path })
+ imageAdapter.data = this.data
+ imageAdapter.notifyDataSetChanged()
+ }else if (requestCode == 555 && resultCode == RESULT_OK) {
+ var path = PreferencesUtils.getString(this@AddPetActivity, Const.IMAGE_PATH,"")
+ uploadImage(path!!)
+ }
+ binding.textPhotoNum.setText((this.data.size - 1 ).toString() + "/3")
+ }
+ fun takePhoto() {
+ try {
+ val openCameraIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
+
+ val vFile = File(
+ getExternalFilesDir(Environment.DIRECTORY_PICTURES),
+ "${System.currentTimeMillis()}.png"
+ )
+
+ val parentDir = vFile.parentFile
+ if (parentDir != null && !parentDir.exists()) {
+ parentDir.mkdirs()
+ }
+ TTLog.e(vFile.absolutePath)
+ PreferencesUtils.putString(getApplicationContext(), Const.IMAGE_PATH, vFile.absolutePath)
+
+ val cameraUri: Uri = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+ FileProvider.getUriForFile(
+ this@AddPetActivity,
+ packageName + ".fileprovider",
+ vFile
+ )
+ } else {
+ Uri.fromFile(vFile)
+ }
+
+ openCameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, cameraUri)
+ startActivityForResult(openCameraIntent, 55)
+ }catch (e: Exception){
+ e.printStackTrace()
+ }
+
+ }
+ fun takePhoto2() {
+ try {
+ val openCameraIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
+
+ val vFile = File(
+ getExternalFilesDir(Environment.DIRECTORY_PICTURES),
+ "${System.currentTimeMillis()}.png"
+ )
+
+ val parentDir = vFile.parentFile
+ if (parentDir != null && !parentDir.exists()) {
+ parentDir.mkdirs()
+ }
+ TTLog.e(vFile.absolutePath)
+ PreferencesUtils.putString(getApplicationContext(), Const.IMAGE_PATH, vFile.absolutePath)
+
+ val cameraUri: Uri = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+ FileProvider.getUriForFile(
+ this@AddPetActivity,
+ packageName + ".fileprovider",
+ vFile
+ )
+ } else {
+ Uri.fromFile(vFile)
+ }
+
+ openCameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, cameraUri)
+ startActivityForResult(openCameraIntent, 555)
+ }catch (e : Exception){
+ e.printStackTrace()
+ }
+
+ }
+ override fun rightButton1OnClick() {
+ CKAlertDialog(this@AddPetActivity,getString(R.string.alert),getString(R.string.alert_delete_pet),object : CKAlertDialog.AlertClickListener{
+ override fun onBack(isConfirm: Boolean) {
+ if (isConfirm){
+ finish()
+ }
+ }
+ }).show()
+ }
+
+
+ fun uploadImage(path: String) {
+
+ var param = TTRequestParam()
+ param.files.add(File(path))
+
+ showProgeassDialog(getString(R.string.see))
+ TTHttpClient.postFile(this, "上传照片s", param, object : ICallback {
+ override fun onSuccess(data: String) {
+ var model = Gson().fromJson(data, UploadModel::class.java)
+
+ //aiPhoto(ActionCode.BASE_URL + "/" + model.fileNames)
+ aiPhoto(model.urls)
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ hiddenProgeassDialog()
+ toast(msg)
+ }
+ })
+ }
+
+ fun aiPhoto(imageUrl: String) {
+
+ TTHttpClient.postJson(this, "AI拍照识别", TTRequestParam().apply {
+ add(TTRequestData("imageUrl", imageUrl))
+ }, object : ICallback {
+ override fun onSuccess(data: String) {
+ hiddenProgeassDialog()
+
+ var model = Gson().fromJson(data, AIPhotoModel::class.java)
+ if ("狗".equals(model.species) || "猫".equals(model.species)) {
+ binding.tvSpecies.text = model.species
+ binding.etBreed.setText(model.variety)
+ } else {
+ toast(getString(R.string.no_data_see))
+ }
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ hiddenProgeassDialog()
+ toast(msg)
+ }
+ })
+ }
+
+
+ class ImageAdapter(var context: AddPetActivity, var data: List) : BaseAdapter() {
+
+ override fun getCount(): Int {
+ var count = if (data.size > 3){
+ 3
+ }else{
+ data.size
+ }
+ return count
+ }
+
+ override fun getItem(p0: Int): Any? {
+ TODO("Not yet implemented")
+ }
+
+ override fun getItemId(p: Int): Long {
+ return p.toLong()
+ }
+
+ override fun getView(
+ p0: Int,
+ p1: View?,
+ p2: ViewGroup?
+ ): View? {
+ var layoutItemImageBinding =
+ LayoutItemImageBinding.inflate(LayoutInflater.from(context))
+ layoutItemImageBinding.root.layoutParams = ViewGroup.LayoutParams(TTUtils.dpToPx(context,70).toInt(),
+ TTUtils.dpToPx(context,70).toInt())
+ var model = data.get(p0)
+ if (model.isAdd) {
+ layoutItemImageBinding.image.setImageResource(R.mipmap.image_photo_add)
+ layoutItemImageBinding.image.scaleType = ImageView.ScaleType.CENTER_INSIDE
+
+ layoutItemImageBinding.imageDelete.visibility = View.GONE
+ } else {
+ layoutItemImageBinding.image.scaleType = ImageView.ScaleType.CENTER_CROP
+ layoutItemImageBinding.image.setImageBitmap(
+ TTUtils.getBitmap(
+ model.path,
+ 200,
+ 200
+ )
+ )
+
+ layoutItemImageBinding.imageDelete.visibility = View.VISIBLE
+ layoutItemImageBinding.imageDelete.setOnClickListener {
+
+ CKAlertDialog(context,context.getString(R.string.alert),context.getString(R.string.alert_delete_photo),object : CKAlertDialog.AlertClickListener{
+ override fun onBack(isConfirm: Boolean) {
+ if (isConfirm){
+ context.data.removeAt(p0)
+ this@ImageAdapter.data = context.data
+ notifyDataSetChanged()
+ }
+ }
+ }).show()
+ }
+ }
+ return layoutItemImageBinding.root
+ }
+ }
+
+
+
+
+}
+
diff --git a/app/src/main/java/com/ck/ckcollar/app/ui/act/petmanager/BoundSuccessActivity.kt b/app/src/main/java/com/ck/ckcollar/app/ui/act/petmanager/BoundSuccessActivity.kt
new file mode 100644
index 0000000..71bdd18
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/ui/act/petmanager/BoundSuccessActivity.kt
@@ -0,0 +1,17 @@
+package com.ck.ckcollar.app.ui.act.petmanager
+
+import android.os.Bundle
+import com.ck.ckcollar.app.databinding.ActivityBoundSuccessBinding
+import com.ck.ckcollar.app.ui.base.CKBaseActivity
+
+class BoundSuccessActivity: CKBaseActivity() {
+
+
+ lateinit var binding: ActivityBoundSuccessBinding
+ override fun onCreate(savedInstanceState: Bundle?) {
+ binding = ActivityBoundSuccessBinding.inflate(layoutInflater)
+ setContentView(binding.root)
+ super.onCreate(savedInstanceState)
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/ui/act/petmanager/EditPetActivity.kt b/app/src/main/java/com/ck/ckcollar/app/ui/act/petmanager/EditPetActivity.kt
new file mode 100644
index 0000000..572222a
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/ui/act/petmanager/EditPetActivity.kt
@@ -0,0 +1,582 @@
+package com.ck.ckcollar.app.ui.act.petmanager
+
+import android.content.Intent
+import android.graphics.Bitmap
+import android.net.Uri
+import android.os.Build
+import android.os.Bundle
+import android.os.Environment
+import android.provider.MediaStore
+import android.text.TextUtils
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.AdapterView
+import android.widget.BaseAdapter
+import android.widget.ImageView
+import androidx.core.content.FileProvider
+import com.bumptech.glide.Glide
+import com.ck.ckcollar.app.R
+import com.ck.ckcollar.app.action.ActionCode
+import com.ck.ckcollar.app.databinding.ActivityAddPetBinding
+import com.ck.ckcollar.app.databinding.LayoutItemImageBinding
+import com.ck.ckcollar.app.model.AIPhotoModel
+import com.ck.ckcollar.app.model.CollarTypeModel
+import com.ck.ckcollar.app.model.ImageModel
+import com.ck.ckcollar.app.model.UploadModel
+import com.ck.ckcollar.app.ui.base.CKBaseActivity
+import com.ck.ckcollar.app.ui.dialog.CKAlertDialog
+import com.ck.ckcollar.app.ui.dialog.CKPhotoDialog
+import com.ck.ckcollar.app.ui.dialog.CKPickViewDialog
+import com.ck.ckcollar.app.utils.CKUtils
+import com.ck.ckcollar.app.utils.Const
+import com.ck.ckcollar.app.utils.networkone.ICallback
+import com.ck.ckcollar.app.utils.networkone.TTHttpClient
+import com.ck.ckcollar.app.utils.networkone.model.TTRequestData
+import com.ck.ckcollar.app.utils.networkone.model.TTRequestParam
+import com.cyclone.shadowsocks.utils.PreferencesUtils
+import com.google.gson.Gson
+import com.tt.kit.model.Data
+import com.tt.kit.model.DataCollection
+import com.tt.kit.utils.LiveDataBus
+import com.tt.kit.utils.TTLog
+import com.tt.kit.utils.TTUtils
+import java.io.File
+
+class EditPetActivity : CKBaseActivity() {
+
+ lateinit var binding: ActivityAddPetBinding
+ lateinit var imageAdapter: ImageAdapter
+ var data = mutableListOf()
+ var model : CollarTypeModel.TypeDataModel? = null
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ binding = ActivityAddPetBinding.inflate(layoutInflater)
+ setContentView(binding.root)
+ super.onCreate(savedInstanceState)
+
+ setTitleText(getString(R.string.edit_pet))
+ setStatusBarColor(resources.getColor(R.color.white))
+ setActionBarColor(resources.getColor(R.color.white))
+
+ setRightText(getString(R.string.delete))
+ setRightTextColor(resources.getColor(R.color.color_F83B3B))
+
+ }
+
+
+ override fun initView() {
+
+ imageAdapter = ImageAdapter(this,data)
+ binding.girdView.adapter = imageAdapter
+ binding.girdView.onItemClickListener = object :
+ AdapterView.OnItemClickListener {
+ override fun onItemClick(
+ p0: AdapterView<*>?,
+ p1: View?,
+ p2: Int,
+ p3: Long
+ ) {
+ if (!data.get(p2).isAdd){
+
+ var urls = mutableListOf()
+ for (d in data){
+ if (d.isAdd){
+ continue
+ }
+ if(TextUtils.isEmpty(d.url)){
+ urls.add(d.path!!)
+ }else{
+ urls.add(d.url!!)
+ }
+ }
+ toActivity(ImageViewActivity::class.java, DataCollection().apply {
+ add(Data("data",Gson().toJson(urls)))
+ add(Data("pos",p2.toString()))
+ })
+
+ return
+ }
+ CKPhotoDialog(this@EditPetActivity,object : CKPhotoDialog.PhotoClickListener{
+ override fun onBack(mark: Int, position: Int) {
+ try {
+ if (mark == 0){
+ if (!checkCameraPermissions()){
+ CKAlertDialog(this@EditPetActivity,getString(R.string.alert),getString(R.string.camera_alert),object : CKAlertDialog.AlertClickListener{
+ override fun onBack(isConfirm: Boolean) {
+ TODO("Not yet implemented")
+ }
+
+ }).show()
+ return
+ }
+ takePhoto()
+ }else{
+ //相册
+ val i = Intent(
+ Intent.ACTION_PICK,
+ MediaStore.Images.Media.EXTERNAL_CONTENT_URI
+ )
+ i.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,"image/*");
+ startActivityForResult(i, 56)
+ }
+ }catch (e : Exception){
+ e.printStackTrace()
+ }
+
+ }
+ }).show()
+ }
+
+ }
+
+
+ binding.tvSpecies.setOnClickListener {
+ CKPickViewDialog(this@EditPetActivity,listOf("猫","狗"),object : CKPickViewDialog.ItemClickListener{
+ override fun onBack(pos: Int, data: String) {
+ binding.tvSpecies.text = data
+ }
+ }).show()
+ }
+ binding.tvBodyType.setOnClickListener {
+ CKPickViewDialog(this@EditPetActivity,listOf("大","中","小"),object : CKPickViewDialog.ItemClickListener{
+ override fun onBack(pos: Int, data: String) {
+ binding.tvBodyType.text = data
+ }
+ }).show()
+ }
+ binding.tvColor.setOnClickListener {
+ CKPickViewDialog(this@EditPetActivity,listOf("红","黄","蓝"),object : CKPickViewDialog.ItemClickListener{
+ override fun onBack(pos: Int, data: String) {
+ binding.tvColor.text = data
+ }
+ }).show()
+ }
+ binding.tvVaccination.setOnClickListener {
+ CKPickViewDialog(this@EditPetActivity,listOf("是","否"),object : CKPickViewDialog.ItemClickListener{
+ override fun onBack(pos: Int, data: String) {
+ binding.tvVaccination.text = data
+ }
+ }).show()
+ }
+
+ binding.btnItem1.setOnClickListener {
+ CKPickViewDialog(this@EditPetActivity,listOf("猫","狗"),object : CKPickViewDialog.ItemClickListener{
+ override fun onBack(pos: Int, data: String) {
+ binding.tvSpecies.text = data
+ }
+ }).show()
+ }
+ binding.btnItem2.setOnClickListener {
+ CKPickViewDialog(this@EditPetActivity,listOf("大","中","小"),object : CKPickViewDialog.ItemClickListener{
+ override fun onBack(pos: Int, data: String) {
+ binding.tvBodyType.text = data
+ }
+ }).show()
+ }
+ binding.btnItem3.setOnClickListener {
+ CKPickViewDialog(this@EditPetActivity,listOf("红","黄","蓝"),object : CKPickViewDialog.ItemClickListener{
+ override fun onBack(pos: Int, data: String) {
+ binding.tvColor.text = data
+ }
+ }).show()
+ }
+ binding.btnItem4.setOnClickListener {
+ CKPickViewDialog(this@EditPetActivity,listOf("是","否"),object : CKPickViewDialog.ItemClickListener{
+ override fun onBack(pos: Int, data: String) {
+ binding.tvVaccination.text = data
+ }
+ }).show()
+ }
+
+ binding.btnSubmit.setOnClickListener {
+ uploadImage()
+ }
+
+ binding.tvAiRecognize.setOnClickListener {
+ takePhoto2()
+ }
+
+
+
+
+ var urls = model!!.patPhoto.split(",")
+ data.clear()
+ for (url in urls){
+ var m = ImageModel()
+ m.url = url
+ data.add(m)
+ }
+ data.add(ImageModel().apply { isAdd = true })
+
+ imageAdapter.data = data
+ imageAdapter.notifyDataSetChanged()
+ binding.textPhotoNum.setText((this.data.size - 1 ).toString() + "/3")
+
+ }
+
+ override fun initData() {
+ model = Gson().fromJson(getReceiveParam().get("data")!!.stringValue,
+ CollarTypeModel.TypeDataModel::class.java)
+
+ binding.etName.setText(model!!.patName)
+ binding.tvSpecies.setText(CKUtils.getPetSpecLab(model!!.patSpecies))
+ binding.etBreed.setText(model!!.patVariety)
+ binding.etAge.setText(model!!.patAge)
+ binding.etHeight.setText(model!!.patHeight)
+ binding.etWeight.setText(model!!.patWeight)
+ binding.tvBodyType.setText(model!!.patBodytype)
+ binding.tvColor.setText(model!!.patColor)
+ binding.tvVaccination.setText(model!!.patProphylactic)
+
+
+
+ }
+
+ fun uploadImage(){
+ if (binding.etName.isEmpty()){
+ toast(getString(R.string.input_name))
+ return
+ }
+ if (binding.tvSpecies.isEmpty()){
+ toast(getString(R.string.select_species))
+ return
+ }
+
+ if (binding.etBreed.isEmpty()){
+ toast(getString(R.string.input_breed))
+ return
+ }
+ if (binding.etAge.isEmpty()){
+ toast(getString(R.string.input_age))
+ return
+ }
+ if (binding.etAge.text.toString().toFloat() > 100){
+ toast(getString(R.string.input_age_over))
+ return
+ }
+
+ if (binding.etHeight.isEmpty()){
+ toast(getString(R.string.input_height))
+ return
+ }
+ if (binding.etHeight.text.toString().toFloat() > 200){
+ toast(getString(R.string.input_height_over))
+ return
+ }
+
+ if (binding.etWeight.isEmpty()){
+ toast(getString(R.string.input_weight))
+ return
+ }
+ if (binding.etWeight.text.toString().toFloat() > 1000){
+ toast(getString(R.string.input_weight_over))
+ return
+ }
+ if (binding.tvBodyType.isEmpty()){
+ toast(getString(R.string.select_body_type))
+ return
+ }
+
+ if (binding.tvColor.isEmpty()){
+ toast(getString(R.string.select_color))
+ return
+ }
+ if (binding.tvVaccination.isEmpty()){
+ toast(getString(R.string.select_vaccination))
+ return
+ }
+ if (data.size == 1){
+ toast(getString(R.string.please_dupload_photos))
+ return
+ }
+
+ var param = TTRequestParam()
+ for (model in data){
+ if (model.isAdd == false && !TextUtils.isEmpty(model.path)){
+ param.files.add(File(model.path))
+ }
+ }
+ if (param.files.size > 0){
+ showProgeassDialog()
+ TTHttpClient.postFile(this,"上传照片s", param,object : ICallback{
+ override fun onSuccess(data: String) {
+ var model = Gson().fromJson(data,UploadModel::class.java)
+
+ var fileNames = model.urls
+
+ for (imageModel in this@EditPetActivity.data){
+ if (imageModel.isAdd == false && !TextUtils.isEmpty(imageModel.url)){
+ fileNames = imageModel.url + "," + fileNames
+ }
+ }
+
+ add(fileNames)
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ hiddenProgeassDialog()
+ toast(msg)
+ }
+ })
+ }else{
+ add(model!!.patPhoto)
+ }
+
+ }
+
+
+ fun add(patPhoto : String){
+
+
+ var param = TTRequestParam().apply {
+ add(TTRequestData("id",model!!.id.toString()))
+ add(TTRequestData("patName",binding.etName.text.toString()))
+ add(TTRequestData("patSpecies", CKUtils.getPetSpecValue(binding.tvSpecies.text.toString())))
+ add(TTRequestData("patVariety",binding.etBreed.text.toString()))
+ add(TTRequestData("patAge",binding.etAge.text.toString()))
+ add(TTRequestData("patHeight",binding.etHeight.text.toString()))
+ add(TTRequestData("patWeight",binding.etWeight.text.toString()))
+ add(TTRequestData("patBodytype",binding.tvBodyType.text.toString()))
+ add(TTRequestData("patColor",binding.tvColor.text.toString()))
+ add(TTRequestData("patProphylactic",binding.tvVaccination.text.toString()))
+ add(TTRequestData("patPhoto",patPhoto))
+ }
+ TTHttpClient.putJson(this,"编辑宠物",param ,object : ICallback{
+ override fun onSuccess(data: String) {
+ toast(getString(R.string.edit_success))
+ finish()
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ toast(msg)
+ }
+ })
+ }
+
+
+ override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
+ super.onActivityResult(requestCode, resultCode, data)
+
+ if (requestCode == 55 && resultCode == RESULT_OK) {
+ var path = PreferencesUtils.getString(this@EditPetActivity, Const.IMAGE_PATH,"")
+ this.data.add(this.data.size - 1,ImageModel().apply { this.path = path })
+ imageAdapter.data = this.data
+ imageAdapter.notifyDataSetChanged()
+ }else if (requestCode == 56 && resultCode == RESULT_OK) {
+ var path = TTUtils.getImageUrl(this, data!!.getData());
+ this.data.add(this.data.size - 1,ImageModel().apply { this.path = path })
+ imageAdapter.data = this.data
+ imageAdapter.notifyDataSetChanged()
+ }else if (requestCode == 555 && resultCode == RESULT_OK) {
+ var path = PreferencesUtils.getString(this@EditPetActivity, Const.IMAGE_PATH,"")
+ uploadImage(path!!)
+ }
+ binding.textPhotoNum.setText((this.data.size - 1 ).toString() + "/3")
+ }
+ fun takePhoto() {
+ try {
+ val openCameraIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
+
+ val vFile = File(
+ getExternalFilesDir(Environment.DIRECTORY_PICTURES),
+ "${System.currentTimeMillis()}.png"
+ )
+
+ val parentDir = vFile.parentFile
+ if (parentDir != null && !parentDir.exists()) {
+ parentDir.mkdirs()
+ }
+ TTLog.e(vFile.absolutePath)
+ PreferencesUtils.putString(getApplicationContext(), Const.IMAGE_PATH, vFile.absolutePath)
+
+ val cameraUri: Uri = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+ FileProvider.getUriForFile(
+ this@EditPetActivity,
+ packageName + ".fileprovider",
+ vFile
+ )
+ } else {
+ Uri.fromFile(vFile)
+ }
+
+ openCameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, cameraUri)
+ startActivityForResult(openCameraIntent, 55)
+ }catch (e: Exception){
+ e.printStackTrace()
+ }
+
+ }
+ fun takePhoto2() {
+ val openCameraIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
+
+ val vFile = File(
+ getExternalFilesDir(Environment.DIRECTORY_PICTURES),
+ "${System.currentTimeMillis()}.png"
+ )
+
+ val parentDir = vFile.parentFile
+ if (parentDir != null && !parentDir.exists()) {
+ parentDir.mkdirs()
+ }
+ TTLog.e(vFile.absolutePath)
+ PreferencesUtils.putString(getApplicationContext(), Const.IMAGE_PATH, vFile.absolutePath)
+
+ val cameraUri: Uri = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+ FileProvider.getUriForFile(
+ this@EditPetActivity,
+ packageName + ".fileprovider",
+ vFile
+ )
+ } else {
+ Uri.fromFile(vFile)
+ }
+
+ openCameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, cameraUri)
+ startActivityForResult(openCameraIntent, 555)
+ }
+ override fun rightButton1OnClick() {
+ CKAlertDialog(this@EditPetActivity,getString(R.string.alert),getString(R.string.alert_delete_pet),object : CKAlertDialog.AlertClickListener{
+ override fun onBack(isConfirm: Boolean) {
+ if (isConfirm){
+ showProgeassDialog(getString(R.string.delete))
+ TTHttpClient.delete(this@EditPetActivity,"删除宠物",model!!.id.toString(),object : ICallback{
+ override fun onSuccess(data: String) {
+ LiveDataBus.get().with("DELETE" + model!!.id).value = 1
+ toast(getString(R.string.delete_success))
+ finish()
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ toast(msg)
+ }
+ })
+ }
+ }
+ }).show()
+ }
+
+
+ fun uploadImage(path: String) {
+
+ var param = TTRequestParam()
+ param.files.add(File(path))
+
+ showProgeassDialog(getString(R.string.see))
+ TTHttpClient.postFile(this, "上传照片s", param, object : ICallback {
+ override fun onSuccess(data: String) {
+ var model = Gson().fromJson(data, UploadModel::class.java)
+
+ //aiPhoto(ActionCode.BASE_URL + "/" + model.fileNames)
+ aiPhoto(model.urls)
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ hiddenProgeassDialog()
+ toast(msg)
+ }
+ })
+ }
+
+ fun aiPhoto(imageUrl: String) {
+
+ TTHttpClient.postJson(this, "AI拍照识别", TTRequestParam().apply {
+ add(TTRequestData("imageUrl", imageUrl))
+ }, object : ICallback {
+ override fun onSuccess(data: String) {
+ hiddenProgeassDialog()
+
+ var model = Gson().fromJson(data, AIPhotoModel::class.java)
+ if ("狗".equals(model.species) || "猫".equals(model.species)) {
+
+ binding.tvSpecies.text = model.species
+ binding.etBreed.setText(model.variety)
+ } else {
+ toast(getString(R.string.no_data_see))
+ }
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ hiddenProgeassDialog()
+ toast(msg)
+ }
+ })
+ }
+
+ class ImageAdapter(var context: EditPetActivity, var data: List) : BaseAdapter() {
+
+ override fun getCount(): Int {
+ var count = if (data.size > 3){
+ 3
+ }else{
+ data.size
+ }
+ return count
+ }
+
+ override fun getItem(p0: Int): Any? {
+ TODO("Not yet implemented")
+ }
+
+ override fun getItemId(p: Int): Long {
+ return p.toLong()
+ }
+
+ override fun getView(
+ p0: Int,
+ p1: View?,
+ p2: ViewGroup?
+ ): View? {
+ var layoutItemImageBinding =
+ LayoutItemImageBinding.inflate(LayoutInflater.from(context))
+ layoutItemImageBinding.root.layoutParams = ViewGroup.LayoutParams(TTUtils.dpToPx(context,70).toInt(),
+ TTUtils.dpToPx(context,70).toInt())
+
+ var model = data.get(p0)
+
+ if (model.isAdd) {
+ layoutItemImageBinding.image.setImageResource(R.mipmap.image_photo_add)
+ layoutItemImageBinding.image.scaleType = ImageView.ScaleType.CENTER_INSIDE
+
+ layoutItemImageBinding.imageDelete.visibility = View.GONE
+ } else {
+ layoutItemImageBinding.image.scaleType = ImageView.ScaleType.CENTER_CROP
+ if (!TextUtils.isEmpty(model.path)){
+ layoutItemImageBinding.image.setImageBitmap(
+ TTUtils.getBitmap(
+ model.path,
+ 200,
+ 200
+ )
+ )
+ }else{
+ Glide.with(context)
+ .load(model.url)
+ .placeholder(R.mipmap.image_default)
+ .centerCrop()
+ .override(300,200)
+ .into(layoutItemImageBinding.image)
+ }
+
+ layoutItemImageBinding.imageDelete.visibility = View.VISIBLE
+ layoutItemImageBinding.imageDelete.setOnClickListener {
+
+ CKAlertDialog(context,context.getString(R.string.alert),context.getString(R.string.alert_delete_photo),object : CKAlertDialog.AlertClickListener{
+ override fun onBack(isConfirm: Boolean) {
+ if (isConfirm){
+ context.data.removeAt(p0)
+ this@ImageAdapter.data = context.data
+ notifyDataSetChanged()
+ }
+ }
+ }).show()
+ }
+
+ }
+ return layoutItemImageBinding.root
+ }
+ }
+
+
+}
+
diff --git a/app/src/main/java/com/ck/ckcollar/app/ui/act/petmanager/ImageViewActivity.kt b/app/src/main/java/com/ck/ckcollar/app/ui/act/petmanager/ImageViewActivity.kt
new file mode 100644
index 0000000..0aa7726
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/ui/act/petmanager/ImageViewActivity.kt
@@ -0,0 +1,84 @@
+package com.ck.ckcollar.app.ui.act.petmanager
+
+import android.os.Bundle
+import android.view.View
+import android.view.ViewGroup
+import android.view.Window
+import android.view.WindowManager
+import androidx.viewpager.widget.PagerAdapter
+import com.bumptech.glide.Glide
+import com.ck.ckcollar.app.R
+import com.ck.ckcollar.app.databinding.ActivityImageViewBinding
+import com.ck.ckcollar.app.databinding.ActivityWelcomeBinding
+import com.ck.ckcollar.app.databinding.LayoutItemImageViewBinding
+import com.ck.ckcollar.app.databinding.LayoutItemWelcomeBinding
+import com.ck.ckcollar.app.ui.act.login.LoginActivity
+import com.ck.ckcollar.app.ui.act.welcome.PermisstionActivity
+import com.ck.ckcollar.app.ui.base.CKBaseActivity
+import com.ck.ckcollar.app.utils.Const
+import com.cyclone.shadowsocks.utils.PreferencesUtils
+import com.google.gson.Gson
+import com.google.gson.reflect.TypeToken
+import com.tt.kit.model.DataCollection
+
+class ImageViewActivity : CKBaseActivity() {
+ lateinit var binding: ActivityImageViewBinding
+ var views = mutableListOf()
+ var data : List? = null
+ var pos = 0
+ override fun onCreate(savedInstanceState: Bundle?) {
+ binding = ActivityImageViewBinding.inflate(layoutInflater)
+ setContentView(binding.root)
+ super.onCreate(savedInstanceState)
+
+ setStatusBarColor2(resources.getColor(R.color.black))
+
+ }
+
+ override fun initView() {
+ for (i in data!!) {
+ var view = LayoutItemImageViewBinding.inflate(layoutInflater);
+ Glide.with(this)
+ .load(i)
+ .placeholder(R.mipmap.image_default)
+ .into(view.imageView)
+ views.add(view.root)
+ }
+ binding.viewPager.adapter = object : PagerAdapter() {
+ override fun getCount(): Int {
+ return views.size
+ }
+
+ override fun isViewFromObject(
+ view: View,
+ `object`: Any
+ ): Boolean {
+ return view == `object`
+ }
+
+ override fun destroyItem(container: ViewGroup, position: Int, `object`: Any) {
+ container.removeView(views.get(position))
+ }
+
+ override fun instantiateItem(container: ViewGroup, position: Int): Any {
+ container.addView(views.get(position))
+ return views.get(position)
+ }
+
+ }
+ binding.viewPager.setCurrentItem(pos,true)
+
+ binding.btnClose.setOnClickListener {
+ finish()
+ }
+
+ }
+
+ override fun initData() {
+ data = Gson().fromJson>(getReceiveParam().get("data")!!.stringValue,object : TypeToken>(){}.type)
+ var data = getReceiveParam().get("pos")
+ if (data != null){
+ pos = data.stringValue!!.toInt()
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/ui/act/petmanager/InputInviteCodeActivity.kt b/app/src/main/java/com/ck/ckcollar/app/ui/act/petmanager/InputInviteCodeActivity.kt
new file mode 100644
index 0000000..77d0f25
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/ui/act/petmanager/InputInviteCodeActivity.kt
@@ -0,0 +1,62 @@
+package com.ck.ckcollar.app.ui.act.petmanager
+
+import android.os.Bundle
+import com.ck.ckcollar.app.R
+import com.ck.ckcollar.app.databinding.ActivityInviteCodeBinding
+import com.ck.ckcollar.app.ui.base.CKBaseActivity
+import com.ck.ckcollar.app.utils.networkone.ICallback
+import com.ck.ckcollar.app.utils.networkone.TTHttpClient
+import com.ck.ckcollar.app.utils.networkone.model.TTRequestData
+import com.ck.ckcollar.app.utils.networkone.model.TTRequestParam
+import com.tt.kit.base.TTBaseActivity
+import com.tt.kit.model.DataCollection
+
+class InputInviteCodeActivity: CKBaseActivity() {
+
+ lateinit var binding: ActivityInviteCodeBinding
+ override fun onCreate(savedInstanceState: Bundle?) {
+ binding = ActivityInviteCodeBinding.inflate(layoutInflater)
+ setContentView(binding.root)
+ super.onCreate(savedInstanceState)
+ }
+
+ override fun initView() {
+
+ binding.btnBound.setOnClickListener {
+
+ bindDevice()
+ }
+
+ }
+ override fun initData() {
+
+ }
+
+
+ fun bindDevice() {
+
+
+
+ var param = TTRequestParam().apply {
+ add(TTRequestData("collNum", getReceiveParam().get("num")!!.stringValue.toString()))
+ add(TTRequestData("inviteCode", binding.editCode.text.toString()))
+ add(TTRequestData("patId", getReceiveParam().get("id")!!.stringValue.toString().toInt()))
+ }
+ showProgeassDialog(getString(R.string.bound))
+
+ TTHttpClient.postJson(this, "绑定设备", param, object : ICallback {
+ override fun onSuccess(data: String) {
+ hiddenProgeassDialog()
+ toast(getString(R.string.bind_success))
+ toActivity(BoundSuccessActivity::class.java, DataCollection())
+ finish()
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ hiddenProgeassDialog()
+ toast(msg)
+ }
+ })
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/ui/act/petmanager/MapLocationActivity.kt b/app/src/main/java/com/ck/ckcollar/app/ui/act/petmanager/MapLocationActivity.kt
new file mode 100644
index 0000000..9ba3636
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/ui/act/petmanager/MapLocationActivity.kt
@@ -0,0 +1,327 @@
+package com.ck.ckcollar.app.ui.act.petmanager
+
+import android.content.Intent
+import android.graphics.Bitmap
+import android.graphics.Canvas
+import android.graphics.Color
+import android.graphics.drawable.BitmapDrawable
+import android.graphics.drawable.Drawable
+import android.net.Uri
+import android.os.Bundle
+import android.os.Handler
+import android.os.Looper
+import android.text.TextUtils
+import android.view.MotionEvent
+import android.view.View
+import android.widget.ImageView
+import androidx.compose.ui.unit.TextUnit
+import androidx.core.content.ContextCompat
+import com.bumptech.glide.Glide
+import com.bumptech.glide.request.target.CustomTarget
+import com.bumptech.glide.request.transition.Transition
+import com.ck.ckcollar.app.R
+import com.ck.ckcollar.app.action.ActionCode
+import com.ck.ckcollar.app.config.Config
+import com.ck.ckcollar.app.databinding.ActivityMapLocationBinding
+import com.ck.ckcollar.app.databinding.LayoutPostionMarkBinding
+import com.ck.ckcollar.app.ui.base.CKBaseActivity
+import com.ck.ckcollar.app.ui.base.CKLHBaseActionBarActivity
+import com.ck.ckcollar.app.ui.dialog.CKNavDialog
+import com.ck.ckcollar.app.utils.CoordinateUtils
+import com.gyf.immersionbar.ImmersionBar
+import com.tt.kit.utils.TTLog
+import com.tt.kit.utils.TTUtils
+import com.tt.kit.utils.ViewUtils
+import org.osmdroid.util.GeoPoint
+import org.osmdroid.views.CustomZoomButtonsController
+import org.osmdroid.views.MapView
+import org.osmdroid.views.overlay.Marker
+import org.osmdroid.views.overlay.Overlay
+import org.osmdroid.views.overlay.ScaleBarOverlay
+import org.osmdroid.views.overlay.compass.CompassOverlay
+import org.osmdroid.views.overlay.gestures.RotationGestureOverlay
+
+class MapLocationActivity : CKLHBaseActionBarActivity() {
+
+ lateinit var mapLocationBinding: ActivityMapLocationBinding
+
+ private var mMarker: Marker? = null
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ mapLocationBinding = ActivityMapLocationBinding.inflate(layoutInflater)
+ setContentView(mapLocationBinding.root)
+ ImmersionBar.with(this)
+ .statusBarDarkFont(true)
+ //.titleBar(mapLocationBinding.image1)
+ .init()
+
+ super.onCreate(savedInstanceState)
+
+
+
+ setRightText(getString(R.string.navigation))
+ }
+
+ override fun initView() {
+ initMap()
+ }
+
+ /**
+ * 初始化地图
+ */
+ private fun initMap() {
+ mapLocationBinding.mapView.apply {
+ setTileSource(Config.TDTCIA_W) // 设置瓦片地图资源
+ minZoomLevel = 5.0 // 最小缩放级别
+ maxZoomLevel = 20.0 // 最大缩放级别
+ isTilesScaledToDpi = true // 图块是否缩放到 DPI
+ // 设置默认的地图中心点
+ controller.apply {
+ setZoom(10.0)
+ setCenter(Config.defaultGeoPoint)
+ }
+ // 缩放控件显示-淡入淡出
+ zoomController.setVisibility(CustomZoomButtonsController.Visibility.SHOW_AND_FADEOUT)
+ this.isAnimating
+ setMultiTouchControls(true)
+ // 覆盖管理器配置
+ overlayManager.apply {
+ tilesOverlay.isEnabled = true
+ add(object : Overlay() {
+ override fun onSingleTapConfirmed(e: MotionEvent?, mapView: MapView?): Boolean {
+ // 获取投影对象后进行坐标转换再切换地图中心位置
+ mapView?.projection?.let { proj ->
+ val geoPoint = proj.fromPixels(e!!.x.toInt(), e.y.toInt()) as GeoPoint
+ TTLog.d("TAG", "onSingleTapConfirmed: 切换地图中心位置")
+ //changeMapCenter(geoPoint)
+ }
+ return super.onSingleTapConfirmed(e, mapView)
+ }
+ })
+ // 添加比例尺
+ add(ScaleBarOverlay(mapLocationBinding.mapView).apply {
+ setAlignBottom(true) // 底部对齐
+ setScaleBarOffset(100, 10) // 设置偏移量
+ })
+ // 添加指南针
+// add(CompassOverlay(this@MapLocationActivity, mapLocationBinding.mapView).apply {
+// enableCompass()
+//
+// })
+
+ // 添加经纬度网格线
+// add(LatLonGridlineOverlay2())
+ // 启用旋转手势
+ add(RotationGestureOverlay(mapLocationBinding.mapView).apply { isEnabled = true })
+ // 添加小地图
+// add(MinimapOverlay(this@MapLocationActivity, mapLocationBinding.mapView.tileRequestCompleteHandler).apply {
+// val dm = resources.displayMetrics
+// width = dm.widthPixels / 4
+// height = dm.heightPixels / 4
+// // 设置小地图资源
+// setTileSource(Config.TDTCIA_W)
+// })
+ }
+ }
+ // 开始定位
+ //startLocation()
+ var lat = getReceiveParam().get("latitude")!!.doubleValue
+ var log = getReceiveParam().get("longitude")!!.doubleValue
+ if (lat == 0.0 || log == 0.0) {
+
+ mapLocationBinding.image.root.visibility = View.GONE
+
+ }else{
+
+ val point = GeoPoint(
+ lat,
+ log
+ )
+
+ handler.post {
+
+ changeMapCenter(point)
+
+ }
+
+ }
+
+
+ }
+
+ override fun initData() {
+
+ }
+ var handler = Handler(Looper.getMainLooper())
+
+ override fun rightButton1OnClick() {
+ CKNavDialog(this, object : CKNavDialog.MapClickListener {
+ override fun onBack(mark: Int, position: Int) {
+ if (mark == 0) {
+ try {
+ var intent = Intent(Intent.ACTION_VIEW);
+
+ var uri = String.format(
+ "amapuri://route/plan/?sourceApplication=%s" +
+ // "&slat=%f&slon=%f&sname=%s" + // 起点信息,可省略
+ "&dlat=%f&dlon=%f&dname=%s" + // 终点信息,必填
+ "&dev=1&t=0", // dev=1 表示坐标是WGS-84,t=0表示驾车
+ getString(R.string.app_name),
+ getReceiveParam().get("latitude")!!.floatValue, // lat: 目的地纬度
+ getReceiveParam().get("longitude")!!.floatValue, // lon: 目的地经度
+ "目的地名称" // 终点示例
+ );
+ intent.setData(Uri.parse(uri));
+
+ startActivity(intent);
+ } catch (e: Exception) {
+ toast(getString(R.string.install_gaode))
+ }
+
+ } else if (mark == 1) {
+ try {
+ var intent = Intent(Intent.ACTION_VIEW);
+
+ var uri = String.format(
+ "baidumap://map/direction?destination=%f,%f&coord_type=wgs84&src=andr.yourCompany.yourApp",
+ getReceiveParam().get("latitude")!!.floatValue, // lat: 目的地纬度
+ getReceiveParam().get("longitude")!!.floatValue // lon: 目的地经度
+ );
+ intent.setData(Uri.parse(uri));
+
+ startActivity(intent);
+ } catch (e: Exception) {
+ toast(getString(R.string.install_baidu))
+ }
+ } else if (mark == 2) {
+ try {
+ val gcj02 = CoordinateUtils.wgs84ToGcj02(getReceiveParam().get("latitude")!!.doubleValue, getReceiveParam().get("longitude")!!.doubleValue)
+ val gcjLat = gcj02[0]
+ val gcjLon = gcj02[1]
+
+ var intent = Intent(Intent.ACTION_VIEW);
+
+ var uri = "qqmap://map/routeplan?type=drive&to=目的地&tocoord=$gcjLat,$gcjLon"
+ intent.setData(Uri.parse(uri));
+
+ startActivity(intent);
+ } catch (e: Exception) {
+ toast(getString(R.string.install_baidu))
+ }
+ }
+
+
+ }
+ }).show()
+
+
+ }
+
+
+ /**
+ * 修改地图中心点
+ */
+ private fun changeMapCenter(geoPoint: GeoPoint) {
+ TTLog.d("TAG", "changeMapCenter: $geoPoint")
+
+ var url = getReceiveParam().get("url")!!.stringValue
+
+ TTLog.e(url.toString())
+ if (TextUtils.isEmpty(url)) {
+
+ // var drawable = ContextCompat.getDrawable(this, R.mipmap.icon)
+ setMark(geoPoint, null)
+ } else {
+ Glide.with(this)
+ .asDrawable() // 指定返回类型为Drawable
+ .load(url) // 加载图片URL或资源ID等
+ .placeholder(R.mipmap.image_default)
+ .into(object : CustomTarget() {
+ override fun onResourceReady(
+ resource: Drawable,
+ transition: Transition?
+ ) {
+ // 图片加载成功,可以在这里使用Drawable
+
+
+ setMark(geoPoint, resource)
+
+ }
+
+ override fun onLoadFailed(errorDrawable: Drawable?) {
+ setMark(geoPoint,null)
+ }
+ override fun onLoadCleared(placeholder: Drawable?) {
+ // 资源被清除时的回调,例如在取消加载时调用
+
+ // setMark(geoPoint, placeholder)
+ }
+ })
+ }
+
+
+ }
+
+ fun setMark(geoPoint: GeoPoint, resource: Drawable?) {
+
+
+
+ mapLocationBinding.mapView.apply {
+ // 移除标点
+ if (mMarker != null) {
+ overlays.remove(mMarker)
+ }
+ // Kotlin
+ var customBitmap : Bitmap? = null
+ if (resource == null){
+ val drawable = ContextCompat.getDrawable(this@MapLocationActivity, R.mipmap.image_mark)
+ customBitmap = (drawable as? BitmapDrawable)?.bitmap
+ mapLocationBinding.image.root.visibility = View.GONE
+
+ }else{
+ mapLocationBinding.image.image.setImageDrawable(resource)
+
+ customBitmap = makeView2Bitmap(mapLocationBinding.image.root)
+
+ mapLocationBinding.image.root.visibility = View.GONE
+ }
+
+ mMarker = Marker(this).apply {
+ title = "宠物位置"
+ position = geoPoint
+ icon = BitmapDrawable(resources, customBitmap);
+ }
+ mMarker!!.setOnMarkerClickListener(object : Marker.OnMarkerClickListener {
+ override fun onMarkerClick(
+ marker: Marker?,
+ mapView: MapView?
+ ): Boolean {
+
+ return true
+ }
+ })
+ // 添加标点
+ overlays.add(mMarker)
+
+ controller.apply {
+ setZoom(12.0)
+ setCenter(geoPoint)
+ }
+ }
+
+
+ }
+
+ fun makeView2Bitmap(view: View): Bitmap {
+ // View是你需要绘画的View
+ val width = TTUtils.dpToPx(this, 70).toInt()
+ val height = TTUtils.dpToPx(this, 84).toInt()
+ val bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
+ val canvas = Canvas(bitmap)
+ // 如果不设置canvas画布为白色,则生成透明
+ canvas.drawColor(Color.TRANSPARENT)
+ view.draw(canvas)
+ return bitmap
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/ui/act/petmanager/PetManagerActivity.kt b/app/src/main/java/com/ck/ckcollar/app/ui/act/petmanager/PetManagerActivity.kt
new file mode 100644
index 0000000..09a69d8
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/ui/act/petmanager/PetManagerActivity.kt
@@ -0,0 +1,149 @@
+package com.ck.ckcollar.app.ui.act.petmanager
+
+import android.net.wifi.ScanResult
+import android.os.Bundle
+import android.view.ViewGroup
+import android.widget.PopupWindow
+import androidx.recyclerview.widget.LinearLayoutManager
+import androidx.recyclerview.widget.RecyclerView
+import com.ck.ckcollar.app.R
+import com.ck.ckcollar.app.databinding.ActivityPetManagerListBinding
+import com.ck.ckcollar.app.databinding.LayoutItemPetManagerBinding
+import com.ck.ckcollar.app.databinding.LayoutItemWifiBinding
+import com.ck.ckcollar.app.model.CollarModel
+import com.ck.ckcollar.app.model.CollarTypeModel
+import com.ck.ckcollar.app.ui.act.WifiListActivity.WifiAdapter
+import com.ck.ckcollar.app.ui.base.CKBaseActivity
+import com.ck.ckcollar.app.ui.popview.CKCollarTypePopView
+import com.ck.ckcollar.app.utils.CKUtils
+import com.ck.ckcollar.app.utils.networkone.ICallback
+import com.ck.ckcollar.app.utils.networkone.TTHttpClient
+import com.ck.ckcollar.app.utils.networkone.model.TTRequestData
+import com.ck.ckcollar.app.utils.networkone.model.TTRequestParam
+import com.google.gson.Gson
+import com.tt.kit.base.TTBaseActivity
+import com.tt.kit.model.Data
+import com.tt.kit.model.DataCollection
+import com.tt.kit.utils.TTLog
+
+class PetManagerActivity : CKBaseActivity() {
+
+ lateinit var binding: ActivityPetManagerListBinding
+ lateinit var petAdapter: PetAdapter
+ var data = listOf()
+ override fun onCreate(savedInstanceState: Bundle?) {
+ binding = ActivityPetManagerListBinding.inflate(layoutInflater)
+ setContentView(binding.root)
+ super.onCreate(savedInstanceState)
+
+ setTitleText(getString(R.string.pet_management))
+ }
+
+ override fun initView() {
+ binding.recyclerView.layoutManager = LinearLayoutManager(this, RecyclerView.VERTICAL, false)
+ binding.recyclerView.setHasFixedSize(true)
+
+
+ petAdapter = PetAdapter(this, data);
+ binding.recyclerView.adapter = petAdapter
+
+ binding.btnAddPet.setOnClickListener {
+ toActivity(AddPetActivity::class.java, DataCollection())
+ }
+ }
+
+
+ override fun initData() {
+
+
+ }
+
+ override fun onStart() {
+ super.onStart()
+ getData()
+ }
+
+ fun getData() {
+ //showProgeassDialog(getString(R.string.search))
+ TTHttpClient.get(this, "宠物列表", TTRequestParam().apply {
+ add(
+ TTRequestData("pageNum", 1)
+ )
+ add(
+ TTRequestData("pageSize", 100)
+ )
+ }, object : ICallback {
+ override fun onSuccess(data: String) {
+
+ hiddenProgeassDialog()
+ var model = Gson().fromJson(data, CollarTypeModel::class.java)
+ this@PetManagerActivity.data = model.rows
+
+ petAdapter.data = this@PetManagerActivity.data
+ petAdapter.notifyDataSetChanged()
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ hiddenProgeassDialog()
+ toast(msg)
+ }
+ })
+ }
+
+ class PetAdapter(var context: CKBaseActivity, var data: List) :
+ RecyclerView.Adapter() {
+ override fun onCreateViewHolder(
+ parent: ViewGroup,
+ viewType: Int
+ ): PetHolder {
+ return PetHolder(
+ LayoutItemPetManagerBinding.inflate(
+ context.layoutInflater,
+ parent,
+ false
+ )
+ )
+ }
+
+ override fun onBindViewHolder(
+ holder: PetHolder,
+ position: Int
+ ) {
+
+ var model = data.get(position)
+
+ holder.binding.textName.text = model.patName
+ holder.binding.textDesc.text =
+ CKUtils.getPetSpecLab(model.patSpecies) + " " + model.patVariety + " " + model.patColor
+
+ holder.binding.textNum.text = (position + 1).toString()
+ holder.binding.btnView.setOnClickListener {
+ context.toActivity(ViewPetFileActivity::class.java, DataCollection().apply {
+ add(
+ Data("data", Gson().toJson(model))
+ )
+ })
+ }
+ holder.binding.btnMotify.setOnClickListener {
+ context.toActivity(EditPetActivity::class.java, DataCollection().apply {
+ add(
+ Data("data", Gson().toJson(model))
+ )
+ })
+ }
+ }
+
+ override fun getItemCount(): Int {
+ return data.size
+ }
+
+ class PetHolder(var binding: LayoutItemPetManagerBinding) :
+ RecyclerView.ViewHolder(binding.root) {
+
+ }
+
+ }
+
+
+}
+
diff --git a/app/src/main/java/com/ck/ckcollar/app/ui/act/petmanager/ViewPetFileActivity.kt b/app/src/main/java/com/ck/ckcollar/app/ui/act/petmanager/ViewPetFileActivity.kt
new file mode 100644
index 0000000..da14cbb
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/ui/act/petmanager/ViewPetFileActivity.kt
@@ -0,0 +1,293 @@
+package com.ck.ckcollar.app.ui.act.petmanager
+
+import android.content.Intent
+import android.os.Bundle
+import android.provider.MediaStore
+import android.text.TextUtils
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.AdapterView
+import android.widget.BaseAdapter
+import android.widget.ImageView
+import com.bumptech.glide.Glide
+import com.ck.ckcollar.app.R
+import com.ck.ckcollar.app.action.ActionCode
+import com.ck.ckcollar.app.databinding.ActivityPetFileBinding
+import com.ck.ckcollar.app.databinding.LayoutItemImageBinding
+import com.ck.ckcollar.app.model.CollarTypeModel
+import com.ck.ckcollar.app.model.HomeModel
+import com.ck.ckcollar.app.model.ImageModel
+import com.ck.ckcollar.app.ui.act.petmanager.AddPetActivity.ImageAdapter
+import com.ck.ckcollar.app.ui.base.CKBaseActivity
+import com.ck.ckcollar.app.ui.dialog.CKAlertDialog
+import com.ck.ckcollar.app.ui.dialog.CKPhotoDialog
+import com.ck.ckcollar.app.utils.CKUtils
+import com.ck.ckcollar.app.utils.networkone.ICallback
+import com.ck.ckcollar.app.utils.networkone.TTHttpClient
+import com.ck.ckcollar.app.utils.networkone.model.TTRequestData
+import com.ck.ckcollar.app.utils.networkone.model.TTRequestParam
+import com.google.gson.Gson
+import com.tt.kit.base.TTBaseActivity
+import com.tt.kit.model.Data
+import com.tt.kit.model.DataCollection
+import com.tt.kit.utils.LiveDataBus
+import com.tt.kit.utils.TTUtils
+
+class ViewPetFileActivity: CKBaseActivity() {
+
+ lateinit var binding: ActivityPetFileBinding
+
+ lateinit var imageAdapter: ImageAdapter
+ var data = mutableListOf()
+
+ var model : CollarTypeModel.TypeDataModel? = null
+ var homeModel : HomeModel.EquipmentModel? = null
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ binding = ActivityPetFileBinding.inflate(layoutInflater)
+ setContentView(binding.root)
+ super.onCreate(savedInstanceState)
+
+ setTitleText(getString(R.string.view_the_file))
+ }
+
+ override fun initView() {
+
+ imageAdapter = ImageAdapter(this,data)
+ binding.girdView.adapter = imageAdapter
+ binding.girdView.onItemClickListener = object :
+ AdapterView.OnItemClickListener {
+ override fun onItemClick(
+ p0: AdapterView<*>?,
+ p1: View?,
+ pos: Int,
+ p3: Long
+ ) {
+ var urls = mutableListOf()
+ for (d in data){
+ urls.add(d.url!!)
+ }
+ toActivity(ImageViewActivity::class.java, DataCollection().apply {
+ add(Data("data",Gson().toJson(urls)))
+ add(Data("pos",pos.toString()))
+ })
+ }
+
+ }
+
+ binding.btnViewPostion.setOnClickListener {
+
+ getData2(model?.id.toString())
+ }
+ binding.btnAdreessDetails.setOnClickListener {
+
+ var urls = model?.patPhoto?.split(",")
+ var url = ""
+ urls?.let {
+ if (urls!!.size > 0) {
+ url = urls.get(0)
+ } else {
+ url = ""
+ }
+ }
+
+
+ if (!TextUtils.isEmpty(homeModel?.collNum)){
+
+ if (homeModel?.latitude == 0.0 || homeModel?.longitude == 0.0){
+ toast(getString(R.string.no_position2))
+ return@setOnClickListener
+ }
+
+ toActivity(MapLocationActivity::class.java, DataCollection().apply {
+ add(Data("latitude", homeModel?.latitude))
+ add(Data("longitude", homeModel?.longitude))
+ add(Data("url", url))
+ })
+ }else{
+ toast(getString(R.string.no_device_data))
+ }
+
+ }
+ binding.btnUnbind.setOnClickListener {
+ CKAlertDialog(this@ViewPetFileActivity,getString(R.string.alert),getString(R.string.unbing_device_alert),object : CKAlertDialog.AlertClickListener{
+ override fun onBack(isConfirm: Boolean) {
+ if (isConfirm){
+ unBind()
+ }
+ }
+
+ }).show()
+ }
+ }
+
+ override fun initData() {
+
+ getData()
+ }
+
+ fun getData(){
+ model = Gson().fromJson(getReceiveParam().get("data")!!.stringValue,
+ CollarTypeModel.TypeDataModel::class.java)
+
+ getData2(model!!.id.toString())
+ showProgeassDialog(getString(R.string.search))
+ TTHttpClient.get(this,"宠物档案",model!!.id.toString(),object : ICallback{
+ override fun onSuccess(data: String) {
+ model = Gson().fromJson(data,
+ CollarTypeModel.TypeDataModel::class.java)
+
+
+ binding.textName.text = model?.patName
+ binding.textSpec.text = CKUtils.getPetSpecLab(model?.patSpecies!!)
+ binding.textBreed.text = model?.patVariety
+ binding.textAge.text = model?.patAge
+ binding.textHeight.text = model?.patHeight
+ binding.textWeigth.text = model?.patWeight
+ binding.textBodyType.text = model?.patBodytype
+ binding.textColor.text = model?.patColor
+ binding.textvacc.text = model?.patProphylactic
+
+ var urls = model?.patPhoto?.split(",")
+
+ this@ViewPetFileActivity.data.clear()
+ if (urls != null) {
+ for (url in urls){
+ var m = ImageModel()
+ m.url = url
+ this@ViewPetFileActivity.data.add(m)
+ }
+ }
+ imageAdapter.data = this@ViewPetFileActivity.data
+ imageAdapter.notifyDataSetChanged()
+
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ toast(msg)
+ }
+ })
+ }
+
+
+ fun getData2(patId : String){
+ TTHttpClient.get(this, "设备信息", TTRequestParam().apply { add(TTRequestData("patId",patId)) },object : ICallback{
+ override fun onSuccess(data: String) {
+ homeModel = Gson().fromJson(data, HomeModel.EquipmentModel::class.java)
+
+
+ if (!TextUtils.isEmpty(homeModel?.collNum)){
+ binding.textHealthPoints!!.text = homeModel?.healthVitality
+ binding.textStep!!.text = homeModel?.steps
+ binding.textAddress!!.text = homeModel?.lastLocation
+ binding.textDistance!!.text = homeModel?.mileage.toString()
+
+ binding.btnViewPostion.visibility = View.GONE
+ binding.btnAdreessDetails?.visibility = View.VISIBLE
+
+ if (homeModel?.noSignal == true){
+ if (TextUtils.isEmpty(homeModel?.lastLocation)){
+ binding.textAddress!!.text = getString(R.string.no_position)
+ }else{
+ binding.textAddress!!.text = "当前位置无法接收信号,最后一次定位是:" + (homeModel?.lastLocation ?: "")
+
+
+ }
+
+ }else{
+ binding.textAddress!!.text = homeModel?.lastLocation
+ }
+
+ }else{
+ binding.textHealthPoints!!.text = "--"
+ binding.textStep!!.text = "-"
+ binding.textAddress!!.text = getString(R.string.no_position)
+ binding.textDistance!!.text = "-"
+
+ binding.btnUnbind.visibility = View.GONE
+
+ binding.btnViewPostion.visibility = View.VISIBLE
+ binding.btnAdreessDetails?.visibility = View.GONE
+ }
+
+
+
+
+
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ toast(msg)
+ }
+ })
+ }
+
+ fun unBind(){
+ if (homeModel == null){
+ toast(getString(R.string.no_device_info))
+ return
+ }
+ showProgeassDialog(getString(R.string.unbind))
+
+ TTHttpClient.post(this,"解绑设备", TTRequestParam().apply { add(TTRequestData("equipmentId",homeModel!!.id)) },object : ICallback{
+ override fun onSuccess(data: String) {
+ LiveDataBus.get().with("BOUND" + model!!.id).value = 1
+ toast(getString(R.string.unbind_success))
+ finish()
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ toast(msg)
+ }
+ })
+ }
+ class ImageAdapter(var context: CKBaseActivity, var data: List) : BaseAdapter() {
+
+ override fun getCount(): Int {
+ var count = if (data.size > 3){
+ 3
+ }else{
+ data.size
+ }
+ return count
+ }
+
+ override fun getItem(p0: Int): Any? {
+ TODO("Not yet implemented")
+ }
+
+ override fun getItemId(p: Int): Long {
+ return p.toLong()
+ }
+
+ override fun getView(
+ p0: Int,
+ p1: View?,
+ p2: ViewGroup?
+ ): View? {
+ var layoutItemImageBinding =
+ LayoutItemImageBinding.inflate(LayoutInflater.from(context))
+
+ layoutItemImageBinding.root.layoutParams = ViewGroup.LayoutParams(TTUtils.dpToPx(context,70).toInt(),
+ TTUtils.dpToPx(context,70).toInt())
+ var model = data.get(p0)
+// layoutItemImageBinding.image.setImageBitmap(
+// TTUtils.getBitmap(
+// model.path,
+// 300,
+// 200
+// )
+// )
+ layoutItemImageBinding.image.scaleType = ImageView.ScaleType.CENTER_CROP
+ Glide.with(context)
+ .load(model.url)
+ .placeholder(R.mipmap.image_default)
+ .centerCrop()
+ .override(300,200)
+ .into(layoutItemImageBinding.image)
+ return layoutItemImageBinding.root
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/ui/act/points/PointsActivity.kt b/app/src/main/java/com/ck/ckcollar/app/ui/act/points/PointsActivity.kt
new file mode 100644
index 0000000..d0b5e41
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/ui/act/points/PointsActivity.kt
@@ -0,0 +1,210 @@
+package com.ck.ckcollar.app.ui.act.points
+
+import android.content.Context
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.recyclerview.widget.LinearLayoutManager
+import androidx.recyclerview.widget.RecyclerView
+import com.ck.ckcollar.app.R
+import com.ck.ckcollar.app.databinding.ActivityPointsBinding
+import com.ck.ckcollar.app.databinding.LayoutItemPointsBinding
+import com.ck.ckcollar.app.databinding.LayoutItemRecordsBinding
+import com.ck.ckcollar.app.listenner.OnItemClickListenner
+import com.ck.ckcollar.app.model.BalanceModle
+import com.ck.ckcollar.app.model.PointsModel
+import com.ck.ckcollar.app.model.RecordModel
+import com.ck.ckcollar.app.ui.act.balance.BalanceActivity.RecordAdapter
+import com.ck.ckcollar.app.ui.act.balance.IncomeRecordDetailsActivity
+import com.ck.ckcollar.app.ui.act.balance.OutRecordDetailsActivity
+import com.ck.ckcollar.app.ui.base.CKLHBaseActionBarActivity
+import com.ck.ckcollar.app.ui.dialog.CKDateMonthDialog
+import com.ck.ckcollar.app.utils.CKUtils
+import com.ck.ckcollar.app.utils.networkone.ICallback
+import com.ck.ckcollar.app.utils.networkone.TTHttpClient
+import com.ck.ckcollar.app.utils.networkone.model.TTRequestData
+import com.ck.ckcollar.app.utils.networkone.model.TTRequestParam
+import com.google.gson.Gson
+import com.google.gson.reflect.TypeToken
+import com.gyf.immersionbar.ImmersionBar
+import com.tt.kit.model.DataCollection
+import java.text.SimpleDateFormat
+import java.util.Date
+
+class PointsActivity : CKLHBaseActionBarActivity() {
+
+ lateinit var binding: ActivityPointsBinding
+ var data = listOf()
+ lateinit var adapter: PointsAdapter
+ var type = "null"
+ var date = ""
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ binding = ActivityPointsBinding.inflate(layoutInflater)
+ setContentView(binding.root)
+ ImmersionBar.with(this)
+ .statusBarDarkFont(true)
+ .init()
+ super.onCreate(savedInstanceState)
+ setTitleText(getString(R.string.points2))
+ }
+
+ override fun initView() {
+
+ binding.recyclerView.layoutManager =
+ LinearLayoutManager(this@PointsActivity, RecyclerView.VERTICAL, false)
+ binding.recyclerView.setHasFixedSize(true)
+ adapter = PointsAdapter(this@PointsActivity, data, object : OnItemClickListenner {
+ override fun onClick(
+ pos: Int,
+ model: Any
+ ) {
+
+ }
+ })
+ binding.recyclerView.adapter = adapter
+
+
+ binding.contentAll.setOnClickListener(itemClickListener)
+ binding.contentIncome.setOnClickListener(itemClickListener)
+ binding.contentOut.setOnClickListener(itemClickListener)
+
+
+ binding.contentDate.setOnClickListener {
+ CKDateMonthDialog(this@PointsActivity, object : CKDateMonthDialog.ItemClickListener {
+ override fun onBack(date: Date, dateText: String) {
+
+ binding.textDate.text = dateText
+ this@PointsActivity.date =
+ SimpleDateFormat(CKUtils.YYYYMM).format(date).toString()
+ getList()
+ }
+ }).show()
+ }
+ }
+
+ override fun initData() {
+
+ binding.textDate.text = CKUtils.getDateForYYYYMM()
+ date = CKUtils.getDateFormat(CKUtils.YYYYMM)
+
+ getList()
+ getPointInfo()
+ }
+
+ var itemClickListener = object : View.OnClickListener {
+ override fun onClick(v: View?) {
+ binding.contentAll.setBackgroundResource(R.drawable.bg_view_white_radius_8)
+ binding.contentIncome.setBackgroundResource(R.drawable.bg_view_white_radius_8)
+ binding.contentOut.setBackgroundResource(R.drawable.bg_view_white_radius_8)
+
+ v?.setBackgroundResource(R.drawable.bg_view_view_radius_8_stroke_1)
+
+ when (v?.id) {
+ R.id.contentAll -> {
+ type = "null"
+ }
+
+ R.id.contentIncome -> {
+ type = "gain"
+ }
+
+ R.id.contentOut -> {
+ type = "used"
+ }
+ }
+ getList()
+ }
+ }
+
+ fun getList() {
+ TTHttpClient.get(this, "积分明细", TTRequestParam().apply {
+ add(TTRequestData("type", type))
+ add(TTRequestData("month", date))
+ }, object : ICallback {
+ override fun onSuccess(data: String) {
+ this@PointsActivity.data = Gson().fromJson>(
+ data,
+ object : TypeToken>() {}.type
+ )
+
+ adapter.data = this@PointsActivity.data
+ adapter.notifyDataSetChanged()
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ toast(msg)
+ }
+ })
+ }
+
+ fun getPointInfo() {
+ TTHttpClient.get(this, "积分总览", TTRequestParam(), object : ICallback {
+ override fun onSuccess(data: String) {
+ var model = Gson().fromJson(data, PointsModel::class.java)
+
+ binding.textPoints.text = model.memberPoints.toString()
+
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ toast(msg)
+ }
+ })
+ }
+
+ class PointsAdapter(
+ var context: Context,
+ var data: List,
+ var onItemClickListenner: OnItemClickListenner
+ ) : RecyclerView.Adapter() {
+
+ override fun onCreateViewHolder(
+ parent: ViewGroup,
+ viewType: Int
+ ): PointsHolder {
+ return PointsHolder(
+ LayoutItemPointsBinding.inflate(
+ LayoutInflater.from(context),
+ parent,
+ false
+ )
+ )
+ }
+
+ override fun onBindViewHolder(
+ holder: PointsHolder,
+ position: Int
+ ) {
+ var model = data.get(position)
+ holder.binding.text.text = model.title
+
+ var code = if (model.amount > 0) {
+ "+"
+ } else {
+ ""
+ }
+ holder.binding.textAmount.text = code + model.amount.toString()
+ holder.binding.textDate.text = model.createTime.toString()
+
+
+
+ holder.binding.root.setTag(position)
+ holder.binding.root.setOnClickListener {
+ val position = it.tag as Int
+ onItemClickListenner.onClick(position, data.get(position))
+ }
+ }
+
+ override fun getItemCount(): Int {
+ return data.size
+ }
+
+ class PointsHolder(var binding: LayoutItemPointsBinding) :
+ RecyclerView.ViewHolder(binding.root) {
+
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/ui/act/setting/AccountCancellationActivity.kt b/app/src/main/java/com/ck/ckcollar/app/ui/act/setting/AccountCancellationActivity.kt
new file mode 100644
index 0000000..05cac13
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/ui/act/setting/AccountCancellationActivity.kt
@@ -0,0 +1,179 @@
+package com.ck.ckcollar.app.ui.act.setting
+
+import android.os.Bundle
+import android.text.SpannableStringBuilder
+import android.text.Spanned
+import android.text.TextPaint
+import android.text.method.LinkMovementMethod
+import android.text.style.ClickableSpan
+import android.view.View
+import com.ck.ckcollar.app.CKApp
+import com.ck.ckcollar.app.R
+import com.ck.ckcollar.app.databinding.ActivityAccountCancellationBinding
+import com.ck.ckcollar.app.model.CancelModel
+import com.ck.ckcollar.app.ui.act.login.AgreementActivity
+import com.ck.ckcollar.app.ui.act.login.LoginActivity
+import com.ck.ckcollar.app.ui.base.CKBaseActivity
+import com.ck.ckcollar.app.ui.dialog.CKAlertDialog
+import com.ck.ckcollar.app.utils.CKUtils
+import com.ck.ckcollar.app.utils.Const
+import com.ck.ckcollar.app.utils.networkone.ICallback
+import com.ck.ckcollar.app.utils.networkone.TTHttpClient
+import com.ck.ckcollar.app.utils.networkone.model.TTRequestData
+import com.ck.ckcollar.app.utils.networkone.model.TTRequestParam
+import com.cyclone.shadowsocks.utils.PreferencesUtils
+import com.google.gson.Gson
+import com.tt.kit.model.Data
+import com.tt.kit.model.DataCollection
+
+class AccountCancellationActivity: CKBaseActivity() {
+ lateinit var binding: ActivityAccountCancellationBinding
+ var isCheck = false
+ var model:CancelModel? = null
+ override fun onCreate(savedInstanceState: Bundle?) {
+ binding = ActivityAccountCancellationBinding.inflate(layoutInflater)
+ setContentView(binding.root)
+ super.onCreate(savedInstanceState)
+ }
+
+
+
+ override fun initView() {
+
+ binding.textPhone.text = getString(R.string.cancel_account_phone, CKUtils.getPhone(CKApp.app.userInfo?.phonenumber ?: ""))
+
+ val text = "我已阅读并同意《用户注销须知》";
+ val spannable = SpannableStringBuilder(text)
+ // 获取需要应用样式的文本的开始和结束索引
+ val start1 = text.indexOf("《用户注销须知》")
+ val end1 = start1 + "《用户注销须知》".length
+
+ var clickableSpan = object : ClickableSpan() {
+ override fun onClick(v: View) {
+ toActivity(AgreementActivity::class.java, DataCollection().apply { add(Data("title","用户注销协议")) })
+ }
+ override fun updateDrawState(ds: TextPaint) {
+ ds.setColor(getColor2(R.attr.appTextColor))
+ }
+ };
+
+
+ binding.textAgreement.setMovementMethod(LinkMovementMethod.getInstance());
+ binding.textAgreement.setHighlightColor(resources.getColor(R.color.transparent))
+ // 应用样式
+ spannable.setSpan(clickableSpan, start1, end1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
+
+ binding.textAgreement.setText(spannable)
+
+ setCheckUI()
+ binding.btnCheck.setOnClickListener {
+ isCheck = !isCheck
+ setCheckUI()
+ }
+
+ binding.btnConfirmCancellation.setOnClickListener {
+ if (!isCheck){
+ toast(getString(R.string.alert_agreement))
+ return@setOnClickListener
+ }
+
+ if (model?.allPassed!! && model?.assetsUncleared!!){
+ CKAlertDialog(this@AccountCancellationActivity,getString(R.string.alert),getString(R.string.delete_user_alert2),object : CKAlertDialog.AlertClickListener{
+ override fun onBack(isConfirm: Boolean) {
+ if (isConfirm){
+ cancel()
+ }
+ }
+ }).show()
+
+ }else if (model?.allPassed!! && !model?.assetsUncleared!!){
+ CKAlertDialog(this@AccountCancellationActivity,getString(R.string.alert),getString(R.string.delete_user_alert),object : CKAlertDialog.AlertClickListener{
+ override fun onBack(isConfirm: Boolean) {
+ if (isConfirm){
+ cancel()
+ }
+ }
+ }).show()
+
+ }else{
+ toast(getString(R.string.cant_cencel_account))
+ }
+
+ }
+ }
+
+ fun cancel(){
+
+ TTHttpClient.post(this@AccountCancellationActivity,"用户注销", TTRequestParam().apply {
+ add(TTRequestData("accept","true"))
+ },object : ICallback{
+ override fun onSuccess(data: String) {
+ PreferencesUtils.clear(this@AccountCancellationActivity)
+ toActivityNewTaskClear(LoginActivity::class.java, DataCollection())
+ finish()
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ toast(msg)
+ }
+ })
+
+ }
+
+ fun check(){
+
+ TTHttpClient.get(this@AccountCancellationActivity,"用户注销检查", TTRequestParam(),object : ICallback{
+ override fun onSuccess(data: String) {
+ model = Gson().fromJson(data,CancelModel::class.java)
+
+ var n = 0
+ for (m in model!!.conditions!!){
+ if (n == 0){
+ if (!m.passed){
+ binding.textAlert1.setTextColor(getColor(R.color.color_F83B3B))
+ binding.textAlert1.text = m.message
+ }
+ }else if (n == 1){
+ if (!m.passed){
+ binding.textAlert2.setTextColor(getColor(R.color.color_F83B3B))
+ binding.textAlert2.text = m.message
+
+ }
+ }else if (n == 2){
+ if (!m.passed){
+ binding.textAlert3.setTextColor(getColor(R.color.color_F83B3B))
+ binding.textAlert3.text = m.message
+
+ }
+ }else if (n == 3){
+ if (!m.passed){
+ binding.textAlert4.setTextColor(getColor(R.color.color_F83B3B))
+ binding.textAlert4.text = m.message
+
+ }
+ }
+ n++
+
+ }
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ toast(msg)
+ finish()
+ }
+ })
+
+ }
+ override fun initData() {
+
+ check()
+ }
+
+ fun setCheckUI(){
+ if (isCheck){
+ binding.check.setImageResource(R.mipmap.image_check_select)
+ }else{
+ binding.check.setImageResource(R.mipmap.image_check_unselect)
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ck/ckcollar/app/ui/act/setting/AddAddressActivity.kt b/app/src/main/java/com/ck/ckcollar/app/ui/act/setting/AddAddressActivity.kt
new file mode 100644
index 0000000..9f62d48
--- /dev/null
+++ b/app/src/main/java/com/ck/ckcollar/app/ui/act/setting/AddAddressActivity.kt
@@ -0,0 +1,281 @@
+package com.ck.ckcollar.app.ui.act.setting
+
+import android.nfc.Tag
+import android.os.Bundle
+import android.text.TextUtils
+import android.view.View
+import com.ck.ckcollar.app.R
+import com.ck.ckcollar.app.databinding.ActivityAddAddressBinding
+import com.ck.ckcollar.app.databinding.LayoutItemAddressTag2Binding
+import com.ck.ckcollar.app.databinding.LayoutItemAddressTagBinding
+import com.ck.ckcollar.app.model.TagModel
+import com.ck.ckcollar.app.ui.base.CKBaseActivity
+import com.ck.ckcollar.app.ui.dialog.CKAlertDialog
+import com.ck.ckcollar.app.ui.dialog.CKEditDialog
+import com.ck.ckcollar.app.ui.dialog.CKProvincePickViewDialog
+import com.ck.ckcollar.app.utils.networkone.ICallback
+import com.ck.ckcollar.app.utils.networkone.TTHttpClient
+import com.ck.ckcollar.app.utils.networkone.model.TTRequestData
+import com.ck.ckcollar.app.utils.networkone.model.TTRequestParam
+import com.ck.ckcollar.app.widget.CKEditView
+import com.google.gson.Gson
+import com.google.gson.reflect.TypeToken
+import com.pinko.flowlayout.FlowLayout
+import com.pinko.flowlayout.TagAdapter
+import com.pinko.flowlayout.TagFlowLayout
+import com.tt.kit.model.DataCollection
+import com.tt.kit.utils.KeyboardUtils
+
+class AddAddressActivity : CKBaseActivity() {
+
+ lateinit var binding: ActivityAddAddressBinding
+ var data = mutableListOf()
+ var pos = -1;
+ var provinceName = ""
+ var cityName = ""
+ var areaName = ""
+ lateinit var tagAdapter : TagAdapter
+ override fun onCreate(savedInstanceState: Bundle?) {
+ binding = ActivityAddAddressBinding.inflate(layoutInflater)
+
+ setContentView(binding.root)
+ super.onCreate(savedInstanceState)
+
+ setTitleText(getString(R.string.add_address))
+ }
+
+ override fun initView() {
+
+
+
+ binding.flowlayout.setOnTagClickListener(object : TagFlowLayout.OnTagClickListener{
+ override fun onTagClick(
+ p0: View?,
+ p: Int,
+ p2: FlowLayout?
+ ): Boolean {
+ if (this@AddAddressActivity.data.get(p).isMore == true){
+ if(pos > -1){
+ tagAdapter.setSelected(pos,this@AddAddressActivity.data.get(pos))
+ }
+ tagAdapter.notifyDataChanged()
+ return true
+ }
+
+ if (this@AddAddressActivity.data.get(p).isAdd == true){
+
+ tagAdapter.notifyDataChanged()
+
+
+ CKEditDialog(this@AddAddressActivity,getString(R.string.custom),getString(R.string.custom),object :
+ CKEditDialog.AlertClickListener{
+ override fun onBack(text: String) {
+ if (!TextUtils.isEmpty(text)){
+ addTag(text)
+ }
+ }
+ }).show()
+
+ return true
+ }
+
+
+ pos = p
+ return false
+ }
+ })
+
+ binding.flowlayout.setOnTagLongClickListener(object : TagFlowLayout.OnTagLongClickListener{
+ override fun onTagLongClick(
+ p0: View?,
+ p1: Int,
+ p2: FlowLayout?
+ ): Boolean {
+
+ if (data.get(p1).isAdd == true || data.get(p1).isMore == true ){
+ return false
+ }
+ deleteTag(data.get(p1).id)
+ return false
+ }
+ })
+
+ binding.textRegion.setOnClickListener {
+ KeyboardUtils.hideKeyboard(this)
+ CKProvincePickViewDialog(this@AddAddressActivity,object : CKProvincePickViewDialog.ItemClickListener{
+ override fun onBack(
+ pos: Int,
+ item1: String,
+ item2: String,
+ item3: String
+ ) {
+ provinceName = item1
+ cityName = item2
+ areaName = item3
+ binding.textRegion.text = item1 + item2 + item3
+ }
+ }).show()
+ }
+ binding.btnSave.setOnClickListener {
+ addAddress()
+ }
+ }
+
+ override fun initData() {
+ getTagList()
+ }
+
+
+ fun addAddress(){
+ if (binding.textName.isEmpty()){
+ toast(getString(R.string.input_name2))
+ return
+ }
+ if (binding.textPhone.isEmpty()){
+ toast(getString(R.string.input_phone))
+ return
+ }
+ if (binding.textPhone.text?.length != 11){
+ toast(getString(R.string.input_phone_alert))
+ return
+ }
+ if (binding.textRegion.isEmpty()){
+ toast(getString(R.string.input_region))
+ return
+ }
+ if (binding.textDetailsAddress.isEmpty()){
+ toast(getString(R.string.input_addres_details))
+ return
+ }
+
+ var selectList = binding.flowlayout.selectedList.toIntArray()
+
+ var tag = if (selectList.size ==0){
+ ""
+ }else{
+ data.get(selectList.get(0)).addressKey!!
+ }
+
+
+ var check = if (binding.switchButton.isChecked){
+ "0"
+ }else{
+ "1"
+ }
+ var param = TTRequestParam().apply {
+ add(TTRequestData("receiverName",binding.textName.text.toString()))
+ add(TTRequestData("receiverPhone",binding.textPhone.text.toString()))
+ add(TTRequestData("provinceName",provinceName))
+ add(TTRequestData("cityName",cityName))
+ add(TTRequestData("areaName",areaName))
+ add(TTRequestData("detailAddress",binding.textDetailsAddress.text.toString()))
+ add(TTRequestData("postalCode",""))
+ add(TTRequestData("isDefault",check))
+ add(TTRequestData("addressTag",tag))
+
+
+ }
+
+ showProgeassDialog(getString(R.string.add))
+ TTHttpClient.postJson(this,"新增收货地址",param,object : ICallback{
+ override fun onSuccess(data: String) {
+ toast(getString(R.string.add_success))
+ finish(DataCollection(),1001)
+ }
+
+ override fun onFailed(code: String, msg: String) {
+ toast(msg)
+ }
+ })
+ }
+
+ fun getTagList(){
+ TTHttpClient.get(this,"地址标签列表", TTRequestParam(),object : ICallback{
+ override fun onSuccess(data: String) {
+ var models = Gson().fromJson>(data,object : TypeToken>(){}.type)
+ this@AddAddressActivity.data.clear()
+ this@AddAddressActivity.data.addAll(models)
+
+ this@AddAddressActivity.data.add(TagModel().apply { addressLabel = getString(R.string.custom)
+ isAdd = true
+ })
+ this@AddAddressActivity.data.add(TagModel().apply { addressLabel = getString(R.string.label_max_length)
+ isMore = true
+ })
+
+
+ pos = -1
+ tagAdapter = object : TagAdapter