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(this@AddAddressActivity.data){ + + override fun getView( + p0: FlowLayout?, + p1: Int, + p2: TagModel? + ): View? { + if (p2!!.isMore == true){ + var binding = LayoutItemAddressTag2Binding.inflate(layoutInflater) + binding.textTag.text = p2.addressLabel + + return binding.root + }else{ + var binding = LayoutItemAddressTagBinding.inflate(layoutInflater) + binding.textTag.text = p2.addressLabel + + return binding.root + } + + + } + } + // tagAdapter.setSelected(pos,this@AddAddressActivity.data.get(pos)) + binding.flowlayout.adapter = tagAdapter + + + + } + + override fun onFailed(code: String, msg: String) { + toast(msg) + } + }) + } + + fun deleteTag(id : Int){ + + CKAlertDialog(this@AddAddressActivity,getString(R.string.alert),getString(R.string.delete_tag_alert),object : + CKAlertDialog.AlertClickListener{ + override fun onBack(isConfirm: Boolean) { + if (isConfirm){ + showProgeassDialog(getString(R.string.delete)) + TTHttpClient.delete(this@AddAddressActivity,"删除标签", id.toString(),object : ICallback{ + override fun onSuccess(data: String) { + + toast(getString(R.string.delete_success)) + getTagList() + + } + + override fun onFailed(code: String, msg: String) { + toast(msg) + } + }) + } + } + }).show() + + + } + + fun addTag(lable : String){ + showProgeassDialog(getString(R.string.add)) + TTHttpClient.postJson(this,"新增标签", TTRequestParam().apply { add(TTRequestData("addressLabel",lable)) },object : ICallback{ + override fun onSuccess(data: String) { + getTagList() + } + + 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/setting/AddressActivity.kt b/app/src/main/java/com/ck/ckcollar/app/ui/act/setting/AddressActivity.kt new file mode 100644 index 0000000..f81ed1b --- /dev/null +++ b/app/src/main/java/com/ck/ckcollar/app/ui/act/setting/AddressActivity.kt @@ -0,0 +1,275 @@ +package com.ck.ckcollar.app.ui.act.setting + +import android.content.Context +import android.location.Address +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.ck.ckcollar.app.R +import com.ck.ckcollar.app.databinding.ActivityAddressBinding +import com.ck.ckcollar.app.databinding.LayoutItemAddressBinding +import com.ck.ckcollar.app.databinding.LayoutItemCustomerMessageBinding +import com.ck.ckcollar.app.listenner.OnItemClickListenner +import com.ck.ckcollar.app.model.AddressModel +import com.ck.ckcollar.app.model.CustomerMessageModel +import com.ck.ckcollar.app.ui.act.customer.CustomerActivity.CustomerMessageAdapter +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.TTUtils +import kotlin.toString + +class AddressActivity : CKBaseActivity() { + lateinit var binding: ActivityAddressBinding + lateinit var addressAdapter: AddressAdapter + var data = listOf() + override fun onCreate(savedInstanceState: Bundle?) { + binding = ActivityAddressBinding.inflate(layoutInflater) + setContentView(binding.root) + super.onCreate(savedInstanceState) + + setTitleText(getString(R.string.shipping_address)) + } + + override fun initView() { + binding.recyclerView.layoutManager = + LinearLayoutManager(this@AddressActivity, RecyclerView.VERTICAL, false) + binding.recyclerView.setHasFixedSize(true) + addressAdapter = AddressAdapter(this@AddressActivity, data, object : OnItemClickListenner { + override fun onClick( + pos: Int, + model: Any + ) { + var flag = getReceiveParam().get("flag")!!.stringValue.toString() + + if ("0".equals(flag)) { + var result = DataCollection().apply { + add(Data("data", Gson().toJson(data.get(pos)))) + } + finish(result, 1001) + } else if ("2".equals(flag)) { + edit(getReceiveParam().get("data")!!.stringValue.toString(),data.get(pos).id.toString()) + } + } + }) + binding.recyclerView.adapter = addressAdapter + + binding.btnAdd.setOnClickListener { + toActivityForResult(AddAddressActivity::class.java, DataCollection(), 1001) + } + } + + override fun initData() { + + getData() + } + + fun edit(id: String, addressId: String) { + CKAlertDialog( + this, + getString(R.string.alert), + getString(R.string.alert_change_address), + object : CKAlertDialog.AlertClickListener { + override fun onBack(isConfirm: Boolean) { + if (isConfirm) { + + showProgeassDialog(getString(R.string.edit)) + TTHttpClient.put( + this@AddressActivity, + "修改收货地址", + TTRequestParam().apply { + add( + TTRequestData("orderId", id) + ) + add(TTRequestData("addressId", addressId)) + }, + object : ICallback { + override fun onSuccess(data: String) { + toast(getString(R.string.edit_success)) + finish(DataCollection(), 1001) + } + + override fun onFailed(code: String, msg: String) { + toast(msg) + } + }) + } + } + }).show() + } + + override fun getResult(data: DataCollection, resultCode: Int) { + getData() + } + + fun getData() { + TTHttpClient.get(this, "收货地址列表", TTRequestParam(), object : ICallback { + override fun onSuccess(data: String) { + + this@AddressActivity.data = Gson().fromJson>(data, + object : TypeToken>() {}.type) + + addressAdapter.data = this@AddressActivity.data + addressAdapter.notifyDataSetChanged() + } + + override fun onFailed(code: String, msg: String) { + + toast(msg) + } + }) + } + + + class AddressAdapter( + var context: AddressActivity, + var data: List, + var onItemClickListenner: OnItemClickListenner + ) : RecyclerView.Adapter() { + + var selectPos = -1 + override fun onCreateViewHolder( + parent: ViewGroup, + viewType: Int + ): AddressHolder { + return AddressHolder( + LayoutItemAddressBinding.inflate( + LayoutInflater.from(context), + parent, + false + ) + ) + } + + override fun onBindViewHolder( + holder: AddressHolder, + position: Int + ) { + // holder.binding.text.text = data.get(position).name + + var model = data.get(position) + if ("0".equals(model.isDefault)) { + holder.binding.check.setImageResource(R.mipmap.image_address_check_select) + } else { + holder.binding.check.setImageResource(R.mipmap.image_address_check_narmal) + } + + holder.binding.btnCheck.setTag(position) + holder.binding.btnCheck.setOnClickListener { + checkDefault(position) + } + + holder.binding.textName.text = model.receiverName + holder.binding.textPhone.text = model.receiverPhone + holder.binding.textAddressDetails.text = model.fullAddress + + + if (model.colUserAddressLabel == null) { + holder.binding.textTag.visibility = View.GONE + } else { + holder.binding.textTag.visibility = View.VISIBLE + holder.binding.textTag.text = model.colUserAddressLabel!!.addressLabel + } + + holder.binding.btnDelete.setOnClickListener { + delete(model.id) + } + holder.binding.btnCopy.setOnClickListener { + TTUtils.copyTextToClipboard( + context, + model.receiverName + " " + model.receiverPhone + "\n" + model.fullAddress + ) + context.toast(context.getString(R.string.copy_success)) + } + holder.binding.btnEdit.setOnClickListener { + context.toActivityForResult( + EditAddressActivity::class.java, + DataCollection().apply { + add( + Data("data", Gson().toJson(model)) + ) + }, + 1001 + ) + } + + + 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 + } + + + fun delete(id: Int) { + CKAlertDialog( + context, + context.getString(R.string.alert), + context.getString(R.string.delete_address_alert), + object : CKAlertDialog.AlertClickListener { + override fun onBack(isConfirm: Boolean) { + if (isConfirm) { + context.showProgeassDialog(context.getString(R.string.delete)) + TTHttpClient.delete( + context, + "删除收货地址", + id.toString(), + object : ICallback { + override fun onSuccess(data: String) { + context.getData() + } + + override fun onFailed(code: String, msg: String) { + context.toast(msg) + } + }) + } + } + }).show() + } + + fun checkDefault(pos: Int) { + context.showProgeassDialog(context.getString(R.string.update)) + TTHttpClient.put( + context, + "设置默认地址", + data.get(pos).id.toString(), + object : ICallback { + override fun onSuccess(data: String) { + + context.toast(context.getString(R.string.option_success)) + + + context.getData() + } + + override fun onFailed(code: String, msg: String) { + context.toast(msg) + } + }) + } + + class AddressHolder(var binding: LayoutItemAddressBinding) : + RecyclerView.ViewHolder(binding.root) { + + } + + } +} \ No newline at end of file diff --git a/app/src/main/java/com/ck/ckcollar/app/ui/act/setting/EditAddressActivity.kt b/app/src/main/java/com/ck/ckcollar/app/ui/act/setting/EditAddressActivity.kt new file mode 100644 index 0000000..7a20956 --- /dev/null +++ b/app/src/main/java/com/ck/ckcollar/app/ui/act/setting/EditAddressActivity.kt @@ -0,0 +1,351 @@ +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.AddressModel +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 EditAddressActivity : CKBaseActivity() { + + lateinit var binding: ActivityAddAddressBinding + var data = mutableListOf() + var pos = -1; + var provinceName = "" + var cityName = "" + var areaName = "" + lateinit var tagAdapter: TagAdapter + + var model: AddressModel? = null + override fun onCreate(savedInstanceState: Bundle?) { + binding = ActivityAddAddressBinding.inflate(layoutInflater) + + setContentView(binding.root) + super.onCreate(savedInstanceState) + + setTitleText(getString(R.string.edit_address)) + } + + override fun initView() { + + + binding.flowlayout.setOnTagClickListener(object : TagFlowLayout.OnTagClickListener { + override fun onTagClick( + p0: View?, + p: Int, + p2: FlowLayout? + ): Boolean { + if (this@EditAddressActivity.data.get(p).isMore == true) { + if (pos > -1) { + tagAdapter.setSelected(pos, this@EditAddressActivity.data.get(pos)) + } + tagAdapter.notifyDataChanged() + return true + } + + if (this@EditAddressActivity.data.get(p).isAdd == true) { + + tagAdapter.notifyDataChanged() + + + CKEditDialog( + this@EditAddressActivity, + 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@EditAddressActivity, + 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 { + editAddress() + } + } + + override fun initData() { + + try { + model = Gson().fromJson( + getReceiveParam().get("data")!!.stringValue, + AddressModel::class.java + ) + + binding.textName.setText(model?.receiverName) + binding.textPhone.setText(model?.receiverPhone) + binding.textRegion.setText(model?.provinceName + model?.cityName + model?.areaName) + binding.textDetailsAddress.setText(model?.detailAddress) + + provinceName = model!!.provinceName!! + cityName = model!!.cityName!! + areaName = model!!.areaName!! + + binding.switchButton.isChecked = "0".equals(model?.isDefault) + } catch (e: Exception) { + e.printStackTrace() + } + + //getData() + getTagList() + + + } + + + fun editAddress() { + 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("id", model?.id.toString())) + 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.update)) + 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 getData() { + + showProgeassDialog(getString(R.string.add)) + TTHttpClient.get(this,"收货地址明细",model!!.id.toString(),object : ICallback{ + override fun onSuccess(data: String) { + + } + + 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@EditAddressActivity.data.clear() + this@EditAddressActivity.data.addAll(models) + + this@EditAddressActivity.data.add(TagModel().apply { + addressLabel = getString(R.string.custom) + isAdd = true + }) + this@EditAddressActivity.data.add(TagModel().apply { + addressLabel = getString(R.string.label_max_length) + isMore = true + }) + + + pos = -1 + tagAdapter = object : TagAdapter(this@EditAddressActivity.data) { + + override fun getView( + p0: FlowLayout?, + p1: Int, + p2: TagModel? + ): View? { + if (p2!!.isMore == true) { + var binding = LayoutItemAddressTag2Binding.inflate(layoutInflater) + binding.textTag.text = p2.addressLabel + + return binding.root + } else { + var binding = LayoutItemAddressTagBinding.inflate(layoutInflater) + binding.textTag.text = p2.addressLabel + + return binding.root + } + + + } + } + + if (model?.colUserAddressLabel != null){ + for (i in this@EditAddressActivity.data.indices){ + if (this@EditAddressActivity.data.get(i).addressKey.equals(model!!.colUserAddressLabel!!.addressKey)){ + pos = i + } + } + } + if (pos > -1){ + tagAdapter.setSelectedList(pos) + } + binding.flowlayout.adapter = tagAdapter + + + } + + override fun onFailed(code: String, msg: String) { + toast(msg) + } + }) + } + + fun deleteTag(id: Int) { + + CKAlertDialog( + this@EditAddressActivity, + getString(R.string.alert), + getString(R.string.delete_tag_alert), + object : + CKAlertDialog.AlertClickListener { + override fun onBack(isConfirm: Boolean) { + if (isConfirm) { + showProgeassDialog(getString(R.string.delete)) + TTHttpClient.delete( + this@EditAddressActivity, + "删除标签", + id.toString(), + object : ICallback { + override fun onSuccess(data: String) { + + toast(getString(R.string.delete_success)) + getTagList() + + } + + override fun onFailed(code: String, msg: String) { + toast(msg) + } + }) + } + } + }).show() + + + } + + fun addTag(lable: String) { + showProgeassDialog(getString(R.string.add)) + TTHttpClient.postJson( + this, + "新增标签", + TTRequestParam().apply { add(TTRequestData("addressLabel", lable)) }, + object : ICallback { + override fun onSuccess(data: String) { + getTagList() + } + + 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/setting/EditPayPsswordActivity.kt b/app/src/main/java/com/ck/ckcollar/app/ui/act/setting/EditPayPsswordActivity.kt new file mode 100644 index 0000000..fb2e6f0 --- /dev/null +++ b/app/src/main/java/com/ck/ckcollar/app/ui/act/setting/EditPayPsswordActivity.kt @@ -0,0 +1,72 @@ +package com.ck.ckcollar.app.ui.act.setting + +import android.os.Bundle +import com.ck.ckcollar.app.R +import com.ck.ckcollar.app.databinding.ActivityEditPasswordBinding +import com.ck.ckcollar.app.databinding.ActivityEditPayPasswordBinding +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 + +class EditPayPsswordActivity : CKBaseActivity() { + + lateinit var binding: ActivityEditPayPasswordBinding + override fun onCreate(savedInstanceState: Bundle?) { + binding = ActivityEditPayPasswordBinding.inflate(layoutInflater) + setContentView(binding.root) + super.onCreate(savedInstanceState) + + setTitleText(getString(R.string.modify_pay_password)) + } + + override fun initView() { + + binding.btnReset.setOnClickListener { + edit() + } + } + override fun initData() { + + } + + fun edit(){ + if (binding.editOldPassword.isEmpty()){ + toast(getString(R.string.new_password_not_empty)) + return + } + if (binding.editNewPwd.isEmpty()){ + toast(getString(R.string.password_not_empty)) + return + } + if (binding.editNewPwd.text.toString().length != 6){ + toast(getString(R.string.six_length_alert)) + return + } + if (!binding.editNewPwd.text.toString().equals(binding.editNewPwdConfirm.text.toString())){ + toast(getString(R.string.confirm_password_not_both)) + return + } + if (binding.editOldPassword.text.toString().equals(binding.editNewPwd.text.toString())){ + toast(getString(R.string.old_new_password_both)) + return + } + + showProgeassDialog(getString(R.string.edit)) + TTHttpClient.postJson(this,"修改支付密码", TTRequestParam().apply { + add(TTRequestData("oldPassword",binding.editOldPassword.text.toString())) + add(TTRequestData("newPassword",binding.editNewPwd.text.toString())) + add(TTRequestData("confirmPassword",binding.editNewPwdConfirm.text.toString())) + },object : ICallback{ + override fun onSuccess(data: String) { + toast(getString(R.string.edit_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/setting/EditPsswordActivity.kt b/app/src/main/java/com/ck/ckcollar/app/ui/act/setting/EditPsswordActivity.kt new file mode 100644 index 0000000..7e7acf3 --- /dev/null +++ b/app/src/main/java/com/ck/ckcollar/app/ui/act/setting/EditPsswordActivity.kt @@ -0,0 +1,75 @@ +package com.ck.ckcollar.app.ui.act.setting + +import android.os.Bundle +import android.view.View +import com.ck.ckcollar.app.CKApp +import com.ck.ckcollar.app.R +import com.ck.ckcollar.app.databinding.ActivityEditPasswordBinding +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 + +class EditPsswordActivity : CKBaseActivity() { + + lateinit var binding: ActivityEditPasswordBinding + override fun onCreate(savedInstanceState: Bundle?) { + binding = ActivityEditPasswordBinding.inflate(layoutInflater) + setContentView(binding.root) + super.onCreate(savedInstanceState) + + } + + override fun initView() { + + binding.btnReset.setOnClickListener { + edit() + } + } + override fun initData() { + + if (!CKApp.app.userInfo!!.isLoginPwdSet){ + binding.contentOldPwd.visibility = View.GONE + setTitleText(getString(R.string.setting_login_password)) + }else{ + setTitleText(getString(R.string.modify_login_password)) + } + } + + fun edit(){ + if (binding.editOldPassword.isEmpty() && binding.contentOldPwd.visibility == View.VISIBLE){ + toast(getString(R.string.new_password_not_empty)) + return + } + if (binding.editNewPwd.isEmpty()){ + toast(getString(R.string.password_not_empty)) + return + } + if (!binding.editNewPwd.text.toString().equals(binding.editNewPwdConfirm.text.toString())){ + toast(getString(R.string.confirm_password_not_both)) + return + } + + if (binding.editOldPassword.text.toString().equals(binding.editNewPwd.text.toString())){ + toast(getString(R.string.old_new_password_both)) + return + } + + showProgeassDialog(getString(R.string.edit)) + TTHttpClient.postJson(this,"修改登录密码", TTRequestParam().apply { + add(TTRequestData("oldPassword",binding.editOldPassword.text.toString())) + add(TTRequestData("newPassword",binding.editNewPwd.text.toString())) + add(TTRequestData("confirmPassword",binding.editNewPwdConfirm.text.toString())) + },object : ICallback{ + override fun onSuccess(data: String) { + toast(getString(R.string.edit_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/setting/FindPasswordActivity.kt b/app/src/main/java/com/ck/ckcollar/app/ui/act/setting/FindPasswordActivity.kt new file mode 100644 index 0000000..b3e9e71 --- /dev/null +++ b/app/src/main/java/com/ck/ckcollar/app/ui/act/setting/FindPasswordActivity.kt @@ -0,0 +1,121 @@ +package com.ck.ckcollar.app.ui.act.setting + +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.ActivityFindPasswordBinding +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 FindPasswordActivity : CKBaseActivity() { + + private lateinit var binding: ActivityFindPasswordBinding + override fun onCreate(savedInstanceState: Bundle?) { + binding = ActivityFindPasswordBinding.inflate(layoutInflater) + setContentView(binding.root) + super.onCreate(savedInstanceState) + + setTitleText(getString(R.string.lost)) + } + + override fun initView() { + binding.btnCode.setOnClickListener { + + sendCode() + + } + binding.btnRegister.setOnClickListener { + find() + } + + } + + 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 find(){ + 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.reset_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/setting/FindPayPasswordActivity.kt b/app/src/main/java/com/ck/ckcollar/app/ui/act/setting/FindPayPasswordActivity.kt new file mode 100644 index 0000000..e9e0654 --- /dev/null +++ b/app/src/main/java/com/ck/ckcollar/app/ui/act/setting/FindPayPasswordActivity.kt @@ -0,0 +1,126 @@ +package com.ck.ckcollar.app.ui.act.setting + +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.ActivityFindPasswordBinding +import com.ck.ckcollar.app.databinding.ActivityFindPayPasswordBinding +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 FindPayPasswordActivity : CKBaseActivity() { + + private lateinit var binding: ActivityFindPayPasswordBinding + override fun onCreate(savedInstanceState: Bundle?) { + binding = ActivityFindPayPasswordBinding.inflate(layoutInflater) + setContentView(binding.root) + super.onCreate(savedInstanceState) + + setTitleText(getString(R.string.lost)) + } + + override fun initView() { + binding.btnCode.setOnClickListener { + + sendCode() + + } + binding.btnRegister.setOnClickListener { + find() + } + + } + + 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 find(){ + 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().length != 6){ + toast(getString(R.string.six_length_alert)) + 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.reset_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/setting/PasswordManagerActivity.kt b/app/src/main/java/com/ck/ckcollar/app/ui/act/setting/PasswordManagerActivity.kt new file mode 100644 index 0000000..ac88a57 --- /dev/null +++ b/app/src/main/java/com/ck/ckcollar/app/ui/act/setting/PasswordManagerActivity.kt @@ -0,0 +1,39 @@ +package com.ck.ckcollar.app.ui.act.setting + +import android.os.Bundle +import com.ck.ckcollar.app.R +import com.ck.ckcollar.app.databinding.ActivityPasswordManagerBinding +import com.ck.ckcollar.app.ui.base.CKBaseActivity +import com.tt.kit.model.DataCollection + +class PasswordManagerActivity : CKBaseActivity() { + + + lateinit var binding: ActivityPasswordManagerBinding + + override fun onCreate(savedInstanceState: Bundle?) { + binding = ActivityPasswordManagerBinding.inflate(layoutInflater) + setContentView(binding.root) + super.onCreate(savedInstanceState) + + setStatusBarColor(resources.getColor(R.color.white)) + setActionBarColor(resources.getColor(R.color.white)) + + setTitleText(getString(R.string.login_password)) + } + + override fun initView() { + + binding.contentEditPassword.setOnClickListener { + toActivity(EditPsswordActivity::class.java, DataCollection()) + } + binding.contentFindPassword.setOnClickListener { + toActivity(FindPasswordActivity::class.java, DataCollection()) + } + + } + + override fun initData() { + + } +} \ No newline at end of file diff --git a/app/src/main/java/com/ck/ckcollar/app/ui/act/setting/PayPasswordManagerActivity.kt b/app/src/main/java/com/ck/ckcollar/app/ui/act/setting/PayPasswordManagerActivity.kt new file mode 100644 index 0000000..e062f63 --- /dev/null +++ b/app/src/main/java/com/ck/ckcollar/app/ui/act/setting/PayPasswordManagerActivity.kt @@ -0,0 +1,40 @@ +package com.ck.ckcollar.app.ui.act.setting + +import android.os.Bundle +import com.ck.ckcollar.app.R +import com.ck.ckcollar.app.databinding.ActivityPasswordManagerBinding +import com.ck.ckcollar.app.databinding.ActivityPayPasswordManagerBinding +import com.ck.ckcollar.app.ui.base.CKBaseActivity +import com.tt.kit.model.DataCollection + +class PayPasswordManagerActivity : CKBaseActivity() { + + + lateinit var binding: ActivityPayPasswordManagerBinding + + override fun onCreate(savedInstanceState: Bundle?) { + binding = ActivityPayPasswordManagerBinding.inflate(layoutInflater) + setContentView(binding.root) + super.onCreate(savedInstanceState) + + setStatusBarColor(resources.getColor(R.color.white)) + setActionBarColor(resources.getColor(R.color.white)) + + setTitleText(getString(R.string.payment_password)) + } + + override fun initView() { + + binding.contentEditPassword.setOnClickListener { + toActivity(EditPayPsswordActivity::class.java, DataCollection()) + } + binding.contentFindPassword.setOnClickListener { + toActivity(FindPayPasswordActivity::class.java, DataCollection()) + } + + } + + override fun initData() { + + } +} \ No newline at end of file diff --git a/app/src/main/java/com/ck/ckcollar/app/ui/act/setting/PayPsswordActivity.kt b/app/src/main/java/com/ck/ckcollar/app/ui/act/setting/PayPsswordActivity.kt new file mode 100644 index 0000000..8f11683 --- /dev/null +++ b/app/src/main/java/com/ck/ckcollar/app/ui/act/setting/PayPsswordActivity.kt @@ -0,0 +1,65 @@ +package com.ck.ckcollar.app.ui.act.setting + +import android.os.Bundle +import com.ck.ckcollar.app.R +import com.ck.ckcollar.app.databinding.ActivityEditPasswordBinding +import com.ck.ckcollar.app.databinding.ActivityEditPayPasswordBinding +import com.ck.ckcollar.app.databinding.ActivityPayPasswordBinding +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.model.DataCollection + +class PayPsswordActivity : CKBaseActivity() { + + lateinit var binding: ActivityPayPasswordBinding + override fun onCreate(savedInstanceState: Bundle?) { + binding = ActivityPayPasswordBinding.inflate(layoutInflater) + setContentView(binding.root) + super.onCreate(savedInstanceState) + + setTitleText(getString(R.string.setting_pay_password)) + } + + override fun initView() { + + binding.btnReset.setOnClickListener { + edit() + } + } + override fun initData() { + + } + + fun edit(){ + + if (binding.editNewPwd.isEmpty()){ + toast(getString(R.string.password_not_empty)) + return + } + if (binding.editNewPwd.text.toString().length != 6){ + toast(getString(R.string.six_length_alert)) + return + } + if (!binding.editNewPwd.text.toString().equals(binding.editNewPwdConfirm.text.toString())){ + toast(getString(R.string.confirm_password_not_both)) + return + } + showProgeassDialog(getString(R.string.edit)) + TTHttpClient.postJson(this,"修改支付密码", TTRequestParam().apply { + add(TTRequestData("newPassword",binding.editNewPwd.text.toString())) + add(TTRequestData("confirmPassword",binding.editNewPwdConfirm.text.toString())) + },object : ICallback{ + override fun onSuccess(data: String) { + toast(getString(R.string.edit_success)) + finish(DataCollection(),10001) + } + + 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/setting/SettingActivity.kt b/app/src/main/java/com/ck/ckcollar/app/ui/act/setting/SettingActivity.kt new file mode 100644 index 0000000..39d804a --- /dev/null +++ b/app/src/main/java/com/ck/ckcollar/app/ui/act/setting/SettingActivity.kt @@ -0,0 +1,83 @@ +package com.ck.ckcollar.app.ui.act.setting + +import android.content.Intent +import android.os.Bundle +import android.view.View +import com.ck.ckcollar.app.R +import com.ck.ckcollar.app.databinding.ActivitySettingBinding +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.cyclone.shadowsocks.utils.PreferencesUtils +import com.tt.kit.model.Data +import com.tt.kit.model.DataCollection + +class SettingActivity : CKBaseActivity(), View.OnClickListener { + lateinit var binding: ActivitySettingBinding + override fun onCreate(savedInstanceState: Bundle?) { + binding = ActivitySettingBinding.inflate(layoutInflater) + setContentView(binding.root) + super.onCreate(savedInstanceState) + + setStatusBarColor(resources.getColor(R.color.white)) + setActionBarColor(resources.getColor(R.color.white)) + + setTitleText(getString(R.string.setting)) + } + + override fun initView() { + binding.contentLoginPassword.setOnClickListener(this) + binding.contentPaymentPassword.setOnClickListener(this) + binding.contentAboutUs.setOnClickListener(this) + binding.contentUserAgreement.setOnClickListener(this) + binding.contentPrivacyAgreement.setOnClickListener(this) + binding.contentShippingAddress.setOnClickListener(this) + binding.contentCancellation.setOnClickListener(this) + binding.btnLogout.setOnClickListener(this) + } + override fun initData() { + + } + + override fun onClick(v: View?) { + + when (v?.id){ + R.id.contentLoginPassword->{ + toActivity(PasswordManagerActivity::class.java, DataCollection()) + } + R.id.contentPaymentPassword->{ + toActivity(PayPasswordManagerActivity::class.java, DataCollection()) + + } + R.id.contentAboutUs->{ + toActivity(AgreementActivity::class.java, DataCollection().apply { add(Data("title","关于我们")) }) + } + R.id.contentUserAgreement->{ + toActivity(AgreementActivity::class.java, DataCollection().apply { add(Data("title","用户协议")) }) + } + R.id.contentPrivacyAgreement->{ + toActivity(AgreementActivity::class.java, DataCollection().apply { add(Data("title","隐私协议")) }) + } + R.id.contentShippingAddress->{ + toActivity(AddressActivity::class.java, DataCollection().apply { add(Data("flag","1")) + }) + } + R.id.contentCancellation->{ + toActivity(AccountCancellationActivity::class.java, DataCollection()) + } + R.id.btnLogout->{ + CKAlertDialog(this@SettingActivity,getString(R.string.logout),getString(R.string.logout_alert),object : CKAlertDialog.AlertClickListener{ + override fun onBack(isConfirm: Boolean) { + if (isConfirm){ + PreferencesUtils.clear(this@SettingActivity) + toActivityNewTaskClear(LoginActivity::class.java, DataCollection()) + finish() + } + } + }).show() + + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/ck/ckcollar/app/ui/act/shop/OrderActivity.kt b/app/src/main/java/com/ck/ckcollar/app/ui/act/shop/OrderActivity.kt new file mode 100644 index 0000000..8a775ee --- /dev/null +++ b/app/src/main/java/com/ck/ckcollar/app/ui/act/shop/OrderActivity.kt @@ -0,0 +1,520 @@ +package com.ck.ckcollar.app.ui.act.shop + +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.ActivityOrderBinding +import com.ck.ckcollar.app.databinding.LayoutItemShopCarBinding +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.CreateOrderModel +import com.ck.ckcollar.app.model.MemberModel +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.ShopCarModel +import com.ck.ckcollar.app.model.ShopProductModel +import com.ck.ckcollar.app.model.UserInfoModel +import com.ck.ckcollar.app.ui.act.order.MyOrderActivity +import com.ck.ckcollar.app.ui.act.setting.AddAddressActivity +import com.ck.ckcollar.app.ui.act.setting.AddressActivity +import com.ck.ckcollar.app.ui.act.setting.PayPsswordActivity +import com.ck.ckcollar.app.ui.act.shop.ShopCarActivity.ShopCarAdapter +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.google.gson.reflect.TypeToken +import com.tt.kit.base.TTBaseActivity +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 org.json.JSONArray +import org.json.JSONObject +import java.math.BigDecimal + +class OrderActivity : CKBaseActivity() { + + lateinit var binding: ActivityOrderBinding + + lateinit var productAdapter: ProductAdapter + + var productDatas = listOf() + + lateinit var model: ConfirmOrderModel + + var memberModel: UserInfoModel? = null + + var payType = "1" + + var selectBalance = false + var selectPoints = false + + lateinit var orderSource: String + + var flag = 0 + override fun onCreate(savedInstanceState: Bundle?) { + binding = ActivityOrderBinding.inflate(layoutInflater) + setContentView(binding.root) + super.onCreate(savedInstanceState) + + setTitleText(getString(R.string.confirm_order)) + } + + override fun initView() { + productAdapter = + ProductAdapter(this@OrderActivity, productDatas, object : OnItemClickListenner { + override fun onClick(pos: Int, model: Any) { + // toActivity(ProductDetailsActivity::class.java, DataCollection()) + } + }) + binding.recyclerView.layoutManager = + LinearLayoutManager(this@OrderActivity, RecyclerView.VERTICAL, false) + binding.recyclerView.setHasFixedSize(true) + binding.recyclerView.adapter = productAdapter + + + binding.btnAli.setOnClickListener(payClick) + binding.btnWX.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.contentAddress.setOnClickListener { + toActivityForResult(AddressActivity::class.java, DataCollection().apply { + add(Data("flag", "0")) + }, 1001) + } + binding.btnBuyNow.setOnClickListener { + + if (selectBalance){ + getPayPassword() + }else{ + order("") + } + + + } + + } + + override fun initData() { + + model = + Gson().fromJson( + getReceiveParam().get("data")!!.stringValue, + ConfirmOrderModel::class.java + ) + + flag = getReceiveParam().get("flag")!!.stringValue!!.toInt() + + + orderSource = getReceiveParam().get("orderSource")!!.stringValue.toString() + + + setView() + + getMemberInfo() + } + + fun setView(){ + model.address?.let { + binding.textName.text = + model.address!!.receiverName + " " + model.address!!.receiverPhone + binding.textAddress.text = model.address!!.fullAddress + } + + binding.textGoodTotal.text = "¥" + model.goodsTotalAmount + binding.textMenTotal.text = "¥" + model.memberAmount + binding.textTotal.text = "¥" + model.payAmount + binding.textShipFeeTotal.text = "¥" + model.freightAmount + if ("1".equals(model.isPoint.toString())){ + binding.textPointsAlert.visibility = View.VISIBLE + } + + productDatas = model.items!! + } + + fun getPayPassword(){ + if (model.address == null) { + toast(getString(R.string.select_address)) + return + } + + if (TextUtils.isEmpty(payType) && memberModel?.balance == 0.0){ + if (!selectPoints || "1".equals(model.isPoint)){ + toast(getString(R.string.balance_over)) + return + } + } + + checkPasswordStatus() + } + + fun refleshData(addressId:String){ + if (flag == 0){ + var json = JSONObject(getReceiveParam().get("param")!!.stringValue) + + var param = TTRequestParam().apply { + add(TTRequestData("addressId",addressId)) + add(TTRequestData("quantity",json.getInt("quantity"))) + add(TTRequestData("specId",json.getInt("specId"))) + } + showProgeassDialog(getString(R.string.edit)) + TTHttpClient.post(this,"直接购买确认订单",param ,object : ICallback{ + override fun onSuccess(data: String) { + hiddenProgeassDialog() + + model = Gson().fromJson(data, ConfirmOrderModel::class.java) + + setView() + + + } + + override fun onFailed(code: String, msg: String) { + hiddenProgeassDialog() + + } + }) + }else if (flag == 1){ + + TTHttpClient.get(this,"购物车购买确认订单", TTRequestParam().apply { + add(TTRequestData("addressId",addressId)) + },object : ICallback{ + override fun onSuccess(data: String) { + hiddenProgeassDialog() + model = Gson().fromJson(data, ConfirmOrderModel::class.java) + setView() + } + + override fun onFailed(code: String, msg: String) { + hiddenProgeassDialog() + + } + }) + } + + } + + fun order(payPassword : String) { + if (model.address == null) { + toast(getString(R.string.select_address)) + return + } + + var items = JSONArray() + for (model in productDatas) { + var json = JSONObject() + json.put("specId", model.specId) + json.put("quantity", model.quantity) + items.put(json) + } + + var payType = payType + if(selectBalance){ + + if (TextUtils.isEmpty(payType) && memberModel?.balance == 0.0){ + toast(getString(R.string.balance_over)) + return + } + + if (TextUtils.isEmpty(payType)){ + payType = "2" + }else{ + payType = payType + ",2" + } + } + if(selectPoints){ + if (TextUtils.isEmpty(payType) && memberModel?.points == 0.0){ + toast(getString(R.string.points_over)) + return + } + + if (TextUtils.isEmpty(payType)){ + payType = "3" + }else{ + payType = payType + ",3" + } + } + + if (TextUtils.isEmpty(payType)){ + toast(getString(R.string.please_select_payment_method)) + return + } + + var param = JSONObject() + param.put("addressId", model.address!!.id) + param.put("orderSource", orderSource) + param.put("payType", payType) + param.put("payAmounts", model.payAmount.toString()) + param.put("buyerNote", "") + param.put("items", items) + param.put("payPassword", payPassword) + showProgeassDialog(getString(R.string.order)) + + TTHttpClient.postJson(this, "下单", param.toString(), object : ICallback { + override fun onSuccess(data: String) { + var model = Gson().fromJson(data, PayOrderModel::class.java) + if ("0".equals(this@OrderActivity.payType)) { + //微信 + }else if ("1".equals(this@OrderActivity.payType)) { + if (TextUtils.isEmpty(model.orderStr)){ + toActivity(OrderSuccessActivity::class.java, DataCollection()) + finish() + }else{ + aliPay(model.orderStr!!) + } + }else{ + toast(getString(R.string.order_success)) + + toActivity(OrderSuccessActivity::class.java, DataCollection()) + finish() + } + + + } + + override fun onFailed(code: String, msg: String) { + + toast(msg) + if (msg.indexOf("不足")>=0){ + toActivity( + MyOrderActivity::class.java, + DataCollection().apply { add(Data("pos", "1")) }) + finish() + } + } + }) + } + + fun aliPay(orderStr: String) { + GlobalScope.launch(Dispatchers.IO) { + + val alipay = PayTask(this@OrderActivity) + 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)) + toActivity(OrderSuccessActivity::class.java, DataCollection()) + finish() + } else { + toast(getString(R.string.payment_faild)) + toActivity( + MyOrderActivity::class.java, + DataCollection().apply { add(Data("pos", "1")) }) + finish() + } + } + } + } + + 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() + } + }) + } + + + 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") + } + + 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 = "" + } + } + + } + } + } + + override fun getResult(data: DataCollection, resultCode: Int) { + if (resultCode == 1001) { + + var addressModel = Gson().fromJson( + data.get("data")!!.stringValue, + AddressModel::class.java + ) + + model.address = ConfirmOrderModel.AddressModel().apply { id = addressModel.id } + + binding.textName.text = addressModel.receiverName + " " + addressModel.receiverPhone + binding.textAddress.text = addressModel.fullAddress + + refleshData(addressModel.id.toString()) + }else if (resultCode == 10001){ + showPayBottomView() + } + } + + 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.comName + holder.binding.textType.text = model.specName + var price = if (CKApp.app.userInfo!!.isMember == true) { + model.memPrice.toString() + } else { + model.comPrice.toString() + } + holder.binding.textPriec.text = "¥" + price + holder.binding.textCount.text = "x" + model.quantity + + 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: LayoutItemShopOrderProductBinding) : + RecyclerView.ViewHolder(binding.root) { + + } + + } +} \ No newline at end of file diff --git a/app/src/main/java/com/ck/ckcollar/app/ui/act/shop/OrderSuccessActivity.kt b/app/src/main/java/com/ck/ckcollar/app/ui/act/shop/OrderSuccessActivity.kt new file mode 100644 index 0000000..c1ef058 --- /dev/null +++ b/app/src/main/java/com/ck/ckcollar/app/ui/act/shop/OrderSuccessActivity.kt @@ -0,0 +1,41 @@ +package com.ck.ckcollar.app.ui.act.shop + +import android.os.Bundle +import com.ck.ckcollar.app.CKApp +import com.ck.ckcollar.app.R +import com.ck.ckcollar.app.databinding.ActivityOrderSuccessBinding +import com.ck.ckcollar.app.ui.act.home.MainActivity +import com.ck.ckcollar.app.ui.act.order.MyOrderActivity +import com.ck.ckcollar.app.ui.base.CKBaseActivity +import com.tt.kit.model.Data +import com.tt.kit.model.DataCollection + +class OrderSuccessActivity: CKBaseActivity() { + + lateinit var binding: ActivityOrderSuccessBinding + override fun onCreate(savedInstanceState: Bundle?) { + binding = ActivityOrderSuccessBinding.inflate(layoutInflater) + setContentView(binding.root) + super.onCreate(savedInstanceState) + + setTitleText(getString(R.string.payment_success)) + + setStatusBarColor2(resources.getColor(R.color.white)) + setActionBarColor(resources.getColor(R.color.white)) + } + + override fun initView() { + + binding.btnReturnHome.setOnClickListener { + toActivityNewTaskClear(MainActivity::class.java, DataCollection()) + } + binding.btnViewOrder.setOnClickListener { + toActivity(MyOrderActivity::class.java, DataCollection().apply { add(Data("pos","0")) }) + finish() + } + } + + override fun initData() { + + } +} \ No newline at end of file diff --git a/app/src/main/java/com/ck/ckcollar/app/ui/act/shop/PayBottomFragment.kt b/app/src/main/java/com/ck/ckcollar/app/ui/act/shop/PayBottomFragment.kt new file mode 100644 index 0000000..febd1f5 --- /dev/null +++ b/app/src/main/java/com/ck/ckcollar/app/ui/act/shop/PayBottomFragment.kt @@ -0,0 +1,70 @@ +package com.ck.ckcollar.app.ui.act.shop + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import com.ck.ckcollar.app.R +import com.ck.ckcollar.app.databinding.FragmentPayPasswordBinding +import com.ck.ckcollar.app.listenner.OnPasswordInputFinish +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.tt.kit.base.TTBaseActivity +import com.tt.kit.dialog.TTBottomSheetDialogFragment + +class PayBottomFragment(var amount: String, var payType : String) : + TTBottomSheetDialogFragment() { + + lateinit var binding: FragmentPayPasswordBinding + + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + binding = FragmentPayPasswordBinding.inflate(inflater) + return binding.root + } + + + override fun initView() { + + binding.btnClose.setOnClickListener { + dismiss() + } + + binding.passView.setOnFinishInput(object : OnPasswordInputFinish{ + override fun inputFinish() { + + toast(binding.passView.strPassword!!) + } + }) + + } + + override fun initData() { + + binding.textPayType.text = payType + binding.textAmount.text = amount + } + + fun checkPassword(){ + showProgeassDialog(getString(R.string.add)) + TTHttpClient.postJson(activity as TTBaseActivity,"添加购物车", TTRequestParam().apply { + + },object : ICallback{ + override fun onSuccess(data: String) { + hiddenProgeassDialog() + toast(getString(R.string.add_success)) + this@PayBottomFragment.dismiss() + } + + 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/shop/PayPasswordBottomFragment.kt b/app/src/main/java/com/ck/ckcollar/app/ui/act/shop/PayPasswordBottomFragment.kt new file mode 100644 index 0000000..90e9fad --- /dev/null +++ b/app/src/main/java/com/ck/ckcollar/app/ui/act/shop/PayPasswordBottomFragment.kt @@ -0,0 +1,69 @@ +package com.ck.ckcollar.app.ui.act.shop + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import com.ck.ckcollar.app.R +import com.ck.ckcollar.app.databinding.FragmentPayPasswordBinding +import com.ck.ckcollar.app.listenner.OnPasswordInputFinish +import com.ck.ckcollar.app.model.PayPasswordStatus +import com.ck.ckcollar.app.ui.act.setting.EditPayPsswordActivity +import com.ck.ckcollar.app.ui.act.setting.PayPsswordActivity +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.base.TTBaseActivity +import com.tt.kit.dialog.TTBottomSheetDialogFragment +import com.tt.kit.model.DataCollection + +class PayPasswordBottomFragment(var amount: String, var payType : String,var passwordCallBack : PasswordCallBack) : + TTBottomSheetDialogFragment() { + + lateinit var binding: FragmentPayPasswordBinding + + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + binding = FragmentPayPasswordBinding.inflate(inflater) + return binding.root + } + + + override fun initView() { + + binding.btnClose.setOnClickListener { + dismiss() + } + + binding.passView.setOnFinishInput(object : OnPasswordInputFinish{ + override fun inputFinish() { + dismiss() + passwordCallBack.callBack(binding.passView.strPassword!!) + } + }) + + } + + override fun initData() { + + binding.textPayType.text = payType + binding.textAmount.text = amount + + } + + override fun onStart() { + super.onStart() + + } + + + + interface PasswordCallBack{ + fun callBack(password : String) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/ck/ckcollar/app/ui/act/shop/ProductBottomFragment.kt b/app/src/main/java/com/ck/ckcollar/app/ui/act/shop/ProductBottomFragment.kt new file mode 100644 index 0000000..6a3c1ab --- /dev/null +++ b/app/src/main/java/com/ck/ckcollar/app/ui/act/shop/ProductBottomFragment.kt @@ -0,0 +1,248 @@ +package com.ck.ckcollar.app.ui.act.shop + +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.R +import com.ck.ckcollar.app.action.ActionCode +import com.ck.ckcollar.app.databinding.FragmentProductBinding +import com.ck.ckcollar.app.databinding.FragmentShopBinding +import com.ck.ckcollar.app.databinding.LayoutItemAddressTag2Binding +import com.ck.ckcollar.app.databinding.LayoutItemAddressTagBinding +import com.ck.ckcollar.app.databinding.LayoutItemProductTypeTagBinding +import com.ck.ckcollar.app.model.AddressModel +import com.ck.ckcollar.app.model.ConfirmOrderModel +import com.ck.ckcollar.app.model.CreateOrderModel +import com.ck.ckcollar.app.model.ProductTypeModel +import com.ck.ckcollar.app.model.ShopProductModel +import com.ck.ckcollar.app.model.TagModel +import com.ck.ckcollar.app.ui.dialog.CKEditDialog +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.pinko.flowlayout.FlowLayout +import com.pinko.flowlayout.TagAdapter +import com.pinko.flowlayout.TagFlowLayout +import com.tt.kit.base.TTBaseActivity +import com.tt.kit.dialog.TTBottomSheetDialogFragment +import com.tt.kit.model.Data +import com.tt.kit.model.DataCollection +import org.json.JSONObject +import java.math.BigDecimal + +class ProductBottomFragment(var productModel: ShopProductModel.ProductModel) : + TTBottomSheetDialogFragment() { + + lateinit var binding: FragmentProductBinding + + var data = listOf() + var pos = 0; + var count = 1 + var tagAdapter: TagAdapter? = null + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + binding = FragmentProductBinding.inflate(inflater) + return binding.root + } + + + override fun initView() { + + tagAdapter = object : TagAdapter(data) { + + override fun getView( + p0: FlowLayout?, + p1: Int, + p2: ProductTypeModel? + ): View? { + var binding = LayoutItemProductTypeTagBinding.inflate(layoutInflater) + binding.textTag.text = p2!!.specifyName + return binding.root + + } + } + binding.flowlayout.adapter = tagAdapter + + binding.flowlayout.setOnTagClickListener(object : TagFlowLayout.OnTagClickListener { + override fun onTagClick( + p0: View?, + p: Int, + p2: FlowLayout? + ): Boolean { + + pos = p + + binding.textPriec.text = "¥" + data.get(pos).comPrice + binding.textMemberPriec.text = + data.get(pos).memPrice.toString() + + count = 1 + binding.textCount.text = count.toString() + + return false + } + }) + + // tagAdapter?.setSelected(pos,data.get(pos)) + + tagAdapter?.setSelectedList(pos) + + binding.btnCountSub.setOnClickListener { + if (count > 1) { + count-- + binding.textCount.text = count.toString() + } + } + binding.btnCountAdd.setOnClickListener { + if (count + 1 > data.get(pos).inventory ){ + toast(getString(R.string.over_stock)) + }else{ + count++ + binding.textCount.text = count.toString() + } + + } + + binding.btnBuyNow.setOnClickListener { + getAddress() + } + binding.btnAddCar.setOnClickListener { + addShopCar() + } + } + + fun confirmOrder(addressId : String){ + var param = TTRequestParam().apply { + add(TTRequestData("addressId",addressId)) + add(TTRequestData("quantity",count)) + add(TTRequestData("specId",data.get(pos).id)) + } + TTHttpClient.post(activity as TTBaseActivity,"直接购买确认订单",param ,object : ICallback{ + override fun onSuccess(data: String) { + hiddenProgeassDialog() + + var model = Gson().fromJson(data, ConfirmOrderModel::class.java) + toActivity(OrderActivity::class.java, DataCollection().apply { + + var json = JSONObject() + json.put("addressId",addressId) + json.put("quantity",count) + json.put("specId",this@ProductBottomFragment.data.get(pos).id) + + add(Data("data", Gson().toJson(model))) + add(Data("param", json.toString())) + add(Data("orderSource","0")) + add(Data("flag","0")) + + }) + dismiss() + + } + + override fun onFailed(code: String, msg: String) { + hiddenProgeassDialog() + toast(msg) + } + }) + } + fun getAddress() { + showProgeassDialog(getString(R.string.order)) + TTHttpClient.get(activity as TTBaseActivity, "收货地址列表", TTRequestParam(), object : ICallback { + override fun onSuccess(data: String) { + + var model = Gson().fromJson>(data, + object : TypeToken>() {}.type) + + if (model.size > 0){ + confirmOrder(model.get(0).id.toString()) + }else{ + confirmOrder("-1") + } + } + + override fun onFailed(code: String, msg: String) { + + hiddenProgeassDialog() + toast(msg) + } + }) + } + + fun buyNow(){ + try { + var model = productModel.toOrderItem() + + model.quantity = count + model.specId = data.get(pos).id + model.specName = data.get(pos).specifyName + + var countDecial = BigDecimal(count) + + model.subtotal = BigDecimal(model.comPrice).multiply(countDecial).toDouble() + model.memSubtotal = BigDecimal(model.memPrice).multiply(countDecial).toDouble() + + var data = listOf(model) + toActivity(OrderActivity::class.java, DataCollection().apply { + add(Data("data", Gson().toJson(data))) + add(Data("total",model.subtotal.toString())) + add(Data("memTotal",model.memSubtotal.toString())) + add(Data("flag","0")) + + }) + dismiss() + }catch (e : Exception){ + e.printStackTrace() + toast("金额计算异常") + } + } + override fun initData() { + data = productModel.colCommodityListCbs!! + + if (data == null){ + data = listOf() + }else{ + binding.textDesc.text = productModel.comName + binding.textPriec.text = "¥" + data.get(pos).comPrice + binding.textMemberPriec.text = data.get(pos).memPrice.toString() + } + + + Glide.with(this) + .load( productModel.comCover) + .placeholder(R.mipmap.image_default) + .into(binding.image) + + } + + fun addShopCar(){ + data?.let { + showProgeassDialog(getString(R.string.add)) + TTHttpClient.postJson(activity as TTBaseActivity,"添加购物车", TTRequestParam().apply { + add(TTRequestData("comId",productModel.id)) + add(TTRequestData("quantity",count)) + add(TTRequestData("specId",data.get(pos).id)) + },object : ICallback{ + override fun onSuccess(data: String) { + hiddenProgeassDialog() + toast(getString(R.string.add_success)) + this@ProductBottomFragment.dismiss() + } + + 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/shop/ProductDetailsActivity.kt b/app/src/main/java/com/ck/ckcollar/app/ui/act/shop/ProductDetailsActivity.kt new file mode 100644 index 0000000..4975a7b --- /dev/null +++ b/app/src/main/java/com/ck/ckcollar/app/ui/act/shop/ProductDetailsActivity.kt @@ -0,0 +1,316 @@ +package com.ck.ckcollar.app.ui.act.shop + +import android.content.Context +import android.os.Bundle +import android.text.Html +import android.view.ViewGroup +import android.webkit.WebChromeClient +import android.webkit.WebSettings +import android.webkit.WebView +import android.webkit.WebViewClient +import android.widget.ImageView +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.ActivityProductDetailsBinding +import com.ck.ckcollar.app.listenner.OnItemClickListenner +import com.ck.ckcollar.app.model.ProductTypeModel +import com.ck.ckcollar.app.model.ShopProductModel +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.home.fragment.HomeFragment +import com.ck.ckcollar.app.ui.act.home.fragment.HomeFragment.ImageAdapter +import com.ck.ckcollar.app.ui.act.petmanager.ImageViewActivity +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.widget.CKImageView +import com.ck.ckcollar.app.widget.CKRoundImageView +import com.google.gson.Gson +import com.gyf.immersionbar.ImmersionBar +import com.tt.kit.model.Data +import com.tt.kit.model.DataCollection +import com.youth.banner.adapter.BannerAdapter +import com.youth.banner.indicator.CircleIndicator + +class ProductDetailsActivity : CKBaseActivity() { + + lateinit var binding: ActivityProductDetailsBinding + + + lateinit var imageAdapter: ImageAdapter + var bannarData = mutableListOf() + + var model : ShopProductModel.ProductModel? = null + override fun onCreate(savedInstanceState: Bundle?) { + binding = ActivityProductDetailsBinding.inflate(layoutInflater) + setContentView(binding.contentView) + + super.onCreate(savedInstanceState) + + setTitleText(getString(R.string.product_details)) + } + + override fun initView() { + + + + + setupWebView(binding.textContent) + + binding.btnAddCar.setOnClickListener { + showProductTypeFragment() + } + binding.btnBuyNow.setOnClickListener { + showProductTypeFragment() + } + + binding.contentShopCar.setOnClickListener { + toActivity(ShopCarActivity::class.java, DataCollection()) + } + binding.contentCustomer.setOnClickListener { + toActivity(PeopleCustomerActivity::class.java, DataCollection().apply { add(Data("chatType","1")) }) + } + } + + override fun initData() { + model = Gson().fromJson(getReceiveParam().get("data")!!.stringValue, + ShopProductModel.ProductModel::class.java) + + setUI() + + getData() + } + + fun setUI(){ + + bannarData.clear() + model!!.comCarousel?.let { + var urls = model!!.comCarousel!!.split(",") + bannarData.addAll(urls) + } + imageAdapter = ImageAdapter(this@ProductDetailsActivity,bannarData,object : OnItemClickListenner{ + override fun onClick(pos: Int, model: Any) { + toActivity(ImageViewActivity::class.java, DataCollection().apply { + add(Data("data",Gson().toJson(bannarData))) + add(Data("pos",pos.toString())) + }) + + } + }) + binding.banner.addBannerLifecycleObserver(this)//添加生命周期观察者 + .setAdapter(imageAdapter) + .setIndicator(CircleIndicator(this)); + + + binding.textDesc.text = model?.comName + binding.textPriec.text = getString(R.string.price_start,model?.comPrice.toString()) + binding.textMemberPriec.text = getString(R.string.member_price,model?.memPrice.toString()) + + loadRichText(binding.textContent,model?.comDetail.toString()) + } + + fun showProductTypeFragment(){ + var fragment = ProductBottomFragment(model!!) + + fragment.show(supportFragmentManager,"ProductBottomFragment") + } + + fun getData(){ + showProgeassDialog(getString(R.string.details)) + TTHttpClient.get(this,"商品明细",model?.id.toString(),object : ICallback{ + override fun onSuccess(data: String) { + model = Gson().fromJson(data, ShopProductModel.ProductModel::class.java) + + setUI() + + } + + override fun onFailed(code: String, msg: String) { + toast(msg) + finish() + } + }) + } + 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 = CKImageView(parent.getContext()) + //注意,必须设置为match_parent,这个是viewpager2强制要求的 + imageView.setLayoutParams( + ViewGroup.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.MATCH_PARENT + ) + ) + imageView.setScaleType(ImageView.ScaleType.FIT_XY) + return BannerViewHolder(imageView) + } + + override fun onBindView( + holder: BannerViewHolder?, + data: String?, + position: Int, + size: Int + ) { + Glide.with(context) + .load( data) + .apply(RequestOptions.bitmapTransform(RoundedCorners(12))) + .placeholder(R.mipmap.image_default) + .into(holder!!.imageView) + + + holder!!.imageView.setTag(position) + holder!!.imageView.setOnClickListener { + var tag = it.tag as Int + itemClickListenner.onClick(tag,data!!.get(tag)) + } + } + + class BannerViewHolder(var imageView: CKImageView) : RecyclerView.ViewHolder( + imageView + ) + } + + 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) { + val styledHtml = """ + + + + + + + + + $htmlContent + + + """.trimIndent() + + // 使用 loadDataWithBaseURL 加载 + webView.loadDataWithBaseURL(null, styledHtml, "text/html", "UTF-8", null) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/ck/ckcollar/app/ui/act/shop/SearchActivity.kt b/app/src/main/java/com/ck/ckcollar/app/ui/act/shop/SearchActivity.kt new file mode 100644 index 0000000..b075044 --- /dev/null +++ b/app/src/main/java/com/ck/ckcollar/app/ui/act/shop/SearchActivity.kt @@ -0,0 +1,207 @@ +package com.ck.ckcollar.app.ui.act.shop + +import android.content.Context +import android.os.Bundle +import android.text.Editable +import android.text.TextWatcher +import android.view.LayoutInflater +import android.view.ViewGroup +import android.view.inputmethod.EditorInfo +import android.view.inputmethod.InputMethodManager +import androidx.recyclerview.widget.GridLayoutManager +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.ActivityShopSearchBinding +import com.ck.ckcollar.app.databinding.LayoutItemShopBinding +import com.ck.ckcollar.app.listenner.OnItemClickListenner +import com.ck.ckcollar.app.model.ShopProductModel +import com.ck.ckcollar.app.ui.act.home.fragment.ShopFragment +import com.ck.ckcollar.app.ui.act.home.fragment.ShopFragment.ProductAdapter +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.gyf.immersionbar.ImmersionBar +import com.tt.kit.model.Data +import com.tt.kit.model.DataCollection +import com.tt.kit.utils.KeyboardUtils + +class SearchActivity : CKLHBaseActionBarActivity() { + lateinit var binding: ActivityShopSearchBinding + lateinit var productAdapter: ProductAdapter + + var productDatas = mutableListOf() + + var page = 1 + override fun onCreate(savedInstanceState: Bundle?) { + binding = ActivityShopSearchBinding.inflate(layoutInflater) + ImmersionBar.with(this) + .statusBarDarkFont(true) + .init() + setContentView(binding.root) + super.onCreate(savedInstanceState) + + setTitleText(getString(R.string.search2)) + } + + override fun initView() { + productAdapter = ProductAdapter(this@SearchActivity, productDatas, object : OnItemClickListenner { + override fun onClick(pos: Int, model: Any) { + toActivity(ProductDetailsActivity::class.java, DataCollection().apply { + add( + Data("data", Gson().toJson(model)) + ) + }) + + } + }) + binding.recyclerView.layoutManager = + GridLayoutManager(this@SearchActivity, 2) + binding.recyclerView.setHasFixedSize(true) + binding.recyclerView.adapter = productAdapter + + + binding.editSearch.setOnEditorActionListener { _, actionId, _ -> + if (actionId == EditorInfo.IME_ACTION_SEARCH) { + if (!binding.editSearch.isEmpty()) { + var text = binding.editSearch.text.toString() + + getData(text) + KeyboardUtils.hideKeyboard(this) + } + true + } else { + false + } + } + + binding.editSearch.addTextChangedListener(object : TextWatcher{ + override fun afterTextChanged(p0: Editable?) { + + getData(binding.editSearch.text.toString()) + } + + override fun beforeTextChanged( + p0: CharSequence?, + p1: Int, + p2: Int, + p3: Int + ) { + + } + + override fun onTextChanged( + p0: CharSequence?, + p1: Int, + p2: Int, + p3: Int + ) { + + } + }) + binding.editSearch.requestFocus() + KeyboardUtils.showKeyboard(binding.editSearch) + + } + + override fun initData() { + + + getData("") + } + + + fun getData(content : String) { + TTHttpClient.get(this, "商品列表", TTRequestParam().apply { + add( + TTRequestData("pageNum", page) + ) + add( + TTRequestData("pageSize", 30) + ) + add(TTRequestData("comName",content)) + }, 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) + binding.refreshLayout.finishRefresh() + } + + override fun onFailed(code: String, msg: String) { + binding.refreshLayout.finishLoadMore(true) + + } + }) + } + + + + + 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/shop/ShopCarActivity.kt b/app/src/main/java/com/ck/ckcollar/app/ui/act/shop/ShopCarActivity.kt new file mode 100644 index 0000000..e04c084 --- /dev/null +++ b/app/src/main/java/com/ck/ckcollar/app/ui/act/shop/ShopCarActivity.kt @@ -0,0 +1,436 @@ +package com.ck.ckcollar.app.ui.act.shop + +import android.content.Context +import android.os.Bundle +import android.text.TextUtils +import android.view.LayoutInflater +import android.view.ViewGroup +import android.view.inputmethod.EditorInfo +import android.view.inputmethod.InputMethodManager +import android.widget.TextView +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.CKApp +import com.ck.ckcollar.app.R +import com.ck.ckcollar.app.action.ActionCode +import com.ck.ckcollar.app.databinding.ActivityShopCarBinding +import com.ck.ckcollar.app.databinding.ActivityShopSearchBinding +import com.ck.ckcollar.app.databinding.LayoutItemShopBinding +import com.ck.ckcollar.app.databinding.LayoutItemShopCarBinding +import com.ck.ckcollar.app.listenner.OnItemClickListenner +import com.ck.ckcollar.app.listenner.OnItemLongClickListenner +import com.ck.ckcollar.app.model.AddressModel +import com.ck.ckcollar.app.model.ConfirmOrderModel +import com.ck.ckcollar.app.model.CreateOrderModel +import com.ck.ckcollar.app.model.ShopCarCoutTotalModel +import com.ck.ckcollar.app.model.ShopCarModel +import com.ck.ckcollar.app.model.ShopProductModel +import com.ck.ckcollar.app.ui.base.CKLHBaseActionBarActivity +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.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.KeyboardUtils +import java.math.BigDecimal + +class ShopCarActivity : CKLHBaseActionBarActivity() { + lateinit var binding: ActivityShopCarBinding + lateinit var shopCarAdapter: ShopCarAdapter + + var productDatas = listOf() + + var selectAll = false + var total = 0.0 + + var isShowDelete = false + override fun onCreate(savedInstanceState: Bundle?) { + binding = ActivityShopCarBinding.inflate(layoutInflater) + ImmersionBar.with(this) + .statusBarDarkFont(true) + .init() + setContentView(binding.root) + super.onCreate(savedInstanceState) + + setTitleText(getString(R.string.shop_car)) + setRightText(getString(R.string.manage)) + + findViewById(R.id.btnRightText).setTextColor(getColor(R.color.textColor)) + } + + override fun initView() { + binding.textTotal.text = getString(R.string.price_total,"0.0") + + shopCarAdapter = ShopCarAdapter(this@ShopCarActivity, productDatas, object : OnItemLongClickListenner { + override fun onClick(pos: Int, model: Any) { + + CKAlertDialog(this@ShopCarActivity,getString(R.string.alert),getString(R.string.delete_product_alert),object : + CKAlertDialog.AlertClickListener{ + override fun onBack(isConfirm: Boolean) { + if (isConfirm){ + + delete(productDatas.get(pos).id.toString()) + } + } + }).show() + + } + }) + binding.recyclerView.layoutManager = + LinearLayoutManager(this@ShopCarActivity, RecyclerView.VERTICAL,false) + binding.recyclerView.setHasFixedSize(true) + binding.recyclerView.adapter = shopCarAdapter + + + binding.checkbox.setOnClickListener { + + selectAll = !selectAll + if (selectAll){ + binding.imageCheck.setImageResource(R.mipmap.image_address_check_select) + }else{ + binding.imageCheck.setImageResource(R.mipmap.image_address_check_narmal) + } + + setSelectAllUI() + } + + binding.btnTotal.setOnClickListener { + + if (isShowDelete){ + + var ids = mutableListOf() + + for (model in productDatas){ + if ("1".equals(model.selected)){ + ids.add(model.id.toString()) + } + } + + var id = ids.joinToString(",") + if (!TextUtils.isEmpty(id)){ + CKAlertDialog(this@ShopCarActivity,getString(R.string.alert),getString(R.string.delete_product_alert),object : + CKAlertDialog.AlertClickListener{ + override fun onBack(isConfirm: Boolean) { + if (isConfirm){ + delete(id) + } + } + }).show() + }else{ + toast(getString(R.string.please_select_data)) + } + + }else{ + var flag = false + for (model in productDatas){ + if ("1".equals(model.selected)){ + flag = true + } + } + + if (!flag){ + toast(getString(R.string.please_choose_product)) + }else{ + getAddress() + } + } + } + } + + override fun initData() { + + getData() + + getTotal() + } + + + override fun rightButton1OnClick() { + isShowDelete = !isShowDelete + + if (isShowDelete){ + setRightText(getString(R.string.complete)) + binding.btnTotal.setBackgroundResource(R.drawable.bg_delete_button) + binding.btnTotal.setText(R.string.delete) + }else{ + setRightText(getString(R.string.manage)) + binding.btnTotal.setBackgroundResource(R.drawable.bg_scan_button) + binding.btnTotal.setText(R.string.settle_accounts) + + } + + } + + fun confirmOrder(addressId : String){ + TTHttpClient.get(this,"购物车购买确认订单", TTRequestParam().apply { + add(TTRequestData("addressId",addressId)) + },object : ICallback{ + override fun onSuccess(data: String) { + hiddenProgeassDialog() + var model = Gson().fromJson(data, ConfirmOrderModel::class.java) + toActivity(OrderActivity::class.java, DataCollection().apply { + add(Data("data", Gson().toJson(model))) + add(Data("orderSource","1")) + add(Data("flag","1")) + + }) + finish() + } + + override fun onFailed(code: String, msg: String) { + hiddenProgeassDialog() + toast(msg) + } + }) + } + fun getAddress() { + showProgeassDialog(getString(R.string.order)) + TTHttpClient.get(this@ShopCarActivity, "收货地址列表", TTRequestParam(), object : ICallback { + override fun onSuccess(data: String) { + + var model = Gson().fromJson>(data, + object : TypeToken>() {}.type) + + if (model.size > 0){ + confirmOrder(model.get(0).id.toString()) + }else{ + confirmOrder("-1") + } + } + + override fun onFailed(code: String, msg: String) { + + hiddenProgeassDialog() + toast(msg) + } + }) + } + fun getData(){ + TTHttpClient.get(this,"购物车列表", TTRequestParam(),object : ICallback{ + override fun onSuccess(data: String) { + this@ShopCarActivity.productDatas = Gson().fromJson>(data, object : TypeToken>(){}.type) + + shopCarAdapter.data = this@ShopCarActivity.productDatas + shopCarAdapter.notifyDataSetChanged() + + var flag = true + for (model in productDatas){ + if ("0".equals(model.selected)){ + flag = false + break + } + } + + selectAll = flag + if (productDatas.size == 0){ + selectAll = false + } + if (selectAll){ + binding.imageCheck.setImageResource(R.mipmap.image_address_check_select) + }else{ + binding.imageCheck.setImageResource(R.mipmap.image_address_check_narmal) + } + getTotal() + } + + override fun onFailed(code: String, msg: String) { + + } + }) + } + + fun getTotal(){ + TTHttpClient.get(this,"购物车数量和合计", TTRequestParam(),object : ICallback{ + override fun onSuccess(data: String) { + var model = Gson().fromJson(data,ShopCarCoutTotalModel::class.java) + + binding.textTotal.text = getString(R.string.price_total,model.totalMoney.toString()) + total = model.totalMoney!! + } + + override fun onFailed(code: String, msg: String) { + total = -1.0 + toast(msg) + } + }) + + } + + + fun delete(id :String){ + showProgeassDialog(getString(R.string.delete)) + TTHttpClient.delete(this,"购物车删除商品", id,object : ICallback{ + override fun onSuccess(data: String) { + getData() + } + + override fun onFailed(code: String, msg: String) { + + } + }) + + } + + fun setSelectAllUI(){ + var select = if (selectAll){ + "1" + }else{ + "0" + } + for (model in productDatas){ + model.selected = select + } + shopCarAdapter.data = productDatas + shopCarAdapter.notifyDataSetChanged() + + + sendSelectAll(select) + } + + fun sendSelectAll(select : String){ + + TTHttpClient.putJson(this,"购物车全部选中", TTRequestParam().apply { add(TTRequestData("selected",select)) },object : ICallback{ + override fun onSuccess(data: String) { + getData() + } + + override fun onFailed(code: String, msg: String) { + + toast(msg) + getData() + } + }) + } + + class ShopCarAdapter( + var context: ShopCarActivity, + var data: List, + var itemClickListenner: OnItemLongClickListenner + ) : RecyclerView.Adapter() { + + var isShowDelete = false + override fun onCreateViewHolder( + parent: ViewGroup, + viewType: Int + ): ShopCarHolder { + return ShopCarHolder( + LayoutItemShopCarBinding.inflate( + LayoutInflater.from(context), + parent, + false + ) + ) + } + + override fun onBindViewHolder( + holder: ShopCarHolder, + position: Int + ) { + + var model = data.get(position) + if (model.selected.equals("1")){ + holder.binding.imageCheck.setImageResource(R.mipmap.image_address_check_select) + }else{ + holder.binding.imageCheck.setImageResource(R.mipmap.image_address_check_narmal) + } + + var price = if (CKApp.app.userInfo!!.isMember == true){ + model.memPrice.toString() + }else{ + model.comPrice.toString() + } + holder.binding.textDesc.text = model.comName + holder.binding.textType.text = model.specName + holder.binding.textPriec.text = "¥" + price + holder.binding.textCount.text = model.quantity.toString() + + holder.binding.btnSub.setOnClickListener { + var count = holder.binding.textCount.text.toString().toInt() + if (count > 1){ + updateCount(count-1,model.id.toString(),holder.binding.textCount,position) + } + } + holder.binding.btnAdd.setOnClickListener { + var count = holder.binding.textCount.text.toString().toInt() + updateCount(count + 1,model.id.toString(),holder.binding.textCount,position) + } + + holder.binding.imageCheck.setOnClickListener { + var selected = if ("1".equals(model.selected)){ + "0" + }else{ + "1" + } + updateSelect(selected,model.id.toString(),position) + } + + Glide.with(context) + .load( model.comCover) + .placeholder(R.mipmap.image_default) + .into(holder.binding.image) + holder.binding.root.setTag(position) + holder.binding.root.setOnLongClickListener { + var tag = it.tag as Int + itemClickListenner.onClick(tag, data.get(tag)) + + false + } + } + + override fun getItemCount(): Int { + return data.size + } + + + fun updateCount(count: Int,id : String,textView : TextView,pos: Int){ + context.showProgeassDialog(context.getString(R.string.update)) + TTHttpClient.putJson(context,"购物车更新数量", TTRequestParam().apply { + add(TTRequestData("quantity",count)) + add(TTRequestData("id",id)) + + },object : ICallback{ + override fun onSuccess(data: String) { + textView.setText(count.toString()) + + this@ShopCarAdapter.data.get(pos).quantity = count + context.getTotal() + } + + override fun onFailed(code: String, msg: String) { + context.toast(msg) + } + }) + } + + fun updateSelect(selected: String,id : String,pos:Int){ + context.showProgeassDialog(context.getString(R.string.update)) + TTHttpClient.putJson(context,"购物车更新选中", TTRequestParam().apply { + add(TTRequestData("selected",selected)) + add(TTRequestData("id",id)) + + },object : ICallback{ + override fun onSuccess(data: String) { + + context.getData() + } + + override fun onFailed(code: String, msg: String) { + context.toast(msg) + } + }) + } + class ShopCarHolder(var binding: LayoutItemShopCarBinding) : + RecyclerView.ViewHolder(binding.root) { + + } + + } +} \ No newline at end of file diff --git a/app/src/main/java/com/ck/ckcollar/app/ui/act/shop/TypeActivity.kt b/app/src/main/java/com/ck/ckcollar/app/ui/act/shop/TypeActivity.kt new file mode 100644 index 0000000..d5893ab --- /dev/null +++ b/app/src/main/java/com/ck/ckcollar/app/ui/act/shop/TypeActivity.kt @@ -0,0 +1,175 @@ +package com.ck.ckcollar.app.ui.act.shop + +import android.content.Context +import android.os.Bundle +import android.view.LayoutInflater +import android.view.ViewGroup +import android.view.inputmethod.EditorInfo +import android.view.inputmethod.InputMethodManager +import androidx.recyclerview.widget.GridLayoutManager +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.ActivityShopSearchBinding +import com.ck.ckcollar.app.databinding.ActivityShopTypeBinding +import com.ck.ckcollar.app.databinding.LayoutItemShopBinding +import com.ck.ckcollar.app.listenner.OnItemClickListenner +import com.ck.ckcollar.app.model.ShopProductModel +import com.ck.ckcollar.app.ui.act.home.fragment.ShopFragment +import com.ck.ckcollar.app.ui.act.home.fragment.ShopFragment.ProductAdapter +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.gyf.immersionbar.ImmersionBar +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.KeyboardUtils + +class TypeActivity : CKLHBaseActionBarActivity() { + lateinit var binding: ActivityShopTypeBinding + lateinit var productAdapter: ProductAdapter + + var productDatas = mutableListOf() + + var page = 1 + override fun onCreate(savedInstanceState: Bundle?) { + binding = ActivityShopTypeBinding.inflate(layoutInflater) + ImmersionBar.with(this) + .statusBarDarkFont(true) + .init() + setContentView(binding.root) + super.onCreate(savedInstanceState) + + setTitleText(getReceiveParam().get("title")?.stringValue!!) + } + + override fun initView() { + productAdapter = ProductAdapter(this@TypeActivity, productDatas, object : OnItemClickListenner { + override fun onClick(pos: Int, model: Any) { + toActivity(ProductDetailsActivity::class.java, DataCollection().apply { + add( + Data("data", Gson().toJson(model)) + ) + }) + } + }) + binding.recyclerView.layoutManager = + GridLayoutManager(this@TypeActivity, 2) + binding.recyclerView.setHasFixedSize(true) + binding.recyclerView.adapter = productAdapter + + binding.refreshLayout.setOnRefreshLoadMoreListener(object : OnRefreshLoadMoreListener{ + override fun onRefresh(refreshLayout: RefreshLayout) { + page=1 + getData() + } + + override fun onLoadMore(refreshLayout: RefreshLayout) { + page++ + getData() + } + }) + + } + + override fun initData() { + + getData() + } + + + fun getData() { + TTHttpClient.get(this, "商品列表", TTRequestParam().apply { + add( + TTRequestData("pageNum", page) + ) + add( + TTRequestData("pageSize", 30) + ) + add(TTRequestData("categoryId",getReceiveParam().get("data")!!.stringValue.toString().toLong())) + }, 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) + binding.refreshLayout.finishRefresh() + } + + override fun onFailed(code: String, msg: String) { + binding.refreshLayout.finishLoadMore(true) + + } + }) + } + + + 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/user/UserInfoActivity.kt b/app/src/main/java/com/ck/ckcollar/app/ui/act/user/UserInfoActivity.kt new file mode 100644 index 0000000..c9c6385 --- /dev/null +++ b/app/src/main/java/com/ck/ckcollar/app/ui/act/user/UserInfoActivity.kt @@ -0,0 +1,325 @@ +package com.ck.ckcollar.app.ui.act.user + +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 androidx.core.content.FileProvider +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.ActivityUserInfoBinding +import com.ck.ckcollar.app.model.ImageModel +import com.ck.ckcollar.app.model.LoginModel +import com.ck.ckcollar.app.model.UploadModel +import com.ck.ckcollar.app.model.UserInfoModel +import com.ck.ckcollar.app.ui.act.home.MainActivity +import com.ck.ckcollar.app.ui.act.login.BoundPhoneActivity +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.CKEditNameDialog +import com.ck.ckcollar.app.ui.dialog.CKEditPhoneDialog +import com.ck.ckcollar.app.ui.dialog.CKPhotoDialog +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.TTLog +import com.tt.kit.utils.TTUtils +import java.io.File + +class UserInfoActivity: CKBaseActivity() { + + lateinit var binding: ActivityUserInfoBinding + + var url = "" + lateinit var api: IWXAPI + + override fun onCreate(savedInstanceState: Bundle?) { + binding = ActivityUserInfoBinding.inflate(layoutInflater) + setContentView(binding.root) + super.onCreate(savedInstanceState) + api = WXAPIFactory.createWXAPI(this, Const.WX_APP_ID) + CKApp.app.wxJump = 1 + + checkAppPermissions() + setStatusBarColor(resources.getColor(R.color.white)) + setActionBarColor(resources.getColor(R.color.white)) + + setTitleText(getString(R.string.edit_user_info)) + } + + override fun initView() { + + binding.textNick.setOnClickListener { + CKEditNameDialog(this@UserInfoActivity,getString(R.string.nickname),binding.textNick.text.toString(),object : CKEditNameDialog.AlertClickListener{ + override fun onBack(text: String) { + binding.textNick.text = text + save() + } + }).show() + + } + binding.textRealName.setOnClickListener { + CKEditDialog(this@UserInfoActivity,getString(R.string.realname),binding.textRealName.text.toString(),object : CKEditDialog.AlertClickListener{ + override fun onBack(text: String) { + binding.textRealName.text = text + save() + } + }).show() + + } + + binding.textPhone.setOnClickListener { + CKEditPhoneDialog( + this@UserInfoActivity, + getString(R.string.bind_phone), + object : CKEditPhoneDialog.AlertClickListener { + override fun onBack(text: String) { + binding.textPhone.text = text + } + }).show() + + } + + + binding.textIdCard.setOnClickListener { + CKEditDialog(this@UserInfoActivity,getString(R.string.id_card),binding.textIdCard.text.toString(),object : CKEditDialog.AlertClickListener{ + override fun onBack(text: String) { + binding.textIdCard.text = text + save() + } + }).show() + + } + + binding.btnCamera.setOnClickListener { + CKPhotoDialog(this@UserInfoActivity,object : CKPhotoDialog.PhotoClickListener{ + override fun onBack(mark: Int, position: Int) { + try { + if (mark == 0){ + if (!checkCameraPermissions()){ + CKAlertDialog(this@UserInfoActivity,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.textWx.setOnClickListener { + if (TextUtils.isEmpty(binding.textWx.text.toString())){ + val req = SendAuth.Req() + req.scope = "snsapi_userinfo" // 只能填 snsapi_userinfo + req.state = "wechat_sdk_demo_test" + api.sendReq(req) + } + } + } + + 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.bound)) + TTHttpClient.postJson(this,"绑定微信", TTRequestParam().apply { add(TTRequestData("code",code)) },object : ICallback{ + override fun onSuccess(data: String) { + try { + toast(getString(R.string.bound_success)) + + + getUserInfo() + } catch (e: Exception) { + e.printStackTrace() + } + + } + + 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@UserInfoActivity, Const.IMAGE_PATH,"") + + // binding.imageUser.setImageBitmap(TTUtils.getBitmap(path,600,600)) + + Glide.with(this) + .load(path) + .placeholder(R.mipmap.image_default) + .into(binding.imageUser) + + uploadImage(path!!) + }else if (requestCode == 56 && resultCode == RESULT_OK) { + var path = TTUtils.getImageUrl(this, data!!.getData()); + // binding.imageUser.setImageBitmap(TTUtils.getBitmap(path,600,600)) + + Glide.with(this) + .load(path) + .placeholder(R.mipmap.image_default) + .into(binding.imageUser) + + + uploadImage(path!!) + + } + } + 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@UserInfoActivity, + packageName + ".fileprovider", + vFile + ) + } else { + Uri.fromFile(vFile) + } + + openCameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, cameraUri) + startActivityForResult(openCameraIntent, 55) + }catch (e: Exception){ + e.printStackTrace() + } + + } + + override fun initData() { + + binding.textNick.text= CKApp.app.userInfo?.custName + binding.textPhone.text= CKApp.app.userInfo?.phonenumber + binding.textIdCard.text= CKApp.app.userInfo?.identityCard + binding.textWx.text= CKApp.app.userInfo?.wxName + binding.textRealName.text= CKApp.app.userInfo?.realName + + Glide.with(this) + .load( CKApp.app.userInfo?.avatar) + .placeholder(R.mipmap.image_default) + .into(binding.imageUser) + + CKApp.app.userInfo?.avatar.let { + url = it.toString() + } + } + + fun save(){ + showProgeassDialog(getString(R.string.edit)) + TTHttpClient.postJson(this, "修改个人信息", TTRequestParam().apply { + add(TTRequestData("custName",binding.textNick.text.toString())) + add(TTRequestData("avatar",url)) + add(TTRequestData("wxName",binding.textWx.text.toString())) + add(TTRequestData("identityCard",binding.textIdCard.text.toString())) + add(TTRequestData("realName",binding.textRealName.text.toString())) + }, object : ICallback { + override fun onSuccess(data: String) { + toast(getString(R.string.edit_success)) + + + } + + override fun onFailed(code: String, msg: String) { + hiddenProgeassDialog() + toast(msg) + } + }) + } + + fun uploadImage(path : String) { + + 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 + + save() + } + + override fun onFailed(code: String, msg: String) { + hiddenProgeassDialog() + 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@UserInfoActivity, Const.USER_DATA,data) + + + initData() + + } + + 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/welcome/IndexActivity.kt b/app/src/main/java/com/ck/ckcollar/app/ui/act/welcome/IndexActivity.kt new file mode 100644 index 0000000..9f7feb2 --- /dev/null +++ b/app/src/main/java/com/ck/ckcollar/app/ui/act/welcome/IndexActivity.kt @@ -0,0 +1,49 @@ +package com.ck.ckcollar.app.ui.act.welcome + +import android.os.Bundle +import android.os.Handler +import android.os.Looper +import android.os.Message +import android.text.TextUtils +import com.ck.ckcollar.app.CKApp +import com.ck.ckcollar.app.databinding.ActivityIndexBinding +import com.ck.ckcollar.app.ui.act.home.MainActivity +import com.ck.ckcollar.app.ui.act.login.LoginActivity +import com.ck.ckcollar.app.ui.base.CKBaseActivity +import com.ck.ckcollar.app.utils.Const +import com.cyclone.shadowsocks.utils.PreferencesUtils +import com.tt.kit.model.DataCollection + +class IndexActivity : CKBaseActivity() { + + lateinit var activityIndexBinding: ActivityIndexBinding + override fun onCreate(savedInstanceState: Bundle?) { + activityIndexBinding = ActivityIndexBinding.inflate(layoutInflater) + setContentView(activityIndexBinding.root) + super.onCreate(savedInstanceState) + + } + var handler = object : Handler(Looper.getMainLooper()){ + override fun handleMessage(msg: Message) { + if (TextUtils.isEmpty(CKApp.app.token)){ + var isFirst = PreferencesUtils.getBolean(this@IndexActivity, Const.FIRST,true) as Boolean + if (isFirst){ + toActivity(WelcomeActivity::class.java, DataCollection()) + }else{ + toActivity(LoginActivity::class.java, DataCollection()) + } + }else{ + toActivity(MainActivity::class.java, DataCollection()) + } + + + finish() + } + } + + override fun initData() { + handler.sendEmptyMessageDelayed(0,1500) + } + + +} \ No newline at end of file diff --git a/app/src/main/java/com/ck/ckcollar/app/ui/act/welcome/PermisstionActivity.kt b/app/src/main/java/com/ck/ckcollar/app/ui/act/welcome/PermisstionActivity.kt new file mode 100644 index 0000000..b3e55cf --- /dev/null +++ b/app/src/main/java/com/ck/ckcollar/app/ui/act/welcome/PermisstionActivity.kt @@ -0,0 +1,45 @@ +package com.ck.ckcollar.app.ui.act.welcome + +import android.os.Build +import android.os.Bundle +import android.view.View +import androidx.appcompat.app.AppCompatActivity +import com.ck.ckcollar.app.databinding.ActivityPermissionBinding +import com.ck.ckcollar.app.ui.act.login.LoginActivity +import com.ck.ckcollar.app.ui.base.CKBaseActivity +import com.ck.ckcollar.app.ui.base.CKLHBaseActivity +import com.ck.ckcollar.app.utils.Const +import com.cyclone.shadowsocks.utils.PreferencesUtils +import com.tt.kit.model.DataCollection + +class PermisstionActivity : CKBaseActivity() { + + lateinit var activityPermissionBinding: ActivityPermissionBinding + override fun onCreate(savedInstanceState: Bundle?) { + activityPermissionBinding = ActivityPermissionBinding.inflate(layoutInflater) + setContentView(activityPermissionBinding.root) + super.onCreate(savedInstanceState) + checkAppPermissions() + } + //隐藏ActionBar的方法 + + + + override fun initView() { + activityPermissionBinding.btnContinue.setOnClickListener { + toActivity(LoginActivity::class.java, DataCollection()) + finish() + } + activityPermissionBinding.btnClose.setOnClickListener { + toActivity(LoginActivity::class.java, DataCollection()) + finish() + } + } + + override fun initData() { + + PreferencesUtils.putBoolean(this@PermisstionActivity, Const.PERMISSIONS_FIRST,true) + } + + +} \ No newline at end of file diff --git a/app/src/main/java/com/ck/ckcollar/app/ui/act/welcome/WelcomeActivity.kt b/app/src/main/java/com/ck/ckcollar/app/ui/act/welcome/WelcomeActivity.kt new file mode 100644 index 0000000..18b5fed --- /dev/null +++ b/app/src/main/java/com/ck/ckcollar/app/ui/act/welcome/WelcomeActivity.kt @@ -0,0 +1,100 @@ +package com.ck.ckcollar.app.ui.act.welcome + +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.ck.ckcollar.app.R +import com.ck.ckcollar.app.databinding.ActivityWelcomeBinding +import com.ck.ckcollar.app.databinding.LayoutItemWelcomeBinding +import com.ck.ckcollar.app.ui.act.login.LoginActivity +import com.ck.ckcollar.app.ui.base.CKBaseActivity +import com.ck.ckcollar.app.utils.Const +import com.cyclone.shadowsocks.utils.PreferencesUtils +import com.tt.kit.model.DataCollection + +class WelcomeActivity : CKBaseActivity() { + lateinit var welcomeBinding: ActivityWelcomeBinding + var views = mutableListOf() + override fun onCreate(savedInstanceState: Bundle?) { + welcomeBinding = ActivityWelcomeBinding.inflate(layoutInflater) + setContentView(welcomeBinding.root) + super.onCreate(savedInstanceState) + + setStatusBarColor(R.attr.mainBackground) + + } + + override fun initView() { + for (i in 0..2) { + var view = LayoutItemWelcomeBinding.inflate(layoutInflater); + if (i == 0) { + view.image.setImageResource(R.mipmap.image_welcome_item_1) + view.btnCome.setBackgroundResource(R.drawable.bg_welcome_next_button) + view.btnCome.setTextColor(getColor2(R.attr.buttonColor)) + view.btnCome.setText(R.string.next) + + view.btnCome.setOnClickListener { + welcomeBinding.viewPager.setCurrentItem(1) + } + + } else if (i == 1) { + view.image.setImageResource(R.mipmap.image_welcome_item_2) + view.btnCome.setBackgroundResource(R.drawable.bg_welcome_next_button) + view.btnCome.setTextColor(getColor2(R.attr.buttonColor)) + view.btnCome.setText(R.string.next) + + view.btnCome.setOnClickListener { + welcomeBinding.viewPager.setCurrentItem(2) + } + + } else if (i == 2) { + view.image.setImageResource(R.mipmap.image_welcome_item_3) + view.btnCome.setBackgroundResource(R.drawable.bg_welcome_button) + view.btnCome.setTextColor(getColor2(R.attr.appTextColor)) + view.btnCome.setText(R.string.into) + + view.btnCome.setOnClickListener { + val toPermisstionActivity = PreferencesUtils.getBolean(this@WelcomeActivity, + Const.PERMISSIONS_FIRST,false) as Boolean + if (!toPermisstionActivity){ + toActivity(PermisstionActivity::class.java, DataCollection()) + }else{ + toActivity(LoginActivity::class.java, DataCollection()) + } + finish() + } + + } + views.add(view.root) + } + welcomeBinding.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) + } + } + } + + override fun initData() { + + PreferencesUtils.putBoolean(this, Const.FIRST, false) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/ck/ckcollar/app/ui/base/CKBaseActionBarActivity.kt b/app/src/main/java/com/ck/ckcollar/app/ui/base/CKBaseActionBarActivity.kt new file mode 100644 index 0000000..9fc7e2c --- /dev/null +++ b/app/src/main/java/com/ck/ckcollar/app/ui/base/CKBaseActionBarActivity.kt @@ -0,0 +1,130 @@ +package com.ck.ckcollar.app.ui.base + +import android.Manifest +import android.graphics.Color +import android.os.Build +import android.os.Bundle +import android.util.TypedValue +import android.view.View +import android.view.WindowManager +import android.widget.ImageButton +import android.widget.ImageView +import android.widget.TextView +import com.ck.ckcollar.app.CKApp +import com.ck.ckcollar.app.R +import com.tt.kit.base.TTBaseActivity +import com.tt.kit.utils.TTUtils +import pub.devrel.easypermissions.EasyPermissions + + +open class CKBaseActionBarActivity : TTBaseActivity(){ + + var perms_= listOf(Manifest.permission.CAMERA, Manifest.permission.READ_MEDIA_IMAGES,Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE) + var perms_tiramisu = listOf(Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.READ_EXTERNAL_STORAGE) + + lateinit var rootView : View + override fun onCreate(savedInstanceState: Bundle?) { + + super.onCreate(savedInstanceState) + TTUtils.init(this) + initActionBarBackgroundColor() + + CKApp.app.activitys.add(this) + setStatusBarColor(R.attr.actionBarBackground) + + + } + + fun checkAppPermissions(){ + if (!checkPermissions()){ + requstPermissions() + } + } + + override fun setContentView(view: View?) { + rootView = view!! + super.setContentView(view) + } + + fun setStatusBarColor(color : Int){ + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + val window = getWindow() + window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) + window.setStatusBarColor(getColor2(color)) // 透明状态栏 + window.setNavigationBarColor(Color.TRANSPARENT) // 透明导航栏 + } + } + + fun setStatusBarColor2(color : Int){ + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + val window = getWindow() + window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) + window.setStatusBarColor(color) // 透明状态栏 + window.setNavigationBarColor(Color.TRANSPARENT) // 透明导航栏 + } + } + + fun initActionBarBackgroundColor(){ + try { + var leftButton = findViewById(R.id.btnLeft) + leftButton.setImageResource(R.mipmap.image_back) + leftButton.scaleType = ImageView.ScaleType.CENTER_INSIDE + leftButton.setOnClickListener { + + } + + + var textTitle = findViewById(R.id.textTitle) + textTitle.setTextColor(getColor2(R.attr.appTextColor)) + + + }catch (e : Exception){ + + } + } + fun getColor2(attrResId: Int): Int { + val typedValue = TypedValue() + getTheme().resolveAttribute(attrResId, typedValue, true) + return typedValue.data + } + + fun setTitle(title :String){ + try { + var textTitle = findViewById(R.id.textTitle) + textTitle.text = title + }catch (e : Exception){ + + } + } + fun setTitleResource(resource : Int){ + acitonBarHelper?.setTitleText(resources.getString(resource)) + } + + + fun checkPermissions() : Boolean{ + var perms = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + perms_ + } else { + perms_tiramisu + } + return EasyPermissions.hasPermissions(this, *perms.toTypedArray()) + } + + fun requstPermissions(){ + var perms = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + perms_ + } else { + perms_tiramisu + } + EasyPermissions.requestPermissions( + this, + "App需要发现权限", + 101, + *perms.toTypedArray() + ) + } + override fun onDestroy() { + super.onDestroy() + CKApp.app.activitys.remove(this) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/ck/ckcollar/app/ui/base/CKBaseActivity.kt b/app/src/main/java/com/ck/ckcollar/app/ui/base/CKBaseActivity.kt new file mode 100644 index 0000000..d2bcd60 --- /dev/null +++ b/app/src/main/java/com/ck/ckcollar/app/ui/base/CKBaseActivity.kt @@ -0,0 +1,248 @@ +package com.ck.ckcollar.app.ui.base + +import android.Manifest +import android.graphics.Color +import android.os.Build +import android.os.Bundle +import android.util.TypedValue +import android.view.View +import android.view.WindowManager +import android.widget.ImageButton +import android.widget.ImageView +import android.widget.TextView +import androidx.appcompat.app.AppCompatDelegate +import androidx.core.app.ActivityCompat +import androidx.core.content.ContextCompat +import androidx.core.view.ViewCompat +import androidx.core.view.WindowCompat +import androidx.core.view.WindowInsetsCompat +import com.ck.ckcollar.app.CKApp +import com.ck.ckcollar.app.R +import com.tt.kit.base.TTBaseActivity +import com.tt.kit.utils.TTLog +import com.tt.kit.utils.TTUtils +import pub.devrel.easypermissions.EasyPermissions + + +open class CKBaseActivity : TTBaseActivity(){ + + var perms_= listOf(Manifest.permission.CAMERA, Manifest.permission.READ_MEDIA_IMAGES,Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE) + var perms_tiramisu = listOf(Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.READ_EXTERNAL_STORAGE) + + var perms_carmra = listOf(Manifest.permission.CAMERA) + + lateinit var rootView : View + override fun onCreate(savedInstanceState: Bundle?) { + + // 允许布局延伸到刘海区域 +// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { +// val lp = window.attributes +// lp.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES +// window.attributes = lp +// } +// +//// 开启 Edge-to-Edge 沉浸式,使内容沉浸至状态栏 +// WindowCompat.setDecorFitsSystemWindows(window, false) + + // AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO) + + + super.onCreate(savedInstanceState) + TTUtils.init(this) + initActionBarBackgroundColor() + + CKApp.app.activitys.add(this) + setStatusBarColor(R.attr.actionBarBackground) + + + } + + fun checkAppPermissions(){ + if (!checkPermissions()){ + requstPermissions() + } + } + + override fun setContentView(view: View?) { + rootView = view!! + super.setContentView(view) + } + + fun setStatusBarColor(color : Int){ + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + val window = getWindow() + window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) + window.setStatusBarColor(getColor2(color)) // 透明状态栏 + window.setNavigationBarColor(Color.TRANSPARENT) // 透明导航栏 + } + } + + fun setStatusBarColor2(color : Int){ + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + val window = getWindow() + window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) + window.setStatusBarColor(color) // 透明状态栏 + window.setNavigationBarColor(Color.TRANSPARENT) // 透明导航栏 + } + } + + fun initActionBarBackgroundColor(){ + acitonBarHelper?.setBackgroundColor(getColor2(R.attr.actionBarBackground)) + acitonBarHelper?.setLeftButtonImage(R.mipmap.image_back) + acitonBarHelper?.btnLeftButton?.scaleType = ImageView.ScaleType.CENTER_INSIDE + acitonBarHelper?.setTitleColor(getColor2(R.attr.appTextColor)) + acitonBarHelper?.setTitleSize(16f) + + try { + var leftButton = findViewById(R.id.btnLeft) + leftButton.setImageResource(R.mipmap.image_back) + leftButton.scaleType = ImageView.ScaleType.CENTER_INSIDE + leftButton.setOnClickListener { + leftButtonOnClick() + } + + + var textTitle = findViewById(R.id.textTitle) + textTitle.setTextColor(getColor2(R.attr.appTextColor)) + + + var btnRightText = findViewById(R.id.btnRightText) + btnRightText.setOnClickListener { + rightButton1OnClick() + } + var btnRight1 = findViewById(R.id.btnRight1) + btnRight1.setOnClickListener { + rightButton1OnClick() + } + var btnRight2 = findViewById(R.id.btnRight2) + btnRight2.setOnClickListener { + rightButton2OnClick() + } + + }catch (e : Exception){ + + } + + + } + fun getColor2(attrResId: Int): Int { + val typedValue = TypedValue() + getTheme().resolveAttribute(attrResId, typedValue, true) + return typedValue.data + } + + override fun setTitleText(text: String) { + super.setTitleText(text) + try{ + + var textTitle = findViewById(R.id.textTitle) + textTitle.setText(text) + }catch (e : Exception){ + + } + } + + fun setTitleTextColor(textColor: Int) { + try{ + + var textTitle = findViewById(R.id.textTitle) + textTitle.setTextColor(textColor) + }catch (e : Exception){ + + } + } + + override fun setRightButton1Image(resource: Int) { + super.setRightButton1Image(resource) + try { + + var btnRight1 = findViewById(R.id.btnRight1) + btnRight1.setImageResource(resource) + }catch (e : Exception){ + + } + } + + fun setActionBarColor(color : Int){ + try{ + + var view = findViewById(R.id.actionBar) + view.setBackgroundColor(color) + + }catch (e : Exception){ + + } + } + override fun setRightText(text: String) { + try { + var btnRightText = findViewById(R.id.btnRightText) + btnRightText.setText(text) + }catch (e: Exception){ + + } + + } + + fun setRightTextColor(color: Int) { + try { + var btnRightText = findViewById(R.id.btnRightText) + btnRightText.setTextColor(color) + }catch (e: Exception){ + + } + + } + + fun setTitleResource(resource : Int){ + acitonBarHelper?.setTitleText(resources.getString(resource)) + } + + + fun checkPermissions() : Boolean{ + var perms = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + perms_ + } else { + perms_tiramisu + } + return EasyPermissions.hasPermissions(this, *perms.toTypedArray()) + } + + fun checkCameraPermissions() : Boolean{ + + return EasyPermissions.hasPermissions(this, *perms_carmra.toTypedArray()) + } + + fun requstPermissions(){ + var perms = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + perms_ + } else { + perms_tiramisu + } +// EasyPermissions.requestPermissions( +// this, +// "App需要发现权限", +// 101, +// *perms.toTypedArray() +// ) + + ActivityCompat.requestPermissions(this, perms.toTypedArray(), 1001) + } + override fun onDestroy() { + super.onDestroy() + CKApp.app.activitys.remove(this) + } + + override fun onResume() { + super.onResume() + + } + + override fun onStop() { + super.onStop() + + } + + override fun onPause() { + super.onPause() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/ck/ckcollar/app/ui/base/CKBaseAdapter.kt b/app/src/main/java/com/ck/ckcollar/app/ui/base/CKBaseAdapter.kt new file mode 100644 index 0000000..ebfaad6 --- /dev/null +++ b/app/src/main/java/com/ck/ckcollar/app/ui/base/CKBaseAdapter.kt @@ -0,0 +1,30 @@ +package com.ck.ckcollar.app.ui.base + +import android.view.View +import android.view.ViewGroup +import androidx.recyclerview.widget.RecyclerView + +class CKBaseAdapter : RecyclerView.Adapter() { + override fun onCreateViewHolder( + parent: ViewGroup, + viewType: Int + ): CKBaseViewHoldr { + TODO("Not yet implemented") + } + + override fun onBindViewHolder( + holder: CKBaseViewHoldr, + position: Int + ) { + TODO("Not yet implemented") + } + + override fun getItemCount(): Int { + TODO("Not yet implemented") + } + + class CKBaseViewHoldr(itemView: View) : RecyclerView.ViewHolder(itemView){ + + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/ck/ckcollar/app/ui/base/CKBaseFragment.kt b/app/src/main/java/com/ck/ckcollar/app/ui/base/CKBaseFragment.kt new file mode 100644 index 0000000..352daa7 --- /dev/null +++ b/app/src/main/java/com/ck/ckcollar/app/ui/base/CKBaseFragment.kt @@ -0,0 +1,18 @@ +package com.ck.ckcollar.app.ui.base + +import android.Manifest +import com.cyclone.shadowsocks.ui.frg.TTBaseFragment +import pub.devrel.easypermissions.EasyPermissions + +open class CKBaseFragment : TTBaseFragment() { + + var perms_carmra = listOf(Manifest.permission.CAMERA) + + + + + fun checkCameraPermissions() : Boolean{ + return EasyPermissions.hasPermissions(activity!!, *perms_carmra.toTypedArray()) + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/ck/ckcollar/app/ui/base/CKLHBaseActionBarActivity.kt b/app/src/main/java/com/ck/ckcollar/app/ui/base/CKLHBaseActionBarActivity.kt new file mode 100644 index 0000000..70556ef --- /dev/null +++ b/app/src/main/java/com/ck/ckcollar/app/ui/base/CKLHBaseActionBarActivity.kt @@ -0,0 +1,205 @@ +package com.ck.ckcollar.app.ui.base + +import android.Manifest +import android.app.Activity +import android.graphics.Color +import android.os.Build +import android.os.Bundle +import android.util.TypedValue +import android.view.View +import android.view.WindowInsets +import android.view.WindowInsetsController +import android.view.WindowManager +import android.widget.ImageView +import androidx.appcompat.app.AppCompatDelegate +import androidx.core.app.ActivityCompat +import androidx.core.content.ContextCompat +import androidx.core.view.ViewCompat +import androidx.core.view.WindowCompat +import androidx.core.view.WindowInsetsCompat +import androidx.core.view.marginBottom +import androidx.core.view.updatePadding +import com.ck.ckcollar.app.CKApp +import com.ck.ckcollar.app.R +import com.tt.kit.base.TTBaseActivity +import com.tt.kit.utils.TTUtils +import pub.devrel.easypermissions.EasyPermissions + + +open class CKLHBaseActionBarActivity : TTBaseActivity(){ + + var perms_= listOf(Manifest.permission.CAMERA, Manifest.permission.READ_MEDIA_IMAGES,Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE) + var perms_tiramisu = listOf(Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.READ_EXTERNAL_STORAGE) + + lateinit var rootView : View + + override fun onCreate(savedInstanceState: Bundle?) { + // AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO) + + // 允许布局延伸到刘海区域 +// if (Build.VERSION.SDK_INT >= 21) { +// var decorView = getWindow().getDecorView(); +// val option = (View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN +// or View.SYSTEM_UI_FLAG_LAYOUT_STABLE) +// decorView.setSystemUiVisibility(option); +// getWindow().setStatusBarColor(Color.TRANSPARENT); +// } + +// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { +// window.setDecorFitsSystemWindows(false) +// window.insetsController?.setSystemBarsAppearance( +// WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS, +// WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS +// ) +// } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { +// window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS) +// window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) +// window.statusBarColor = Color.TRANSPARENT +// window.decorView.systemUiVisibility = ( +// View.SYSTEM_UI_FLAG_LAYOUT_STABLE or +// View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN +// ) +// } + + + + //setupImmersiveStatusBar(this) + TTUtils.init(this) + + + + super.onCreate(savedInstanceState) + initActionBarBackgroundColor() + + CKApp.app.activitys.add(this) +// setStatusBarColor2(R.color.transparent) +// +// getWindow().setStatusBarColor(Color.TRANSPARENT); + +// +// ViewCompat.setOnApplyWindowInsetsListener(rootView) { v, insets -> +// val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars()) +// v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom) +// insets +// } + + if (!checkPermissions()){ + requstPermissions() + } + + } + + + override fun setContentView(view: View?) { + rootView = view!! + super.setContentView(view) + } + + + fun setStatusBarColor(color : Int){ + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + val window = getWindow() + window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) + window.setStatusBarColor(getColor2(color)) // 透明状态栏 + window.setNavigationBarColor(Color.TRANSPARENT) // 透明导航栏 + } + } + + fun setStatusBarColor2(color : Int){ + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + val window = getWindow() + window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) + window.setStatusBarColor(resources.getColor(color)) // 透明状态栏 + window.setNavigationBarColor(Color.TRANSPARENT) // 透明导航栏 + } + } + + fun initActionBarBackgroundColor(){ + acitonBarHelper?.setBackgroundColor(getColor2(R.attr.actionBarBackground)) + acitonBarHelper?.setLeftButtonImage(R.mipmap.image_back) + acitonBarHelper?.btnLeftButton?.scaleType = ImageView.ScaleType.CENTER_INSIDE + acitonBarHelper?.setTitleColor(getColor2(R.attr.appTextColor)) + acitonBarHelper?.setTitleSize(16f) + } + fun getColor2(attrResId: Int): Int { + val typedValue = TypedValue() + getTheme().resolveAttribute(attrResId, typedValue, true) + return typedValue.data + } + + fun setTitle(title :String){ + acitonBarHelper?.setTitleText(title) + } + fun setTitleResource(resource : Int){ + acitonBarHelper?.setTitleText(resources.getString(resource)) + } + + + fun checkPermissions() : Boolean{ + var perms = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + perms_ + } else { + perms_tiramisu + } + return EasyPermissions.hasPermissions(this, *perms.toTypedArray()) + } + + fun requstPermissions(){ + var perms = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + perms_ + } else { + perms_tiramisu + } +// EasyPermissions.requestPermissions( +// this, +// "App需要发现权限", +// 101, +// *perms.toTypedArray() +// ) + + ActivityCompat.requestPermissions(this, perms.toTypedArray(), 1001) + + } + override fun onDestroy() { + super.onDestroy() + CKApp.app.activitys.remove(this) + } + + + // Kotlin示例:安全设置沉浸式状态栏 + fun setupImmersiveStatusBar(activity: Activity) { + val window = activity.window + var insetsController: WindowInsetsController? = null + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + insetsController = window.insetsController + insetsController?.apply { + setSystemBarsAppearance( + WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS, + WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS + ) + setSystemBarsBehavior(WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE) + } + window.statusBarColor = Color.TRANSPARENT + } else { + // 兼容旧版本 + window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) + window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS) + window.statusBarColor = Color.TRANSPARENT + + @Suppress("DEPRECATION") + window.decorView.systemUiVisibility = ( + View.SYSTEM_UI_FLAG_LAYOUT_STABLE or + View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or + View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR + ) + } + + // 统一处理布局避让 +// ViewCompat.setOnApplyWindowInsetsListener(activity.findViewById(R.id.root_container)) { view, insets -> +// val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars()) +// view.updatePadding(top = systemBars.top) +// insets +// } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/ck/ckcollar/app/ui/base/CKLHBaseActivity.kt b/app/src/main/java/com/ck/ckcollar/app/ui/base/CKLHBaseActivity.kt new file mode 100644 index 0000000..13b9130 --- /dev/null +++ b/app/src/main/java/com/ck/ckcollar/app/ui/base/CKLHBaseActivity.kt @@ -0,0 +1,209 @@ +package com.ck.ckcollar.app.ui.base + +import android.Manifest +import android.app.Activity +import android.graphics.Color +import android.os.Build +import android.os.Bundle +import android.util.TypedValue +import android.view.View +import android.view.WindowInsetsController +import android.view.WindowManager +import android.widget.ImageView +import androidx.appcompat.app.AppCompatDelegate +import androidx.core.app.ActivityCompat +import androidx.core.content.ContextCompat +import androidx.core.view.ViewCompat +import androidx.core.view.WindowCompat +import androidx.core.view.WindowInsetsCompat +import androidx.core.view.updatePadding +import com.ck.ckcollar.app.CKApp +import com.ck.ckcollar.app.R +import com.efs.sdk.launch.LaunchManager +import com.tt.kit.base.TTBaseActivity +import com.tt.kit.utils.TTUtils +import com.umeng.analytics.MobclickAgent +import pub.devrel.easypermissions.EasyPermissions + + +open class CKLHBaseActivity : TTBaseActivity(){ + + var perms_= listOf(Manifest.permission.CAMERA, Manifest.permission.READ_MEDIA_IMAGES,Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE) + var perms_tiramisu = listOf(Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.READ_EXTERNAL_STORAGE) + override fun onCreate(savedInstanceState: Bundle?) { + // AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO) + + // 允许布局延伸到刘海区域 +// if (Build.VERSION.SDK_INT >= 21) { +// var decorView = getWindow().getDecorView(); +// val option = (View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN +// or View.SYSTEM_UI_FLAG_LAYOUT_STABLE) +// decorView.setSystemUiVisibility(option); +// getWindow().setStatusBarColor(Color.TRANSPARENT); +// } + +// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { +// window.setDecorFitsSystemWindows(false) +// window.insetsController?.setSystemBarsAppearance( +// WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS, +// WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS +// ) +// } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { +// window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS) +// window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) +// window.statusBarColor = Color.TRANSPARENT +// window.decorView.systemUiVisibility = ( +// View.SYSTEM_UI_FLAG_LAYOUT_STABLE or +// View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN +// ) +// } + + + + //setupImmersiveStatusBar(this) + TTUtils.init(this) + + + + super.onCreate(savedInstanceState) + initActionBarBackgroundColor() + + CKApp.app.activitys.add(this) +// setStatusBarColor2(R.color.transparent) +// +// getWindow().setStatusBarColor(Color.TRANSPARENT); + + + if (!checkPermissions()){ + requstPermissions() + } + } + + + fun setStatusBarColor(color : Int){ + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + val window = getWindow() + window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) + window.setStatusBarColor(getColor2(color)) // 透明状态栏 + window.setNavigationBarColor(Color.TRANSPARENT) // 透明导航栏 + } + } + + fun setStatusBarColor2(color : Int){ + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + val window = getWindow() + window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) + window.setStatusBarColor(resources.getColor(color)) // 透明状态栏 + window.setNavigationBarColor(Color.TRANSPARENT) // 透明导航栏 + } + } + + fun initActionBarBackgroundColor(){ + acitonBarHelper?.setBackgroundColor(getColor2(R.attr.actionBarBackground)) + acitonBarHelper?.setLeftButtonImage(R.mipmap.image_back) + acitonBarHelper?.btnLeftButton?.scaleType = ImageView.ScaleType.CENTER_INSIDE + acitonBarHelper?.setTitleColor(getColor2(R.attr.appTextColor)) + acitonBarHelper?.setTitleSize(16f) + } + fun getColor2(attrResId: Int): Int { + val typedValue = TypedValue() + getTheme().resolveAttribute(attrResId, typedValue, true) + return typedValue.data + } + + fun setTitle(title :String){ + acitonBarHelper?.setTitleText(title) + } + fun setTitleResource(resource : Int){ + acitonBarHelper?.setTitleText(resources.getString(resource)) + } + + + fun checkPermissions() : Boolean{ + var perms = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + perms_ + } else { + perms_tiramisu + } + return EasyPermissions.hasPermissions(this, *perms.toTypedArray()) + } + + fun requstPermissions(){ + var perms = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + perms_ + } else { + perms_tiramisu + } +// EasyPermissions.requestPermissions( +// this, +// "App需要发现权限", +// 101, +// *perms.toTypedArray() +// ) + + ActivityCompat.requestPermissions(this, perms.toTypedArray(), 1001) + + } + override fun onDestroy() { + super.onDestroy() + CKApp.app.activitys.remove(this) + } + + + // Kotlin示例:安全设置沉浸式状态栏 + fun setupImmersiveStatusBar(activity: Activity) { + val window = activity.window + var insetsController: WindowInsetsController? = null + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + insetsController = window.insetsController + insetsController?.apply { + setSystemBarsAppearance( + WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS, + WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS + ) + setSystemBarsBehavior(WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE) + } + window.statusBarColor = Color.TRANSPARENT + } else { + // 兼容旧版本 + window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) + window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS) + window.statusBarColor = Color.TRANSPARENT + + @Suppress("DEPRECATION") + window.decorView.systemUiVisibility = ( + View.SYSTEM_UI_FLAG_LAYOUT_STABLE or + View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or + View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR + ) + } + + // 统一处理布局避让 +// ViewCompat.setOnApplyWindowInsetsListener(activity.findViewById(R.id.root_container)) { view, insets -> +// val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars()) +// view.updatePadding(top = systemBars.top) +// insets +// } + } + + override fun onResume() { + super.onResume() + LaunchManager.onTracePage(this, LaunchManager.PAGE_ON_RESUME, false); + MobclickAgent.onResume(this) + MobclickAgent.onPageStart("view") + + } + + override fun onStop() { + super.onStop() + LaunchManager.onTracePage(this, LaunchManager.PAGE_ON_STOP, true); + + } + override fun onPause() { + super.onPause() + MobclickAgent.onPause(this) + MobclickAgent.onPageEnd("view") + + } +} \ No newline at end of file diff --git a/app/src/main/java/com/ck/ckcollar/app/ui/dialog/CKAlertDialog.kt b/app/src/main/java/com/ck/ckcollar/app/ui/dialog/CKAlertDialog.kt new file mode 100644 index 0000000..2da79c2 --- /dev/null +++ b/app/src/main/java/com/ck/ckcollar/app/ui/dialog/CKAlertDialog.kt @@ -0,0 +1,58 @@ +package com.ck.ckcollar.app.ui.dialog + +import android.content.Context +import android.text.TextUtils +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import com.ck.ckcollar.app.databinding.DialogAlertBinding +import com.ck.ckcollar.app.databinding.DialogMakePhotoBinding +import com.tt.kit.dialog.TTBaseDialog +import com.tt.kit.dialog.TTBaseDialogBottom +import com.tt.kit.utils.TTUtils + +class CKAlertDialog( + var mContext: Context, + var title : String,var alertText: String, + var alertClickListener: AlertClickListener +) : TTBaseDialog(mContext){ + + override fun show() { + try { + var dialogAlertBinding = + DialogAlertBinding.inflate(LayoutInflater.from(mContext)) + if (!TextUtils.isEmpty(title)){ + dialogAlertBinding.title.text = title + } + dialogAlertBinding.alertText.text = alertText + dialogAlertBinding.cancelButton.setOnClickListener(object : View.OnClickListener { + override fun onClick(v: View?) { + cancel() + + alertClickListener.onBack(false) + } + }) + + //dialogView.findViewById(R.id.photo).setVisibility(View.GONE); + dialogAlertBinding.confirmButton.setOnClickListener(object : View.OnClickListener { + override fun onClick(v: View?) { + // TODO Auto-generated method stub + cancel() + alertClickListener.onBack(true) + } + }) + + setContentView(dialogAlertBinding.root,ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)) + + } catch (e: Exception) { + e.printStackTrace() + } + + super.show() + } + + + interface AlertClickListener { + fun onBack(isConfirm : Boolean) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/ck/ckcollar/app/ui/dialog/CKDateMonthDialog.kt b/app/src/main/java/com/ck/ckcollar/app/ui/dialog/CKDateMonthDialog.kt new file mode 100644 index 0000000..a8c90a7 --- /dev/null +++ b/app/src/main/java/com/ck/ckcollar/app/ui/dialog/CKDateMonthDialog.kt @@ -0,0 +1,63 @@ +package com.ck.ckcollar.app.ui.dialog + +import android.content.Context +import android.graphics.Color +import android.view.View +import com.ck.ckcollar.app.R +import com.tangtang.pickerview.builder.TimePickerBuilder +import com.tangtang.pickerview.listener.OnTimeSelectListener +import com.tangtang.pickerview.view.TimePickerView +import java.text.SimpleDateFormat +import java.util.Calendar +import java.util.Date + + +class CKDateMonthDialog( + var mContext: Context, + var itemClickListener: ItemClickListener? +) { + + fun show() { + + try { + var pvTime = TimePickerBuilder(mContext, object : OnTimeSelectListener { + override fun onTimeSelect(date: Date?, v: View?) { //选中事件回调 + itemClickListener?.onBack(date!!, SimpleDateFormat("yyyy年MM月").format(date)) + } + }) + .setType(booleanArrayOf(true, true, false, false, false, false))// 默认全部显示 + + .setSubmitText("确定") //确定按钮文字 + .setCancelText("取消") //取消按钮文字 + .setTitleText("") //标题 + .setSubCalSize(14) //确定和取消文字大小 + .setTitleSize(14) //标题文字大小 + .setTitleColor(Color.TRANSPARENT) //标题文字颜色 + .setSubmitColor(mContext.resources.getColor(R.color.appStyleColor)) //确定按钮文字颜色 + .setCancelColor(mContext.resources.getColor(R.color.textSecondColor)) //取消按钮文字颜色 + .setTitleBgColor(mContext.resources.getColor(R.color.white))//标题背景颜色 Night mode + .setBgColor(mContext.resources.getColor(R.color.white))//滚轮背景颜色 Night mode + .setContentTextSize(14) //滚轮文字大小 + //.setLinkage(false)//设置是否联动,默认true + // .setLabels("省", "市", "区")//设置选择的三级单位 + .isCenterLabel(false) //是否只显示中间选中项的label文字,false则每项item全部都带有label。 + .setOutSideCancelable(true) //点击外部dismiss default true + .isDialog(false) //是否显示为对话框样式 + .setDate(Calendar.getInstance())// 如果不设置的话,默认是系统时间*/ + + .build() + + pvTime.show() + + } catch (e: Exception) { + e.printStackTrace() + } + + + } + + + interface ItemClickListener { + fun onBack(date: Date, dateText: String) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/ck/ckcollar/app/ui/dialog/CKEditDialog.kt b/app/src/main/java/com/ck/ckcollar/app/ui/dialog/CKEditDialog.kt new file mode 100644 index 0000000..9ef86ea --- /dev/null +++ b/app/src/main/java/com/ck/ckcollar/app/ui/dialog/CKEditDialog.kt @@ -0,0 +1,58 @@ +package com.ck.ckcollar.app.ui.dialog + +import android.content.Context +import android.text.TextUtils +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import com.ck.ckcollar.app.databinding.DialogAlertBinding +import com.ck.ckcollar.app.databinding.DialogEditBinding +import com.ck.ckcollar.app.databinding.DialogMakePhotoBinding +import com.tt.kit.dialog.TTBaseDialog +import com.tt.kit.dialog.TTBaseDialogBottom +import com.tt.kit.utils.TTUtils + +class CKEditDialog( + var mContext: Context, + var title : String,var alertText: String, + var alertClickListener: AlertClickListener +) : TTBaseDialog(mContext){ + + override fun show() { + try { + var dialogAlertBinding = + DialogEditBinding.inflate(LayoutInflater.from(mContext)) + if (!TextUtils.isEmpty(title)){ + dialogAlertBinding.title.text = title + } + dialogAlertBinding.alertText.setHint(alertText) + dialogAlertBinding.cancelButton.setOnClickListener(object : View.OnClickListener { + override fun onClick(v: View?) { + cancel() + + } + }) + + //dialogView.findViewById(R.id.photo).setVisibility(View.GONE); + dialogAlertBinding.confirmButton.setOnClickListener(object : View.OnClickListener { + override fun onClick(v: View?) { + // TODO Auto-generated method stub + cancel() + alertClickListener.onBack(dialogAlertBinding.alertText.text.toString()) + } + }) + + setContentView(dialogAlertBinding.root,ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)) + + } catch (e: Exception) { + e.printStackTrace() + } + + super.show() + } + + + interface AlertClickListener { + fun onBack(text : String) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/ck/ckcollar/app/ui/dialog/CKEditNameDialog.kt b/app/src/main/java/com/ck/ckcollar/app/ui/dialog/CKEditNameDialog.kt new file mode 100644 index 0000000..10d28bf --- /dev/null +++ b/app/src/main/java/com/ck/ckcollar/app/ui/dialog/CKEditNameDialog.kt @@ -0,0 +1,60 @@ +package com.ck.ckcollar.app.ui.dialog + +import android.content.Context +import android.text.InputFilter +import android.text.TextUtils +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import com.ck.ckcollar.app.databinding.DialogAlertBinding +import com.ck.ckcollar.app.databinding.DialogEditBinding +import com.ck.ckcollar.app.databinding.DialogMakePhotoBinding +import com.tt.kit.dialog.TTBaseDialog +import com.tt.kit.dialog.TTBaseDialogBottom +import com.tt.kit.utils.TTUtils + +class CKEditNameDialog( + var mContext: Context, + var title : String,var alertText: String, + var alertClickListener: AlertClickListener +) : TTBaseDialog(mContext){ + + override fun show() { + try { + var dialogAlertBinding = + DialogEditBinding.inflate(LayoutInflater.from(mContext)) + if (!TextUtils.isEmpty(title)){ + dialogAlertBinding.title.text = title + } + dialogAlertBinding.alertText.setHint(alertText) + dialogAlertBinding.alertText.filters = arrayOf(InputFilter.LengthFilter(10)) + dialogAlertBinding.cancelButton.setOnClickListener(object : View.OnClickListener { + override fun onClick(v: View?) { + cancel() + + } + }) + + //dialogView.findViewById(R.id.photo).setVisibility(View.GONE); + dialogAlertBinding.confirmButton.setOnClickListener(object : View.OnClickListener { + override fun onClick(v: View?) { + // TODO Auto-generated method stub + cancel() + alertClickListener.onBack(dialogAlertBinding.alertText.text.toString()) + } + }) + + setContentView(dialogAlertBinding.root,ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)) + + } catch (e: Exception) { + e.printStackTrace() + } + + super.show() + } + + + interface AlertClickListener { + fun onBack(text : String) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/ck/ckcollar/app/ui/dialog/CKEditPhoneDialog.kt b/app/src/main/java/com/ck/ckcollar/app/ui/dialog/CKEditPhoneDialog.kt new file mode 100644 index 0000000..64fd3dd --- /dev/null +++ b/app/src/main/java/com/ck/ckcollar/app/ui/dialog/CKEditPhoneDialog.kt @@ -0,0 +1,111 @@ +package com.ck.ckcollar.app.ui.dialog + +import android.content.Context +import android.text.TextUtils +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import com.ck.ckcollar.app.R +import com.ck.ckcollar.app.databinding.DialogAlertBinding +import com.ck.ckcollar.app.databinding.DialogEditBinding +import com.ck.ckcollar.app.databinding.DialogEditPhoneBinding +import com.ck.ckcollar.app.databinding.DialogMakePhotoBinding +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.dialog.TTBaseDialog +import com.tt.kit.dialog.TTBaseDialogBottom +import com.tt.kit.utils.TTUtils + +class CKEditPhoneDialog( + var mContext: TTBaseActivity, + var title : String, + var alertClickListener: AlertClickListener +) : TTBaseDialog(mContext){ + lateinit var dialogAlertBinding :DialogEditPhoneBinding + override fun show() { + try { + dialogAlertBinding = + DialogEditPhoneBinding.inflate(LayoutInflater.from(mContext)) + if (!TextUtils.isEmpty(title)){ + dialogAlertBinding.title.text = title + } + dialogAlertBinding.btnSendCode.setOnClickListener { sendCode() } + dialogAlertBinding.cancelButton.setOnClickListener(object : View.OnClickListener { + override fun onClick(v: View?) { + cancel() + } + }) + + //dialogView.findViewById(R.id.photo).setVisibility(View.GONE); + dialogAlertBinding.confirmButton.setOnClickListener(object : View.OnClickListener { + override fun onClick(v: View?) { + // TODO Auto-generated method stub + send() + } + }) + + setContentView(dialogAlertBinding.root,ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)) + + } catch (e: Exception) { + e.printStackTrace() + } + + super.show() + } + + fun send(){ + if (dialogAlertBinding.textPhone.isEmpty()){ + mContext.toast(mContext.getString(R.string.phone_not_empty)) + return + } + if (dialogAlertBinding.textCode.isEmpty()){ + mContext.toast(mContext.getString(R.string.code_not_empty)) + return + } + + mContext.showProgeassDialog(mContext.getString(R.string.edit)) + TTHttpClient.postJson(mContext,"修改绑定手机", TTRequestParam().apply { + add(TTRequestData("phonenumber",dialogAlertBinding.textPhone.text.toString())) + add(TTRequestData("smsCode",dialogAlertBinding.textCode.text.toString())) + },object : ICallback{ + override fun onSuccess(data: String) { + mContext.toast(mContext.getString(R.string.send_success)) + cancel() + } + + override fun onFailed(code: String, msg: String) { + mContext.toast(msg) + } + }) + + } + fun sendCode() { + if (dialogAlertBinding.textPhone.isEmpty()) { + mContext.toast(mContext.getString(R.string.phone_not_empty)) + return + } + + mContext.showProgeassDialog(mContext.getString(R.string.send)) + TTHttpClient.postJson(mContext,"发送验证码", TTRequestParam().apply { + add(TTRequestData("phonenumber",dialogAlertBinding.textPhone.text.toString())) + add(TTRequestData("scene","changePhone")) + },object : ICallback{ + override fun onSuccess(data: String) { + mContext.toast(mContext.getString(R.string.edit_success)) + alertClickListener.onBack(dialogAlertBinding.textPhone.text.toString()) + + } + + override fun onFailed(code: String, msg: String) { + mContext.toast(msg) + } + }) + } + + interface AlertClickListener { + fun onBack(text : String) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/ck/ckcollar/app/ui/dialog/CKNavDialog.kt b/app/src/main/java/com/ck/ckcollar/app/ui/dialog/CKNavDialog.kt new file mode 100644 index 0000000..e7cf42b --- /dev/null +++ b/app/src/main/java/com/ck/ckcollar/app/ui/dialog/CKNavDialog.kt @@ -0,0 +1,57 @@ +package com.ck.ckcollar.app.ui.dialog + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import com.ck.ckcollar.app.databinding.DialogMakePhotoBinding +import com.ck.ckcollar.app.databinding.DialogNavBinding +import com.tt.kit.dialog.TTBaseDialogBottom +import com.tt.kit.utils.TTUtils + +class CKNavDialog( + var mContext: Context, + var photoClickListener: MapClickListener +) : TTBaseDialogBottom(mContext){ + + override fun show() { + try { + var dialogNavBinding = + DialogNavBinding.inflate(LayoutInflater.from(mContext)) + + + dialogNavBinding.btn1.setOnClickListener(object : View.OnClickListener { + override fun onClick(v: View?) { + cancel() + photoClickListener.onBack(0, 0) + } + }) + + //dialogView.findViewById(R.id.photo).setVisibility(View.GONE); + dialogNavBinding.btn2.setOnClickListener(object : View.OnClickListener { + override fun onClick(v: View?) { + cancel() + photoClickListener.onBack(1, 0) + } + }) + dialogNavBinding.btn3.setOnClickListener(object : View.OnClickListener { + override fun onClick(v: View?) { + cancel() + photoClickListener.onBack(2, 0) + } + }) + + setContentView(dialogNavBinding.root,ViewGroup.LayoutParams(TTUtils.width, ViewGroup.LayoutParams.WRAP_CONTENT)) + + } catch (e: Exception) { + e.printStackTrace() + } + + super.show() + } + + + interface MapClickListener { + fun onBack(mark: Int, position: Int) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/ck/ckcollar/app/ui/dialog/CKPhotoDialog.kt b/app/src/main/java/com/ck/ckcollar/app/ui/dialog/CKPhotoDialog.kt new file mode 100644 index 0000000..3f40e3f --- /dev/null +++ b/app/src/main/java/com/ck/ckcollar/app/ui/dialog/CKPhotoDialog.kt @@ -0,0 +1,51 @@ +package com.ck.ckcollar.app.ui.dialog + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import com.ck.ckcollar.app.databinding.DialogMakePhotoBinding +import com.tt.kit.dialog.TTBaseDialogBottom +import com.tt.kit.utils.TTUtils + +class CKPhotoDialog( + var mContext: Context, + var photoClickListener: PhotoClickListener +) : TTBaseDialogBottom(mContext){ + + override fun show() { + try { + var dialogMakePhotoBinding = + DialogMakePhotoBinding.inflate(LayoutInflater.from(mContext)) + + + dialogMakePhotoBinding.makePhoto.setOnClickListener(object : View.OnClickListener { + override fun onClick(v: View?) { + cancel() + photoClickListener.onBack(0, 0) + } + }) + + //dialogView.findViewById(R.id.photo).setVisibility(View.GONE); + dialogMakePhotoBinding.photo.setOnClickListener(object : View.OnClickListener { + override fun onClick(v: View?) { + // TODO Auto-generated method stub + cancel() + photoClickListener.onBack(1, 0) + } + }) + + setContentView(dialogMakePhotoBinding.root,ViewGroup.LayoutParams(TTUtils.width, ViewGroup.LayoutParams.WRAP_CONTENT)) + + } catch (e: Exception) { + e.printStackTrace() + } + + super.show() + } + + + interface PhotoClickListener { + fun onBack(mark: Int, position: Int) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/ck/ckcollar/app/ui/dialog/CKPickViewDialog.kt b/app/src/main/java/com/ck/ckcollar/app/ui/dialog/CKPickViewDialog.kt new file mode 100644 index 0000000..716c50f --- /dev/null +++ b/app/src/main/java/com/ck/ckcollar/app/ui/dialog/CKPickViewDialog.kt @@ -0,0 +1,78 @@ +package com.ck.ckcollar.app.ui.dialog + +import android.content.Context +import android.graphics.Color +import android.view.View +import android.widget.Toast +import com.ck.ckcollar.app.R +import com.tangtang.pickerview.builder.OptionsPickerBuilder +import com.tangtang.pickerview.listener.OnOptionsSelectChangeListener +import com.tangtang.pickerview.listener.OnOptionsSelectListener +import com.tangtang.pickerview.view.OptionsPickerView +import com.tt.kit.base.TTBaseActivity +import com.tt.kit.utils.KeyboardUtils + +class CKPickViewDialog( + var mContext: Context, + var data : List, + var itemClickListener: ItemClickListener? +) { + + fun show() { + try { + val pvOptions = + OptionsPickerBuilder(mContext, object : OnOptionsSelectListener { + override fun onOptionsSelect( + options1: Int, + option2: Int, + options3: Int, + v: View? + ) { + itemClickListener?.onBack(options1,data.get(options1)) + } + }).setOptionsSelectChangeListener(object : OnOptionsSelectChangeListener { + override fun onOptionsSelectChanged( + options1: Int, + options2: Int, + options3: Int + ) { + + } + }) + .setSubmitText("确定") //确定按钮文字 + .setCancelText("取消") //取消按钮文字 + .setTitleText("") //标题 + .setSubCalSize(14) //确定和取消文字大小 + .setTitleSize(14) //标题文字大小 + .setTitleColor(Color.TRANSPARENT) //标题文字颜色 + .setSubmitColor(mContext.resources.getColor(R.color.appStyleColor)) //确定按钮文字颜色 + .setCancelColor(mContext.resources.getColor(R.color.textSecondColor)) //取消按钮文字颜色 + .setTitleBgColor(mContext.resources.getColor(R.color.white))//标题背景颜色 Night mode + .setBgColor(mContext.resources.getColor(R.color.white))//滚轮背景颜色 Night mode + .setContentTextSize(14) //滚轮文字大小 + //.setLinkage(false)//设置是否联动,默认true + // .setLabels("省", "市", "区")//设置选择的三级单位 + .isCenterLabel(false) //是否只显示中间选中项的label文字,false则每项item全部都带有label。 + .setCyclic(false, false, false) //循环与否 + .setSelectOptions(0, 0, 0) //设置默认选中项 + .setOutSideCancelable(true) //点击外部dismiss default true + .isDialog(false) //是否显示为对话框样式 + .isRestoreItem(true) //切换时是否还原,设置默认选中第一项。 + .build() + + pvOptions.setPicker(data) //添加数据源 + pvOptions.show() + + KeyboardUtils.hideKeyboard(mContext as TTBaseActivity) + } catch (e: Exception) { + e.printStackTrace() + } + + + } + + + interface ItemClickListener { + fun onBack(pos : Int,data:String) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/ck/ckcollar/app/ui/dialog/CKProvincePickViewDialog.kt b/app/src/main/java/com/ck/ckcollar/app/ui/dialog/CKProvincePickViewDialog.kt new file mode 100644 index 0000000..13871d4 --- /dev/null +++ b/app/src/main/java/com/ck/ckcollar/app/ui/dialog/CKProvincePickViewDialog.kt @@ -0,0 +1,150 @@ +package com.ck.ckcollar.app.ui.dialog + +import JsonBean +import android.content.Context +import android.graphics.Color +import android.view.View +import com.ck.ckcollar.app.R +import com.ck.ckcollar.app.utils.CKUtils +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken +import com.tangtang.pickerview.builder.OptionsPickerBuilder +import com.tangtang.pickerview.listener.OnOptionsSelectChangeListener +import com.tangtang.pickerview.listener.OnOptionsSelectListener + + +class CKProvincePickViewDialog( + var mContext: Context, + var itemClickListener: ItemClickListener? +) { + + private var options1Items1 = listOf() + private var options2Items2 = listOf?>() + private var options3Items3 = listOf?>?>() + fun show() { + try { + + + val jsonData: String? = + CKUtils.getJson(mContext, "province.json") //获取assets目录下的json文件数据 + + val jsonBean = Gson().fromJson>(jsonData,object : TypeToken>(){}.type) //用Gson 转成实体 + + + + var options2Items = mutableListOf?>() + var options3Items = mutableListOf?>?>() + /** + * 添加省份数据 + * + * 注意:如果是添加的JavaBean实体,则实体类需要实现 IPickerViewData 接口, + * PickerView会通过getPickerViewText方法获取字符串显示出来。 + */ + options1Items1 = jsonBean + + for (i in jsonBean.indices) { //遍历省份 + val cityList = ArrayList() //该省的城市列表(第二级) + val province_AreaList: ArrayList?>? = ArrayList?>() //该省的所有地区列表(第三极) + + if (jsonBean.get(i).city != null){ + for (c in jsonBean.get(i)?.city!!.indices) { //遍历该省份的所有城市 + val cityName = jsonBean.get(i)!!.city!!.get(c)!!.name + cityList.add(cityName) //添加城市 + val city_AreaList = mutableListOf() //该城市的所有地区列表 + + //如果无地区数据,建议添加空字符串,防止数据为null 导致三个选项长度不匹配造成崩溃 + /*if (jsonBean.get(i).getCityList().get(c).getArea() == null + || jsonBean.get(i).getCityList().get(c).getArea().size() == 0) { + city_AreaList.add(""); + } else { + city_AreaList.addAll(jsonBean.get(i).getCityList().get(c).getArea()); + }*/ + city_AreaList.addAll(jsonBean.get(i)!!.city!!.get(c)!!.area!!) + province_AreaList!!.add(city_AreaList as ArrayList?) //添加该省所有地区数据 + } + } + + + /** + * 添加城市数据 + */ + options2Items.add(cityList) + + /** + * 添加地区数据 + */ + options3Items.add(province_AreaList) + } + + options2Items2 = options2Items + options3Items3 = options3Items + + val pvOptions = + OptionsPickerBuilder(mContext, object : OnOptionsSelectListener { + override fun onOptionsSelect( + options1: Int, + options2: Int, + options3: Int, + v: View? + ) { + + val opt1tx: String? = + if (options1Items1.size > 0) options1Items1.get(options1) + .getPickerViewText() else "" + + val opt2tx: String = (if (options2Items2.size > 0 + && options2Items2.get(options1)!!.size > 0 + ) options2Items2.get(options1)!!.get(options2) else "")!! + + val opt3tx = if (options2Items2.size > 0 && options3Items3.get(options1) + !!.size > 0 && options3Items3.get(options1)!!.get(options2) + !!.size > 0 + ) options3Items3.get(options1)!!.get(options2)!!.get(options3) else "" + + itemClickListener?.onBack(options1,opt1tx!!,opt2tx,opt3tx!!) + } + }).setOptionsSelectChangeListener(object : OnOptionsSelectChangeListener { + override fun onOptionsSelectChanged( + options1: Int, + options2: Int, + options3: Int + ) { + + } + }) + .setSubmitText("确定") //确定按钮文字 + .setCancelText("取消") //取消按钮文字 + .setTitleText("") //标题 + .setSubCalSize(14) //确定和取消文字大小 + .setTitleSize(14) //标题文字大小 + .setTitleColor(Color.TRANSPARENT) //标题文字颜色 + .setSubmitColor(mContext.resources.getColor(R.color.appStyleColor)) //确定按钮文字颜色 + .setCancelColor(mContext.resources.getColor(R.color.textSecondColor)) //取消按钮文字颜色 + .setTitleBgColor(mContext.resources.getColor(R.color.white))//标题背景颜色 Night mode + .setBgColor(mContext.resources.getColor(R.color.white))//滚轮背景颜色 Night mode + .setContentTextSize(14) //滚轮文字大小 + //.setLinkage(false)//设置是否联动,默认true + // .setLabels("省", "市", "区")//设置选择的三级单位 + .isCenterLabel(false) //是否只显示中间选中项的label文字,false则每项item全部都带有label。 + .setCyclic(false, false, false) //循环与否 + .setSelectOptions(0, 0, 0) //设置默认选中项 + .setOutSideCancelable(true) //点击外部dismiss default true + .isDialog(false) //是否显示为对话框样式 + .isRestoreItem(true) //切换时是否还原,设置默认选中第一项。 + .build() + + pvOptions.setPicker(options1Items1,options2Items2,options3Items3) //添加数据源 + pvOptions.show() + + } catch (e: Exception) { + e.printStackTrace() + } + + + } + + + interface ItemClickListener { + fun onBack(pos : Int,item1:String,item2:String,item3: String) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/ck/ckcollar/app/ui/dialog/CKUpdateAlertDialog.kt b/app/src/main/java/com/ck/ckcollar/app/ui/dialog/CKUpdateAlertDialog.kt new file mode 100644 index 0000000..c6878ee --- /dev/null +++ b/app/src/main/java/com/ck/ckcollar/app/ui/dialog/CKUpdateAlertDialog.kt @@ -0,0 +1,62 @@ +package com.ck.ckcollar.app.ui.dialog + +import android.content.Context +import android.text.TextUtils +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import com.ck.ckcollar.app.databinding.DialogAlertBinding +import com.ck.ckcollar.app.databinding.DialogMakePhotoBinding +import com.ck.ckcollar.app.databinding.DialogUpdateAlertBinding +import com.tt.kit.dialog.TTBaseDialog +import com.tt.kit.dialog.TTBaseDialogBottom +import com.tt.kit.utils.TTUtils + +class CKUpdateAlertDialog( + var mContext: Context, + var alertText: String, + var isForce : Boolean, + var alertClickListener: AlertClickListener +) : TTBaseDialog(mContext){ + + override fun show() { + try { + var dialogAlertBinding = + DialogUpdateAlertBinding.inflate(LayoutInflater.from(mContext)) + + dialogAlertBinding.textAlert.text = alertText + if (isForce){ + dialogAlertBinding.btnCenlel.visibility = View.GONE + } + dialogAlertBinding.btnCenlel.setOnClickListener(object : View.OnClickListener { + override fun onClick(v: View?) { + cancel() + + alertClickListener.onBack(false) + } + }) + + //dialogView.findViewById(R.id.photo).setVisibility(View.GONE); + dialogAlertBinding.btnConfirm.setOnClickListener(object : View.OnClickListener { + override fun onClick(v: View?) { + // TODO Auto-generated method stub + cancel() + alertClickListener.onBack(true) + } + }) + + setContentView(dialogAlertBinding.root,ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)) + + } catch (e: Exception) { + e.printStackTrace() + } + + super.show() + setCancelable(false) + } + + + interface AlertClickListener { + fun onBack(isConfirm : Boolean) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/ck/ckcollar/app/ui/popview/CKCollarTypePopView.kt b/app/src/main/java/com/ck/ckcollar/app/ui/popview/CKCollarTypePopView.kt new file mode 100644 index 0000000..d9ce3d4 --- /dev/null +++ b/app/src/main/java/com/ck/ckcollar/app/ui/popview/CKCollarTypePopView.kt @@ -0,0 +1,88 @@ +package com.ck.ckcollar.app.ui.popview + +import android.content.Context +import android.graphics.Color +import android.graphics.drawable.ColorDrawable +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.PopupWindow +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView +import com.ck.ckcollar.app.databinding.LayoutItemCollarTypeBinding +import com.ck.ckcollar.app.databinding.PopupCollarTypeBinding +import com.ck.ckcollar.app.model.CollarTypeModel +import com.tt.kit.utils.TTUtils + + +class CKCollarTypePopView(var context: Context, var anchorView : View, var data : List, var onDismissListener : PopupWindow.OnDismissListener ) { + + + + fun show(onItemDataClickListenner : OnItemDataClickListenner) { + val popupWindow = PopupWindow() + + var popupCollarTypeBinding = PopupCollarTypeBinding.inflate(LayoutInflater.from(context)) + popupWindow.contentView = popupCollarTypeBinding.root + + popupCollarTypeBinding.recyclerView.layoutManager = LinearLayoutManager(context, RecyclerView.VERTICAL,false) + popupCollarTypeBinding.recyclerView.setHasFixedSize(true) + popupCollarTypeBinding.recyclerView.adapter = CollarTypeAdapter(context,data,object : CollarTypeAdapter.OnItemClickListenner{ + override fun onClick( + pos: Int, + model: CollarTypeModel.TypeDataModel + ) { + popupWindow.dismiss() + onItemDataClickListenner.onClick(pos,model) + } + }) + + + popupWindow.setWidth(TTUtils.dpToPx(context,120).toInt()); // 设置宽度 + popupWindow.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT); // 设置高度 + popupWindow.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT)); // 设置背景为透明 + popupWindow.setOutsideTouchable(true); + popupWindow.showAsDropDown(anchorView); + + popupWindow.setOnDismissListener(onDismissListener) + } + + + class CollarTypeAdapter(var context: Context, var data: List,var onItemClickListenner :OnItemClickListenner) : RecyclerView.Adapter() { + override fun onCreateViewHolder( + parent: ViewGroup, + viewType: Int + ): CollarTypeHolder { + return CollarTypeHolder(LayoutItemCollarTypeBinding.inflate(LayoutInflater.from(context),parent,false)) + } + + override fun onBindViewHolder( + holder: CollarTypeHolder, + position: Int + ) { + holder.binding.text.text = data.get(position).patName + 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 CollarTypeHolder(var binding: LayoutItemCollarTypeBinding) : RecyclerView.ViewHolder(binding.root){ + + } + + interface OnItemClickListenner{ + fun onClick(pos: Int, model: CollarTypeModel.TypeDataModel) + } + + } + + interface OnItemDataClickListenner{ + fun onClick(pos : Int,model : CollarTypeModel.TypeDataModel) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/ck/ckcollar/app/ui/popview/CKPowerAlertView.kt b/app/src/main/java/com/ck/ckcollar/app/ui/popview/CKPowerAlertView.kt new file mode 100644 index 0000000..79802a5 --- /dev/null +++ b/app/src/main/java/com/ck/ckcollar/app/ui/popview/CKPowerAlertView.kt @@ -0,0 +1,71 @@ +package com.ck.ckcollar.app.ui.popview + + +import android.content.Context +import android.graphics.Color +import android.graphics.drawable.ColorDrawable +import android.view.Gravity +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.PopupWindow +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView +import com.ck.ckcollar.app.databinding.LayoutItemCollarTypeBinding +import com.ck.ckcollar.app.databinding.PopupCollarTypeBinding +import com.ck.ckcollar.app.databinding.PopupPowerAlertBinding +import com.ck.ckcollar.app.model.CollarTypeModel +import com.tt.kit.utils.TTUtils + + +class CKPowerAlertView(var context: Context, var anchorView : View, var text : String, var onDismissListener : PopupWindow.OnDismissListener ) { + + + + fun show() { + val popupWindow = PopupWindow() + + var binding = PopupPowerAlertBinding.inflate(LayoutInflater.from(context)) + popupWindow.contentView = binding.root + + binding.textAlert.text = text + binding.btnClose.setOnClickListener { + popupWindow.dismiss() + } + var popupWidth = TTUtils.width - TTUtils.dpToPx(context,60).toInt() + popupWindow.setWidth(popupWidth) // 设置宽度 + popupWindow.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT); // 设置高度 + popupWindow.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT)); // 设置背景为透明 + popupWindow.setOutsideTouchable(true); + + + val location = IntArray(2) + anchorView.getLocationOnScreen(location) + val anchorX = location[0] + val anchorY = location[1] + val anchorWidth = anchorView.width + val anchorHeight = anchorView.height + + // 计算 Popup 的位置(控件的中间下方) + val offsetX = (anchorWidth - popupWidth) / 2 + val x = anchorX + offsetX + val y = anchorY + anchorHeight + + // 显示 + // popupWindow.showAtLocation(anchorView, Gravity.NO_GRAVITY, x, y) + + + // 4. 显示在控件下方(水平居中) + popupWindow.showAsDropDown(anchorView, offsetX, 0) + + + popupWindow.setOnDismissListener(onDismissListener) + } + + + + + interface OnItemDataClickListenner{ + fun onClick(pos : Int,model : CollarTypeModel) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/ck/ckcollar/app/utils/CKUtils.kt b/app/src/main/java/com/ck/ckcollar/app/utils/CKUtils.kt new file mode 100644 index 0000000..d8ccb6e --- /dev/null +++ b/app/src/main/java/com/ck/ckcollar/app/utils/CKUtils.kt @@ -0,0 +1,185 @@ +package com.ck.ckcollar.app.utils + +import android.content.Context +import android.content.Intent +import android.net.Uri +import java.io.BufferedReader +import java.io.IOException +import java.io.InputStreamReader +import java.text.SimpleDateFormat +import java.util.Date + + +object CKUtils { + + var YYYYMMDD_HHMMSS = "yyyy-MM-dd HH:mm:ss" + var YYYYMMDD_HHMM = "yyyy-MM-dd HH:mm" + var YYYYMMDD = "yyyy-MM-dd" + var YYYYMM = "yyyy-MM" + + + fun getPhone(phone: String): String { + if (phone.length < 4) { + return phone + } + var start = phone.substring(0, 4) + var end = phone.substring(phone.length - 4) + + return start + "****" + end + } + + fun getDateForYYYYMM(): String { + return SimpleDateFormat("yyyy年MM月").format(Date()) + } + + fun getDateFormat(format: String): String { + return SimpleDateFormat(format).format(Date()) + } + + fun dataToFormat(date: String?, oldFormat: String, newFormat: String): String { + try { + var d = SimpleDateFormat(oldFormat).parse(date) + + return SimpleDateFormat(newFormat).format(d) + } catch (e: Exception) { + e.printStackTrace() + } + return "" + } + + fun getPetSpecValue(text: String): Int { + try { + when (text) { + "狗" -> return 0 + "猫" -> return 1 + } + } catch (e: Exception) { + e.printStackTrace() + } + + return -1 + } + + fun getPetSpecLab(patSpec: String): String { + try { + when (patSpec.toInt()) { + 0 -> return "狗" + 1 -> return "猫" + } + } catch (e: Exception) { + e.printStackTrace() + } + + return "" + } + + fun getApplyStatusLab(patSpec: String): String { + try { + when (patSpec.toInt()) { + 0 -> return "待审核" + 1 -> return "审核通过" + 2 -> return "审核拒绝" + } + } catch (e: Exception) { + e.printStackTrace() + } + + return "" + } + + fun getJson(context: Context, fileName: String): String { + val stringBuilder = StringBuilder() + try { + val assetManager = context.getAssets() + val bf = BufferedReader( + InputStreamReader( + assetManager.open(fileName) + ) + ) + var line: String? + while ((bf.readLine().also { line = it }) != null) { + stringBuilder.append(line) + } + } catch (e: IOException) { + e.printStackTrace() + } + return stringBuilder.toString() + } + + fun getOrderStatus(status: Int): String { + when (status) { + 0 -> return "待付款" + 1 -> return "待发货" + 2 -> return "已发货" + 3 -> return "已收货" + 4 -> return "已完成" + 5 -> return "已关闭" + 6 -> return "已取消" + 7 -> return "待审核" + 8 -> return "已退款" + 9 -> return "退款中" + 10 -> return "拒绝退款" + + } + return "" + } + + fun extractImgSrc(html: String): String? { + // 正则解释: + // ]+src="([^"]+)"""", RegexOption.IGNORE_CASE) + return pattern.find(html)?.groupValues?.get(1) + } + + fun extractImgSrc2(html: String): String? { + // 正则解释: + // = 0) { + text.substring(0, index + keyword.length) + } else { + text // 没找到关键字,返回原文本 + } + return result + } + + fun callPhone(context: Context, phoneNumber: String) { + + val uri = Uri.parse("tel:${phoneNumber}") + val intent = Intent(Intent.ACTION_DIAL, uri) + context.startActivity(intent) + } + + + fun logisticsStatusText(value: String): String { + + //物流状态(0已发货 1已揽收 2运输中 3已签收 4异常 5转寄 6退回 7派送中) + when (value) { + "0" -> return "已发货" + "1" -> return "已揽收" + "2" -> return "运输中" + "3" -> return "已签收" + "4" -> return "异常" + "5" -> return "转寄" + "6" -> return "退回" + "7" -> return "派送中" + } + + return "" + } +} \ No newline at end of file diff --git a/app/src/main/java/com/ck/ckcollar/app/utils/Const.kt b/app/src/main/java/com/ck/ckcollar/app/utils/Const.kt new file mode 100644 index 0000000..68f5c6c --- /dev/null +++ b/app/src/main/java/com/ck/ckcollar/app/utils/Const.kt @@ -0,0 +1,17 @@ +package com.ck.ckcollar.app.utils + +object Const { + const val FIRST = "first" + const val PERMISSIONS_FIRST = "permissions_first" + const val AGREEMENT_CHECK = "agreement_check" + const val IMAGE_PATH ="imagePath" + const val MESSAGE ="message" + + const val USER_DATA = "user_data" + const val PET_DATA = "pet_data" + const val LOGIN_NAME = "login_name" + const val LOGIN_PWD = "login_pwd" + const val TOKEN = "token" + const val WX_APP_ID = "wx7681e74df7d88ddc" + +} \ No newline at end of file diff --git a/app/src/main/java/com/ck/ckcollar/app/utils/CoordinateUtils.kt b/app/src/main/java/com/ck/ckcollar/app/utils/CoordinateUtils.kt new file mode 100644 index 0000000..7bc343c --- /dev/null +++ b/app/src/main/java/com/ck/ckcollar/app/utils/CoordinateUtils.kt @@ -0,0 +1,46 @@ +package com.ck.ckcollar.app.utils +// Kotlin - WGS-84 转 GCJ-02 +object CoordinateUtils { + + private const val pi = 3.1415926535897932384626 + private const val a = 6378245.0 + private const val ee = 0.00669342162296594323 + + /** + * WGS-84 转 GCJ-02 + */ + fun wgs84ToGcj02(wgLat: Double, wgLon: Double): DoubleArray { + if (outOfChina(wgLat, wgLon)) { + return doubleArrayOf(wgLat, wgLon) + } + var dLat = transformLat(wgLon - 105.0, wgLat - 35.0) + var dLon = transformLon(wgLon - 105.0, wgLat - 35.0) + val radLat = wgLat / 180.0 * pi + var magic = Math.sin(radLat) + magic = 1 - ee * magic * magic + val sqrtMagic = Math.sqrt(magic) + dLat = dLat * 180.0 / ((a * (1 - ee)) / (magic * sqrtMagic) * pi) + dLon = dLon * 180.0 / (a / sqrtMagic * Math.cos(radLat) * pi) + return doubleArrayOf(wgLat + dLat, wgLon + dLon) + } + + private fun outOfChina(lat: Double, lon: Double): Boolean { + return lon < 72.004 || lon > 137.8347 || lat < 0.8293 || lat > 55.8271 + } + + private fun transformLat(x: Double, y: Double): Double { + var ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * Math.sqrt(Math.abs(x)) + ret += (20.0 * Math.sin(6.0 * x * pi) + 20.0 * Math.sin(2.0 * x * pi)) * 2.0 / 3.0 + ret += (20.0 * Math.sin(y * pi) + 40.0 * Math.sin(y / 3.0 * pi)) * 2.0 / 3.0 + ret += (160.0 * Math.sin(y / 12.0 * pi) + 320 * Math.sin(y * pi / 30.0)) * 2.0 / 3.0 + return ret + } + + private fun transformLon(x: Double, y: Double): Double { + var ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * Math.sqrt(Math.abs(x)) + ret += (20.0 * Math.sin(6.0 * x * pi) + 20.0 * Math.sin(2.0 * x * pi)) * 2.0 / 3.0 + ret += (20.0 * Math.sin(x * pi) + 40.0 * Math.sin(x / 3.0 * pi)) * 2.0 / 3.0 + ret += (150.0 * Math.sin(x / 12.0 * pi) + 300.0 * Math.sin(x / 30.0 * pi)) * 2.0 / 3.0 + return ret + } +} \ No newline at end of file diff --git a/app/src/main/java/com/ck/ckcollar/app/utils/networkone/ICallback.kt b/app/src/main/java/com/ck/ckcollar/app/utils/networkone/ICallback.kt new file mode 100644 index 0000000..112c402 --- /dev/null +++ b/app/src/main/java/com/ck/ckcollar/app/utils/networkone/ICallback.kt @@ -0,0 +1,5 @@ +package com.ck.ckcollar.app.utils.networkone +interface ICallback { + fun onSuccess(data: String) + fun onFailed(code: String, msg: String) +} diff --git a/app/src/main/java/com/ck/ckcollar/app/utils/networkone/TTHttpClient.kt b/app/src/main/java/com/ck/ckcollar/app/utils/networkone/TTHttpClient.kt new file mode 100644 index 0000000..d3d5ce5 --- /dev/null +++ b/app/src/main/java/com/ck/ckcollar/app/utils/networkone/TTHttpClient.kt @@ -0,0 +1,991 @@ +package com.ck.ckcollar.app.utils.networkone + +import android.app.Activity +import android.util.Log +import com.ck.ckcollar.app.CKApp +import com.ck.ckcollar.app.action.ActionCode +import com.ck.ckcollar.app.action.ActionCode.BASE_URL +import com.ck.ckcollar.app.utils.networkone.interceptor.RequestInterceptor +import com.ck.ckcollar.app.utils.networkone.interceptor.ResponseInterceptor +import com.ck.ckcollar.app.utils.networkone.model.TTRequestParam +import com.google.android.material.color.utilities.MaterialDynamicColors.onError +import com.google.gson.Gson +import com.tt.kit.base.TTBaseActivity +import com.tt.kit.utils.Const +import com.tt.kit.utils.TTLog +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext +import okhttp3.Call +import okhttp3.Callback +import okhttp3.FormBody +import okhttp3.MediaType.Companion.toMediaType +import okhttp3.MediaType.Companion.toMediaTypeOrNull +import okhttp3.MultipartBody +import okhttp3.OkHttpClient +import okhttp3.Request +import okhttp3.RequestBody +import okhttp3.RequestBody.Companion.toRequestBody +import okhttp3.Response +import okhttp3.sse.EventSource +import okhttp3.sse.EventSourceListener +import okhttp3.sse.EventSources.createFactory +import org.json.JSONObject +import java.io.BufferedReader +import java.io.IOException +import java.io.InputStreamReader +import java.net.HttpURLConnection +import java.net.URL +import java.util.concurrent.TimeUnit + +object TTHttpClient { + + /** + * post请求 + */ + @JvmStatic + fun post( + activity: TTBaseActivity, + actionCode: String, + params: TTRequestParam, + iCallback: ICallback + ) { + val formBody = FormBody.Builder() + for (item in params.params) { + formBody.add(item.key, item.value.toString()) + } + val requestBody = formBody.build() + TTLog.e("requestUrl=" + Gson().toJson(requestBody)) + val request = Request.Builder() + .url(BASE_URL + ActionCode.getUrl(actionCode)) + .post(requestBody) + .build() + + val okHttpClient = OkHttpClient().newBuilder() + okHttpClient.addInterceptor(RequestInterceptor(activity)) + okHttpClient.addInterceptor(ResponseInterceptor(activity)) + okHttpClient.build().newCall(request) + .enqueue(object : Callback { + override fun onFailure(call: Call, e: IOException) { + activity.runOnUiThread { + activity.hiddenProgeassDialog() + iCallback.onFailed("600", "网络连接失败,请检查网络") + } + } + + override fun onResponse(call: Call, response: Response) { + val string = response.body?.string() + string?.let { TTLog.e("response", actionCode + "====" + it) } + var model = JSONObject(string) + if (isSusscee(model)) { + activity.runOnUiThread { + activity.hiddenProgeassDialog() + iCallback.onSuccess(getData(model)) + } + } else { + activity.runOnUiThread { + activity.hiddenProgeassDialog() + iCallback.onFailed(getCode(model), getMessage(model)) + } + } + } + }) + + } + + /** + * json请求 + */ + @JvmStatic + fun postJson( + activity: TTBaseActivity, + actionCode: String, + params: TTRequestParam, + iCallback: ICallback + ) { + var jsonParam = JSONObject(); + for (item in params.params) { + jsonParam.put(item.key, item.value) + } + val requestBody = jsonParam.toString().toRequestBody(Const.JSON.toMediaType()) + val request = Request.Builder() + .url(BASE_URL + ActionCode.getUrl(actionCode)) + .post(requestBody) + .build() + TTLog.e("requestUrl=" + request.url) + TTLog.e("param=" + jsonParam.toString()) + + + val okHttpClient = OkHttpClient().newBuilder() + okHttpClient.connectTimeout(60, TimeUnit.SECONDS) + okHttpClient.writeTimeout(60, TimeUnit.SECONDS) + okHttpClient.readTimeout(60, TimeUnit.SECONDS) + okHttpClient.addInterceptor(RequestInterceptor(activity)) + okHttpClient.addInterceptor(ResponseInterceptor(activity)) + okHttpClient.build() + .newCall(request) + .enqueue(object : Callback { + override fun onFailure(call: Call, e: IOException) { + activity.runOnUiThread { + activity.hiddenProgeassDialog() + iCallback.onFailed("600", "网络连接失败,请检查网络") + } + } + + override fun onResponse(call: Call, response: Response) { + val string = response.body?.string() + string?.let { TTLog.e("response", actionCode + "====" + it) } + var model = JSONObject(string) + if (isSusscee(model)) { + activity.runOnUiThread { + activity.hiddenProgeassDialog() + iCallback.onSuccess(getData(model)) + } + } else { + activity.runOnUiThread { + activity.hiddenProgeassDialog() + iCallback.onFailed(getCode(model), getMessage(model)) + } + } + } + }) + + } + + + @JvmStatic + fun postJsonStream( + activity: TTBaseActivity, + actionCode: String, + params: TTRequestParam, + iCallback: ICallback + ) { + var jsonParam = JSONObject(); + for (item in params.params) { + jsonParam.put(item.key, item.value) + } + val requestBody = jsonParam.toString().toRequestBody(Const.JSON.toMediaType()) + + val request = Request.Builder() + .url(BASE_URL + ActionCode.getUrl(actionCode)) + .post(requestBody) + .addHeader("Accept", "text/event-stream") + .addHeader("Content-Type", "application/json") + .addHeader("Authorization", "Bearer " + CKApp.app.token) + .addHeader("X-Read-Timeout", "60") + .build() + TTLog.e("requestUrl=" + request.url) + TTLog.e("param=" + jsonParam.toString()) + + + val client = OkHttpClient() + + var okHttpClient = client.newBuilder() + okHttpClient.connectTimeout(60, TimeUnit.SECONDS) + okHttpClient.readTimeout(0, TimeUnit.MILLISECONDS) + okHttpClient.callTimeout(0, TimeUnit.MILLISECONDS) + // okHttpClient.addInterceptor(RequestInterceptor(activity)) + // okHttpClient.addInterceptor(ResponseInterceptor(activity)) + + + val factory = createFactory(client) + val eventSource = factory.newEventSource(request, object : EventSourceListener() { + + override fun onClosed(eventSource: EventSource) { + println("SSE 连接已关闭") + + } + + override fun onEvent( + eventSource: EventSource, + id: String?, + type: String?, + data: String + ) { + println("收到数据块: $data") + + if ("[DONE]".equals(data)) { + eventSource.cancel(); + } + if ("complete".equals(data)) { + eventSource.cancel(); + } + activity.runOnUiThread { + iCallback.onSuccess(data) + } + } + + override fun onFailure( + eventSource: EventSource, + t: Throwable?, + response: Response? + ) { + + println("SSE 连接异常: ${t?.message}") + + eventSource.cancel() + activity.runOnUiThread { + iCallback.onFailed("500", t.toString()) + } + } + + override fun onOpen(eventSource: EventSource, response: Response) { + println("SSE 连接已建立") + + } + }) + } + + + @JvmStatic + fun postJsonStream2( + activity: TTBaseActivity, + actionCode: String, + params: TTRequestParam, + iCallback: ICallback + ) { + var jsonParam = JSONObject(); + for (item in params.params) { + jsonParam.put(item.key, item.value) + } + val requestBody = jsonParam.toString().toRequestBody(Const.JSON.toMediaType()) + + val request = Request.Builder() + .url(BASE_URL + ActionCode.getUrl(actionCode)) + .post(requestBody) + .addHeader("Accept", "text/event-stream") + .addHeader("Content-Type", "application/json") + .addHeader("Authorization", "Bearer " + CKApp.app.token) + .addHeader("X-Read-Timeout", "60") + .build() + TTLog.e("requestUrl=" + request.url) + TTLog.e("param=" + jsonParam.toString()) + + + val client = OkHttpClient() + + var okHttpClient = client.newBuilder() + okHttpClient.connectTimeout(60, TimeUnit.SECONDS) + okHttpClient.writeTimeout(60, TimeUnit.SECONDS) + okHttpClient.readTimeout(60, TimeUnit.SECONDS) + // okHttpClient.addInterceptor(RequestInterceptor(activity)) + // okHttpClient.addInterceptor(ResponseInterceptor(activity)) + + + okHttpClient.build() + .newCall(request) + .enqueue(object : Callback { + override fun onFailure(call: Call, e: IOException) { + activity.runOnUiThread { + activity.hiddenProgeassDialog() + iCallback.onFailed("600", "网络连接失败,请检查网络") + } + } + + override fun onResponse(call: Call, response: Response) { + +// val responseBody = response.body +// if (responseBody == null) { +// return +// } +// +// val source = responseBody.source() +// +// while (!source.exhausted()) { +// val line = source.readUtf8Line() +// +// if (line == null) { +// break +// } +// +// if (line.isBlank()) { +// continue +// } +// activity.runOnUiThread { +// activity.hiddenProgeassDialog() +// iCallback.onSuccess(line) +// } +// println("收到: " + line) + + + val reader = BufferedReader( + InputStreamReader( + response.body?.byteStream(), + Charsets.UTF_8 + ) + ) + var line: String? + while (reader.readLine().also { line = it } != null) { + var data = line ?: continue + // 处理每一行 JSON 数据 + println("收到: $data") + + // 如果遇到结束标记,退出循环 + if (data == "[DONE]") break + + if (data == "event:delta") continue + + + if (data.startsWith("data:")) { + data = line.substring("data:".length).trim { it <= ' ' } + } + activity.runOnUiThread { + activity.hiddenProgeassDialog() + iCallback.onSuccess(data) + } + } + + } + + + }) + } + + + @JvmStatic + fun postJsonStream3( + activity: TTBaseActivity, + actionCode: String, + params: TTRequestParam, + iCallback: ICallback + ) { + var jsonParam = JSONObject(); + for (item in params.params) { + jsonParam.put(item.key, item.value) + } + + TTLog.e("param===" + jsonParam.toString()) + GlobalScope.launch(Dispatchers.IO) { + + try { + val connection = URL(BASE_URL + ActionCode.getUrl(actionCode)).openConnection() as HttpURLConnection + + + connection.apply { + requestMethod = "POST" + connectTimeout = 100000 + readTimeout = 100000 // 30 秒 + doOutput = true + doInput = true + setRequestProperty("Content-Type", "application/json; charset=utf-8") + setRequestProperty("Authorization", "Bearer " + CKApp.app.token) + setRequestProperty("Accept", "text/event-stream") + setRequestProperty("Cache-Control", "no-cache") + } + + // 2. 发送请求体 + connection.outputStream.use { os -> + os.write(jsonParam.toString().toByteArray(Charsets.UTF_8)) + os.flush() + } + + // 3. 检查响应状态 + val responseCode = connection.responseCode + if (responseCode != HttpURLConnection.HTTP_OK) { + val errorMsg = connection.errorStream?.bufferedReader()?.readText() + ?: "请求失败: $responseCode" + withContext(Dispatchers.Main) { + iCallback.onFailed("500", "网络连接失败,请检查网络") + } + return@launch + } + + // 4. 分块读取响应 + var isRunning = true + connection.inputStream?.bufferedReader(Charsets.UTF_8)?.use { reader -> + var line: String? = null + while (isRunning && reader.readLine().also { line = it } != null) { + val data = line ?: continue + + // 跳过空行或注释行 + if (data.isBlank() || data.startsWith(":")) continue + + // 解析 SSE 格式: "data: {...}" + val jsonData = if (data.startsWith("data:")) { + data.substring(5).trim() + } else { + data + } + + if (jsonData == "[DONE]") { + break + } + + // 提取内容 + var content : String = jsonData + if (content == "event:delta") continue + + + if (content.startsWith("data:")) { + content = content.substring("data:".length).trim { it <= ' ' } + } + if (content.isNotEmpty()) { + withContext(Dispatchers.Main) { + iCallback.onSuccess(content) + } + } + } + } + + withContext(Dispatchers.Main) { + iCallback.onFailed("500", "网络连接失败,请检查网络") + } + }catch (e: Exception){ + + } + + } + +} + +@JvmStatic +fun postJson( + activity: TTBaseActivity, + actionCode: String, + jsonParam: String, + iCallback: ICallback +) { + + val requestBody = jsonParam.toString().toRequestBody(Const.JSON.toMediaType()) + val request = Request.Builder() + .url(BASE_URL + ActionCode.getUrl(actionCode)) + .post(requestBody) + .build() + TTLog.e("requestUrl=" + request.url) + TTLog.e("param=" + jsonParam.toString()) + + + val okHttpClient = OkHttpClient().newBuilder() + okHttpClient.connectTimeout(60, TimeUnit.SECONDS) + okHttpClient.writeTimeout(60, TimeUnit.SECONDS) + okHttpClient.readTimeout(60, TimeUnit.SECONDS) + okHttpClient.addInterceptor(RequestInterceptor(activity)) + okHttpClient.addInterceptor(ResponseInterceptor(activity)) + okHttpClient.build() + .newCall(request) + .enqueue(object : Callback { + override fun onFailure(call: Call, e: IOException) { + activity.runOnUiThread { + activity.hiddenProgeassDialog() + iCallback.onFailed("600", "网络连接失败,请检查网络") + } + } + + override fun onResponse(call: Call, response: Response) { + val string = response.body?.string() + string?.let { TTLog.e("response", actionCode + "====" + it) } + var model = JSONObject(string) + if (isSusscee(model)) { + activity.runOnUiThread { + activity.hiddenProgeassDialog() + iCallback.onSuccess(getData(model)) + } + } else { + activity.runOnUiThread { + activity.hiddenProgeassDialog() + iCallback.onFailed(getCode(model), getMessage(model)) + } + } + } + }) + +} + +@JvmStatic +fun putJson( + activity: TTBaseActivity, + actionCode: String, + params: TTRequestParam, + iCallback: ICallback +) { + var jsonParam = JSONObject(); + for (item in params.params) { + jsonParam.put(item.key, item.value) + } + val requestBody = jsonParam.toString().toRequestBody(Const.JSON.toMediaType()) + val request = Request.Builder() + .url(BASE_URL + ActionCode.getUrl(actionCode)) + .put(requestBody) + .build() + TTLog.e("requestUrl=" + request.url) + TTLog.e("param=" + jsonParam.toString()) + + + val okHttpClient = OkHttpClient().newBuilder() + okHttpClient.addInterceptor(RequestInterceptor(activity)) + okHttpClient.addInterceptor(ResponseInterceptor(activity)) + okHttpClient.build().newCall(request) + .enqueue(object : Callback { + override fun onFailure(call: Call, e: IOException) { + activity.runOnUiThread { + activity.hiddenProgeassDialog() + iCallback.onFailed("600", "网络连接失败,请检查网络") + } + } + + override fun onResponse(call: Call, response: Response) { + val string = response.body?.string() + string?.let { TTLog.e("response", actionCode + "====" + it) } + var model = JSONObject(string) + if (isSusscee(model)) { + activity.runOnUiThread { + activity.hiddenProgeassDialog() + iCallback.onSuccess(getData(model)) + } + } else { + activity.runOnUiThread { + activity.hiddenProgeassDialog() + iCallback.onFailed(getCode(model), getMessage(model)) + } + } + } + }) + +} + + +/** + * post文件上传 + */ +@JvmStatic +fun postFile( + activity: Activity, + actionCode: String, + params: TTRequestParam, + iCallback: ICallback +) { + val formBody = MultipartBody.Builder() + .setType(MultipartBody.FORM) + if (params != null) { + for (item in params.params) { + formBody.addFormDataPart(item.key, item.value.toString()) + } + if (params.files != null) { + for (file in params.files) { + formBody.addFormDataPart( + "files", file.name, RequestBody.create( + "image/*".toMediaTypeOrNull(), + file + ) + ) + } + } + } + val requestBody = formBody.build() + val request = Request.Builder() + .url(BASE_URL + ActionCode.getUrl(actionCode)) + .post(requestBody) + .build() + TTLog.e("requestUrl=" + request.url) + + val okHttpClient = OkHttpClient().newBuilder() + okHttpClient.connectTimeout(60, TimeUnit.SECONDS) + okHttpClient.writeTimeout(60, TimeUnit.SECONDS) + okHttpClient.readTimeout(60, TimeUnit.SECONDS) + okHttpClient.addInterceptor(RequestInterceptor(activity)) + okHttpClient.addInterceptor(ResponseInterceptor(activity)) + okHttpClient.build().newCall(request) + .enqueue(object : Callback { + override fun onFailure(call: Call, e: IOException) { + activity.runOnUiThread { + iCallback.onFailed("600", "网络连接失败,请检查网络") + } + } + + override fun onResponse(call: Call, response: Response) { + val string = response.body?.string() + string?.let { TTLog.e("response", actionCode + "====" + it) } + var model = JSONObject(string) + if (isSusscee(model)) { + activity.runOnUiThread { + iCallback.onSuccess(getData(model)) + } + } else { + activity.runOnUiThread { + iCallback.onFailed(getCode(model), getMessage(model)) + } + } + } + }) + + +} + +/** + * get + */ +@JvmStatic +fun get( + activity: TTBaseActivity, + actionCode: String, + params: TTRequestParam, + iCallback: ICallback +) { + var url = BASE_URL + ActionCode.getUrl(actionCode) + for ((index, item) in params.params.withIndex()) { + if (index == 0) { + url = url + "?" + item.key + "=" + item.value.toString() + } else { + url = url + "&" + item.key + "=" + item.value.toString() + } + } + TTLog.e("requestUrl=" + url) + val request = Request.Builder() + .url(url) + .get() + .build() + + val okHttpClient = OkHttpClient().newBuilder() + okHttpClient.addInterceptor(RequestInterceptor(activity)) + okHttpClient.addInterceptor(ResponseInterceptor(activity)) + okHttpClient.build().newCall(request) + .enqueue(object : Callback { + override fun onFailure(call: Call, e: IOException) { + activity.runOnUiThread { + activity.hiddenProgeassDialog() + iCallback.onFailed("600", "网络连接失败,请检查网络") + } + } + + override fun onResponse(call: Call, response: Response) { + val string = response.body?.string() + string?.let { TTLog.e("response", actionCode + "====" + it) } + var model = JSONObject(string) + if (isSusscee(model)) { + activity.runOnUiThread { + activity.hiddenProgeassDialog() + iCallback.onSuccess(getData(model)) + } + } else { + activity.runOnUiThread { + activity.hiddenProgeassDialog() + iCallback.onFailed(getCode(model), getMessage(model)) + } + } + } + }) + +} + + +@JvmStatic +fun put( + activity: TTBaseActivity, + actionCode: String, + params: TTRequestParam, + iCallback: ICallback +) { + var url = BASE_URL + ActionCode.getUrl(actionCode) + for ((index, item) in params.params.withIndex()) { + if (index == 0) { + url = url + "?" + item.key + "=" + item.value.toString() + } else { + url = url + "&" + item.key + "=" + item.value.toString() + } + } + TTLog.e("requestUrl=" + url) + val requestBody = "".toString().toRequestBody(Const.JSON.toMediaType()) + + val request = Request.Builder() + .url(url) + .put(requestBody) + .build() + + val okHttpClient = OkHttpClient().newBuilder() + okHttpClient.addInterceptor(RequestInterceptor(activity)) + okHttpClient.addInterceptor(ResponseInterceptor(activity)) + okHttpClient.build().newCall(request) + .enqueue(object : Callback { + override fun onFailure(call: Call, e: IOException) { + activity.runOnUiThread { + activity.hiddenProgeassDialog() + iCallback.onFailed("600", "网络连接失败,请检查网络") + } + } + + override fun onResponse(call: Call, response: Response) { + val string = response.body?.string() + string?.let { TTLog.e("response", actionCode + "====" + it) } + var model = JSONObject(string) + if (isSusscee(model)) { + activity.runOnUiThread { + activity.hiddenProgeassDialog() + iCallback.onSuccess(getData(model)) + } + } else { + activity.runOnUiThread { + activity.hiddenProgeassDialog() + iCallback.onFailed(getCode(model), getMessage(model)) + } + } + } + }) + +} + +@JvmStatic +fun delete( + activity: TTBaseActivity, + actionCode: String, + params: TTRequestParam, + iCallback: ICallback +) { + var url = BASE_URL + ActionCode.getUrl(actionCode) + for ((index, item) in params.params.withIndex()) { + if (index == 0) { + url = url + "?" + item.key + "=" + item.value.toString() + } else { + url = url + "&" + item.key + "=" + item.value.toString() + } + } + TTLog.e("requestUrl=" + url) + val requestBody = "".toString().toRequestBody(Const.JSON.toMediaType()) + + val request = Request.Builder() + .url(url) + .delete(requestBody) + .build() + + val okHttpClient = OkHttpClient().newBuilder() + okHttpClient.addInterceptor(RequestInterceptor(activity)) + okHttpClient.addInterceptor(ResponseInterceptor(activity)) + okHttpClient.build().newCall(request) + .enqueue(object : Callback { + override fun onFailure(call: Call, e: IOException) { + activity.runOnUiThread { + activity.hiddenProgeassDialog() + iCallback.onFailed("600", "网络连接失败,请检查网络") + } + } + + override fun onResponse(call: Call, response: Response) { + val string = response.body?.string() + string?.let { TTLog.e("response", actionCode + "====" + it) } + var model = JSONObject(string) + if (isSusscee(model)) { + activity.runOnUiThread { + activity.hiddenProgeassDialog() + iCallback.onSuccess(getData(model)) + } + } else { + activity.runOnUiThread { + activity.hiddenProgeassDialog() + iCallback.onFailed(getCode(model), getMessage(model)) + } + } + } + }) + +} + + +@JvmStatic +fun put(activity: TTBaseActivity, actionCode: String, params: String, iCallback: ICallback) { + var url = BASE_URL + ActionCode.getUrl(actionCode) + "/" + params + + TTLog.e("requestUrl=" + url) + val requestBody = "".toString().toRequestBody(Const.JSON.toMediaType()) + + val request = Request.Builder() + .url(url) + .put(requestBody) + .build() + + val okHttpClient = OkHttpClient().newBuilder() + okHttpClient.addInterceptor(RequestInterceptor(activity)) + okHttpClient.addInterceptor(ResponseInterceptor(activity)) + okHttpClient.build().newCall(request) + .enqueue(object : Callback { + override fun onFailure(call: Call, e: IOException) { + activity.runOnUiThread { + activity.hiddenProgeassDialog() + iCallback.onFailed("600", "网络连接失败,请检查网络") + } + } + + override fun onResponse(call: Call, response: Response) { + val string = response.body?.string() + string?.let { TTLog.e("response", actionCode + "====" + it) } + var model = JSONObject(string) + if (isSusscee(model)) { + activity.runOnUiThread { + activity.hiddenProgeassDialog() + iCallback.onSuccess(getData(model)) + } + } else { + activity.runOnUiThread { + activity.hiddenProgeassDialog() + iCallback.onFailed(getCode(model), getMessage(model)) + } + } + } + }) + +} + +@JvmStatic +fun post(activity: TTBaseActivity, actionCode: String, params: String, iCallback: ICallback) { + var url = BASE_URL + ActionCode.getUrl(actionCode) + "/" + params + + TTLog.e("requestUrl=" + url) + val requestBody = "".toString().toRequestBody(Const.JSON.toMediaType()) + + val request = Request.Builder() + .url(url) + .post(requestBody) + .build() + + val okHttpClient = OkHttpClient().newBuilder() + okHttpClient.addInterceptor(RequestInterceptor(activity)) + okHttpClient.addInterceptor(ResponseInterceptor(activity)) + okHttpClient.build().newCall(request) + .enqueue(object : Callback { + override fun onFailure(call: Call, e: IOException) { + activity.runOnUiThread { + activity.hiddenProgeassDialog() + iCallback.onFailed("600", "网络连接失败,请检查网络") + } + } + + override fun onResponse(call: Call, response: Response) { + val string = response.body?.string() + string?.let { TTLog.e("response", actionCode + "====" + it) } + var model = JSONObject(string) + if (isSusscee(model)) { + activity.runOnUiThread { + activity.hiddenProgeassDialog() + iCallback.onSuccess(getData(model)) + } + } else { + activity.runOnUiThread { + activity.hiddenProgeassDialog() + iCallback.onFailed(getCode(model), getMessage(model)) + } + } + } + }) + +} + + +fun get(activity: TTBaseActivity, actionCode: String, params: String, iCallback: ICallback) { + var url = BASE_URL + ActionCode.getUrl(actionCode) + "/" + params + + TTLog.e("requestUrl=" + url) + val request = Request.Builder() + .url(url) + .get() + .build() + + val okHttpClient = OkHttpClient().newBuilder() + okHttpClient.addInterceptor(RequestInterceptor(activity)) + okHttpClient.addInterceptor(ResponseInterceptor(activity)) + okHttpClient.build().newCall(request) + .enqueue(object : Callback { + override fun onFailure(call: Call, e: IOException) { + activity.runOnUiThread { + activity.hiddenProgeassDialog() + iCallback.onFailed("600", "网络连接失败,请检查网络") + } + } + + override fun onResponse(call: Call, response: Response) { + val string = response.body?.string() + string?.let { TTLog.e("response", actionCode + "====" + it) } + var model = JSONObject(string) + if (isSusscee(model)) { + activity.runOnUiThread { + activity.hiddenProgeassDialog() + iCallback.onSuccess(getData(model)) + } + } else { + activity.runOnUiThread { + activity.hiddenProgeassDialog() + iCallback.onFailed(getCode(model), getMessage(model)) + } + } + } + }) + +} + +@JvmStatic +fun delete(activity: TTBaseActivity, actionCode: String, params: String, iCallback: ICallback) { + var url = BASE_URL + ActionCode.getUrl(actionCode) + "/" + params + + TTLog.e("requestUrl=" + url) + val request = Request.Builder() + .url(url) + .delete() + .build() + + val okHttpClient = OkHttpClient().newBuilder() + okHttpClient.addInterceptor(RequestInterceptor(activity)) + okHttpClient.addInterceptor(ResponseInterceptor(activity)) + okHttpClient.build().newCall(request) + .enqueue(object : Callback { + override fun onFailure(call: Call, e: IOException) { + activity.runOnUiThread { + activity.hiddenProgeassDialog() + iCallback.onFailed("600", "网络连接失败,请检查网络") + } + } + + override fun onResponse(call: Call, response: Response) { + val string = response.body?.string() + string?.let { TTLog.e("response", actionCode + "====" + it) } + var model = JSONObject(string) + if (isSusscee(model)) { + activity.runOnUiThread { + activity.hiddenProgeassDialog() + iCallback.onSuccess(getData(model)) + } + } else { + activity.runOnUiThread { + activity.hiddenProgeassDialog() + iCallback.onFailed(getCode(model), getMessage(model)) + } + } + } + }) + +} + +private fun isSusscee(data: JSONObject): Boolean { + try { + return data.get("code") == 200 + } catch (e: Exception) { + return false + } +} + +private fun getData(data: JSONObject): String { + try { + if (data.has("rows")) { + return data.get("rows").toString() + } + return data.get("data").toString() + + } catch (e: Exception) { + e.printStackTrace() + } + return "{}" +} + +private fun getCode(data: JSONObject): String { + try { + return data.get("code").toString() + } catch (e: Exception) { + return "" + } +} + +private fun getMessage(data: JSONObject): String { + try { + return data.get("msg").toString() + } catch (e: Exception) { + return "" + } +} +} \ No newline at end of file diff --git a/app/src/main/java/com/ck/ckcollar/app/utils/networkone/interceptor/RequestInterceptor.kt b/app/src/main/java/com/ck/ckcollar/app/utils/networkone/interceptor/RequestInterceptor.kt new file mode 100644 index 0000000..7aa7aea --- /dev/null +++ b/app/src/main/java/com/ck/ckcollar/app/utils/networkone/interceptor/RequestInterceptor.kt @@ -0,0 +1,70 @@ +package com.ck.ckcollar.app.utils.networkone.interceptor + +import android.content.Context +import com.ck.ckcollar.app.CKApp +import com.tt.kit.utils.TTLog +import okhttp3.FormBody +import okhttp3.Interceptor +import okhttp3.MultipartBody +import okhttp3.Response +import java.nio.Buffer +import java.nio.charset.Charset +import java.util.TreeMap +class RequestInterceptor(val content : Context) : Interceptor{ + + private val TAG : String = "RequestInterceptor" + override fun intercept(chain: Interceptor.Chain): Response { + val request = chain.request() + val requestBuilder = request.newBuilder() + val httpUrl = request.url.newBuilder().build() + // 请求头map + var headerMap: Map = HashMap() + try { + when (request.method.toString()) { + "GET" -> { +// // 解析url传递参数 +// val paramKeys = httpUrl.queryParameterNames +// // TreeMap 默认元素迭代升序 +// val map = TreeMap() +// for (key: String in paramKeys) { +// map[key] = httpUrl.queryParameter(key).toString() +// } + // 制作带签名的请求头map + // headerMap = RequestHeader.makeRequestHeaderMap(map, httpUrl) + } + "POST" -> { + // TreeMap 默认元素迭代升序 + // 解析body传递参数 +// when (val body = request.body) { +// is FormBody -> { +// for (i in 0 until body.size) { +// map[body.encodedName(i)] = body.encodedValue(i) +// } +// val map = TreeMap() +// } +// is MultipartBody -> { +// //TODO +// } +// else -> { +// //TODO +// } +// } + // 制作带签名的请求头map + // headerMap = RequestHeader.makeRequestHeaderMap(map, httpUrl) + } + } + }catch (e : Exception){ + + } + + requestBuilder.addHeader("Authorization", "Bearer " + CKApp.app.token) + + TTLog.e(CKApp.app.token) + // 添加请求头map 到请求头 +// for (item in headerMap) { +// requestBuilder.addHeader(item.key, item.value) +// } + return chain.proceed(requestBuilder.build()) + + } +} \ No newline at end of file diff --git a/app/src/main/java/com/ck/ckcollar/app/utils/networkone/interceptor/ResponseInterceptor.kt b/app/src/main/java/com/ck/ckcollar/app/utils/networkone/interceptor/ResponseInterceptor.kt new file mode 100644 index 0000000..bb64d0d --- /dev/null +++ b/app/src/main/java/com/ck/ckcollar/app/utils/networkone/interceptor/ResponseInterceptor.kt @@ -0,0 +1,52 @@ +package com.ck.ckcollar.app.utils.networkone.interceptor + +import android.content.Context +import android.content.Intent +import com.ck.ckcollar.app.ui.act.login.LoginActivity +import com.google.gson.Gson +import com.tt.kit.networktwo.model.TTResposeData +import com.tt.kit.utils.TTLog +import okhttp3.Interceptor +import okhttp3.Response +import okhttp3.ResponseBody +import okhttp3.ResponseBody.Companion.toResponseBody + +class ResponseInterceptor(val context : Context) : Interceptor{ + + override fun intercept(chain: Interceptor.Chain): Response { + val response = chain.proceed(chain.request()) + if (response.body != null) { + var body: String? = response.body!!.string() + try { + val model = Gson().fromJson(body, TTResposeData::class.java) + TTLog.i("ResponseInterceptor", "intercept model:" + body) + // token失效,统一处理 + if (model.code == 401){ + var intent = Intent(context, LoginActivity::class.java) + intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK + context.startActivity(intent) + + val res = TTResposeData() + res.code = 500 + res.msg = "认证失败,请重新登录" + body = Gson().toJson(res) + val responseBody = body.toResponseBody(null)// ResponseBody.create(null, body!!) + return response.newBuilder().body(responseBody).build() + } + + } catch (e: Exception) { + TTLog.i("ResponseInterceptor", "intercept body: $body") + // body数据异常时,重新构建ResultData + val res = TTResposeData() + res.code = 500 + res.msg = "服务器异常,数据解析异常!" + body = Gson().toJson(res) + } + val responseBody = body!!.toResponseBody(null)// ResponseBody.create(null, body!!) + return response.newBuilder().body(responseBody).build() + } else { + return response + } + + } +} \ No newline at end of file diff --git a/app/src/main/java/com/ck/ckcollar/app/utils/networkone/model/TTRequestData.kt b/app/src/main/java/com/ck/ckcollar/app/utils/networkone/model/TTRequestData.kt new file mode 100644 index 0000000..0413099 --- /dev/null +++ b/app/src/main/java/com/ck/ckcollar/app/utils/networkone/model/TTRequestData.kt @@ -0,0 +1,7 @@ +package com.ck.ckcollar.app.utils.networkone.model + +class TTRequestData( + var key: String, + var value: Any +) { +} \ No newline at end of file diff --git a/app/src/main/java/com/ck/ckcollar/app/utils/networkone/model/TTRequestParam.kt b/app/src/main/java/com/ck/ckcollar/app/utils/networkone/model/TTRequestParam.kt new file mode 100644 index 0000000..f695f4b --- /dev/null +++ b/app/src/main/java/com/ck/ckcollar/app/utils/networkone/model/TTRequestParam.kt @@ -0,0 +1,14 @@ +package com.ck.ckcollar.app.utils.networkone.model +import java.io.File + +class TTRequestParam { + var params : MutableList = mutableListOf() + var files : MutableList = mutableListOf() + fun add(data : TTRequestData){ + params.add(data) + } + + fun addFile(file: File){ + files.add(file) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/ck/ckcollar/app/utils/networkone/model/TTResposeData.kt b/app/src/main/java/com/ck/ckcollar/app/utils/networkone/model/TTResposeData.kt new file mode 100644 index 0000000..b7ec24d --- /dev/null +++ b/app/src/main/java/com/ck/ckcollar/app/utils/networkone/model/TTResposeData.kt @@ -0,0 +1,19 @@ +package com.ck.ckcollar.app.utils.networkone.model + +class TTResposeData{ + var code : Int = 0 + var message : String = "" + var result : T? = null + + fun isList() : Boolean{ + + if (result is List<*>){ + return true + } + return false + } + + inline fun isTList(): Boolean { + return R::class.java == List::class.java + } +} \ No newline at end of file diff --git a/app/src/main/java/com/ck/ckcollar/app/utils/websocket/MyWebSocketClient.kt b/app/src/main/java/com/ck/ckcollar/app/utils/websocket/MyWebSocketClient.kt new file mode 100644 index 0000000..fce637a --- /dev/null +++ b/app/src/main/java/com/ck/ckcollar/app/utils/websocket/MyWebSocketClient.kt @@ -0,0 +1,28 @@ +package com.ck.ckcollar.app.utils.websocket + +import android.util.Log +import org.java_websocket.client.WebSocketClient +import org.java_websocket.handshake.ServerHandshake +import java.lang.Exception +import java.net.URI + +open class MyWebSocketClient(serverUri: URI?) : WebSocketClient(serverUri) { + + val TAG = "MyWebSocketClient" + + override fun onOpen(handshakedata: ServerHandshake?) { + Log.e(TAG, "onOpen handshakedata=$handshakedata") + } + + override fun onMessage(message: String?) { + Log.e(TAG, "onMessage message=$message") + } + + override fun onClose(code: Int, reason: String?, remote: Boolean) { + Log.e(TAG, "onClose code=$code reason=$reason remote=$remote") + } + + override fun onError(ex: Exception?) { + Log.e(TAG, "onError ex=$ex") + } +} diff --git a/app/src/main/java/com/ck/ckcollar/app/widget/CKButton.kt b/app/src/main/java/com/ck/ckcollar/app/widget/CKButton.kt new file mode 100644 index 0000000..5b19e66 --- /dev/null +++ b/app/src/main/java/com/ck/ckcollar/app/widget/CKButton.kt @@ -0,0 +1,52 @@ +package com.ck.ckcollar.app.widget + +import android.content.Context +import android.graphics.Typeface +import android.util.AttributeSet +import android.util.TypedValue +import android.view.Gravity +import androidx.appcompat.widget.AppCompatButton +import androidx.appcompat.widget.AppCompatTextView +import androidx.core.content.res.ResourcesCompat +import com.ck.ckcollar.app.R + +class CKButton : AppCompatTextView{ + + val tag = ""//"skin:buttonTextColor:textColor" + + constructor(context: Context) : super(context){ + if (getTag() == null){ + setTag(tag) + } + initView() + } + + constructor(context: Context, attrs: AttributeSet?) : super(context, attrs){ + if (getTag() == null){ + setTag(tag) + } + initView() + } + + constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr){ + if (getTag() == null){ + setTag(tag) + } + initView() + } + + fun initView(){ + //setTextColor(getColor(R.attr.buttonTextColor)) + val currentStyle = Typeface.BOLD + val typeface = ResourcesCompat.getFont(this.context, R.font.pingfangscmedium) + this.typeface = Typeface.create(typeface,currentStyle) + + this.gravity = Gravity.CENTER + } + + fun getColor(attrResId: Int): Int { + val typedValue = TypedValue() + context.getTheme().resolveAttribute(attrResId, typedValue, true) + return typedValue.data + } +} diff --git a/app/src/main/java/com/ck/ckcollar/app/widget/CKButtonRotate.kt b/app/src/main/java/com/ck/ckcollar/app/widget/CKButtonRotate.kt new file mode 100644 index 0000000..7a27b8f --- /dev/null +++ b/app/src/main/java/com/ck/ckcollar/app/widget/CKButtonRotate.kt @@ -0,0 +1,33 @@ +package com.ck.ckcollar.app.widget + +import android.animation.ObjectAnimator +import android.content.Context +import android.util.AttributeSet +import androidx.appcompat.widget.AppCompatImageView + +/** + * 箭头按钮指示器,用于 + */ +class CKButtonRotate(context: Context, attrs: AttributeSet?) : AppCompatImageView(context, attrs) { + private val mIsExpand = false + + /** + * 向上旋转 + */ + fun rotateUpwards() { + setImageArrowAnimator(180f, 0f) + } + + /** + * 向下旋转 + */ + fun rotateDownward() { + setImageArrowAnimator(0f, 180f) + } + + private fun setImageArrowAnimator(start: Float, end: Float) { + val animator = ObjectAnimator.ofFloat(this, "rotation", start, end) + animator.setDuration(300) // 设置动画时长为1秒 + animator.start() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/ck/ckcollar/app/widget/CKCountDownButton.kt b/app/src/main/java/com/ck/ckcollar/app/widget/CKCountDownButton.kt new file mode 100644 index 0000000..f59bbd0 --- /dev/null +++ b/app/src/main/java/com/ck/ckcollar/app/widget/CKCountDownButton.kt @@ -0,0 +1,78 @@ +package com.ck.ckcollar.app.widget + +import android.content.Context +import android.os.Handler +import android.os.Looper +import android.os.Message +import android.util.AttributeSet +import android.util.TypedValue +import android.view.View +import androidx.appcompat.widget.AppCompatButton +import com.ck.ckcollar.app.R + +class CKCountDownButton : AppCompatButton, View.OnClickListener{ + + val tag = "skin:buttonTextColor:textColor" + + var time = 3 + var onCountDownListenner : OnCountDownListenner? = null + constructor(context: Context) : super(context){ + if (getTag() == null){ + setTag(tag) + } + //initView() + } + + constructor(context: Context, attrs: AttributeSet?) : super(context, attrs){ + if (getTag() == null){ + setTag(tag) + } + //initView() + } + + constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr){ + if (getTag() == null){ + setTag(tag) + } + // initView() + } + + fun initView(){ + setOnClickListener { this } + } + + override fun onClick(v: View?) { + onCountDownListenner?.onClick() + } + + + var handle = object : Handler(Looper.getMainLooper()){ + override fun handleMessage(msg: Message) { + time -- + if (time == 0){ + onCountDownListenner?.onClick() + }else{ + setText(String.format(context.resources.getString(R.string.go_to_main),time.toString())) + sendEmptyMessageDelayed(0,1000) + } + } + } + fun startCountDown(){ + setText(String.format(context.resources.getString(R.string.go_to_main),time.toString())) + handle.sendEmptyMessageDelayed(0,1000) + } + fun stopCountDown(){ + handle.removeMessages(0) + } + + fun getColor(attrResId: Int): Int { + val typedValue = TypedValue() + context.getTheme().resolveAttribute(attrResId, typedValue, true) + return typedValue.data + } + + interface OnCountDownListenner{ + fun onClick() + } + +} diff --git a/app/src/main/java/com/ck/ckcollar/app/widget/CKEditView.kt b/app/src/main/java/com/ck/ckcollar/app/widget/CKEditView.kt new file mode 100644 index 0000000..224e5f7 --- /dev/null +++ b/app/src/main/java/com/ck/ckcollar/app/widget/CKEditView.kt @@ -0,0 +1,100 @@ +package com.ck.ckcollar.app.widget + +import android.content.Context +import android.graphics.Typeface +import android.text.InputFilter +import android.text.Spanned +import android.text.TextUtils +import android.util.AttributeSet +import androidx.appcompat.widget.AppCompatEditText +import androidx.appcompat.widget.AppCompatTextView +import androidx.core.content.res.ResourcesCompat +import com.ck.ckcollar.app.R + +class CKEditView : AppCompatEditText { + + val tag = "skin:textColor:textColor" + + constructor(context: Context) : super(context){ + if (getTag(com.zhy.changeskin.R.id.skin_tag_id) == null){ + setTag(tag) + } + setHintTextColor(context.resources.getColor(R.color.textSecondColor,context.theme)) + init() + } + + constructor(context: Context, attrs: AttributeSet?) : super(context, attrs){ + if (getTag(com.zhy.changeskin.R.id.skin_tag_id) == null){ + setTag(tag) + } + init() + } + + constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr){ + if (getTag(com.zhy.changeskin.R.id.skin_tag_id) == null){ + setTag(tag) + } + init() + } + fun init(){ + val currentStyle = this.typeface?.style ?: Typeface.NORMAL + val typeface = ResourcesCompat.getFont(this.context, R.font.pingfangscmedium) + this.typeface = Typeface.create(typeface,currentStyle) + } + fun isEmpty() : Boolean{ + return TextUtils.isEmpty(text.toString().trim()) + } + + + // Kotlin 版本 + class DecimalDigitsInputFilter(private val decimalDigits: Int = 2) : InputFilter { + + override fun filter( + source: CharSequence, + start: Int, + end: Int, + dest: Spanned, + dstart: Int, + dend: Int + ): CharSequence? { + + // 允许删除操作 + if (source.isEmpty()) { + return null + } + + // 构建完整的输入字符串 + val fullString = StringBuilder(dest) + fullString.replace(dstart, dend, source.subSequence(start, end).toString()) + + // 正则表达式:整数部分不限长度,小数部分限制位数 + val pattern = if (decimalDigits > 0) { + Regex("^\\d*\\.?\\d{0,$decimalDigits}$") + } else { + Regex("^\\d*\\.?\\d*$") + } + + return if (pattern.matches(fullString)) { + null // 输入有效,允许 + } else { + "" // 输入无效,拒绝 + } + } + } + + class AlphanumericInputFilter : InputFilter { + override fun filter( + source: CharSequence, + start: Int, + end: Int, + dest: Spanned, + dstart: Int, + dend: Int + ): CharSequence? { + // 只允许字母(包括大小写)和数字 + val pattern = Regex("[^A-Za-z0-9]") + // 如果输入中有非法字符,全部替换为空字符串 + return source.replace(pattern, "") + } + } +} diff --git a/app/src/main/java/com/ck/ckcollar/app/widget/CKFrameLayout.kt b/app/src/main/java/com/ck/ckcollar/app/widget/CKFrameLayout.kt new file mode 100644 index 0000000..16032f3 --- /dev/null +++ b/app/src/main/java/com/ck/ckcollar/app/widget/CKFrameLayout.kt @@ -0,0 +1,15 @@ +package com.ck.ckcollar.app.widget + +import android.content.Context +import android.util.AttributeSet +import android.widget.FrameLayout +import android.widget.RelativeLayout + +class CKFrameLayout : FrameLayout { + + constructor(context: Context) : super(context) + + constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) + + constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) +} diff --git a/app/src/main/java/com/ck/ckcollar/app/widget/CKImageView.kt b/app/src/main/java/com/ck/ckcollar/app/widget/CKImageView.kt new file mode 100644 index 0000000..4b6e803 --- /dev/null +++ b/app/src/main/java/com/ck/ckcollar/app/widget/CKImageView.kt @@ -0,0 +1,15 @@ +package com.ck.ckcollar.app.widget + +import android.content.Context +import android.util.AttributeSet +import androidx.appcompat.widget.AppCompatImageView + +class CKImageView : AppCompatImageView { + + + constructor(context: Context) : super(context) + + constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) + + constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) +} diff --git a/app/src/main/java/com/ck/ckcollar/app/widget/CKLinearLayout.kt b/app/src/main/java/com/ck/ckcollar/app/widget/CKLinearLayout.kt new file mode 100644 index 0000000..bf856d3 --- /dev/null +++ b/app/src/main/java/com/ck/ckcollar/app/widget/CKLinearLayout.kt @@ -0,0 +1,15 @@ +package com.ck.ckcollar.app.widget + +import android.content.Context +import android.util.AttributeSet +import android.widget.LinearLayout +import androidx.appcompat.widget.AppCompatEditText + +class CKLinearLayout : LinearLayout { + + constructor(context: Context) : super(context) + + constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) + + constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) +} diff --git a/app/src/main/java/com/ck/ckcollar/app/widget/CKNoSwipeViewPager.kt b/app/src/main/java/com/ck/ckcollar/app/widget/CKNoSwipeViewPager.kt new file mode 100644 index 0000000..ee4f5fd --- /dev/null +++ b/app/src/main/java/com/ck/ckcollar/app/widget/CKNoSwipeViewPager.kt @@ -0,0 +1,31 @@ +package com.ck.ckcollar.app.widget + +import android.content.Context +import android.util.AttributeSet +import android.view.MotionEvent +import androidx.viewpager.widget.ViewPager + +class CKNoSwipeViewPager(context: Context, attrs: AttributeSet? = null) : ViewPager(context, attrs) { + + private var isPagingEnabled = true + + override fun onTouchEvent(ev: MotionEvent?): Boolean { + return if (isPagingEnabled) { + super.onTouchEvent(ev) + } else { + false // 不消费触摸事件,禁止滑动 + } + } + + override fun onInterceptTouchEvent(ev: MotionEvent?): Boolean { + return if (isPagingEnabled) { + super.onInterceptTouchEvent(ev) + } else { + false // 不拦截触摸事件 + } + } + + fun setPagingEnabled(enabled: Boolean) { + isPagingEnabled = enabled + } +} \ No newline at end of file diff --git a/app/src/main/java/com/ck/ckcollar/app/widget/CKPassView.kt b/app/src/main/java/com/ck/ckcollar/app/widget/CKPassView.kt new file mode 100644 index 0000000..f0f5602 --- /dev/null +++ b/app/src/main/java/com/ck/ckcollar/app/widget/CKPassView.kt @@ -0,0 +1,111 @@ +package com.ck.ckcollar.app.widget + +import android.content.Context +import android.text.Editable +import android.text.TextWatcher +import android.util.AttributeSet +import android.view.LayoutInflater +import android.view.View +import android.widget.ImageView +import android.widget.LinearLayout +import android.widget.TextView +import androidx.appcompat.widget.AppCompatTextView +import com.ck.ckcollar.app.R +import com.ck.ckcollar.app.listenner.OnPasswordInputFinish + + +class PassView : LinearLayout, View.OnClickListener { + private lateinit var tvList: Array + private lateinit var tv: Array + private var iv_del: ImageView? = null + private var view: View? = null + var strPassword: String? = null //��������� + private set + private var currentIndex = -1 //���ڼ�¼��ǰ���������λ�� + + constructor(context: Context) : super(context){ + initView() + + } + + constructor(context: Context, attrs: AttributeSet?) : super(context, attrs){ + initView() + } + + constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr){ + initView() + } + + fun initView(){ + view = LayoutInflater.from(context).inflate( R.layout.item_paypassword, null) + tvList = arrayOfNulls(6) + tvList[0] = view!!.findViewById(R.id.pay_box1) as TextView? + tvList[1] = view!!.findViewById(R.id.pay_box2) as TextView? + tvList[2] = view!!.findViewById(R.id.pay_box3) as TextView? + tvList[3] = view!!.findViewById(R.id.pay_box4) as TextView? + tvList[4] = view!!.findViewById(R.id.pay_box5) as TextView? + tvList[5] = view!!.findViewById(R.id.pay_box6) as TextView? + tv = arrayOfNulls(10) + tv[0] = view!!.findViewById(R.id.pay_keyboard_zero) as TextView? + tv[1] = view!!.findViewById(R.id.pay_keyboard_one) as TextView? + tv[2] = view!!.findViewById(R.id.pay_keyboard_two) as TextView? + tv[3] = view!!.findViewById(R.id.pay_keyboard_three) as TextView? + tv[4] = view!!.findViewById(R.id.pay_keyboard_four) as TextView? + tv[5] = view!!.findViewById(R.id.pay_keyboard_five) as TextView? + tv[6] = view!!.findViewById(R.id.pay_keyboard_sex) as TextView? + tv[7] = view!!.findViewById(R.id.pay_keyboard_seven) as TextView? + tv[8] = view!!.findViewById(R.id.pay_keyboard_eight) as TextView? + tv[9] = view!!.findViewById(R.id.pay_keyboard_nine) as TextView? + iv_del = view!!.findViewById(R.id.pay_keyboard_del) as ImageView + for (i in 0..9) { + tv[i]!!.setOnClickListener(this) + } + iv_del!!.setOnClickListener(this) + addView(view) + } + //���ü����������ڵ�6λ������ɺ󴥷� + fun setOnFinishInput(pass: OnPasswordInputFinish) { + tvList[5]!!.addTextChangedListener(object : TextWatcher { + override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) { + } + + override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { + } + + override fun afterTextChanged(s: Editable) { + if (s.toString().length == 1) { + strPassword = + "" //ÿ�δ�����Ҫ�Ƚ�strPassword�ÿգ������»�ȡ��������������ɾ����������ɻ��� + for (i in 0..5) { + strPassword += tvList[i]!!.getText().toString().trim { it <= ' ' } + } + pass.inputFinish() //�ӿ���Ҫʵ�ֵķ������������������ɺ����Ӧ�߼� + } + } + }) + } + + public override fun onClick(v: View) { + when (v.getId()) { + R.id.pay_keyboard_one -> getPass("1") + R.id.pay_keyboard_two -> getPass("2") + R.id.pay_keyboard_three -> getPass("3") + R.id.pay_keyboard_four -> getPass("4") + R.id.pay_keyboard_five -> getPass("5") + R.id.pay_keyboard_sex -> getPass("6") + R.id.pay_keyboard_seven -> getPass("7") + R.id.pay_keyboard_eight -> getPass("8") + R.id.pay_keyboard_nine -> getPass("9") + R.id.pay_keyboard_zero -> getPass("0") + R.id.pay_keyboard_del -> if (currentIndex - 1 >= -1) { //�ж��Ƿ�ɾ����ϡ�������ҪС������Խ�� + tvList[currentIndex--]!!.setText("") + } + } + } + + fun getPass(str: String?) { + if (currentIndex >= -1 && currentIndex < 5) { + tvList[++currentIndex]!!.setText(str) + } + } +} diff --git a/app/src/main/java/com/ck/ckcollar/app/widget/CKRelativeLayout.kt b/app/src/main/java/com/ck/ckcollar/app/widget/CKRelativeLayout.kt new file mode 100644 index 0000000..35b9481 --- /dev/null +++ b/app/src/main/java/com/ck/ckcollar/app/widget/CKRelativeLayout.kt @@ -0,0 +1,17 @@ +package com.ck.ckcollar.app.widget + +import android.content.Context +import android.util.AttributeSet +import android.widget.FrameLayout +import android.widget.RelativeLayout + +class CKRelativeLayout : RelativeLayout { + + val tag = "skin:" + + constructor(context: Context) : super(context) + + constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) + + constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) +} diff --git a/app/src/main/java/com/ck/ckcollar/app/widget/CKRoundImageView.kt b/app/src/main/java/com/ck/ckcollar/app/widget/CKRoundImageView.kt new file mode 100644 index 0000000..c897012 --- /dev/null +++ b/app/src/main/java/com/ck/ckcollar/app/widget/CKRoundImageView.kt @@ -0,0 +1,140 @@ +package com.ck.ckcollar.app.widget + +import android.content.Context +import android.graphics.Canvas +import android.graphics.Color +import android.graphics.Paint +import android.graphics.Path +import android.graphics.RectF +import android.util.AttributeSet +import androidx.appcompat.widget.AppCompatImageView +import com.ck.ckcollar.app.R + +class CKRoundImageView @JvmOverloads constructor( + context: Context, + attrs: AttributeSet? = null, + defStyleAttr: Int = 0 +) : AppCompatImageView(context, attrs, defStyleAttr) { + + private val paint = Paint(Paint.ANTI_ALIAS_FLAG) + private val path = Path() + private val bounds = RectF() + + private var topLeftRadius = 0f + private var topRightRadius = 0f + private var bottomLeftRadius = 0f + private var bottomRightRadius = 0f + private var isCircle = false + + private var borderPaint: Paint? = null + private var borderWidth = 0f + private var borderColor = Color.TRANSPARENT + + init { + context.obtainStyledAttributes(attrs, R.styleable.RoundImageView).apply { + val roundRadius = getDimension(R.styleable.RoundImageView_roundRadius, 0f) + topLeftRadius = getDimension(R.styleable.RoundImageView_topLeftRadius, roundRadius) + topRightRadius = getDimension(R.styleable.RoundImageView_topRightRadius, roundRadius) + bottomLeftRadius = getDimension(R.styleable.RoundImageView_bottomLeftRadius, roundRadius) + bottomRightRadius = getDimension(R.styleable.RoundImageView_bottomRightRadius, roundRadius) + + isCircle = getBoolean(R.styleable.RoundImageView_isCircle, false) + + borderWidth = getDimension(R.styleable.RoundImageView_borderWidth, 0f) + borderColor = getColor(R.styleable.RoundImageView_borderColor, Color.TRANSPARENT) + + recycle() + } + + if (borderWidth > 0) { + borderPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply { + style = Paint.Style.STROKE + strokeWidth = borderWidth + color = borderColor + } + } + + scaleType = ScaleType.CENTER_CROP + } + + override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) { + super.onSizeChanged(w, h, oldw, oldh) + updatePath() + } + + private fun updatePath() { + path.reset() + + if (isCircle) { + val cx = width / 2f + val cy = height / 2f + val radius = Math.min(width, height) / 2f - borderWidth / 2f + path.addCircle(cx, cy, radius, Path.Direction.CW) + } else { + bounds.set(0f, 0f, width.toFloat(), height.toFloat()) + if (borderWidth > 0) { + bounds.inset(borderWidth / 2f, borderWidth / 2f) + } + + val radii = floatArrayOf( + topLeftRadius, topLeftRadius, + topRightRadius, topRightRadius, + bottomRightRadius, bottomRightRadius, + bottomLeftRadius, bottomLeftRadius + ) + path.addRoundRect(bounds, radii, Path.Direction.CW) + } + } + + override fun onDraw(canvas: Canvas) { + canvas.save() + canvas.clipPath(path) + super.onDraw(canvas) + canvas.restore() + + borderPaint?.let { canvas.drawPath(path, it) } + } + + // 公开方法 + fun setRoundRadius(radius: Float) { + this.topLeftRadius = radius + this.topRightRadius = radius + this.bottomLeftRadius = radius + this.bottomRightRadius = radius + updatePath() + invalidate() + } + + fun setRadius(topLeft: Float, topRight: Float, bottomLeft: Float, bottomRight: Float) { + this.topLeftRadius = topLeft + this.topRightRadius = topRight + this.bottomLeftRadius = bottomLeft + this.bottomRightRadius = bottomRight + updatePath() + invalidate() + } + + fun setCircle(circle: Boolean) { + this.isCircle = circle + updatePath() + invalidate() + } + + fun setBorder(width: Float, color: Int) { + this.borderWidth = width + this.borderColor = color + + borderPaint = if (width > 0) { + Paint(Paint.ANTI_ALIAS_FLAG).apply { + style = Paint.Style.STROKE + strokeWidth = width + this.color = color + } + } else { + null + } + + updatePath() + invalidate() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/ck/ckcollar/app/widget/CKSendCodeButton.kt b/app/src/main/java/com/ck/ckcollar/app/widget/CKSendCodeButton.kt new file mode 100644 index 0000000..6c4837a --- /dev/null +++ b/app/src/main/java/com/ck/ckcollar/app/widget/CKSendCodeButton.kt @@ -0,0 +1,75 @@ +package com.ck.ckcollar.app.widget + +import android.content.Context +import android.graphics.Typeface +import android.os.Handler +import android.os.Looper +import android.os.Message +import android.util.AttributeSet +import android.util.TypedValue +import androidx.appcompat.widget.AppCompatButton +import androidx.core.content.res.ResourcesCompat +import com.ck.ckcollar.app.R + +class CKSendCodeButton : AppCompatButton{ + + val tag = "skin:buttonTextColor:textColor" + + var time = 60 + constructor(context: Context) : super(context){ + if (getTag() == null){ + setTag(tag) + } + initView() + } + + constructor(context: Context, attrs: AttributeSet?) : super(context, attrs){ + if (getTag() == null){ + setTag(tag) + } + initView() + } + + constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr){ + if (getTag() == null){ + setTag(tag) + } + initView() + } + + fun initView(){ + val currentStyle = this.typeface?.style ?: Typeface.NORMAL + val typeface = ResourcesCompat.getFont(this.context, R.font.pingfangscmedium) + this.typeface = Typeface.create(typeface,currentStyle) + } + + var handle = object : Handler(Looper.getMainLooper()){ + override fun handleMessage(msg: Message) { + time -- + if (time == 0){ + isEnabled = true + setText(context.resources.getString(R.string.send_code)) + }else{ + setText(String.format(context.resources.getString(R.string.time),time.toString())) + sendEmptyMessageDelayed(0,1000) + } + } + } + fun startCountDown(){ + time = 60 + this.isEnabled = false; + setText(String.format(context.resources.getString(R.string.time),time.toString())) + handle.sendEmptyMessageDelayed(0,1000) + } + fun stopCountDown(){ + handle.removeMessages(0) + } + + fun getColor(attrResId: Int): Int { + val typedValue = TypedValue() + context.getTheme().resolveAttribute(attrResId, typedValue, true) + return typedValue.data + } + + +} diff --git a/app/src/main/java/com/ck/ckcollar/app/widget/CKTextView.kt b/app/src/main/java/com/ck/ckcollar/app/widget/CKTextView.kt new file mode 100644 index 0000000..cc51204 --- /dev/null +++ b/app/src/main/java/com/ck/ckcollar/app/widget/CKTextView.kt @@ -0,0 +1,50 @@ +package com.ck.ckcollar.app.widget + +import android.content.Context +import android.graphics.Typeface +import android.text.TextUtils +import android.util.AttributeSet +import androidx.appcompat.widget.AppCompatEditText +import androidx.appcompat.widget.AppCompatTextView +import androidx.core.content.res.ResourcesCompat +import com.ck.ckcollar.app.R +import com.tt.kit.utils.AttrHelper +class CKTextView : AppCompatTextView{ + + val tag = "skin:textColor:textColor" + + constructor(context: Context) : super(context){ + if (getTag() == null){ + setTag(tag) + } + init() + } + + constructor(context: Context, attrs: AttributeSet?) : super(context, attrs){ + if (getTag() == null){ + setTag(tag) + } + init() + } + + constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr){ + if (getTag() == null){ + setTag(tag) + } + init() + } + + fun init(){ + // setTextColor(AttrHelper(context).getColor(R.attr.appTextColor)) + + val currentStyle = this.typeface?.style ?: Typeface.NORMAL + val typeface = ResourcesCompat.getFont(this.context, R.font.pingfangscmedium) + this.typeface = Typeface.create(typeface,currentStyle) + + } + + fun isEmpty() : Boolean{ + return TextUtils.isEmpty(text) + } + +} diff --git a/app/src/main/java/com/ck/ckcollar/app/widget/CKTextViewSecond.kt b/app/src/main/java/com/ck/ckcollar/app/widget/CKTextViewSecond.kt new file mode 100644 index 0000000..0058886 --- /dev/null +++ b/app/src/main/java/com/ck/ckcollar/app/widget/CKTextViewSecond.kt @@ -0,0 +1,30 @@ +package com.ck.ckcollar.app.widget + +import android.content.Context +import android.util.AttributeSet +import androidx.appcompat.widget.AppCompatEditText +import androidx.appcompat.widget.AppCompatTextView +import com.zhy.changeskin.R + +class CKTextViewSecond : AppCompatTextView{ + + val tag = "skin:textColor:textSecondColor" + constructor(context: Context) : super(context){ + if (getTag() == null){ + setTag(tag) + } + } + + constructor(context: Context, attrs: AttributeSet?) : super(context, attrs){ + if (getTag() == null){ + setTag(tag) + } + } + + constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr){ + if (getTag() == null){ + setTag(tag) + } + } + +} diff --git a/app/src/main/java/com/ck/ckcollar/app/widget/CKViewPager.kt b/app/src/main/java/com/ck/ckcollar/app/widget/CKViewPager.kt new file mode 100644 index 0000000..4f770ba --- /dev/null +++ b/app/src/main/java/com/ck/ckcollar/app/widget/CKViewPager.kt @@ -0,0 +1,26 @@ +package com.ck.ckcollar.app.widget + +import android.content.Context +import android.util.AttributeSet +import android.view.MotionEvent +import androidx.appcompat.widget.AppCompatImageView +import androidx.viewpager.widget.ViewPager + +class CKViewPager : ViewPager{ + + + constructor(context: Context) : super(context) + + constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) + + + override fun onInterceptTouchEvent(ev: MotionEvent?): Boolean { + try { + return super.onInterceptTouchEvent(ev) + + }catch (e : Exception){ + e.printStackTrace() + } + return false + } +} \ No newline at end of file diff --git a/app/src/main/java/com/ck/ckcollar/app/wxapi/WXEntryActivity.kt b/app/src/main/java/com/ck/ckcollar/app/wxapi/WXEntryActivity.kt new file mode 100644 index 0000000..92f5272 --- /dev/null +++ b/app/src/main/java/com/ck/ckcollar/app/wxapi/WXEntryActivity.kt @@ -0,0 +1,62 @@ +package com.ck.ckcollar.app.wxapi + +import android.app.Activity +import android.content.Intent +import android.os.Bundle +import com.ck.ckcollar.app.CKApp +import com.ck.ckcollar.app.ui.act.login.LoginActivity +import com.ck.ckcollar.app.ui.act.user.UserInfoActivity +import com.ck.ckcollar.app.utils.Const +import com.tencent.mm.opensdk.constants.ConstantsAPI +import com.tencent.mm.opensdk.modelbase.BaseReq +import com.tencent.mm.opensdk.modelbase.BaseResp +import com.tencent.mm.opensdk.modelmsg.SendAuth +import com.tencent.mm.opensdk.openapi.IWXAPI +import com.tencent.mm.opensdk.openapi.IWXAPIEventHandler +import com.tencent.mm.opensdk.openapi.WXAPIFactory +import com.tt.kit.utils.TTLog + + +class WXEntryActivity : Activity(), IWXAPIEventHandler { + lateinit var api: IWXAPI + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + api = WXAPIFactory.createWXAPI(this, Const.WX_APP_ID, false); + + try { + val intent = getIntent() + api.handleIntent(intent, this) + } catch (e: Exception) { + e.printStackTrace() + } + } + + override fun onNewIntent(intent: Intent?) { + super.onNewIntent(intent) + + setIntent(intent) + api.handleIntent(intent, this) + } + + override fun onReq(req: BaseReq?) { + + } + + override fun onResp(resp: BaseResp?) { + if (resp!!.getType() === ConstantsAPI.COMMAND_SENDAUTH) { + val authResp = resp as SendAuth.Resp + val code = authResp.code + TTLog.e("code====" + code) + var intent = Intent() + if (CKApp.app.wxJump == 0) { + intent.setClass(this, LoginActivity::class.java) + } else if (CKApp.app.wxJump == 1) { + intent.setClass(this, UserInfoActivity::class.java) + } + intent.putExtra("code", code) + startActivity(intent) + finish() + } + finish() + } +} \ No newline at end of file diff --git a/app/src/main/res/color/bottom_nav_ico_selector_color.xml b/app/src/main/res/color/bottom_nav_ico_selector_color.xml new file mode 100644 index 0000000..dc035e9 --- /dev/null +++ b/app/src/main/res/color/bottom_nav_ico_selector_color.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/app/src/main/res/color/bottom_nav_selector_color.xml b/app/src/main/res/color/bottom_nav_selector_color.xml new file mode 100644 index 0000000..8b91a76 --- /dev/null +++ b/app/src/main/res/color/bottom_nav_selector_color.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/app/src/main/res/drawable/bg_address_tag.xml b/app/src/main/res/drawable/bg_address_tag.xml new file mode 100644 index 0000000..21e1a9a --- /dev/null +++ b/app/src/main/res/drawable/bg_address_tag.xml @@ -0,0 +1,8 @@ + + + + + + diff --git a/app/src/main/res/drawable/bg_after_sales_step_normal.xml b/app/src/main/res/drawable/bg_after_sales_step_normal.xml new file mode 100644 index 0000000..82f2b9e --- /dev/null +++ b/app/src/main/res/drawable/bg_after_sales_step_normal.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_after_sales_step_select.xml b/app/src/main/res/drawable/bg_after_sales_step_select.xml new file mode 100644 index 0000000..13daf65 --- /dev/null +++ b/app/src/main/res/drawable/bg_after_sales_step_select.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_back_home_button.xml b/app/src/main/res/drawable/bg_back_home_button.xml new file mode 100644 index 0000000..14eb9d9 --- /dev/null +++ b/app/src/main/res/drawable/bg_back_home_button.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/bg_bannar.xml b/app/src/main/res/drawable/bg_bannar.xml new file mode 100644 index 0000000..6ebbe11 --- /dev/null +++ b/app/src/main/res/drawable/bg_bannar.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/res/drawable/bg_bound_button.xml b/app/src/main/res/drawable/bg_bound_button.xml new file mode 100644 index 0000000..4b7fd2e --- /dev/null +++ b/app/src/main/res/drawable/bg_bound_button.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/bg_card_age.xml b/app/src/main/res/drawable/bg_card_age.xml new file mode 100644 index 0000000..9d99c49 --- /dev/null +++ b/app/src/main/res/drawable/bg_card_age.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/res/drawable/bg_card_body_type.xml b/app/src/main/res/drawable/bg_card_body_type.xml new file mode 100644 index 0000000..6bb2ea7 --- /dev/null +++ b/app/src/main/res/drawable/bg_card_body_type.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/res/drawable/bg_card_breed.xml b/app/src/main/res/drawable/bg_card_breed.xml new file mode 100644 index 0000000..fc3f67d --- /dev/null +++ b/app/src/main/res/drawable/bg_card_breed.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/res/drawable/bg_card_color.xml b/app/src/main/res/drawable/bg_card_color.xml new file mode 100644 index 0000000..29b2421 --- /dev/null +++ b/app/src/main/res/drawable/bg_card_color.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/res/drawable/bg_card_height.xml b/app/src/main/res/drawable/bg_card_height.xml new file mode 100644 index 0000000..ec00bea --- /dev/null +++ b/app/src/main/res/drawable/bg_card_height.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/res/drawable/bg_card_name.xml b/app/src/main/res/drawable/bg_card_name.xml new file mode 100644 index 0000000..456ded0 --- /dev/null +++ b/app/src/main/res/drawable/bg_card_name.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/res/drawable/bg_card_species.xml b/app/src/main/res/drawable/bg_card_species.xml new file mode 100644 index 0000000..5a1b8ba --- /dev/null +++ b/app/src/main/res/drawable/bg_card_species.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/res/drawable/bg_card_vaccination.xml b/app/src/main/res/drawable/bg_card_vaccination.xml new file mode 100644 index 0000000..91e4a56 --- /dev/null +++ b/app/src/main/res/drawable/bg_card_vaccination.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/res/drawable/bg_card_weight.xml b/app/src/main/res/drawable/bg_card_weight.xml new file mode 100644 index 0000000..bbe0fdc --- /dev/null +++ b/app/src/main/res/drawable/bg_card_weight.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/res/drawable/bg_cz_button.xml b/app/src/main/res/drawable/bg_cz_button.xml new file mode 100644 index 0000000..a883be2 --- /dev/null +++ b/app/src/main/res/drawable/bg_cz_button.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/bg_delete_button.xml b/app/src/main/res/drawable/bg_delete_button.xml new file mode 100644 index 0000000..8256aca --- /dev/null +++ b/app/src/main/res/drawable/bg_delete_button.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/bg_express_step.xml b/app/src/main/res/drawable/bg_express_step.xml new file mode 100644 index 0000000..6988102 --- /dev/null +++ b/app/src/main/res/drawable/bg_express_step.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_health_item1.xml b/app/src/main/res/drawable/bg_health_item1.xml new file mode 100644 index 0000000..c87349b --- /dev/null +++ b/app/src/main/res/drawable/bg_health_item1.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/res/drawable/bg_home_item2.xml b/app/src/main/res/drawable/bg_home_item2.xml new file mode 100644 index 0000000..14ab71a --- /dev/null +++ b/app/src/main/res/drawable/bg_home_item2.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/res/drawable/bg_home_item6.xml b/app/src/main/res/drawable/bg_home_item6.xml new file mode 100644 index 0000000..3666447 --- /dev/null +++ b/app/src/main/res/drawable/bg_home_item6.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/res/drawable/bg_home_item7.xml b/app/src/main/res/drawable/bg_home_item7.xml new file mode 100644 index 0000000..0056c50 --- /dev/null +++ b/app/src/main/res/drawable/bg_home_item7.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/res/drawable/bg_input_message.xml b/app/src/main/res/drawable/bg_input_message.xml new file mode 100644 index 0000000..9d9b257 --- /dev/null +++ b/app/src/main/res/drawable/bg_input_message.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/res/drawable/bg_item_member.xml b/app/src/main/res/drawable/bg_item_member.xml new file mode 100644 index 0000000..194c99f --- /dev/null +++ b/app/src/main/res/drawable/bg_item_member.xml @@ -0,0 +1,9 @@ + + + + + diff --git a/app/src/main/res/drawable/bg_item_member_normal.xml b/app/src/main/res/drawable/bg_item_member_normal.xml new file mode 100644 index 0000000..46f798e --- /dev/null +++ b/app/src/main/res/drawable/bg_item_member_normal.xml @@ -0,0 +1,8 @@ + + + + + diff --git a/app/src/main/res/drawable/bg_item_member_radius_16.xml b/app/src/main/res/drawable/bg_item_member_radius_16.xml new file mode 100644 index 0000000..ee17c8c --- /dev/null +++ b/app/src/main/res/drawable/bg_item_member_radius_16.xml @@ -0,0 +1,15 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_keyboard_key.xml b/app/src/main/res/drawable/bg_keyboard_key.xml new file mode 100644 index 0000000..f032a10 --- /dev/null +++ b/app/src/main/res/drawable/bg_keyboard_key.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/bg_login_button.xml b/app/src/main/res/drawable/bg_login_button.xml new file mode 100644 index 0000000..0584f91 --- /dev/null +++ b/app/src/main/res/drawable/bg_login_button.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/bg_login_input.xml b/app/src/main/res/drawable/bg_login_input.xml new file mode 100644 index 0000000..e64801c --- /dev/null +++ b/app/src/main/res/drawable/bg_login_input.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/res/drawable/bg_member_open_button.xml b/app/src/main/res/drawable/bg_member_open_button.xml new file mode 100644 index 0000000..bdde2c4 --- /dev/null +++ b/app/src/main/res/drawable/bg_member_open_button.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/bg_member_title.xml b/app/src/main/res/drawable/bg_member_title.xml new file mode 100644 index 0000000..e17981d --- /dev/null +++ b/app/src/main/res/drawable/bg_member_title.xml @@ -0,0 +1,18 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_message_from.xml b/app/src/main/res/drawable/bg_message_from.xml new file mode 100644 index 0000000..06947fd --- /dev/null +++ b/app/src/main/res/drawable/bg_message_from.xml @@ -0,0 +1,11 @@ + + + + + diff --git a/app/src/main/res/drawable/bg_message_to.xml b/app/src/main/res/drawable/bg_message_to.xml new file mode 100644 index 0000000..06947fd --- /dev/null +++ b/app/src/main/res/drawable/bg_message_to.xml @@ -0,0 +1,11 @@ + + + + + diff --git a/app/src/main/res/drawable/bg_no_reason.xml b/app/src/main/res/drawable/bg_no_reason.xml new file mode 100644 index 0000000..864d8b8 --- /dev/null +++ b/app/src/main/res/drawable/bg_no_reason.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/bg_number.xml b/app/src/main/res/drawable/bg_number.xml new file mode 100644 index 0000000..7e675ee --- /dev/null +++ b/app/src/main/res/drawable/bg_number.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_open_button.xml b/app/src/main/res/drawable/bg_open_button.xml new file mode 100644 index 0000000..1e07b13 --- /dev/null +++ b/app/src/main/res/drawable/bg_open_button.xml @@ -0,0 +1,15 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_out_login_button.xml b/app/src/main/res/drawable/bg_out_login_button.xml new file mode 100644 index 0000000..c062bbe --- /dev/null +++ b/app/src/main/res/drawable/bg_out_login_button.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/bg_password.xml b/app/src/main/res/drawable/bg_password.xml new file mode 100644 index 0000000..87e0d65 --- /dev/null +++ b/app/src/main/res/drawable/bg_password.xml @@ -0,0 +1,9 @@ + + + + + + diff --git a/app/src/main/res/drawable/bg_points_date.xml b/app/src/main/res/drawable/bg_points_date.xml new file mode 100644 index 0000000..fd621ba --- /dev/null +++ b/app/src/main/res/drawable/bg_points_date.xml @@ -0,0 +1,18 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_product.xml b/app/src/main/res/drawable/bg_product.xml new file mode 100644 index 0000000..d383c8b --- /dev/null +++ b/app/src/main/res/drawable/bg_product.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/bg_product_tag.xml b/app/src/main/res/drawable/bg_product_tag.xml new file mode 100644 index 0000000..e785658 --- /dev/null +++ b/app/src/main/res/drawable/bg_product_tag.xml @@ -0,0 +1,10 @@ + + + + + + diff --git a/app/src/main/res/drawable/bg_red.xml b/app/src/main/res/drawable/bg_red.xml new file mode 100644 index 0000000..90279ce --- /dev/null +++ b/app/src/main/res/drawable/bg_red.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_scan_button.xml b/app/src/main/res/drawable/bg_scan_button.xml new file mode 100644 index 0000000..13bdf5b --- /dev/null +++ b/app/src/main/res/drawable/bg_scan_button.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/bg_send_code_button_enable.xml b/app/src/main/res/drawable/bg_send_code_button_enable.xml new file mode 100644 index 0000000..8ac5ede --- /dev/null +++ b/app/src/main/res/drawable/bg_send_code_button_enable.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/bg_send_code_button_unenable.xml b/app/src/main/res/drawable/bg_send_code_button_unenable.xml new file mode 100644 index 0000000..b02fd30 --- /dev/null +++ b/app/src/main/res/drawable/bg_send_code_button_unenable.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/res/drawable/bg_step.xml b/app/src/main/res/drawable/bg_step.xml new file mode 100644 index 0000000..2133574 --- /dev/null +++ b/app/src/main/res/drawable/bg_step.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_step_3.xml b/app/src/main/res/drawable/bg_step_3.xml new file mode 100644 index 0000000..82f2b9e --- /dev/null +++ b/app/src/main/res/drawable/bg_step_3.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_tag_normal.xml b/app/src/main/res/drawable/bg_tag_normal.xml new file mode 100644 index 0000000..fcd655a --- /dev/null +++ b/app/src/main/res/drawable/bg_tag_normal.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/res/drawable/bg_tag_select.xml b/app/src/main/res/drawable/bg_tag_select.xml new file mode 100644 index 0000000..3d7b2a4 --- /dev/null +++ b/app/src/main/res/drawable/bg_tag_select.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/res/drawable/bg_tag_select2.xml b/app/src/main/res/drawable/bg_tag_select2.xml new file mode 100644 index 0000000..cf0f2d5 --- /dev/null +++ b/app/src/main/res/drawable/bg_tag_select2.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/res/drawable/bg_top_balance.xml b/app/src/main/res/drawable/bg_top_balance.xml new file mode 100644 index 0000000..21950f9 --- /dev/null +++ b/app/src/main/res/drawable/bg_top_balance.xml @@ -0,0 +1,18 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_top_open_member.xml b/app/src/main/res/drawable/bg_top_open_member.xml new file mode 100644 index 0000000..cee0aff --- /dev/null +++ b/app/src/main/res/drawable/bg_top_open_member.xml @@ -0,0 +1,14 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_top_points.xml b/app/src/main/res/drawable/bg_top_points.xml new file mode 100644 index 0000000..2e8e7f6 --- /dev/null +++ b/app/src/main/res/drawable/bg_top_points.xml @@ -0,0 +1,18 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_view_black_radius_16.xml b/app/src/main/res/drawable/bg_view_black_radius_16.xml new file mode 100644 index 0000000..17b533f --- /dev/null +++ b/app/src/main/res/drawable/bg_view_black_radius_16.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/res/drawable/bg_view_black_radius_16_stroke_1.xml b/app/src/main/res/drawable/bg_view_black_radius_16_stroke_1.xml new file mode 100644 index 0000000..f9298a1 --- /dev/null +++ b/app/src/main/res/drawable/bg_view_black_radius_16_stroke_1.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/res/drawable/bg_view_gray_radius_12.xml b/app/src/main/res/drawable/bg_view_gray_radius_12.xml new file mode 100644 index 0000000..2b4247d --- /dev/null +++ b/app/src/main/res/drawable/bg_view_gray_radius_12.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/res/drawable/bg_view_gray_radius_12_stroke_1.xml b/app/src/main/res/drawable/bg_view_gray_radius_12_stroke_1.xml new file mode 100644 index 0000000..b3c8e54 --- /dev/null +++ b/app/src/main/res/drawable/bg_view_gray_radius_12_stroke_1.xml @@ -0,0 +1,9 @@ + + + + + + diff --git a/app/src/main/res/drawable/bg_view_gray_radius_16.xml b/app/src/main/res/drawable/bg_view_gray_radius_16.xml new file mode 100644 index 0000000..255f3de --- /dev/null +++ b/app/src/main/res/drawable/bg_view_gray_radius_16.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/res/drawable/bg_view_gray_radius_16_2.xml b/app/src/main/res/drawable/bg_view_gray_radius_16_2.xml new file mode 100644 index 0000000..b7ca045 --- /dev/null +++ b/app/src/main/res/drawable/bg_view_gray_radius_16_2.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/res/drawable/bg_view_gray_radius_8.xml b/app/src/main/res/drawable/bg_view_gray_radius_8.xml new file mode 100644 index 0000000..a678933 --- /dev/null +++ b/app/src/main/res/drawable/bg_view_gray_radius_8.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/res/drawable/bg_view_postion_button.xml b/app/src/main/res/drawable/bg_view_postion_button.xml new file mode 100644 index 0000000..f709b41 --- /dev/null +++ b/app/src/main/res/drawable/bg_view_postion_button.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/bg_view_top_gray_radius_16.xml b/app/src/main/res/drawable/bg_view_top_gray_radius_16.xml new file mode 100644 index 0000000..9991eed --- /dev/null +++ b/app/src/main/res/drawable/bg_view_top_gray_radius_16.xml @@ -0,0 +1,9 @@ + + + + + diff --git a/app/src/main/res/drawable/bg_view_top_white_radius_16.xml b/app/src/main/res/drawable/bg_view_top_white_radius_16.xml new file mode 100644 index 0000000..e0fef53 --- /dev/null +++ b/app/src/main/res/drawable/bg_view_top_white_radius_16.xml @@ -0,0 +1,9 @@ + + + + + diff --git a/app/src/main/res/drawable/bg_view_view_radius_8_stroke_1.xml b/app/src/main/res/drawable/bg_view_view_radius_8_stroke_1.xml new file mode 100644 index 0000000..5482eb3 --- /dev/null +++ b/app/src/main/res/drawable/bg_view_view_radius_8_stroke_1.xml @@ -0,0 +1,9 @@ + + + + + + diff --git a/app/src/main/res/drawable/bg_view_white_radius_12.xml b/app/src/main/res/drawable/bg_view_white_radius_12.xml new file mode 100644 index 0000000..5243140 --- /dev/null +++ b/app/src/main/res/drawable/bg_view_white_radius_12.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/res/drawable/bg_view_white_radius_12_stroke_1.xml b/app/src/main/res/drawable/bg_view_white_radius_12_stroke_1.xml new file mode 100644 index 0000000..fb701a1 --- /dev/null +++ b/app/src/main/res/drawable/bg_view_white_radius_12_stroke_1.xml @@ -0,0 +1,9 @@ + + + + + + diff --git a/app/src/main/res/drawable/bg_view_white_radius_16.xml b/app/src/main/res/drawable/bg_view_white_radius_16.xml new file mode 100644 index 0000000..0056c50 --- /dev/null +++ b/app/src/main/res/drawable/bg_view_white_radius_16.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/res/drawable/bg_view_white_radius_4.xml b/app/src/main/res/drawable/bg_view_white_radius_4.xml new file mode 100644 index 0000000..35f4685 --- /dev/null +++ b/app/src/main/res/drawable/bg_view_white_radius_4.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/res/drawable/bg_view_white_radius_4_stroke_1.xml b/app/src/main/res/drawable/bg_view_white_radius_4_stroke_1.xml new file mode 100644 index 0000000..09f6aff --- /dev/null +++ b/app/src/main/res/drawable/bg_view_white_radius_4_stroke_1.xml @@ -0,0 +1,9 @@ + + + + + + diff --git a/app/src/main/res/drawable/bg_view_white_radius_8.xml b/app/src/main/res/drawable/bg_view_white_radius_8.xml new file mode 100644 index 0000000..9cf9a8d --- /dev/null +++ b/app/src/main/res/drawable/bg_view_white_radius_8.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/res/drawable/bg_view_white_radius_8_stroke_1.xml b/app/src/main/res/drawable/bg_view_white_radius_8_stroke_1.xml new file mode 100644 index 0000000..4e31a00 --- /dev/null +++ b/app/src/main/res/drawable/bg_view_white_radius_8_stroke_1.xml @@ -0,0 +1,9 @@ + + + + + + diff --git a/app/src/main/res/drawable/bg_view_yellow_radius_32.xml b/app/src/main/res/drawable/bg_view_yellow_radius_32.xml new file mode 100644 index 0000000..a89a3b4 --- /dev/null +++ b/app/src/main/res/drawable/bg_view_yellow_radius_32.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/res/drawable/bg_view_yellow_radius_4.xml b/app/src/main/res/drawable/bg_view_yellow_radius_4.xml new file mode 100644 index 0000000..750625d --- /dev/null +++ b/app/src/main/res/drawable/bg_view_yellow_radius_4.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/res/drawable/bg_welcome_button.xml b/app/src/main/res/drawable/bg_welcome_button.xml new file mode 100644 index 0000000..3c525ae --- /dev/null +++ b/app/src/main/res/drawable/bg_welcome_button.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/bg_welcome_next_button.xml b/app/src/main/res/drawable/bg_welcome_next_button.xml new file mode 100644 index 0000000..6890d9a --- /dev/null +++ b/app/src/main/res/drawable/bg_welcome_next_button.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/res/drawable/bg_welcome_point_narmal.xml b/app/src/main/res/drawable/bg_welcome_point_narmal.xml new file mode 100644 index 0000000..5dd8556 --- /dev/null +++ b/app/src/main/res/drawable/bg_welcome_point_narmal.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/res/drawable/bg_welcome_point_select.xml b/app/src/main/res/drawable/bg_welcome_point_select.xml new file mode 100644 index 0000000..e80d87b --- /dev/null +++ b/app/src/main/res/drawable/bg_welcome_point_select.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/res/drawable/ic_add.xml b/app/src/main/res/drawable/ic_add.xml new file mode 100644 index 0000000..4c1b0a8 --- /dev/null +++ b/app/src/main/res/drawable/ic_add.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 0000000..07d5da9 --- /dev/null +++ b/app/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_launcher_foreground.xml b/app/src/main/res/drawable/ic_launcher_foreground.xml new file mode 100644 index 0000000..2b068d1 --- /dev/null +++ b/app/src/main/res/drawable/ic_launcher_foreground.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/font/pingfangscmedium.otf b/app/src/main/res/font/pingfangscmedium.otf new file mode 100644 index 0000000..f40327f Binary files /dev/null and b/app/src/main/res/font/pingfangscmedium.otf differ diff --git a/app/src/main/res/layout/action_bar.xml b/app/src/main/res/layout/action_bar.xml new file mode 100644 index 0000000..77fd486 --- /dev/null +++ b/app/src/main/res/layout/action_bar.xml @@ -0,0 +1,65 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_account_cancellation.xml b/app/src/main/res/layout/activity_account_cancellation.xml new file mode 100644 index 0000000..2e43e3f --- /dev/null +++ b/app/src/main/res/layout/activity_account_cancellation.xml @@ -0,0 +1,205 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_add_address.xml b/app/src/main/res/layout/activity_add_address.xml new file mode 100644 index 0000000..c054629 --- /dev/null +++ b/app/src/main/res/layout/activity_add_address.xml @@ -0,0 +1,251 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_add_pet.xml b/app/src/main/res/layout/activity_add_pet.xml new file mode 100644 index 0000000..6ce03cf --- /dev/null +++ b/app/src/main/res/layout/activity_add_pet.xml @@ -0,0 +1,479 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_address.xml b/app/src/main/res/layout/activity_address.xml new file mode 100644 index 0000000..3a5060d --- /dev/null +++ b/app/src/main/res/layout/activity_address.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_after_sales.xml b/app/src/main/res/layout/activity_after_sales.xml new file mode 100644 index 0000000..a0016ce --- /dev/null +++ b/app/src/main/res/layout/activity_after_sales.xml @@ -0,0 +1,308 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_after_sales_progress.xml b/app/src/main/res/layout/activity_after_sales_progress.xml new file mode 100644 index 0000000..09db47b --- /dev/null +++ b/app/src/main/res/layout/activity_after_sales_progress.xml @@ -0,0 +1,507 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_agreement.xml b/app/src/main/res/layout/activity_agreement.xml new file mode 100644 index 0000000..ec05bb2 --- /dev/null +++ b/app/src/main/res/layout/activity_agreement.xml @@ -0,0 +1,26 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_balance.xml b/app/src/main/res/layout/activity_balance.xml new file mode 100644 index 0000000..70f7834 --- /dev/null +++ b/app/src/main/res/layout/activity_balance.xml @@ -0,0 +1,201 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_bluetooth.xml b/app/src/main/res/layout/activity_bluetooth.xml new file mode 100644 index 0000000..231a299 --- /dev/null +++ b/app/src/main/res/layout/activity_bluetooth.xml @@ -0,0 +1,20 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_bound_success.xml b/app/src/main/res/layout/activity_bound_success.xml new file mode 100644 index 0000000..43bb6bc --- /dev/null +++ b/app/src/main/res/layout/activity_bound_success.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_customer.xml b/app/src/main/res/layout/activity_customer.xml new file mode 100644 index 0000000..acd16ca --- /dev/null +++ b/app/src/main/res/layout/activity_customer.xml @@ -0,0 +1,128 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_demo.xml b/app/src/main/res/layout/activity_demo.xml new file mode 100644 index 0000000..dc42de9 --- /dev/null +++ b/app/src/main/res/layout/activity_demo.xml @@ -0,0 +1,83 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_deposit.xml b/app/src/main/res/layout/activity_deposit.xml new file mode 100644 index 0000000..574b90a --- /dev/null +++ b/app/src/main/res/layout/activity_deposit.xml @@ -0,0 +1,87 @@ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_edit_password.xml b/app/src/main/res/layout/activity_edit_password.xml new file mode 100644 index 0000000..8d2a5e2 --- /dev/null +++ b/app/src/main/res/layout/activity_edit_password.xml @@ -0,0 +1,108 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_edit_pay_password.xml b/app/src/main/res/layout/activity_edit_pay_password.xml new file mode 100644 index 0000000..fda3bee --- /dev/null +++ b/app/src/main/res/layout/activity_edit_pay_password.xml @@ -0,0 +1,107 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_feed_back.xml b/app/src/main/res/layout/activity_feed_back.xml new file mode 100644 index 0000000..47c1cb4 --- /dev/null +++ b/app/src/main/res/layout/activity_feed_back.xml @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_find_password.xml b/app/src/main/res/layout/activity_find_password.xml new file mode 100644 index 0000000..514569e --- /dev/null +++ b/app/src/main/res/layout/activity_find_password.xml @@ -0,0 +1,142 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_find_pay_password.xml b/app/src/main/res/layout/activity_find_pay_password.xml new file mode 100644 index 0000000..2b589c2 --- /dev/null +++ b/app/src/main/res/layout/activity_find_pay_password.xml @@ -0,0 +1,143 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_image_view.xml b/app/src/main/res/layout/activity_image_view.xml new file mode 100644 index 0000000..4a6088f --- /dev/null +++ b/app/src/main/res/layout/activity_image_view.xml @@ -0,0 +1,23 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_income_record_details.xml b/app/src/main/res/layout/activity_income_record_details.xml new file mode 100644 index 0000000..6fe8797 --- /dev/null +++ b/app/src/main/res/layout/activity_income_record_details.xml @@ -0,0 +1,178 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_index.xml b/app/src/main/res/layout/activity_index.xml new file mode 100644 index 0000000..6945258 --- /dev/null +++ b/app/src/main/res/layout/activity_index.xml @@ -0,0 +1,31 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_input_logistics_num.xml b/app/src/main/res/layout/activity_input_logistics_num.xml new file mode 100644 index 0000000..bf8b4cb --- /dev/null +++ b/app/src/main/res/layout/activity_input_logistics_num.xml @@ -0,0 +1,163 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_invite_code.xml b/app/src/main/res/layout/activity_invite_code.xml new file mode 100644 index 0000000..3b11201 --- /dev/null +++ b/app/src/main/res/layout/activity_invite_code.xml @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml new file mode 100644 index 0000000..6f313f4 --- /dev/null +++ b/app/src/main/res/layout/activity_login.xml @@ -0,0 +1,234 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_logistics_info.xml b/app/src/main/res/layout/activity_logistics_info.xml new file mode 100644 index 0000000..617c7e8 --- /dev/null +++ b/app/src/main/res/layout/activity_logistics_info.xml @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_lost.xml b/app/src/main/res/layout/activity_lost.xml new file mode 100644 index 0000000..bb14945 --- /dev/null +++ b/app/src/main/res/layout/activity_lost.xml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..ba60dd4 --- /dev/null +++ b/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,148 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_map_location.xml b/app/src/main/res/layout/activity_map_location.xml new file mode 100644 index 0000000..4121099 --- /dev/null +++ b/app/src/main/res/layout/activity_map_location.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_member.xml b/app/src/main/res/layout/activity_member.xml new file mode 100644 index 0000000..dac5559 --- /dev/null +++ b/app/src/main/res/layout/activity_member.xml @@ -0,0 +1,272 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_message_center.xml b/app/src/main/res/layout/activity_message_center.xml new file mode 100644 index 0000000..a005f7c --- /dev/null +++ b/app/src/main/res/layout/activity_message_center.xml @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_message_details.xml b/app/src/main/res/layout/activity_message_details.xml new file mode 100644 index 0000000..2db077e --- /dev/null +++ b/app/src/main/res/layout/activity_message_details.xml @@ -0,0 +1,26 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_modify_address.xml b/app/src/main/res/layout/activity_modify_address.xml new file mode 100644 index 0000000..054b9d5 --- /dev/null +++ b/app/src/main/res/layout/activity_modify_address.xml @@ -0,0 +1,30 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_my_order.xml b/app/src/main/res/layout/activity_my_order.xml new file mode 100644 index 0000000..3052ead --- /dev/null +++ b/app/src/main/res/layout/activity_my_order.xml @@ -0,0 +1,97 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_note_details.xml b/app/src/main/res/layout/activity_note_details.xml new file mode 100644 index 0000000..cd9bc8b --- /dev/null +++ b/app/src/main/res/layout/activity_note_details.xml @@ -0,0 +1,24 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_open_member.xml b/app/src/main/res/layout/activity_open_member.xml new file mode 100644 index 0000000..801c47a --- /dev/null +++ b/app/src/main/res/layout/activity_open_member.xml @@ -0,0 +1,204 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_order.xml b/app/src/main/res/layout/activity_order.xml new file mode 100644 index 0000000..9b0accb --- /dev/null +++ b/app/src/main/res/layout/activity_order.xml @@ -0,0 +1,420 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_order_details.xml b/app/src/main/res/layout/activity_order_details.xml new file mode 100644 index 0000000..4316581 --- /dev/null +++ b/app/src/main/res/layout/activity_order_details.xml @@ -0,0 +1,611 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_order_success.xml b/app/src/main/res/layout/activity_order_success.xml new file mode 100644 index 0000000..7cff9c4 --- /dev/null +++ b/app/src/main/res/layout/activity_order_success.xml @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_out_record_details.xml b/app/src/main/res/layout/activity_out_record_details.xml new file mode 100644 index 0000000..245dc0b --- /dev/null +++ b/app/src/main/res/layout/activity_out_record_details.xml @@ -0,0 +1,377 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_password_manager.xml b/app/src/main/res/layout/activity_password_manager.xml new file mode 100644 index 0000000..7026667 --- /dev/null +++ b/app/src/main/res/layout/activity_password_manager.xml @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_pay_order.xml b/app/src/main/res/layout/activity_pay_order.xml new file mode 100644 index 0000000..5b2d452 --- /dev/null +++ b/app/src/main/res/layout/activity_pay_order.xml @@ -0,0 +1,390 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_pay_password.xml b/app/src/main/res/layout/activity_pay_password.xml new file mode 100644 index 0000000..6fe1a84 --- /dev/null +++ b/app/src/main/res/layout/activity_pay_password.xml @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_pay_password_manager.xml b/app/src/main/res/layout/activity_pay_password_manager.xml new file mode 100644 index 0000000..4ecb57f --- /dev/null +++ b/app/src/main/res/layout/activity_pay_password_manager.xml @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_permission.xml b/app/src/main/res/layout/activity_permission.xml new file mode 100644 index 0000000..91183b4 --- /dev/null +++ b/app/src/main/res/layout/activity_permission.xml @@ -0,0 +1,144 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_pet_file.xml b/app/src/main/res/layout/activity_pet_file.xml new file mode 100644 index 0000000..778e84c --- /dev/null +++ b/app/src/main/res/layout/activity_pet_file.xml @@ -0,0 +1,603 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_pet_manager_list.xml b/app/src/main/res/layout/activity_pet_manager_list.xml new file mode 100644 index 0000000..7b86d0f --- /dev/null +++ b/app/src/main/res/layout/activity_pet_manager_list.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_points.xml b/app/src/main/res/layout/activity_points.xml new file mode 100644 index 0000000..0b2b2bb --- /dev/null +++ b/app/src/main/res/layout/activity_points.xml @@ -0,0 +1,182 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_product_details.xml b/app/src/main/res/layout/activity_product_details.xml new file mode 100644 index 0000000..a3f93fe --- /dev/null +++ b/app/src/main/res/layout/activity_product_details.xml @@ -0,0 +1,183 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_recharge.xml b/app/src/main/res/layout/activity_recharge.xml new file mode 100644 index 0000000..ec3f2da --- /dev/null +++ b/app/src/main/res/layout/activity_recharge.xml @@ -0,0 +1,141 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_refund.xml b/app/src/main/res/layout/activity_refund.xml new file mode 100644 index 0000000..3132009 --- /dev/null +++ b/app/src/main/res/layout/activity_refund.xml @@ -0,0 +1,247 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_register.xml b/app/src/main/res/layout/activity_register.xml new file mode 100644 index 0000000..eca402f --- /dev/null +++ b/app/src/main/res/layout/activity_register.xml @@ -0,0 +1,165 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_register_success.xml b/app/src/main/res/layout/activity_register_success.xml new file mode 100644 index 0000000..4a89c98 --- /dev/null +++ b/app/src/main/res/layout/activity_register_success.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_return_device.xml b/app/src/main/res/layout/activity_return_device.xml new file mode 100644 index 0000000..40930e1 --- /dev/null +++ b/app/src/main/res/layout/activity_return_device.xml @@ -0,0 +1,213 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_seting_password.xml b/app/src/main/res/layout/activity_seting_password.xml new file mode 100644 index 0000000..738dd14 --- /dev/null +++ b/app/src/main/res/layout/activity_seting_password.xml @@ -0,0 +1,111 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_setting.xml b/app/src/main/res/layout/activity_setting.xml new file mode 100644 index 0000000..5ad206a --- /dev/null +++ b/app/src/main/res/layout/activity_setting.xml @@ -0,0 +1,196 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_shop_car.xml b/app/src/main/res/layout/activity_shop_car.xml new file mode 100644 index 0000000..d6086d3 --- /dev/null +++ b/app/src/main/res/layout/activity_shop_car.xml @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_shop_search.xml b/app/src/main/res/layout/activity_shop_search.xml new file mode 100644 index 0000000..e0b75a9 --- /dev/null +++ b/app/src/main/res/layout/activity_shop_search.xml @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_shop_type.xml b/app/src/main/res/layout/activity_shop_type.xml new file mode 100644 index 0000000..a758828 --- /dev/null +++ b/app/src/main/res/layout/activity_shop_type.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_start_deposit.xml b/app/src/main/res/layout/activity_start_deposit.xml new file mode 100644 index 0000000..def4fe8 --- /dev/null +++ b/app/src/main/res/layout/activity_start_deposit.xml @@ -0,0 +1,104 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_user_info.xml b/app/src/main/res/layout/activity_user_info.xml new file mode 100644 index 0000000..fd0ae71 --- /dev/null +++ b/app/src/main/res/layout/activity_user_info.xml @@ -0,0 +1,202 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_welcome.xml b/app/src/main/res/layout/activity_welcome.xml new file mode 100644 index 0000000..71a2806 --- /dev/null +++ b/app/src/main/res/layout/activity_welcome.xml @@ -0,0 +1,24 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_wifi_list.xml b/app/src/main/res/layout/activity_wifi_list.xml new file mode 100644 index 0000000..1abcfbb --- /dev/null +++ b/app/src/main/res/layout/activity_wifi_list.xml @@ -0,0 +1,14 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_withdraw.xml b/app/src/main/res/layout/activity_withdraw.xml new file mode 100644 index 0000000..4d58ee7 --- /dev/null +++ b/app/src/main/res/layout/activity_withdraw.xml @@ -0,0 +1,193 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_withdraw_success.xml b/app/src/main/res/layout/activity_withdraw_success.xml new file mode 100644 index 0000000..81d9c3e --- /dev/null +++ b/app/src/main/res/layout/activity_withdraw_success.xml @@ -0,0 +1,116 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/dialog_alert.xml b/app/src/main/res/layout/dialog_alert.xml new file mode 100644 index 0000000..f31f38a --- /dev/null +++ b/app/src/main/res/layout/dialog_alert.xml @@ -0,0 +1,71 @@ + + + + + + + + + + + +