This commit is contained in:
fengjignqi
2026-07-30 15:22:32 +08:00
parent f689e5ae15
commit 6fc4fc29b9
1004 changed files with 49259 additions and 0 deletions

1
app/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/build

159
app/build.gradle Normal file
View File

@@ -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'
}

BIN
app/libs/Flowlayout.aar Normal file

Binary file not shown.

BIN
app/libs/MNMLKitScanner.aar Normal file

Binary file not shown.

BIN
app/libs/changeskin.aar Normal file

Binary file not shown.

BIN
app/libs/library.aar Normal file

Binary file not shown.

BIN
app/libs/photoview.aar Normal file

Binary file not shown.

BIN
app/libs/pickerview.aar Normal file

Binary file not shown.

BIN
app/libs/wheelview.aar Normal file

Binary file not shown.

51
app/proguard-rules.pro vendored Normal file
View File

@@ -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 <init> (org.json.JSONObject);
}
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}

Binary file not shown.

Binary file not shown.

View File

@@ -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
}

View File

@@ -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)
}
}

View File

@@ -0,0 +1,329 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<application
android:name=".CKApp"
android:allowBackup="true"
android:extractNativeLibs="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/icon"
android:label="@string/app_name"
android:networkSecurityConfig="@xml/network_security_config"
android:requestLegacyExternalStorage="true"
android:roundIcon="@mipmap/icon"
android:supportsRtl="true"
android:theme="@style/Theme.CkCollar_app">
<activity
android:name=".ui.act.welcome.IndexActivity"
android:exported="true"
android:label="@string/app_name"
android:theme="@style/Theme.CkCollar_app.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".ui.act.welcome.WelcomeActivity"
android:theme="@style/Theme.CkCollar_app.NoActionBar"></activity>
<activity
android:name=".ui.act.welcome.PermisstionActivity"
android:theme="@style/Theme.CkCollar_app.NoActionBar"></activity>
<activity
android:name=".ui.act.login.LoginActivity"
android:launchMode="singleTask"
android:theme="@style/Theme.CkCollar_app.NoActionBar"></activity>
<activity
android:name=".ui.act.login.RegisterActivity"
android:theme="@style/Theme.CkCollar_app.NoActionBar"></activity>
<activity
android:name=".ui.act.login.BoundPhoneActivity"
android:theme="@style/Theme.CkCollar_app.NoActionBar"></activity>
<activity
android:name=".ui.act.login.RegisterSuccessActivity"
android:theme="@style/Theme.CkCollar_app.NoActionBar"></activity>
<activity
android:name=".ui.act.login.LostActivity"
android:theme="@style/Theme.CkCollar_app.NoActionBar"></activity>
<activity
android:name=".ui.act.login.AgreementActivity"
android:theme="@style/Theme.CkCollar_app.NoActionBar"></activity>
<activity
android:name=".ui.act.home.MainActivity"
android:launchMode="singleTask"
android:theme="@style/Theme.CkCollar_app.MainTheme"></activity>
<activity
android:name=".wxapi.WXEntryActivity"
android:exported="true"
android:label="@string/app_name"
android:launchMode="singleTask"
android:taskAffinity="com.ck.ckcollar.app"
android:theme="@android:style/Theme.Translucent.NoTitleBar"></activity>
<activity
android:name=".ui.act.petmanager.PetManagerActivity"
android:theme="@style/Theme.CkCollar_app.NoActionBar"></activity>
<activity
android:name=".ui.act.petmanager.AddPetActivity"
android:theme="@style/Theme.CkCollar_app.NoActionBar"></activity>
<activity
android:name=".ui.act.petmanager.EditPetActivity"
android:theme="@style/Theme.CkCollar_app.NoActionBar"></activity>
<activity
android:name=".ui.act.petmanager.ViewPetFileActivity"
android:theme="@style/Theme.CkCollar_app.NoActionBar"></activity>
<activity
android:name=".ui.act.customer.CustomerActivity"
android:theme="@style/Theme.CkCollar_app.NoActionBar"></activity>
<activity
android:name=".ui.act.user.UserInfoActivity"
android:launchMode="singleTask"
android:theme="@style/Theme.CkCollar_app.NoActionBar"></activity>
<activity
android:name=".ui.act.message.MessageCenterActivity"
android:theme="@style/Theme.CkCollar_app.NoActionBar"></activity>
<activity
android:name=".ui.act.setting.SettingActivity"
android:theme="@style/Theme.CkCollar_app.NoActionBar"></activity>
<activity
android:name=".ui.act.setting.PasswordManagerActivity"
android:theme="@style/Theme.CkCollar_app.NoActionBar"></activity>
<activity
android:name=".ui.act.setting.EditPsswordActivity"
android:theme="@style/Theme.CkCollar_app.NoActionBar"></activity>
<activity
android:name=".ui.act.setting.FindPasswordActivity"
android:theme="@style/Theme.CkCollar_app.NoActionBar"></activity>
<activity
android:name=".ui.act.setting.AddressActivity"
android:theme="@style/Theme.CkCollar_app.NoActionBar"></activity>
<activity
android:name=".ui.act.setting.AddAddressActivity"
android:theme="@style/Theme.CkCollar_app.NoActionBar"></activity>
<activity
android:name=".ui.act.setting.AccountCancellationActivity"
android:theme="@style/Theme.CkCollar_app.NoActionBar"></activity>
<activity
android:name=".ui.act.balance.BalanceActivity"
android:theme="@style/Theme.CkCollar_app.MapTheme"></activity>
<activity
android:name=".ui.act.balance.RechargeActivity"
android:theme="@style/Theme.CkCollar_app.NoActionBar"></activity>
<activity
android:name=".ui.act.balance.WithDrawActivity"
android:theme="@style/Theme.CkCollar_app.MapTheme"></activity>
<activity
android:name=".ui.act.balance.WithDrawSuccessActivity"
android:theme="@style/Theme.CkCollar_app.NoActionBar"></activity>
<activity
android:name=".ui.act.balance.OutRecordDetailsActivity"
android:theme="@style/Theme.CkCollar_app.NoActionBar"></activity>
<activity
android:name=".ui.act.balance.IncomeRecordDetailsActivity"
android:theme="@style/Theme.CkCollar_app.NoActionBar"></activity>
<activity
android:name=".ui.act.points.PointsActivity"
android:theme="@style/Theme.CkCollar_app.MapTheme"></activity>
<activity
android:name=".ui.act.member.MemberActivity"
android:theme="@style/Theme.CkCollar_app.NoActionBar"></activity>
<activity
android:name=".ui.act.member.OpenMemberActivity"
android:theme="@style/Theme.CkCollar_app.MapTheme"></activity>
<activity
android:name=".ui.act.mine.ReturnDeviceActivity"
android:theme="@style/Theme.CkCollar_app.NoActionBar"></activity>
<activity
android:name=".ui.act.mine.FeedBackActivity"
android:theme="@style/Theme.CkCollar_app.NoActionBar"></activity>
<activity
android:name=".ui.act.shop.SearchActivity"
android:theme="@style/Theme.CkCollar_app.MapTheme"
android:windowSoftInputMode="stateAlwaysVisible"></activity>
<activity
android:name=".ui.act.shop.ShopCarActivity"
android:theme="@style/Theme.CkCollar_app.MapTheme"
android:windowSoftInputMode="stateAlwaysVisible"></activity>
<activity
android:name=".ui.act.shop.TypeActivity"
android:theme="@style/Theme.CkCollar_app.MapTheme"
android:windowSoftInputMode="stateAlwaysVisible"></activity>
<activity
android:name=".ui.act.shop.ProductDetailsActivity"
android:theme="@style/Theme.CkCollar_app.NoActionBar"></activity>
<activity
android:name=".ui.act.shop.OrderActivity"
android:theme="@style/Theme.CkCollar_app.NoActionBar"></activity>
<activity
android:name=".ui.act.shop.OrderSuccessActivity"
android:theme="@style/Theme.CkCollar_app.NoActionBar"></activity>
<activity
android:name=".ui.act.order.MyOrderActivity"
android:theme="@style/Theme.CkCollar_app.NoActionBar"></activity>
<activity
android:name=".ui.act.order.OrderDetailsActivity"
android:theme="@style/Theme.CkCollar_app.NoActionBar"></activity>
<activity
android:name=".ui.act.order.AfterSalesActivity"
android:theme="@style/Theme.CkCollar_app.NoActionBar"></activity>
<activity
android:name=".ui.act.order.RefundActivity"
android:theme="@style/Theme.CkCollar_app.NoActionBar"></activity>
<activity
android:name=".ui.act.order.ModifyAddressActivity"
android:theme="@style/Theme.CkCollar_app.NoActionBar"></activity>
<activity
android:name=".ui.act.order.AfterSalesProgressActivity"
android:theme="@style/Theme.CkCollar_app.NoActionBar"></activity>
<activity
android:name=".ui.act.order.LogisticsInfoActivity"
android:theme="@style/Theme.CkCollar_app.NoActionBar"></activity>
<activity
android:name=".ui.act.note.NoteDetailsActivity"
android:theme="@style/Theme.CkCollar_app.NoActionBar"></activity>
<activity
android:name=".ui.act.setting.EditAddressActivity"
android:theme="@style/Theme.CkCollar_app.NoActionBar"></activity>
<activity
android:name=".ui.act.order.InputLogisticsNumActivity"
android:theme="@style/Theme.CkCollar_app.NoActionBar"></activity>
<activity
android:name=".ui.act.message.MessageDetailsActivity"
android:theme="@style/Theme.CkCollar_app.NoActionBar"></activity>
<activity
android:name=".ui.act.setting.PayPasswordManagerActivity"
android:theme="@style/Theme.CkCollar_app.NoActionBar"></activity>
<activity
android:name=".ui.act.setting.FindPayPasswordActivity"
android:theme="@style/Theme.CkCollar_app.NoActionBar"></activity>
<activity
android:name=".ui.act.setting.EditPayPsswordActivity"
android:theme="@style/Theme.CkCollar_app.NoActionBar"></activity>
<activity
android:name=".ui.act.setting.PayPsswordActivity"
android:theme="@style/Theme.CkCollar_app.NoActionBar"></activity>
<activity
android:name=".ui.act.order.PayOrderActivity"
android:theme="@style/Theme.CkCollar_app.NoActionBar"></activity>
<activity
android:name=".ui.act.deposit.DepositActivity"
android:theme="@style/Theme.CkCollar_app.NoActionBar"></activity>
<activity
android:name=".ui.act.customer.PeopleCustomerActivity"
android:windowSoftInputMode="adjustResize"
android:theme="@style/Theme.CkCollar_app.NoActionBar"></activity>
<activity
android:name=".ui.act.petmanager.InputInviteCodeActivity"
android:theme="@style/Theme.CkCollar_app.NoActionBar"></activity>
<activity
android:name=".ui.act.petmanager.BoundSuccessActivity"
android:theme="@style/Theme.CkCollar_app.NoActionBar"></activity>
<activity
android:name=".ui.act.deposit.StartDepositActivity"
android:theme="@style/Theme.CkCollar_app.NoActionBar"></activity>
<activity
android:name=".ui.act.petmanager.ImageViewActivity"
android:theme="@style/Theme.CkCollar_app.NoActionBar"></activity>
<activity
android:name=".ui.act.customer.MineCustomerActivity"
android:theme="@style/Theme.CkCollar_app.NoActionBar"></activity>
<activity
android:name=".ui.act.customer.ShopCustomerActivity"
android:theme="@style/Theme.CkCollar_app.NoActionBar"></activity>
<activity
android:name=".ui.act.WifiListActivity"
android:theme="@style/Theme.CkCollar_app.DarkActionBar"></activity>
<activity
android:name=".ui.act.BlueToothActivity"
android:theme="@style/Theme.CkCollar_app.DarkActionBar"></activity>
<activity
android:name=".ui.act.petmanager.MapLocationActivity"
android:theme="@style/Theme.CkCollar_app.MapTheme"></activity>
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="com.ck.ckcollar.app.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
</application>
<queries>
<package android:name="com.tencent.mm" />
</queries>
<queries>
<package android:name="com.eg.android.AlipayGphone" /> <!-- 支付宝 -->
<package android:name="hk.alipay.wallet" /> <!-- AlipayHK -->
</queries>
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<!-- <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />-->
<!-- <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />-->
<!-- <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />-->
<!-- <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />-->
<!-- &lt;!&ndash; 声明应用需要使用蓝牙功能 &ndash;&gt;-->
<!-- <uses-feature-->
<!-- android:name="android.hardware.bluetooth"-->
<!-- android:required="true" />-->
<!-- &lt;!&ndash; 必要的蓝牙权限 &ndash;&gt;-->
<!-- <uses-permission android:name="android.permission.BLUETOOTH" />-->
<!-- <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />-->
<!-- &lt;!&ndash; 从 Android 12 (API 31) 开始,需要新的蓝牙扫描/连接权限 &ndash;&gt;-->
<!-- <uses-permission android:name="android.permission.BLUETOOTH_SCAN" />-->
<!-- <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />-->
<!-- <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />-->
<!-- 基础网络权限 -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!-- 摄像头权限 -->
<uses-permission android:name="android.permission.CAMERA" />
<!-- 声明需要使用摄像头功能 -->
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
</manifest>

File diff suppressed because it is too large Load Diff

View File

@@ -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<TTBaseActivity>()
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<UserInfoModel>(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)
}
}

View File

@@ -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;
}
}

View File

@@ -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)}")
}
}

View File

@@ -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<String?, String?> = HashMap<String?, String?>()
// 用于格式化日期,作为日志文件名的一部分
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<String?, String?> {
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()
}
}
}

View File

@@ -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)
}

View File

@@ -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)
}

View File

@@ -0,0 +1,8 @@
package com.ck.ckcollar.app.listenner
/**
* 自定义接口用于给密码输入完成添加回掉事<E68E89>?
*/
interface OnPasswordInputFinish {
fun inputFinish();
}

View File

@@ -0,0 +1,8 @@
package com.ck.ckcollar.app.model
class AIMessageModel: CkBaseModel() {
var answer :String? = ""
var chatId :String? = ""
var conversationId :String? = ""
}

View File

@@ -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? = "" // 置信度
}

View File

@@ -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
}

View File

@@ -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<OrderProgress>? = 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? = "" // 更新时间
}
}

View File

@@ -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? = "" // 更新时间
}

View File

@@ -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
}

View File

@@ -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? = ""
}

View File

@@ -0,0 +1,15 @@
package com.ck.ckcollar.app.model
class CancelModel : CkBaseModel() {
var allPassed: Boolean = false // 是否全部通过
var conditions: List<Condition>? = null // 注销条件列表
var phoneNumber: String? = "" // 手机号
var assetsUncleared: Boolean = false //账户是否仍有未结清的余额或积分
}
class Condition {
var name: String? = "" // 条件名称
var passed: Boolean = false // 是否通过
var message: String? = "" // 提示消息
}

View File

@@ -0,0 +1,6 @@
package com.ck.ckcollar.app.model
import com.google.gson.annotations.SerializedName
import java.io.Serializable
open class CkBaseModel : Serializable {
}

View File

@@ -0,0 +1,5 @@
package com.ck.ckcollar.app.model
class CollarModel {
var name : String? = ""
}

View File

@@ -0,0 +1,33 @@
package com.ck.ckcollar.app.model
class CollarTypeModel : CkBaseModel(){
var total : Int = 0
var rows : List<TypeDataModel> = 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
}
}

View File

@@ -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<OrderItem>? = 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? = "" // 收货人电话
}
}

View File

@@ -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<OrderItem>? = 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 // 会员价小计金额
}
}

View File

@@ -0,0 +1,29 @@
package com.ck.ckcollar.app.model
class CustomerMessageModel {
var total : Int = 0
var rows: List<MessageItemModel>? = 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? = ""
}
}

View File

@@ -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? = ""
}

View File

@@ -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 // 金额
}

View File

@@ -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<String, Any?>? = 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<ColLogisticsInfo>? = null // 物流信息列表
class ColLogisticsInfo {
var createBy: String? = "" // 创建人
var createTime: String? = "" // 创建时间
var updateBy: String? = "" // 更新人
var updateTime: String? = "" // 更新时间
var remark: String? = "" // 备注
var params: Map<String, Any?>? = null // 参数
var id: Int = 0 // ID
var logisticsId: Int = 0 // 物流ID
var logisticsTime: String? = "" // 物流时间
var logisticsDesc: String? = "" // 物流描述
}
}

View File

@@ -0,0 +1,21 @@
package com.ck.ckcollar.app.model
class HealthNoteModel : CkBaseModel(){
var total : Int = 0
var rows : List<NoteModel> = 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? = "" // 更新时间
}
}

View File

@@ -0,0 +1,46 @@
package com.ck.ckcollar.app.model
class HomeModel : CkBaseModel() {
var banners: List<BannarModel>? = 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 //
}
}

View File

@@ -0,0 +1,9 @@
package com.ck.ckcollar.app.model
class ImageModel {
var isAdd : Boolean = false
var path : String? = ""
var url : String? = ""
}

View File

@@ -0,0 +1,28 @@
import com.contrarywind.interfaces.IPickerViewData
class JsonBean : IPickerViewData {
/**
* name : 省份
* city : [{"name":"北京市","area":["东城区","西城区","崇文区","宣武区","朝阳区"]}]
*/
var name: String? = null
var city: MutableList<CityBean?>? = null
// 实现 IPickerViewData 接口,
// 这个用来显示在PickerView上面的字符串
// PickerView会通过IPickerViewData获取getPickerViewText方法显示出来。
override fun getPickerViewText(): String? {
return this.name
}
class CityBean {
/**
* name : 城市
* area : ["东城区","西城区","崇文区","昌平区"]
*/
var name: String? = null
var area: MutableList<String?>? = null
}
}

View File

@@ -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? = ""
}

View File

@@ -0,0 +1,6 @@
package com.ck.ckcollar.app.model
class LogisticsModel : CkBaseModel() {
var code : String? = ""
var name : String? = ""
}

View File

@@ -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
}
}

View File

@@ -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 // 价格
}

View File

@@ -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? = "" // 更新时间
}

View File

@@ -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<Order>? = null
class Order{
var buyerNote: String? = "" // 买家备注
// var colLogistics: List<ColLogistics>? = null // 物流信息
var colOrderItems: List<OrderItem>? = 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? = ""
}
}

View File

@@ -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? = ""
}

View File

@@ -0,0 +1,7 @@
package com.ck.ckcollar.app.model
class PayPasswordStatus : CkBaseModel(){
var isSet : Boolean = false
var status : String? = ""
}

View File

@@ -0,0 +1,48 @@
package com.ck.ckcollar.app.model
import android.text.TextUtils
class PayResult(rawResult: Map<String?, String?>?) {
/**
* @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 + "}")
}
}

View File

@@ -0,0 +1,7 @@
package com.ck.ckcollar.app.model
class PeopleCustomerMessageModel {
var messages: List<CustomerMessageModel.MessageItemModel>? = null
}

View File

@@ -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? = ""
}
}

View File

@@ -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 // 重量
}

View File

@@ -0,0 +1,7 @@
package com.ck.ckcollar.app.model
class RechargeModel {
var orderStr :String? = null
var amount : Double? = null
var RC1782974779440000002 : String? = null
}

View File

@@ -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? = "" // 标题
}

View File

@@ -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退款
}

View File

@@ -0,0 +1,7 @@
package com.ck.ckcollar.app.model
class ShopCarCoutTotalModel : CkBaseModel() {
var count : Int = 0
var totalMoney : Double? = 0.0
}

View File

@@ -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
}
}

View File

@@ -0,0 +1,4 @@
package com.ck.ckcollar.app.model
class ShopHotModel {
}

View File

@@ -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
}

View File

@@ -0,0 +1,48 @@
package com.ck.ckcollar.app.model
class ShopProductModel : CkBaseModel() {
var total : Int = 0
var rows: List<ProductModel>? = listOf()
class ProductModel : CkBaseModel() {
var colCommodityListCbs: List<ProductTypeModel>? = 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<String>? = 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
}
}
}

View File

@@ -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
}

View File

@@ -0,0 +1,8 @@
package com.ck.ckcollar.app.model
class UnReadModel : CkBaseModel(){
var unreadCount : Int = 0
}

View File

@@ -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? = ""
}

View File

@@ -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 = ""
}

View File

@@ -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//金额转积分比例
}

View File

@@ -0,0 +1,7 @@
package com.ck.ckcollar.app.model
class WithDrawModel {
var amount :String? = ""
var payMethod :String? = ""
}

View File

@@ -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<String>()
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<String?>,
grantResults: IntArray
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this)
}
override fun onPermissionsGranted(
requestCode: Int,
perms: List<String?>
) {
initData()
}
override fun onPermissionsDenied(
requestCode: Int,
perms: List<String?>
) {
}
class BlueBoothAdapter(var context: CKBaseActivity, var scanResults: List<String>) : RecyclerView.Adapter<BlueBoothAdapter.BlueBoothHolder>() {
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){
}
}
}

View File

@@ -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<HmsScan?>(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中
}
}
}

View File

@@ -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<ScanResult>()
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<String?>,
grantResults: IntArray
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this)
}
override fun onPermissionsGranted(
requestCode: Int,
perms: List<String?>
) {
initData()
}
override fun onPermissionsDenied(
requestCode: Int,
perms: List<String?>
) {
}
class WifiAdapter(var context: CKBaseActivity, var scanResults: List<ScanResult>) : RecyclerView.Adapter<WifiAdapter.WifiiewHoldr>() {
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){
}
}
}

View File

@@ -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<RecordModel>()
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<BalanceModle>(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<List<RecordModel>>(data, object : TypeToken<List<RecordModel>>(){}.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<RecordModel>, var onItemClickListenner : OnItemClickListenner) : RecyclerView.Adapter<RecordAdapter.RecordHolder>() {
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){
}
}
}

View File

@@ -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<RecordDetailsModel>(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)
}
})
}
}

View File

@@ -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<RecordDetailsModel>(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)
}
})
}
}

View File

@@ -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<RechargeModel>(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))
}
}
}
}
}

View File

@@ -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<WithDrawModel>(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<BalanceModle>(data, BalanceModle::class.java)
binding.textAmount.text = model?.balance.toString()
}
override fun onFailed(code: String, msg: String) {
toast(msg)
}
})
}
}

View File

@@ -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<WithDrawModel>(getReceiveParam().get("data")!!.stringValue,
WithDrawModel::class.java)
binding.textAmount.text = model.amount
binding.textType.text = model.payMethod
}
}

View File

@@ -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<CustomerMessageModel.MessageItemModel>()
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<List<CustomerMessageModel.MessageItemModel>>(dataStr,object : TypeToken<List<CustomerMessageModel.MessageItemModel>>(){}.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<AIMessageModel>(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<AIMessageModel>(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<UploadModel>(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<CustomerMessageModel>(data,CustomerMessageModel::class.java)
// model.rows?.let {
// this@CustomerActivity.data.addAll(model.rows!!)
// }
var model = Gson().fromJson<List<CustomerMessageModel.MessageItemModel>>(
data,
object : TypeToken<List<CustomerMessageModel.MessageItemModel>>() {}.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<CustomerMessageModel.MessageItemModel>,
var onItemClickListenner: OnItemClickListenner
) : RecyclerView.Adapter<CustomerMessageAdapter.CustomerMessageHolder>() {
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<String>()
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()))
})
}
}
}
}

View File

@@ -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<CustomerMessageModel.MessageItemModel>()
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<UploadModel>(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<CustomerMessageModel>(data, CustomerMessageModel::class.java)
model.rows?.let {
this@MineCustomerActivity.data.clear()
this@MineCustomerActivity.data.addAll(model.rows!!)
}
// var model = Gson().fromJson<List<CustomerMessageModel.MessageItemModel>>(
// data,
// object : TypeToken<List<CustomerMessageModel.MessageItemModel>>() {}.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<CustomerMessageModel.MessageItemModel>,
var onItemClickListenner: OnItemClickListenner
) : RecyclerView.Adapter<CustomerMessageAdapter.CustomerMessageHolder>() {
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) {
}
}
}

View File

@@ -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<CustomerMessageModel.MessageItemModel>()
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<CustomerStatusModel>(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{
"<img src=\"$content\"/>"
}
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<UploadModel>(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<CustomerMessageModel>(data, CustomerMessageModel::class.java)
model.rows?.let {
this@PeopleCustomerActivity.data.clear()
this@PeopleCustomerActivity.data.addAll(model.rows!!)
}
// var model = Gson().fromJson<List<CustomerMessageModel.MessageItemModel>>(
// data,
// object : TypeToken<List<CustomerMessageModel.MessageItemModel>>() {}.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("<img")>=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<CustomerMessageModel.MessageItemModel>,
var onItemClickListenner: OnItemClickListenner
) : RecyclerView.Adapter<CustomerMessageAdapter.CustomerMessageHolder>() {
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<String>()
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()))
})
}
}
}
}

View File

@@ -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<CustomerMessageModel.MessageItemModel>()
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<UploadModel>(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<CustomerMessageModel>(data, CustomerMessageModel::class.java)
model.rows?.let {
this@ShopCustomerActivity.data.clear()
this@ShopCustomerActivity.data.addAll(model.rows!!)
}
// var model = Gson().fromJson<List<CustomerMessageModel.MessageItemModel>>(
// data,
// object : TypeToken<List<CustomerMessageModel.MessageItemModel>>() {}.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<CustomerMessageModel.MessageItemModel>,
var onItemClickListenner: OnItemClickListenner
) : RecyclerView.Adapter<CustomerMessageAdapter.CustomerMessageHolder>() {
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) {
}
}
}

View File

@@ -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<UserInfoModel>(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<DepositModel>(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)
}
})
}
}

View File

@@ -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<UserInfoModel>(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<DepositModel>(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()
}
})
}
}

View File

@@ -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<CKBaseFragment>(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<UpdateModel>(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)
}
})
}
}

View File

@@ -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<TTBaseFragment>) : 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) {
}
}

View File

@@ -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<HealthNoteModel.NoteModel>()
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<CustomerStatusModel>(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<HealthNoteModel>(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<HealthNoteModel.NoteModel>, var onItemClickListenner : OnItemClickListenner) : RecyclerView.Adapter<NoteAdapter.NoteHolder>() {
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){
}
}
}

View File

@@ -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<CollarTypeModel.TypeDataModel>()
lateinit var imageAdapter: ImageAdapter
var bannarData = listOf<BannarModel>()
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<CollarTypeModel.TypeDataModel>(
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<Int?> {
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<HomeModel>(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<HomeModel.EquipmentModel>(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<Int?> {
override fun onChanged(result: Int?) {
getData(dataModel?.id.toString())
}
})
LiveDataBus.get().with("DELETE" + dataModel!!.id, Int::class.java)
.observe(viewLifecycleOwner, object : Observer<Int?> {
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<CollarTypeModel.TypeDataModel>(
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<CollarTypeModel>(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<CollarTypeModel>(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<UploadModel>(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<AIPhotoModel>(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<BannarModel?>?,
var itemClickListenner: OnItemClickListenner
) :
BannerAdapter<BannarModel?, ImageAdapter.BannerViewHolder?>(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
)
}
}

View File

@@ -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<UserInfoModel>(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<UnReadModel>(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)
}
})
}
}

View File

@@ -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<BannarModel>()
var itemDatas = mutableListOf<ShopItemModel>()
var hotDatas = mutableListOf<ShopProductModel.ProductModel>()
var productDatas = mutableListOf<ShopProductModel.ProductModel>()
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<List<ShopItemModel>>(
data,
object : TypeToken<List<ShopItemModel>>() {}.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<ShopProductModel>(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<ShopProductModel>(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<ShopCarCoutTotalModel>(
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<List<BannarModel>>(
data,
object : TypeToken<List<BannarModel>>(){}.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<BannarModel?>?,
var itemClickListenner: OnItemClickListenner
) :
BannerAdapter<BannarModel?, ImageAdapter.BannerViewHolder?>(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<ShopItemModel>) : 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<ShopProductModel.ProductModel>) :
RecyclerView.Adapter<HotAdapter.HotHolder>() {
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<ShopProductModel.ProductModel>,
var itemClickListenner: OnItemClickListenner
) : RecyclerView.Adapter<ProductAdapter.ProductHolder>() {
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) {
}
}
}

View File

@@ -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<AgreementModel>(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) {
}
})
}
}

View File

@@ -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<ImageButton>(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<UserInfoModel>(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<LoginModel>(getReceiveParam().get("data")!!.stringValue,LoginModel::class.java)
}
override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent)
setIntent(intent)
}
}

View File

@@ -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<LoginModel>(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<LoginModel>(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<UserInfoModel>(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<LoginModel>(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)
}
})
}
}

View File

@@ -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)
}
}

View File

@@ -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<LoginModel>(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<UserInfoModel>(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)
}
}

View File

@@ -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()
}
}

View File

@@ -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<ImageButton>(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<List<MemberPriceModel>>(data, object : TypeToken<List<MemberPriceModel>>(){}.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<UserInfoModel>(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)
}
})
}
}

View File

@@ -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<MemberPriceModel>()
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<MemberModel>(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<List<MemberPriceModel>>(data, object : TypeToken<List<MemberPriceModel>>(){}.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<TextView>(R.id.textMoney)
var textMonth = view.findViewById<TextView>(R.id.textMonth)
var textGoNoMoney = view.findViewById<TextView>(R.id.textGoNoMoney)
var textUnit = view.findViewById<TextView>(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))
}
}
}
}
}

View File

@@ -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<MessageModel>()
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<List<MessageModel>>(data,object : TypeToken<List<MessageModel>>(){}.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<MessageModel>, var onItemClickListenner : OnItemClickListenner) : RecyclerView.Adapter<MessageAdapter.MessageHolder>() {
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){
}
}
}

Some files were not shown because too many files have changed in this diff Show More