Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4c11b3f9c3 | ||
|
|
577f49e032 | ||
|
|
a279230669 | ||
|
|
969338f3bd | ||
|
|
c2dfa9145a | ||
|
|
499673782c | ||
|
|
f3006f4255 | ||
|
|
579e9427c8 | ||
|
|
39dbe5f1e4 | ||
|
|
9806e66790 | ||
|
|
c6eeb1321c | ||
|
|
9d432dba67 | ||
|
|
54dc0b5598 | ||
|
|
170936fd23 | ||
|
|
bc0c7adb41 | ||
|
|
12fecfbe41 |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
2229
.idea/caches/deviceStreaming.xml
generated
2229
.idea/caches/deviceStreaming.xml
generated
File diff suppressed because it is too large
Load Diff
7
.idea/deploymentTargetSelector.xml
generated
7
.idea/deploymentTargetSelector.xml
generated
@@ -4,6 +4,13 @@
|
||||
<selectionStates>
|
||||
<SelectionState runConfigName="app">
|
||||
<option name="selectionMode" value="DROPDOWN" />
|
||||
<DropdownSelection timestamp="2026-08-14T02:57:51.212958400Z">
|
||||
<Target type="DEFAULT_BOOT">
|
||||
<handle>
|
||||
<DeviceId pluginId="PhysicalDevice" identifier="serial=D122222104A9" />
|
||||
</handle>
|
||||
</Target>
|
||||
</DropdownSelection>
|
||||
<DialogSelection />
|
||||
</SelectionState>
|
||||
</selectionStates>
|
||||
|
||||
13
.idea/deviceManager.xml
generated
Normal file
13
.idea/deviceManager.xml
generated
Normal file
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="DeviceTable">
|
||||
<option name="columnSorters">
|
||||
<list>
|
||||
<ColumnSorterState>
|
||||
<option name="column" value="Name" />
|
||||
<option name="order" value="ASCENDING" />
|
||||
</ColumnSorterState>
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
||||
@@ -84,6 +84,8 @@ dependencies {
|
||||
implementation libs.androidx.compose.material3
|
||||
implementation libs.material
|
||||
implementation libs.appcompat
|
||||
implementation libs.luban
|
||||
implementation 'io.noties.markwon:core:4.6.2'
|
||||
testImplementation libs.junit
|
||||
androidTestImplementation libs.androidx.junit
|
||||
androidTestImplementation libs.androidx.espresso.core
|
||||
@@ -156,4 +158,7 @@ dependencies {
|
||||
|
||||
implementation 'com.github.yyued:SVGAPlayer-Android:2.6.1'
|
||||
|
||||
}
|
||||
//圆形视图库
|
||||
implementation 'com.makeramen:roundedimageview:2.3.0'
|
||||
|
||||
}
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
||||
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
|
||||
|
||||
<application
|
||||
android:name=".CKApp"
|
||||
android:allowBackup="true"
|
||||
@@ -29,10 +32,10 @@
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".ui.act.welcome.WelcomeActivity"
|
||||
android:theme="@style/Theme.CkCollar_app.NoActionBar"></activity>
|
||||
android:theme="@style/Theme.CkCollar_app.NoActionBar"/>
|
||||
<activity
|
||||
android:name=".ui.act.welcome.PermisstionActivity"
|
||||
android:theme="@style/Theme.CkCollar_app.NoActionBar"></activity>
|
||||
android:theme="@style/Theme.CkCollar_app.NoActionBar"/>
|
||||
<activity
|
||||
android:name=".ui.act.login.LoginActivity"
|
||||
android:launchMode="singleTask"
|
||||
@@ -53,6 +56,9 @@
|
||||
<activity
|
||||
android:name=".ui.act.login.AgreementActivity"
|
||||
android:theme="@style/Theme.CkCollar_app.NoActionBar"></activity>
|
||||
<activity
|
||||
android:name=".ui.act.setting.SettingWebViewActivity"
|
||||
android:theme="@style/Theme.CkCollar_app.NoActionBar"></activity>
|
||||
<activity
|
||||
android:name=".ui.act.home.MainActivity"
|
||||
android:launchMode="singleTask"
|
||||
@@ -64,6 +70,12 @@
|
||||
android:launchMode="singleTask"
|
||||
android:taskAffinity="com.ck.ckcollar.app"
|
||||
android:theme="@android:style/Theme.Translucent.NoTitleBar"></activity>
|
||||
<activity
|
||||
android:name=".wxapi.WXPayEntryActivity"
|
||||
android:exported="true"
|
||||
android:launchMode="singleTop"
|
||||
android:taskAffinity="com.ck.ckcollar.app"
|
||||
android:theme="@android:style/Theme.Translucent.NoTitleBar" />
|
||||
<activity
|
||||
android:name=".ui.act.petmanager.PetManagerActivity"
|
||||
android:theme="@style/Theme.CkCollar_app.NoActionBar"></activity>
|
||||
@@ -269,7 +281,7 @@
|
||||
|
||||
<provider
|
||||
android:name="androidx.core.content.FileProvider"
|
||||
android:authorities="com.ck.ckcollar.app.fileprovider"
|
||||
android:authorities="${applicationId}.fileprovider"
|
||||
android:exported="false"
|
||||
android:grantUriPermissions="true">
|
||||
<meta-data
|
||||
@@ -291,11 +303,10 @@
|
||||
<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_FINE_LOCATION" />
|
||||
<!-- <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />-->
|
||||
<!-- <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />-->
|
||||
|
||||
@@ -305,12 +316,12 @@
|
||||
<!-- android:required="true" />-->
|
||||
|
||||
<!-- <!– 必要的蓝牙权限 –>-->
|
||||
<!-- <uses-permission android:name="android.permission.BLUETOOTH" />-->
|
||||
<!-- <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />-->
|
||||
<uses-permission android:name="android.permission.BLUETOOTH" android:maxSdkVersion="30" />
|
||||
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" android:maxSdkVersion="30" />
|
||||
|
||||
<!-- <!– 从 Android 12 (API 31) 开始,需要新的蓝牙扫描/连接权限 –>-->
|
||||
<!-- <uses-permission android:name="android.permission.BLUETOOTH_SCAN" />-->
|
||||
<!-- <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />-->
|
||||
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
|
||||
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
|
||||
<!-- <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />-->
|
||||
|
||||
|
||||
@@ -326,4 +337,4 @@
|
||||
<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>
|
||||
</manifest>
|
||||
|
||||
@@ -22,6 +22,8 @@ class CKApp : Application() {
|
||||
|
||||
var activitys = mutableListOf<TTBaseActivity>()
|
||||
lateinit var token : String
|
||||
var isUserLoggedIn: Boolean = false
|
||||
private set
|
||||
var wxJump = 0
|
||||
var userInfo : UserInfoModel? = null
|
||||
companion object {
|
||||
@@ -33,7 +35,8 @@ class CKApp : Application() {
|
||||
super.onCreate()
|
||||
app = this
|
||||
|
||||
token = PreferencesUtils.getString(this, Const.TOKEN,"").toString()
|
||||
token = PreferencesUtils.getString(this, Const.TOKEN, "").orEmpty()
|
||||
isUserLoggedIn = token.isNotBlank()
|
||||
var userData = PreferencesUtils.getString(this, Const.USER_DATA,"").toString()
|
||||
if (!TextUtils.isEmpty(userData)){
|
||||
userInfo = Gson().fromJson<UserInfoModel>(userData, UserInfoModel::class.java)
|
||||
@@ -51,16 +54,31 @@ class CKApp : Application() {
|
||||
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, "");
|
||||
// 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)
|
||||
}
|
||||
|
||||
fun setLoginToken(value: String) {
|
||||
token = value
|
||||
isUserLoggedIn = value.isNotBlank()
|
||||
PreferencesUtils.putString(this, Const.TOKEN, value)
|
||||
if (isUserLoggedIn) {
|
||||
PreferencesUtils.putBoolean(this, Const.FIRST, false)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
fun clearLoginState() {
|
||||
token = ""
|
||||
userInfo = null
|
||||
isUserLoggedIn = false
|
||||
PreferencesUtils.putString(this, Const.TOKEN, "")
|
||||
PreferencesUtils.putString(this, Const.USER_DATA, "")
|
||||
PreferencesUtils.putString(this, Const.PET_DATA, "")
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -7,7 +7,10 @@ object ActionCode {
|
||||
//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 BASE_URL = "http://192.168.1.187:8080"
|
||||
const val CUSTOMER_URL = "wss://d.chongdunpet.com/ws/chat?role=customer&token=";
|
||||
|
||||
|
||||
@@ -152,6 +155,7 @@ object ActionCode {
|
||||
"找回支付密码" -> url = "/app/setting/payPassword/reset"
|
||||
"查询支付密码状态" -> url = "/app/setting/payPassword/status"
|
||||
"订单支付" -> url = "/app/order/pay"
|
||||
"取消待支付订单" -> url = "/app/order/cancelPending"
|
||||
|
||||
|
||||
"修改个人信息" -> url = "/app/profile/update"
|
||||
@@ -175,6 +179,7 @@ object ActionCode {
|
||||
"绑定微信" -> url = "/app/profile/wx/bind"
|
||||
|
||||
|
||||
|
||||
}
|
||||
TTLog.e(url)
|
||||
return url;
|
||||
|
||||
@@ -34,4 +34,9 @@ object Config : TileSourceFactory() {
|
||||
override fun getTileURLString(pMapTileIndex: Long) =
|
||||
("$baseUrl&X=${MapTileIndex.getX(pMapTileIndex)}&Y=${MapTileIndex.getY(pMapTileIndex)}&L=${MapTileIndex.getZoom(pMapTileIndex)}")
|
||||
}
|
||||
|
||||
//隐私政策
|
||||
var PRIVACY_POLICY = "http://f.chongdunpet.com/privacy_policy.html#a6";
|
||||
//三方SDK
|
||||
var THIRD_PARTY_SDK = "http://h.chongdunpet.com/third_party_sdk.html";
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.ck.ckcollar.app.model
|
||||
|
||||
class BannarModel : CkBaseModel(){
|
||||
var localImageRes: Int = 0
|
||||
var bannerStatus: String? = ""
|
||||
var bannerUrl: String? = ""
|
||||
var createBy: String? = ""
|
||||
@@ -11,4 +12,4 @@ class BannarModel : CkBaseModel(){
|
||||
var sortOrder: Int = 0
|
||||
var updateBy: String? = ""
|
||||
var updateTime: String? = ""
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,14 @@ class MemberModel {
|
||||
var amount: Double = 0.0 // 金额
|
||||
var payType: String? = "" // 支付方式
|
||||
var orderNo: String? = "" // 订单编号
|
||||
var timeStamp: String? = null // 微信支付时间戳
|
||||
var packageVal: String? = null // 微信支付扩展字段
|
||||
var paySign: String? = null // 微信支付签名
|
||||
var appId: String? = null // 微信 AppID
|
||||
var partnerId: String? = null // 微信支付商户号
|
||||
var prepayId: String? = null // 微信预支付订单号
|
||||
var signType: String? = null // 签名类型
|
||||
var nonceStr: String? = null // 随机字符串
|
||||
var order: MemberOrder? = null // 订单信息
|
||||
|
||||
class MemberOrder {
|
||||
@@ -33,4 +41,4 @@ class MemberModel {
|
||||
var updateTime: String? = "" // 更新时间
|
||||
var userId: Int = 0 // 用户ID
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.ck.ckcollar.app.model
|
||||
|
||||
import com.google.gson.JsonElement
|
||||
|
||||
class OrderPaymentModel {
|
||||
var orderId: Int = 0
|
||||
var orderStr: JsonElement? = null
|
||||
var wxMap: JsonElement? = null
|
||||
var pointsAmount: Double = 0.0
|
||||
var balanceAmount: Double = 0.0
|
||||
var alipayAmount: Double = 0.0
|
||||
var info: String? = ""
|
||||
}
|
||||
@@ -4,5 +4,13 @@ class PayOrderModel : CkBaseModel(){
|
||||
var orderStr: String? = "" // 订单字符串
|
||||
var amount: String? = "" // 金额
|
||||
var orderNo: String? = "" // 订单编号
|
||||
var timeStamp: String? = null // 微信支付时间戳
|
||||
var packageVal: String? = null // 微信支付扩展字段
|
||||
var paySign: String? = null // 微信支付签名
|
||||
var appId: String? = null // 微信 AppID
|
||||
var partnerId: String? = null // 微信支付商户号
|
||||
var prepayId: String? = null // 微信预支付订单号
|
||||
var signType: String? = null // 签名类型
|
||||
var nonceStr: String? = null // 随机字符串
|
||||
var info : String? = ""
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,22 @@
|
||||
package com.ck.ckcollar.app.model
|
||||
|
||||
class RechargeModel {
|
||||
var orderStr :String? = null
|
||||
var amount : Double? = null
|
||||
// Alipay
|
||||
var orderStr: String? = null
|
||||
|
||||
// Common
|
||||
var amount: Double? = null
|
||||
var orderNo: String? = null
|
||||
|
||||
// WeChat Pay
|
||||
var timeStamp: String? = null
|
||||
var packageVal: String? = null
|
||||
var paySign: String? = null
|
||||
var appId: String? = null
|
||||
var partnerId: String? = null
|
||||
var prepayId: String? = null
|
||||
var signType: String? = null
|
||||
var nonceStr: String? = null
|
||||
|
||||
var RC1782974779440000002 : String? = null
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
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? = ""
|
||||
|
||||
}
|
||||
var content: String? = ""
|
||||
var downloadUrl: String? = ""
|
||||
var hasUpdate: Boolean = false
|
||||
var isForce: Boolean = false
|
||||
var versionCode: Int = 0
|
||||
var versionName: String? = ""
|
||||
}
|
||||
|
||||
@@ -4,4 +4,10 @@ class WithDrawModel {
|
||||
|
||||
var amount :String? = ""
|
||||
var payMethod :String? = ""
|
||||
}
|
||||
var authPackageInfo :String? = null
|
||||
var thirdOrderNo :String? = null
|
||||
var outBillNo :String? = null
|
||||
var mchId :String? = null
|
||||
var appId :String? = null
|
||||
var needConfirm :Boolean = false
|
||||
}
|
||||
|
||||
@@ -29,7 +29,11 @@ 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)
|
||||
val permissions = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||
listOf(Manifest.permission.BLUETOOTH_SCAN, Manifest.permission.BLUETOOTH_CONNECT)
|
||||
} else {
|
||||
listOf(Manifest.permission.ACCESS_FINE_LOCATION)
|
||||
}
|
||||
|
||||
lateinit var blueBoothAdapter: BlueBoothAdapter
|
||||
var devices = mutableListOf<String>()
|
||||
@@ -185,7 +189,17 @@ class BlueToothActivity : CKBaseActivity() , PermissionCallbacks{
|
||||
requestCode: Int,
|
||||
perms: List<String?>
|
||||
) {
|
||||
val deniedPermissions = perms.filterNotNull().toTypedArray()
|
||||
val permanentlyDenied = deniedPermissions.any {
|
||||
!ActivityCompat.shouldShowRequestPermissionRationale(this, it)
|
||||
}
|
||||
if (permanentlyDenied) {
|
||||
super.onPermissionsDenied(requestCode, deniedPermissions, true)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onPermissionsGranted(requestCode: Int, permissions: Array<String>) {
|
||||
initData()
|
||||
}
|
||||
|
||||
class BlueBoothAdapter(var context: CKBaseActivity, var scanResults: List<String>) : RecyclerView.Adapter<BlueBoothAdapter.BlueBoothHolder>() {
|
||||
@@ -215,4 +229,4 @@ class BlueToothActivity : CKBaseActivity() , PermissionCallbacks{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -143,7 +143,17 @@ class WifiListActivity : CKBaseActivity(), PermissionCallbacks {
|
||||
requestCode: Int,
|
||||
perms: List<String?>
|
||||
) {
|
||||
val deniedPermissions = perms.filterNotNull().toTypedArray()
|
||||
val permanentlyDenied = deniedPermissions.any {
|
||||
!ActivityCompat.shouldShowRequestPermissionRationale(this, it)
|
||||
}
|
||||
if (permanentlyDenied) {
|
||||
super.onPermissionsDenied(requestCode, deniedPermissions, true)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onPermissionsGranted(requestCode: Int, permissions: Array<String>) {
|
||||
initData()
|
||||
}
|
||||
|
||||
class WifiAdapter(var context: CKBaseActivity, var scanResults: List<ScanResult>) : RecyclerView.Adapter<WifiAdapter.WifiiewHoldr>() {
|
||||
@@ -177,4 +187,4 @@ class WifiListActivity : CKBaseActivity(), PermissionCallbacks {
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,6 +39,8 @@ import java.text.SimpleDateFormat
|
||||
import java.util.Date
|
||||
|
||||
class BalanceActivity : CKLHBaseActionBarActivity() , View.OnClickListener{
|
||||
override val shouldRequestPermissionsOnCreate: Boolean = false
|
||||
|
||||
lateinit var binding: ActivityBalanceBinding
|
||||
var data = listOf<RecordModel>()
|
||||
lateinit var adapter: RecordAdapter
|
||||
@@ -116,9 +118,16 @@ class BalanceActivity : CKLHBaseActionBarActivity() , View.OnClickListener{
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
|
||||
getBalanceInfo()
|
||||
|
||||
getList()
|
||||
showProgeassDialog()
|
||||
var pendingRequests = 2
|
||||
val onRequestFinished = {
|
||||
pendingRequests--
|
||||
if (pendingRequests == 0) {
|
||||
hiddenProgeassDialog()
|
||||
}
|
||||
}
|
||||
getBalanceInfo(onRequestFinished)
|
||||
getList(onRequestFinished)
|
||||
}
|
||||
override fun getResult(data: DataCollection, resultCode: Int) {
|
||||
if (resultCode == 1001){
|
||||
@@ -127,22 +136,24 @@ class BalanceActivity : CKLHBaseActionBarActivity() , View.OnClickListener{
|
||||
getList()
|
||||
}
|
||||
}
|
||||
fun getBalanceInfo(){
|
||||
fun getBalanceInfo(onFinished: (() -> Unit)? = null){
|
||||
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()
|
||||
onFinished?.invoke()
|
||||
|
||||
}
|
||||
|
||||
override fun onFailed(code: String, msg: String) {
|
||||
onFinished?.invoke()
|
||||
toast(msg)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fun getList(){
|
||||
fun getList(onFinished: (() -> Unit)? = null){
|
||||
TTHttpClient.get(this,"余额明细列表", TTRequestParam().apply { add(TTRequestData("type",type))
|
||||
add(TTRequestData("month",""))},object : ICallback{
|
||||
override fun onSuccess(data: String) {
|
||||
@@ -150,9 +161,11 @@ class BalanceActivity : CKLHBaseActionBarActivity() , View.OnClickListener{
|
||||
|
||||
adapter.data = this@BalanceActivity.data
|
||||
adapter.notifyDataSetChanged()
|
||||
onFinished?.invoke()
|
||||
}
|
||||
|
||||
override fun onFailed(code: String, msg: String) {
|
||||
onFinished?.invoke()
|
||||
toast(msg)
|
||||
}
|
||||
})
|
||||
@@ -238,4 +251,4 @@ class BalanceActivity : CKLHBaseActionBarActivity() , View.OnClickListener{
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
package com.ck.ckcollar.app.ui.act.balance
|
||||
|
||||
import android.content.pm.ApplicationInfo
|
||||
import android.os.Bundle
|
||||
import android.text.TextUtils
|
||||
import com.alipay.sdk.app.EnvUtils
|
||||
import com.alipay.sdk.app.PayTask
|
||||
import com.ck.ckcollar.app.R
|
||||
import com.ck.ckcollar.app.utils.Const
|
||||
import com.ck.ckcollar.app.databinding.ActivityRechargeBinding
|
||||
import com.ck.ckcollar.app.model.PayResult
|
||||
import com.ck.ckcollar.app.model.RechargeModel
|
||||
@@ -14,7 +17,10 @@ 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.tencent.mm.opensdk.modelpay.PayReq
|
||||
import com.tencent.mm.opensdk.openapi.WXAPIFactory
|
||||
import com.tt.kit.model.DataCollection
|
||||
import com.tt.kit.utils.LiveDataBus
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.launch
|
||||
@@ -23,7 +29,7 @@ import kotlinx.coroutines.withContext
|
||||
|
||||
class RechargeActivity : CKBaseActivity() {
|
||||
lateinit var binding: ActivityRechargeBinding
|
||||
var payType = "1"
|
||||
var payType = "0"
|
||||
var model : RechargeModel? = null
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
binding = ActivityRechargeBinding.inflate(layoutInflater)
|
||||
@@ -35,6 +41,17 @@ class RechargeActivity : CKBaseActivity() {
|
||||
|
||||
override fun initView() {
|
||||
|
||||
LiveDataBus.get().with(WX_PAY_RESULT, Int::class.java).observe(this) { result ->
|
||||
when (result) {
|
||||
0 -> {
|
||||
toast(getString(R.string.recharge_success))
|
||||
finish(DataCollection(), 1001)
|
||||
}
|
||||
-2 -> toast("已取消微信支付")
|
||||
else -> toast(getString(R.string.recharge_faild))
|
||||
}
|
||||
}
|
||||
|
||||
binding.btnAli.setOnClickListener {
|
||||
binding.image1.setImageResource(R.mipmap.image_address_check_select)
|
||||
binding.image2.setImageResource(R.mipmap.image_address_check_narmal)
|
||||
@@ -69,6 +86,8 @@ class RechargeActivity : CKBaseActivity() {
|
||||
|
||||
if ("1".equals(payType)){
|
||||
aliPay()
|
||||
}else if("0".equals(payType)){
|
||||
wxPay()
|
||||
}
|
||||
|
||||
}
|
||||
@@ -87,7 +106,10 @@ class RechargeActivity : CKBaseActivity() {
|
||||
|
||||
fun aliPay(){
|
||||
GlobalScope.launch(Dispatchers.IO){
|
||||
|
||||
// [支付宝沙箱测试] 仅 Debug 包启用,Release 包继续使用正式环境。
|
||||
if (applicationInfo.flags and ApplicationInfo.FLAG_DEBUGGABLE != 0) {
|
||||
// EnvUtils.setEnv(EnvUtils.EnvEnum.SANDBOX)
|
||||
}
|
||||
val alipay = PayTask(this@RechargeActivity)
|
||||
val result = alipay.payV2(model?.orderStr, true)
|
||||
|
||||
@@ -107,4 +129,54 @@ class RechargeActivity : CKBaseActivity() {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
private fun wxPay() {
|
||||
val payModel = model ?: return
|
||||
val requiredValues = listOf(
|
||||
payModel.appId,
|
||||
payModel.partnerId,
|
||||
payModel.prepayId,
|
||||
payModel.packageVal,
|
||||
payModel.nonceStr,
|
||||
payModel.timeStamp,
|
||||
payModel.paySign
|
||||
)
|
||||
if (requiredValues.any { it.isNullOrBlank() }) {
|
||||
hiddenProgeassDialog()
|
||||
toast("微信支付参数不完整,请检查商户号等支付参数")
|
||||
return
|
||||
}
|
||||
if (payModel.appId != Const.WX_APP_ID) {
|
||||
hiddenProgeassDialog()
|
||||
toast("微信支付 AppID 不匹配")
|
||||
return
|
||||
}
|
||||
|
||||
val api = WXAPIFactory.createWXAPI(this, Const.WX_APP_ID, true)
|
||||
api.registerApp(Const.WX_APP_ID)
|
||||
if (!api.isWXAppInstalled) {
|
||||
hiddenProgeassDialog()
|
||||
toast("请先安装微信")
|
||||
return
|
||||
}
|
||||
|
||||
val request = PayReq().apply {
|
||||
appId = payModel.appId
|
||||
partnerId = payModel.partnerId
|
||||
prepayId = payModel.prepayId
|
||||
packageValue = payModel.packageVal
|
||||
nonceStr = payModel.nonceStr
|
||||
timeStamp = payModel.timeStamp
|
||||
sign = payModel.paySign
|
||||
extData = payModel.orderNo
|
||||
}
|
||||
hiddenProgeassDialog()
|
||||
if (!api.sendReq(request)) {
|
||||
toast("微信支付拉起失败")
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val WX_PAY_RESULT = "wx_pay_result"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -20,13 +20,19 @@ import com.google.gson.Gson
|
||||
import com.gyf.immersionbar.ImmersionBar
|
||||
import com.tt.kit.model.Data
|
||||
import com.tt.kit.model.DataCollection
|
||||
import com.tt.kit.utils.LiveDataBus
|
||||
import com.tencent.mm.opensdk.modelbiz.WXOpenBusinessView
|
||||
import com.tencent.mm.opensdk.openapi.WXAPIFactory
|
||||
import com.ck.ckcollar.app.utils.Const
|
||||
import java.net.URLEncoder
|
||||
import java.math.BigDecimal
|
||||
|
||||
class WithDrawActivity : CKLHBaseActionBarActivity() {
|
||||
lateinit var binding: ActivityWithdrawBinding
|
||||
var model : BalanceModle? = null
|
||||
private var pendingWithdraw: WithDrawModel? = null
|
||||
|
||||
var payType = "1"
|
||||
var payType = "0"
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
binding = ActivityWithdrawBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
@@ -39,6 +45,14 @@ class WithDrawActivity : CKLHBaseActionBarActivity() {
|
||||
}
|
||||
|
||||
override fun initView() {
|
||||
LiveDataBus.get().with(WX_WITHDRAW_RESULT, Int::class.java).observe(this) { resultCode ->
|
||||
val withdraw = pendingWithdraw ?: return@observe
|
||||
if (resultCode == 0) {
|
||||
showWithdrawSuccess(withdraw)
|
||||
} else {
|
||||
toast(if (resultCode == -2) "已取消微信收款确认" else "微信提现确认失败")
|
||||
}
|
||||
}
|
||||
|
||||
binding.btnAli.setOnClickListener {
|
||||
binding.image1.setImageResource(R.mipmap.image_address_check_select)
|
||||
@@ -70,29 +84,34 @@ class WithDrawActivity : CKLHBaseActionBarActivity() {
|
||||
toast(getString(R.string.no_balance_data))
|
||||
return
|
||||
}
|
||||
if (TextUtils.isEmpty(binding.editAmount.text.toString())){
|
||||
val amountText = binding.editAmount.text.toString()
|
||||
if (TextUtils.isEmpty(amountText)){
|
||||
toast(getString(R.string.withdraw_amount_not_empty))
|
||||
return
|
||||
}
|
||||
if (binding.editAmount.text.toString().toDouble() > model!!.balance){
|
||||
val amount = amountText.toBigDecimalOrNull()
|
||||
if (amount == null || amount < BigDecimal("0.1")) {
|
||||
toast(getString(R.string.withdraw_amount_minimum))
|
||||
return
|
||||
}
|
||||
if (amount > BigDecimal.valueOf(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("amount", amountText))
|
||||
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()
|
||||
val withdraw = Gson().fromJson(data, WithDrawModel::class.java)
|
||||
pendingWithdraw = withdraw
|
||||
if (withdraw.needConfirm && "0" == payType) {
|
||||
openWeChatTransferConfirm(withdraw)
|
||||
} else {
|
||||
showWithdrawSuccess(withdraw)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -104,6 +123,52 @@ class WithDrawActivity : CKLHBaseActionBarActivity() {
|
||||
|
||||
}
|
||||
|
||||
private fun openWeChatTransferConfirm(withdraw: WithDrawModel) {
|
||||
val mchId = withdraw.mchId
|
||||
val appId = withdraw.appId
|
||||
val packageInfo = withdraw.authPackageInfo
|
||||
if (mchId.isNullOrBlank() || appId.isNullOrBlank() || packageInfo.isNullOrBlank()) {
|
||||
toast("微信收款确认参数不完整")
|
||||
return
|
||||
}
|
||||
if (appId != Const.WX_APP_ID) {
|
||||
toast("微信支付 AppID 不匹配")
|
||||
return
|
||||
}
|
||||
|
||||
val api = WXAPIFactory.createWXAPI(this, Const.WX_APP_ID, true)
|
||||
api.registerApp(Const.WX_APP_ID)
|
||||
if (!api.isWXAppInstalled) {
|
||||
toast("请先安装微信")
|
||||
return
|
||||
}
|
||||
if (api.wxAppSupportAPI < 0x28002d33) {
|
||||
toast("当前微信版本过低,请升级微信")
|
||||
return
|
||||
}
|
||||
|
||||
val request = WXOpenBusinessView.Req().apply {
|
||||
businessType = "requestMerchantTransfer"
|
||||
query = "mchId=${URLEncoder.encode(mchId, "UTF-8")}" +
|
||||
"&appId=${URLEncoder.encode(appId, "UTF-8")}" +
|
||||
"&package=${URLEncoder.encode(packageInfo, "UTF-8")}"
|
||||
}
|
||||
if (!api.sendReq(request)) {
|
||||
toast("微信收款确认页拉起失败")
|
||||
}
|
||||
}
|
||||
|
||||
private fun showWithdrawSuccess(withdraw: WithDrawModel) {
|
||||
toActivity(WithDrawSuccessActivity::class.java, DataCollection().apply {
|
||||
add(Data("data", Gson().toJson(withdraw)))
|
||||
})
|
||||
finish()
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val WX_WITHDRAW_RESULT = "wx_withdraw_result"
|
||||
}
|
||||
|
||||
|
||||
fun getBalanceInfo(){
|
||||
TTHttpClient.get(this,"余额", TTRequestParam(),object : ICallback{
|
||||
@@ -119,4 +184,4 @@ class WithDrawActivity : CKLHBaseActionBarActivity() {
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
package com.ck.ckcollar.app.ui.act.customer
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.widget.ImageView
|
||||
import com.bumptech.glide.Glide
|
||||
import com.bumptech.glide.load.DataSource
|
||||
import com.bumptech.glide.load.engine.GlideException
|
||||
import com.bumptech.glide.request.RequestListener
|
||||
import com.bumptech.glide.request.target.Target
|
||||
import com.ck.ckcollar.app.R
|
||||
|
||||
object ChatImageLoader {
|
||||
fun load(context: Context, imageView: ImageView, imageUrl: String) {
|
||||
imageView.tag = imageUrl
|
||||
resetSize(imageView)
|
||||
Glide.with(context)
|
||||
.load(imageUrl)
|
||||
.placeholder(R.mipmap.image_default)
|
||||
.listener(object : RequestListener<Drawable> {
|
||||
override fun onLoadFailed(
|
||||
e: GlideException?,
|
||||
model: Any?,
|
||||
target: Target<Drawable>?,
|
||||
isFirstResource: Boolean
|
||||
): Boolean = false
|
||||
|
||||
override fun onResourceReady(
|
||||
resource: Drawable,
|
||||
model: Any,
|
||||
target: Target<Drawable>?,
|
||||
dataSource: DataSource,
|
||||
isFirstResource: Boolean
|
||||
): Boolean {
|
||||
if (imageView.tag == imageUrl) {
|
||||
setSize(imageView, resource.intrinsicWidth, resource.intrinsicHeight)
|
||||
}
|
||||
return false
|
||||
}
|
||||
})
|
||||
.into(imageView)
|
||||
}
|
||||
|
||||
private fun resetSize(imageView: ImageView) {
|
||||
val density = imageView.resources.displayMetrics.density
|
||||
imageView.layoutParams = imageView.layoutParams.apply {
|
||||
width = maxWidth(imageView, density)
|
||||
height = (200 * density).toInt()
|
||||
}
|
||||
}
|
||||
|
||||
private fun setSize(imageView: ImageView, sourceWidth: Int, sourceHeight: Int) {
|
||||
if (sourceWidth <= 0 || sourceHeight <= 0) return
|
||||
val density = imageView.resources.displayMetrics.density
|
||||
val maxWidth = maxWidth(imageView, density).toFloat()
|
||||
val maxHeight = 200 * density
|
||||
val scale = minOf(1f, maxWidth / sourceWidth, maxHeight / sourceHeight)
|
||||
imageView.layoutParams = imageView.layoutParams.apply {
|
||||
width = (sourceWidth * scale).toInt().coerceAtLeast(1)
|
||||
height = (sourceHeight * scale).toInt().coerceAtLeast(1)
|
||||
}
|
||||
}
|
||||
|
||||
private fun maxWidth(imageView: ImageView, density: Float): Int {
|
||||
val requestedWidth = (200 * density).toInt()
|
||||
val availableWidth = imageView.resources.displayMetrics.widthPixels - (155 * density).toInt()
|
||||
return minOf(requestedWidth, availableWidth.coerceAtLeast(1))
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,9 @@
|
||||
package com.ck.ckcollar.app.ui.act.customer
|
||||
|
||||
import android.Manifest
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
@@ -10,21 +12,23 @@ 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.view.inputmethod.InputMethodManager
|
||||
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.bumptech.glide.load.DataSource
|
||||
import com.bumptech.glide.load.engine.GlideException
|
||||
import com.bumptech.glide.request.RequestListener
|
||||
import com.bumptech.glide.request.target.Target
|
||||
import com.ck.ckcollar.app.CKApp
|
||||
import com.ck.ckcollar.app.R
|
||||
import com.ck.ckcollar.app.action.ActionCode
|
||||
@@ -40,6 +44,7 @@ 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.LubanCompressUtil
|
||||
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
|
||||
@@ -53,9 +58,49 @@ 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 io.noties.markwon.Markwon
|
||||
import java.io.File
|
||||
import java.util.UUID
|
||||
import kotlin.math.min
|
||||
|
||||
private object CustomerMarkdownDetector {
|
||||
private val blockMarkdown = Regex(
|
||||
"(?m)^(?:\\s{0,3}(?:#{1,6}\\s+|[-*+]\\s+|>\\s+|\\d+\\.\\s+|```|~~~|(?:-{3,}|_{3,}|\\*{3,})\\s*$))"
|
||||
)
|
||||
private val inlineMarkdown = Regex("(?:\\*\\*[^\\n]+?\\*\\*|`[^\\n]+?`|\\[[^\\]]+?\\]\\([^\\s)]+?\\))")
|
||||
|
||||
fun isMarkdown(content: String): Boolean = content.isNotBlank() &&
|
||||
(blockMarkdown.containsMatchIn(content) || inlineMarkdown.containsMatchIn(content))
|
||||
|
||||
fun normalize(content: String): String {
|
||||
val normalized = content
|
||||
// SSE chunks contain JSON-escaped line breaks; Markwon otherwise renders
|
||||
// "\\n\\n" as "nn" and keeps the first list item inside the heading.
|
||||
.replace("\\r\\n", "\n")
|
||||
.replace("\\n", "\n")
|
||||
// AI responses commonly omit the required spaces after block markers.
|
||||
.replace(Regex("(?m)^(\\s{0,3}#{1,6})(?=\\S)"), "$1 ")
|
||||
.replace(Regex("(?m)^(\\s{0,3}>)(?=\\S)"), "$1 ")
|
||||
.replace(Regex("(?m)^(\\s{0,3}[-+])(?!\\s)(?=\\S)"), "$1 ")
|
||||
.replace(Regex("(?m)^(\\s{0,3}\\*)(?![\\s*])(?=\\S)"), "$1 ")
|
||||
.replace(Regex("(?m)^(\\s{0,3}\\d+\\.)(?=\\S)"), "$1 ")
|
||||
// Split compact numbered sections such as "。2.**标题**" into list rows.
|
||||
.replace(Regex("(\\d+)\\.\\s*(?=\\*\\*)"), "$1. ")
|
||||
.replace(Regex("([^\\n])(?=\\d+\\. \\*\\*)")) { match ->
|
||||
match.value + "\n"
|
||||
}
|
||||
.replace(Regex("([^\\n])(?=免责声明[::])")) { match ->
|
||||
match.value + "\n\n"
|
||||
}
|
||||
|
||||
// TextView has no CSS-like heading margins, so preserve a blank line
|
||||
// after Markdown headings for readable streamed responses.
|
||||
return normalized.replace(
|
||||
Regex("(?m)^(\\s{0,3}#{1,6}\\s+[^\\n]+)\\n(?!\\n)")
|
||||
) { match ->
|
||||
match.groupValues[1] + "\n\n"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class CustomerActivity : CKBaseActivity() {
|
||||
|
||||
@@ -64,6 +109,8 @@ class CustomerActivity : CKBaseActivity() {
|
||||
var data = mutableListOf<CustomerMessageModel.MessageItemModel>()
|
||||
|
||||
var path = ""
|
||||
private var isSending = false
|
||||
private var isAiResponding = false
|
||||
var url = ""
|
||||
|
||||
var lock = true
|
||||
@@ -71,7 +118,6 @@ class CustomerActivity : CKBaseActivity() {
|
||||
binding = ActivityCustomerBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
super.onCreate(savedInstanceState)
|
||||
checkAppPermissions()
|
||||
|
||||
setTitleText(getString(R.string.customer_service4))
|
||||
|
||||
@@ -94,6 +140,28 @@ class CustomerActivity : CKBaseActivity() {
|
||||
binding.recyclerView.adapter = customerMessageAdapter
|
||||
|
||||
binding.editMessage.setHorizontallyScrolling(false);
|
||||
binding.btnSend.setOnClickListener {
|
||||
if (isAiResponding) {
|
||||
toast("请等待当前问题回答结束")
|
||||
return@setOnClickListener
|
||||
}
|
||||
isSending = true
|
||||
// Reset the action controls immediately. The send flow captures the
|
||||
// submitted text and image path before clearing the visible draft.
|
||||
binding.btnSend.visibility = View.GONE
|
||||
binding.btnMore.visibility = View.VISIBLE
|
||||
binding.editMessage.onEditorAction(EditorInfo.IME_ACTION_SEND)
|
||||
}
|
||||
updateSendControls()
|
||||
// Use the traditional multiline keyboard action; sending is handled by the
|
||||
// activity's own message flow rather than the IME action button.
|
||||
binding.editMessage.setSingleLine(false)
|
||||
binding.editMessage.imeOptions = EditorInfo.IME_ACTION_NONE
|
||||
binding.editMessage.setRawInputType(android.text.InputType.TYPE_CLASS_TEXT or android.text.InputType.TYPE_TEXT_FLAG_MULTI_LINE)
|
||||
// setSingleLine(false) resets the XML maxLines value, so apply it last.
|
||||
binding.editMessage.maxLines = 4
|
||||
binding.editMessage.maxHeight = (70 * resources.displayMetrics.density).toInt()
|
||||
binding.editMessage.isVerticalScrollBarEnabled = true
|
||||
|
||||
binding.editMessage.setOnEditorActionListener(object : TextView.OnEditorActionListener {
|
||||
override fun onEditorAction(
|
||||
@@ -101,21 +169,21 @@ class CustomerActivity : CKBaseActivity() {
|
||||
actionId: Int,
|
||||
ketEvent: KeyEvent?
|
||||
): Boolean {
|
||||
if (actionId == EditorInfo.IME_ACTION_UNSPECIFIED ||
|
||||
actionId == EditorInfo.IME_ACTION_SEND ||
|
||||
(ketEvent != null && ketEvent.keyCode == KeyEvent.KEYCODE_ENTER)
|
||||
) {
|
||||
if (actionId == EditorInfo.IME_ACTION_SEND) {
|
||||
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)) {
|
||||
// Whitespace-only input is not a message. A selected image may still be sent alone.
|
||||
val text = binding.editMessage.text.toString().trim()
|
||||
if (text.isNotEmpty() || path.isNotEmpty()) {
|
||||
lock = false
|
||||
KeyboardUtils.hideKeyboard(this@CustomerActivity)
|
||||
binding.editMessage.clearFocus()
|
||||
handler.post {
|
||||
sendMessage(UUID.randomUUID().toString(),text,false)
|
||||
if (!TextUtils.isEmpty(path)) {
|
||||
uploadImage(text, path)
|
||||
} else {
|
||||
sendMessage(UUID.randomUUID().toString(), text, false, "")
|
||||
}
|
||||
clearInputViews()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -153,31 +221,19 @@ class CustomerActivity : CKBaseActivity() {
|
||||
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()
|
||||
}
|
||||
if (p0?.toString()?.trim()?.isNotEmpty() == true) isSending = false
|
||||
updateSendControls()
|
||||
}
|
||||
})
|
||||
binding.btnMore.setOnClickListener {
|
||||
if (binding.contentBottom.visibility == View.GONE) {
|
||||
KeyboardUtils.hideKeyboard(this@CustomerActivity)
|
||||
val inputMethodManager =
|
||||
getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
|
||||
inputMethodManager.hideSoftInputFromWindow(binding.editMessage.windowToken, 0)
|
||||
binding.editMessage.clearFocus()
|
||||
binding.contentBottom.visibility = View.VISIBLE
|
||||
} else {
|
||||
binding.contentBottom.visibility = View.GONE
|
||||
binding.editMessage.requestFocus()
|
||||
KeyboardUtils.showKeyboard(binding.editMessage)
|
||||
}
|
||||
}
|
||||
binding.btnSmile.setOnClickListener {
|
||||
@@ -185,25 +241,35 @@ class CustomerActivity : CKBaseActivity() {
|
||||
binding.editMessage.requestFocus()
|
||||
KeyboardUtils.showKeyboard(binding.editMessage)
|
||||
}
|
||||
binding.btnDeleteImage.setOnClickListener {
|
||||
clearSelectedImage()
|
||||
}
|
||||
//拍照
|
||||
binding.conetnt1.setOnClickListener {
|
||||
|
||||
if (TextUtils.isEmpty(path)) {
|
||||
takePhoto()
|
||||
getPermissionRequst(
|
||||
Manifest.permission.CAMERA,
|
||||
REQUEST_CAMERA_PERMISSION
|
||||
)
|
||||
} 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
|
||||
val permission = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
Manifest.permission.READ_MEDIA_IMAGES
|
||||
} else {
|
||||
Manifest.permission.READ_EXTERNAL_STORAGE
|
||||
}
|
||||
getPermissionRequst(
|
||||
permission,
|
||||
REQUEST_PHOTO_PERMISSION
|
||||
)
|
||||
i.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,"image/*");
|
||||
startActivityForResult(i, 56)
|
||||
} else {
|
||||
toast(getString(R.string.only_one_photo))
|
||||
}
|
||||
@@ -223,7 +289,22 @@ class CustomerActivity : CKBaseActivity() {
|
||||
}
|
||||
}
|
||||
handleMessage()
|
||||
binding.btnSmile.visibility = View.GONE;
|
||||
}
|
||||
|
||||
override fun onPermissionsGranted(requestCode: Int, permissions: Array<String>) {
|
||||
when (requestCode) {
|
||||
REQUEST_CAMERA_PERMISSION -> takePhoto()
|
||||
REQUEST_PHOTO_PERMISSION -> {
|
||||
val intent = Intent(
|
||||
Intent.ACTION_PICK,
|
||||
MediaStore.Images.Media.EXTERNAL_CONTENT_URI
|
||||
).apply {
|
||||
setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*")
|
||||
}
|
||||
startActivityForResult(intent, 56)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun initData() {
|
||||
@@ -270,7 +351,7 @@ class CustomerActivity : CKBaseActivity() {
|
||||
|
||||
if (!TextUtils.isEmpty(sendConetnt) || !TextUtils.isEmpty(url)){
|
||||
handler.post {
|
||||
sendMessage2(UUID.randomUUID().toString(),sendConetnt,true)
|
||||
sendMessage2(UUID.randomUUID().toString(),sendConetnt,true, url)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -297,15 +378,18 @@ class CustomerActivity : CKBaseActivity() {
|
||||
}).show()
|
||||
}
|
||||
|
||||
fun sendMessage(uuid :String ,content: String,isResend : Boolean) {
|
||||
fun sendMessage(uuid :String ,content: String,isResend : Boolean, imageUrl: String) {
|
||||
|
||||
if (!TextUtils.isEmpty(url)) {
|
||||
isAiResponding = true
|
||||
val rawStreamResponse = StringBuilder()
|
||||
|
||||
if (!TextUtils.isEmpty(imageUrl)) {
|
||||
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
|
||||
this.url = imageUrl
|
||||
})
|
||||
}
|
||||
if (!TextUtils.isEmpty(content) && !isResend) {
|
||||
@@ -325,13 +409,13 @@ class CustomerActivity : CKBaseActivity() {
|
||||
|
||||
|
||||
TTHttpClient.postJsonStream3(this, "发送会话消息stream", TTRequestParam().apply {
|
||||
add(TTRequestData("imageUrl", url))
|
||||
add(TTRequestData("imageUrl", imageUrl))
|
||||
|
||||
add(TTRequestData("question", content))
|
||||
}, object : ICallback {
|
||||
override fun onSuccess(data: String) {
|
||||
|
||||
lock = true
|
||||
rawStreamResponse.append(data)
|
||||
|
||||
// var model = Gson().fromJson<AIMessageModel>(data, AIMessageModel::class.java)
|
||||
|
||||
@@ -354,9 +438,6 @@ class CustomerActivity : CKBaseActivity() {
|
||||
}
|
||||
|
||||
|
||||
binding.editMessage.setText("")
|
||||
path = ""
|
||||
url = ""
|
||||
customerMessageAdapter.data = this@CustomerActivity.data
|
||||
customerMessageAdapter.notifyDataSetChanged()
|
||||
|
||||
@@ -376,13 +457,19 @@ class CustomerActivity : CKBaseActivity() {
|
||||
}
|
||||
|
||||
override fun onFailed(code: String, msg: String) {
|
||||
isAiResponding = false
|
||||
lock = true
|
||||
TTLog.e("AI_STREAM_FULL[$uuid][FAILED]: $rawStreamResponse")
|
||||
// toast(msg)
|
||||
//TTLog.e(msg)
|
||||
}
|
||||
})
|
||||
|
||||
binding.editMessage.setText("")
|
||||
override fun onComplete() {
|
||||
isAiResponding = false
|
||||
lock = true
|
||||
TTLog.e("AI_STREAM_FULL[$uuid]: $rawStreamResponse")
|
||||
}
|
||||
})
|
||||
|
||||
customerMessageAdapter.data = this@CustomerActivity.data
|
||||
customerMessageAdapter.notifyDataSetChanged()
|
||||
@@ -393,7 +480,9 @@ class CustomerActivity : CKBaseActivity() {
|
||||
|
||||
|
||||
|
||||
fun sendMessage2(uuid :String ,content: String,isResend : Boolean) {
|
||||
fun sendMessage2(uuid :String ,content: String,isResend : Boolean, imageUrl: String) {
|
||||
isAiResponding = true
|
||||
val rawStreamResponse = StringBuilder()
|
||||
lock = false
|
||||
if (!TextUtils.isEmpty(content) && !isResend) {
|
||||
this@CustomerActivity.data.add(CustomerMessageModel.MessageItemModel().apply {
|
||||
@@ -412,13 +501,13 @@ class CustomerActivity : CKBaseActivity() {
|
||||
|
||||
|
||||
TTHttpClient.postJsonStream3(this, "发送会话消息stream", TTRequestParam().apply {
|
||||
add(TTRequestData("imageUrl", url))
|
||||
add(TTRequestData("imageUrl", imageUrl))
|
||||
|
||||
add(TTRequestData("question", content))
|
||||
}, object : ICallback {
|
||||
override fun onSuccess(data: String) {
|
||||
|
||||
lock = true
|
||||
rawStreamResponse.append(data)
|
||||
|
||||
// var model = Gson().fromJson<AIMessageModel>(data, AIMessageModel::class.java)
|
||||
|
||||
@@ -441,9 +530,6 @@ class CustomerActivity : CKBaseActivity() {
|
||||
}
|
||||
|
||||
|
||||
binding.editMessage.setText("")
|
||||
path = ""
|
||||
url = ""
|
||||
customerMessageAdapter.data = this@CustomerActivity.data
|
||||
customerMessageAdapter.notifyDataSetChanged()
|
||||
|
||||
@@ -463,13 +549,19 @@ class CustomerActivity : CKBaseActivity() {
|
||||
}
|
||||
|
||||
override fun onFailed(code: String, msg: String) {
|
||||
isAiResponding = false
|
||||
lock = true
|
||||
TTLog.e("AI_STREAM_FULL[$uuid][FAILED]: $rawStreamResponse")
|
||||
// toast(msg)
|
||||
//TTLog.e(msg)
|
||||
}
|
||||
})
|
||||
|
||||
binding.editMessage.setText("")
|
||||
override fun onComplete() {
|
||||
isAiResponding = false
|
||||
lock = true
|
||||
TTLog.e("AI_STREAM_FULL[$uuid]: $rawStreamResponse")
|
||||
}
|
||||
})
|
||||
|
||||
customerMessageAdapter.data = this@CustomerActivity.data
|
||||
customerMessageAdapter.notifyDataSetChanged()
|
||||
@@ -479,10 +571,10 @@ class CustomerActivity : CKBaseActivity() {
|
||||
}
|
||||
|
||||
|
||||
fun uploadImage() {
|
||||
fun uploadImage(content: String, imagePath: String) {
|
||||
|
||||
var param = TTRequestParam()
|
||||
param.files.add(File(path))
|
||||
param.files.add(File(imagePath))
|
||||
|
||||
showProgeassDialog()
|
||||
TTHttpClient.postFile(this, "上传照片s", param, object : ICallback {
|
||||
@@ -490,33 +582,25 @@ class CustomerActivity : CKBaseActivity() {
|
||||
hiddenProgeassDialog()
|
||||
var model = Gson().fromJson<UploadModel>(data, UploadModel::class.java)
|
||||
|
||||
url = model.urls
|
||||
handler.post {
|
||||
sendMessage(UUID.randomUUID().toString(), content, false, model.urls)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override fun onFailed(code: String, msg: String) {
|
||||
hiddenProgeassDialog()
|
||||
lock = true
|
||||
if (path.isEmpty() && binding.editMessage.text.toString().isEmpty()) {
|
||||
path = imagePath
|
||||
showImagePreview(imagePath)
|
||||
binding.editMessage.setText(content)
|
||||
}
|
||||
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) {
|
||||
@@ -546,17 +630,89 @@ class CustomerActivity : CKBaseActivity() {
|
||||
|
||||
if (requestCode == 55 && resultCode == RESULT_OK) {
|
||||
path = PreferencesUtils.getString(this@CustomerActivity, Const.IMAGE_PATH, "")!!
|
||||
|
||||
addImage(path!!)
|
||||
uploadImage()
|
||||
prepareSelectedImage()
|
||||
} else if (requestCode == 56 && resultCode == RESULT_OK) {
|
||||
path = TTUtils.getImageUrl(this, data!!.getData());
|
||||
addImage(path)
|
||||
uploadImage()
|
||||
prepareSelectedImage()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private fun prepareSelectedImage() {
|
||||
if (TextUtils.isEmpty(path)) return
|
||||
|
||||
LubanCompressUtil.getCompressFile(
|
||||
this,
|
||||
File(path),
|
||||
object : LubanCompressUtil.CompressCallback {
|
||||
override fun success(file: File) {
|
||||
if (isFinishing || isDestroyed) return
|
||||
path = file.absolutePath
|
||||
lock = true
|
||||
binding.contentBottom.visibility = View.GONE
|
||||
showImagePreview(path)
|
||||
binding.editMessage.requestFocus()
|
||||
KeyboardUtils.showKeyboard(binding.editMessage)
|
||||
// Rebind the IME after selecting an image so its action button is
|
||||
// available even though the text field itself is empty.
|
||||
binding.editMessage.postDelayed({
|
||||
val imm = getSystemService(INPUT_METHOD_SERVICE) as? android.view.inputmethod.InputMethodManager
|
||||
imm?.restartInput(binding.editMessage)
|
||||
}, 150L)
|
||||
}
|
||||
|
||||
override fun fail(failMsg: String) {
|
||||
if (isFinishing || isDestroyed) return
|
||||
lock = true
|
||||
path = ""
|
||||
toast(failMsg)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
private fun showImagePreview(imagePath: String) {
|
||||
isSending = false
|
||||
binding.contentImagePreview.visibility = View.VISIBLE
|
||||
updateSendControls()
|
||||
binding.imagePreview.scaleType = android.widget.ImageView.ScaleType.CENTER_CROP
|
||||
Glide.with(this)
|
||||
.load(imagePath)
|
||||
.into(binding.imagePreview)
|
||||
}
|
||||
|
||||
private fun clearSelectedImage() {
|
||||
path = ""
|
||||
url = ""
|
||||
binding.imagePreview.setImageDrawable(null)
|
||||
binding.contentImagePreview.visibility = View.GONE
|
||||
updateSendControls()
|
||||
}
|
||||
|
||||
private fun clearInputViews() {
|
||||
binding.editMessage.setText("")
|
||||
path = ""
|
||||
url = ""
|
||||
binding.imagePreview.setImageDrawable(null)
|
||||
binding.contentImagePreview.visibility = View.GONE
|
||||
// Sending has already been initiated; keep the controls in their idle state
|
||||
// until the user starts composing the next draft.
|
||||
binding.btnSend.visibility = View.GONE
|
||||
binding.btnMore.visibility = View.VISIBLE
|
||||
}
|
||||
|
||||
private fun updateSendControls() {
|
||||
val hasImage = path.isNotEmpty()
|
||||
val hasText = binding.editMessage.text.toString().trim().isNotEmpty()
|
||||
if (isSending) {
|
||||
binding.btnSend.visibility = View.GONE
|
||||
binding.btnMore.visibility = View.VISIBLE
|
||||
return
|
||||
}
|
||||
binding.btnSend.visibility = if (hasImage || hasText) View.VISIBLE else View.GONE
|
||||
binding.btnMore.visibility = if (hasImage) View.GONE else View.VISIBLE
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
|
||||
@@ -602,6 +758,8 @@ class CustomerActivity : CKBaseActivity() {
|
||||
var data: List<CustomerMessageModel.MessageItemModel>,
|
||||
var onItemClickListenner: OnItemClickListenner
|
||||
) : RecyclerView.Adapter<CustomerMessageAdapter.CustomerMessageHolder>() {
|
||||
private val markwon = Markwon.create(context)
|
||||
|
||||
override fun onCreateViewHolder(
|
||||
parent: ViewGroup,
|
||||
viewType: Int
|
||||
@@ -626,7 +784,16 @@ class CustomerActivity : CKBaseActivity() {
|
||||
holder.binding.contentTo.visibility = View.GONE
|
||||
holder.binding.contentFrom.visibility = View.VISIBLE
|
||||
|
||||
holder.binding.textFrom.text = model.content
|
||||
val content = model.content.orEmpty()
|
||||
val normalizedContent = CustomerMarkdownDetector.normalize(content)
|
||||
if (CustomerMarkdownDetector.isMarkdown(normalizedContent)) {
|
||||
markwon.setMarkdown(
|
||||
holder.binding.textFrom,
|
||||
normalizedContent
|
||||
)
|
||||
} else {
|
||||
holder.binding.textFrom.text = content
|
||||
}
|
||||
holder.binding.textFromNick.text = model.senderName
|
||||
|
||||
Glide.with(context)
|
||||
@@ -658,14 +825,42 @@ class CustomerActivity : CKBaseActivity() {
|
||||
if (!TextUtils.isEmpty(model.url)) {
|
||||
holder.binding.textTo.visibility = View.GONE
|
||||
holder.binding.imageContentTo.visibility = View.VISIBLE
|
||||
val imageView = holder.binding.imageContentTo
|
||||
val imageUrl = model.url!!
|
||||
imageView.setTag(imageUrl)
|
||||
resetImageContentSize(imageView)
|
||||
|
||||
Glide.with(context)
|
||||
.load( model.url)
|
||||
.load(imageUrl)
|
||||
.placeholder(R.mipmap.image_default)
|
||||
.into(holder.binding.imageContentTo)
|
||||
.listener(object : RequestListener<Drawable> {
|
||||
override fun onLoadFailed(
|
||||
e: GlideException?,
|
||||
model: Any?,
|
||||
target: Target<Drawable>?,
|
||||
isFirstResource: Boolean
|
||||
): Boolean = false
|
||||
|
||||
holder.binding.imageContentTo.setTag(model.url)
|
||||
holder.binding.imageContentTo.setOnClickListener(imageClick)
|
||||
override fun onResourceReady(
|
||||
resource: Drawable,
|
||||
model: Any,
|
||||
target: Target<Drawable>?,
|
||||
dataSource: DataSource,
|
||||
isFirstResource: Boolean
|
||||
): Boolean {
|
||||
if (imageView.tag == imageUrl) {
|
||||
setImageContentSize(
|
||||
imageView,
|
||||
resource.intrinsicWidth,
|
||||
resource.intrinsicHeight
|
||||
)
|
||||
}
|
||||
return false
|
||||
}
|
||||
})
|
||||
.into(imageView)
|
||||
|
||||
imageView.setOnClickListener(imageClick)
|
||||
} else {
|
||||
holder.binding.textTo.visibility = View.VISIBLE
|
||||
holder.binding.imageContentTo.visibility = View.GONE
|
||||
@@ -680,6 +875,39 @@ class CustomerActivity : CKBaseActivity() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun resetImageContentSize(imageView: View) {
|
||||
val density = imageView.resources.displayMetrics.density
|
||||
imageView.layoutParams = imageView.layoutParams.apply {
|
||||
width = getMaxImageWidth(density)
|
||||
height = (200 * density).toInt()
|
||||
}
|
||||
}
|
||||
|
||||
private fun setImageContentSize(imageView: View, sourceWidth: Int, sourceHeight: Int) {
|
||||
if (sourceWidth <= 0 || sourceHeight <= 0) return
|
||||
|
||||
val density = imageView.resources.displayMetrics.density
|
||||
val maxWidth = getMaxImageWidth(density).toFloat()
|
||||
val maxHeight = (200 * density).toFloat()
|
||||
val scale = minOf(
|
||||
1f,
|
||||
maxWidth / sourceWidth.toFloat(),
|
||||
maxHeight / sourceHeight.toFloat()
|
||||
)
|
||||
|
||||
imageView.layoutParams = imageView.layoutParams.apply {
|
||||
width = (sourceWidth * scale).toInt().coerceAtLeast(1)
|
||||
height = (sourceHeight * scale).toInt().coerceAtLeast(1)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getMaxImageWidth(density: Float): Int {
|
||||
val requestedWidth = (200 * density).toInt()
|
||||
// Reserve the avatar, paddings, and the bubble's left inset.
|
||||
val availableWidth = context.resources.displayMetrics.widthPixels - (155 * density).toInt()
|
||||
return minOf(requestedWidth, availableWidth.coerceAtLeast(1))
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int {
|
||||
return data.size
|
||||
}
|
||||
@@ -715,4 +943,9 @@ class CustomerActivity : CKBaseActivity() {
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val REQUEST_CAMERA_PERMISSION = 1001
|
||||
private const val REQUEST_PHOTO_PERMISSION = 1002
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,891 @@
|
||||
package com.ck.ckcollar.app.ui.act.customer
|
||||
|
||||
import android.Manifest
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.graphics.drawable.Drawable
|
||||
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.InputType
|
||||
import android.text.TextUtils
|
||||
import android.text.TextWatcher
|
||||
import android.view.KeyEvent
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.inputmethod.EditorInfo
|
||||
import android.view.inputmethod.InputMethodManager
|
||||
import android.widget.ImageView
|
||||
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.bumptech.glide.load.DataSource
|
||||
import com.bumptech.glide.load.engine.GlideException
|
||||
import com.bumptech.glide.request.RequestListener
|
||||
import com.bumptech.glide.request.target.Target
|
||||
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.LubanCompressUtil
|
||||
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
|
||||
|
||||
class CustomerActivity_copy : CKBaseActivity() {
|
||||
|
||||
lateinit var binding: ActivityCustomerBinding
|
||||
lateinit var customerMessageAdapter: CustomerMessageAdapter
|
||||
var data = mutableListOf<CustomerMessageModel.MessageItemModel>()
|
||||
|
||||
var path = ""
|
||||
private var isSending = false
|
||||
private var isAiResponding = false
|
||||
var url = ""
|
||||
|
||||
var lock = true
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
binding = ActivityCustomerBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
setTitleText(getString(R.string.customer_service4))
|
||||
|
||||
setRightText(getString(R.string.clear))
|
||||
}
|
||||
|
||||
override fun initView() {
|
||||
binding.recyclerView.layoutManager =
|
||||
LinearLayoutManager(this@CustomerActivity_copy, RecyclerView.VERTICAL, false)
|
||||
binding.recyclerView.setHasFixedSize(true)
|
||||
customerMessageAdapter =
|
||||
CustomerMessageAdapter(this@CustomerActivity_copy, data, object : OnItemClickListenner {
|
||||
override fun onClick(
|
||||
pos: Int,
|
||||
model: Any
|
||||
) {
|
||||
|
||||
}
|
||||
})
|
||||
binding.recyclerView.adapter = customerMessageAdapter
|
||||
|
||||
binding.editMessage.setHorizontallyScrolling(false);
|
||||
binding.btnSend.setOnClickListener {
|
||||
if (isAiResponding) {
|
||||
toast("请等待当前问题回答结束")
|
||||
return@setOnClickListener
|
||||
}
|
||||
isSending = true
|
||||
// Reset the action controls immediately. The send flow captures the
|
||||
// submitted text and image path before clearing the visible draft.
|
||||
binding.btnSend.visibility = View.GONE
|
||||
binding.btnMore.visibility = View.VISIBLE
|
||||
binding.editMessage.onEditorAction(EditorInfo.IME_ACTION_SEND)
|
||||
}
|
||||
updateSendControls()
|
||||
// Use the traditional multiline keyboard action; sending is handled by the
|
||||
// activity's own message flow rather than the IME action button.
|
||||
binding.editMessage.setSingleLine(false)
|
||||
binding.editMessage.imeOptions = EditorInfo.IME_ACTION_NONE
|
||||
binding.editMessage.setRawInputType(InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_FLAG_MULTI_LINE)
|
||||
// setSingleLine(false) resets the XML maxLines value, so apply it last.
|
||||
binding.editMessage.maxLines = 4
|
||||
binding.editMessage.maxHeight = (70 * resources.displayMetrics.density).toInt()
|
||||
binding.editMessage.isVerticalScrollBarEnabled = true
|
||||
|
||||
binding.editMessage.setOnEditorActionListener(object : TextView.OnEditorActionListener {
|
||||
override fun onEditorAction(
|
||||
p0: TextView?,
|
||||
actionId: Int,
|
||||
ketEvent: KeyEvent?
|
||||
): Boolean {
|
||||
if (actionId == EditorInfo.IME_ACTION_SEND) {
|
||||
if (lock) {
|
||||
// Whitespace-only input is not a message. A selected image may still be sent alone.
|
||||
val text = binding.editMessage.text.toString().trim()
|
||||
if (text.isNotEmpty() || path.isNotEmpty()) {
|
||||
lock = false
|
||||
KeyboardUtils.hideKeyboard(this@CustomerActivity_copy)
|
||||
binding.editMessage.clearFocus()
|
||||
handler.post {
|
||||
if (!TextUtils.isEmpty(path)) {
|
||||
uploadImage(text, path)
|
||||
} else {
|
||||
sendMessage(UUID.randomUUID().toString(), text, false, "")
|
||||
}
|
||||
clearInputViews()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
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
|
||||
) {
|
||||
if (p0?.toString()?.trim()?.isNotEmpty() == true) isSending = false
|
||||
updateSendControls()
|
||||
}
|
||||
})
|
||||
binding.btnMore.setOnClickListener {
|
||||
if (binding.contentBottom.visibility == View.GONE) {
|
||||
val inputMethodManager =
|
||||
getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager
|
||||
inputMethodManager.hideSoftInputFromWindow(binding.editMessage.windowToken, 0)
|
||||
binding.editMessage.clearFocus()
|
||||
binding.contentBottom.visibility = View.VISIBLE
|
||||
} else {
|
||||
binding.contentBottom.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
binding.btnSmile.setOnClickListener {
|
||||
binding.contentBottom.visibility = View.GONE
|
||||
binding.editMessage.requestFocus()
|
||||
KeyboardUtils.showKeyboard(binding.editMessage)
|
||||
}
|
||||
binding.btnDeleteImage.setOnClickListener {
|
||||
clearSelectedImage()
|
||||
}
|
||||
//拍照
|
||||
binding.conetnt1.setOnClickListener {
|
||||
|
||||
if (TextUtils.isEmpty(path)) {
|
||||
getPermissionRequst(
|
||||
Manifest.permission.CAMERA,
|
||||
REQUEST_CAMERA_PERMISSION
|
||||
)
|
||||
} else {
|
||||
toast(getString(R.string.only_one_photo))
|
||||
}
|
||||
|
||||
}
|
||||
//相册
|
||||
binding.conetnt2.setOnClickListener {
|
||||
|
||||
if (TextUtils.isEmpty(path)) {
|
||||
val permission = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
Manifest.permission.READ_MEDIA_IMAGES
|
||||
} else {
|
||||
Manifest.permission.READ_EXTERNAL_STORAGE
|
||||
}
|
||||
getPermissionRequst(
|
||||
permission,
|
||||
REQUEST_PHOTO_PERMISSION
|
||||
)
|
||||
} else {
|
||||
toast(getString(R.string.only_one_photo))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Handler(Looper.getMainLooper()).post {
|
||||
binding.recyclerView.scrollToPosition(this@CustomerActivity_copy.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()
|
||||
binding.btnSmile.visibility = View.GONE;
|
||||
}
|
||||
|
||||
override fun onPermissionsGranted(requestCode: Int, permissions: Array<String>) {
|
||||
when (requestCode) {
|
||||
REQUEST_CAMERA_PERMISSION -> takePhoto()
|
||||
REQUEST_PHOTO_PERMISSION -> {
|
||||
val intent = Intent(
|
||||
Intent.ACTION_PICK,
|
||||
MediaStore.Images.Media.EXTERNAL_CONTENT_URI
|
||||
).apply {
|
||||
setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*")
|
||||
}
|
||||
startActivityForResult(intent, 56)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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, url)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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_copy, Const.MESSAGE,"[]")
|
||||
data.clear()
|
||||
|
||||
customerMessageAdapter.data = data
|
||||
customerMessageAdapter.notifyDataSetChanged()
|
||||
}
|
||||
}
|
||||
}).show()
|
||||
}
|
||||
|
||||
fun sendMessage(uuid :String ,content: String,isResend : Boolean, imageUrl: String) {
|
||||
|
||||
isAiResponding = true
|
||||
|
||||
if (!TextUtils.isEmpty(imageUrl)) {
|
||||
this@CustomerActivity_copy.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 = imageUrl
|
||||
})
|
||||
}
|
||||
if (!TextUtils.isEmpty(content) && !isResend) {
|
||||
this@CustomerActivity_copy.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_copy.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", imageUrl))
|
||||
|
||||
add(TTRequestData("question", content))
|
||||
}, object : ICallback {
|
||||
override fun onSuccess(data: String) {
|
||||
|
||||
// var model = Gson().fromJson<AIMessageModel>(data, AIMessageModel::class.java)
|
||||
|
||||
var flag = false
|
||||
for (i in 0..this@CustomerActivity_copy.data.size -1){
|
||||
if (this@CustomerActivity_copy.data.get(i).uuid.equals(uuid)){
|
||||
flag = true
|
||||
this@CustomerActivity_copy.data.get(i).content = CKUtils.subMessage(this@CustomerActivity_copy.data.get(i).content + data)
|
||||
|
||||
}
|
||||
}
|
||||
if (!flag){
|
||||
this@CustomerActivity_copy.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
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
customerMessageAdapter.data = this@CustomerActivity_copy.data
|
||||
customerMessageAdapter.notifyDataSetChanged()
|
||||
|
||||
if (this@CustomerActivity_copy.data.last().content!!.indexOf("不能替代兽医诊断") > 0) {
|
||||
binding.recyclerView.scrollToPosition(this@CustomerActivity_copy.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) {
|
||||
isAiResponding = false
|
||||
lock = true
|
||||
// toast(msg)
|
||||
//TTLog.e(msg)
|
||||
}
|
||||
|
||||
override fun onComplete() {
|
||||
isAiResponding = false
|
||||
lock = true
|
||||
}
|
||||
})
|
||||
|
||||
customerMessageAdapter.data = this@CustomerActivity_copy.data
|
||||
customerMessageAdapter.notifyDataSetChanged()
|
||||
|
||||
binding.recyclerView.scrollToPosition(this@CustomerActivity_copy.data.size - 1)
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
fun sendMessage2(uuid :String ,content: String,isResend : Boolean, imageUrl: String) {
|
||||
isAiResponding = true
|
||||
lock = false
|
||||
if (!TextUtils.isEmpty(content) && !isResend) {
|
||||
this@CustomerActivity_copy.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_copy.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", imageUrl))
|
||||
|
||||
add(TTRequestData("question", content))
|
||||
}, object : ICallback {
|
||||
override fun onSuccess(data: String) {
|
||||
|
||||
// var model = Gson().fromJson<AIMessageModel>(data, AIMessageModel::class.java)
|
||||
|
||||
var flag = false
|
||||
for (i in 0..this@CustomerActivity_copy.data.size -1){
|
||||
if (this@CustomerActivity_copy.data.get(i).uuid.equals(uuid)){
|
||||
flag = true
|
||||
this@CustomerActivity_copy.data.get(i).content = CKUtils.subMessage(this@CustomerActivity_copy.data.get(i).content + data)
|
||||
|
||||
}
|
||||
}
|
||||
if (!flag){
|
||||
this@CustomerActivity_copy.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
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
customerMessageAdapter.data = this@CustomerActivity_copy.data
|
||||
customerMessageAdapter.notifyDataSetChanged()
|
||||
|
||||
if (this@CustomerActivity_copy.data.last().content!!.indexOf("不能替代兽医诊断") > 0) {
|
||||
binding.recyclerView.scrollToPosition(this@CustomerActivity_copy.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) {
|
||||
isAiResponding = false
|
||||
lock = true
|
||||
// toast(msg)
|
||||
//TTLog.e(msg)
|
||||
}
|
||||
|
||||
override fun onComplete() {
|
||||
isAiResponding = false
|
||||
lock = true
|
||||
}
|
||||
})
|
||||
|
||||
customerMessageAdapter.data = this@CustomerActivity_copy.data
|
||||
customerMessageAdapter.notifyDataSetChanged()
|
||||
|
||||
binding.recyclerView.scrollToPosition(this@CustomerActivity_copy.data.size - 1)
|
||||
|
||||
}
|
||||
|
||||
|
||||
fun uploadImage(content: String, imagePath: String) {
|
||||
|
||||
var param = TTRequestParam()
|
||||
param.files.add(File(imagePath))
|
||||
|
||||
showProgeassDialog()
|
||||
TTHttpClient.postFile(this, "上传照片s", param, object : ICallback {
|
||||
override fun onSuccess(data: String) {
|
||||
hiddenProgeassDialog()
|
||||
var model = Gson().fromJson<UploadModel>(data, UploadModel::class.java)
|
||||
|
||||
handler.post {
|
||||
sendMessage(UUID.randomUUID().toString(), content, false, model.urls)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override fun onFailed(code: String, msg: String) {
|
||||
hiddenProgeassDialog()
|
||||
lock = true
|
||||
if (path.isEmpty() && binding.editMessage.text.toString().isEmpty()) {
|
||||
path = imagePath
|
||||
showImagePreview(imagePath)
|
||||
binding.editMessage.setText(content)
|
||||
}
|
||||
toast(msg)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
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_copy.data.addAll(model)
|
||||
customerMessageAdapter.data = this@CustomerActivity_copy.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_copy, Const.IMAGE_PATH, "")!!
|
||||
prepareSelectedImage()
|
||||
} else if (requestCode == 56 && resultCode == RESULT_OK) {
|
||||
path = TTUtils.getImageUrl(this, data!!.getData());
|
||||
prepareSelectedImage()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private fun prepareSelectedImage() {
|
||||
if (TextUtils.isEmpty(path)) return
|
||||
|
||||
LubanCompressUtil.getCompressFile(
|
||||
this,
|
||||
File(path),
|
||||
object : LubanCompressUtil.CompressCallback {
|
||||
override fun success(file: File) {
|
||||
if (isFinishing || isDestroyed) return
|
||||
path = file.absolutePath
|
||||
lock = true
|
||||
binding.contentBottom.visibility = View.GONE
|
||||
showImagePreview(path)
|
||||
binding.editMessage.requestFocus()
|
||||
KeyboardUtils.showKeyboard(binding.editMessage)
|
||||
// Rebind the IME after selecting an image so its action button is
|
||||
// available even though the text field itself is empty.
|
||||
binding.editMessage.postDelayed({
|
||||
val imm = getSystemService(INPUT_METHOD_SERVICE) as? InputMethodManager
|
||||
imm?.restartInput(binding.editMessage)
|
||||
}, 150L)
|
||||
}
|
||||
|
||||
override fun fail(failMsg: String) {
|
||||
if (isFinishing || isDestroyed) return
|
||||
lock = true
|
||||
path = ""
|
||||
toast(failMsg)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
private fun showImagePreview(imagePath: String) {
|
||||
isSending = false
|
||||
binding.contentImagePreview.visibility = View.VISIBLE
|
||||
updateSendControls()
|
||||
binding.imagePreview.scaleType = ImageView.ScaleType.CENTER_CROP
|
||||
Glide.with(this)
|
||||
.load(imagePath)
|
||||
.into(binding.imagePreview)
|
||||
}
|
||||
|
||||
private fun clearSelectedImage() {
|
||||
path = ""
|
||||
url = ""
|
||||
binding.imagePreview.setImageDrawable(null)
|
||||
binding.contentImagePreview.visibility = View.GONE
|
||||
updateSendControls()
|
||||
}
|
||||
|
||||
private fun clearInputViews() {
|
||||
binding.editMessage.setText("")
|
||||
path = ""
|
||||
url = ""
|
||||
binding.imagePreview.setImageDrawable(null)
|
||||
binding.contentImagePreview.visibility = View.GONE
|
||||
// Sending has already been initiated; keep the controls in their idle state
|
||||
// until the user starts composing the next draft.
|
||||
binding.btnSend.visibility = View.GONE
|
||||
binding.btnMore.visibility = View.VISIBLE
|
||||
}
|
||||
|
||||
private fun updateSendControls() {
|
||||
val hasImage = path.isNotEmpty()
|
||||
val hasText = binding.editMessage.text.toString().trim().isNotEmpty()
|
||||
if (isSending) {
|
||||
binding.btnSend.visibility = View.GONE
|
||||
binding.btnMore.visibility = View.VISIBLE
|
||||
return
|
||||
}
|
||||
binding.btnSend.visibility = if (hasImage || hasText) View.VISIBLE else View.GONE
|
||||
binding.btnMore.visibility = if (hasImage) View.GONE else View.VISIBLE
|
||||
}
|
||||
|
||||
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_copy,
|
||||
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
|
||||
val imageView = holder.binding.imageContentTo
|
||||
val imageUrl = model.url!!
|
||||
imageView.setTag(imageUrl)
|
||||
resetImageContentSize(imageView)
|
||||
|
||||
Glide.with(context)
|
||||
.load(imageUrl)
|
||||
.placeholder(R.mipmap.image_default)
|
||||
.listener(object : RequestListener<Drawable> {
|
||||
override fun onLoadFailed(
|
||||
e: GlideException?,
|
||||
model: Any?,
|
||||
target: Target<Drawable>?,
|
||||
isFirstResource: Boolean
|
||||
): Boolean = false
|
||||
|
||||
override fun onResourceReady(
|
||||
resource: Drawable,
|
||||
model: Any,
|
||||
target: Target<Drawable>?,
|
||||
dataSource: DataSource,
|
||||
isFirstResource: Boolean
|
||||
): Boolean {
|
||||
if (imageView.tag == imageUrl) {
|
||||
setImageContentSize(
|
||||
imageView,
|
||||
resource.intrinsicWidth,
|
||||
resource.intrinsicHeight
|
||||
)
|
||||
}
|
||||
return false
|
||||
}
|
||||
})
|
||||
.into(imageView)
|
||||
|
||||
imageView.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))
|
||||
}
|
||||
}
|
||||
|
||||
private fun resetImageContentSize(imageView: View) {
|
||||
val density = imageView.resources.displayMetrics.density
|
||||
imageView.layoutParams = imageView.layoutParams.apply {
|
||||
width = getMaxImageWidth(density)
|
||||
height = (200 * density).toInt()
|
||||
}
|
||||
}
|
||||
|
||||
private fun setImageContentSize(imageView: View, sourceWidth: Int, sourceHeight: Int) {
|
||||
if (sourceWidth <= 0 || sourceHeight <= 0) return
|
||||
|
||||
val density = imageView.resources.displayMetrics.density
|
||||
val maxWidth = getMaxImageWidth(density).toFloat()
|
||||
val maxHeight = (200 * density).toFloat()
|
||||
val scale = minOf(
|
||||
1f,
|
||||
maxWidth / sourceWidth.toFloat(),
|
||||
maxHeight / sourceHeight.toFloat()
|
||||
)
|
||||
|
||||
imageView.layoutParams = imageView.layoutParams.apply {
|
||||
width = (sourceWidth * scale).toInt().coerceAtLeast(1)
|
||||
height = (sourceHeight * scale).toInt().coerceAtLeast(1)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getMaxImageWidth(density: Float): Int {
|
||||
val requestedWidth = (200 * density).toInt()
|
||||
// Reserve the avatar, paddings, and the bubble's left inset.
|
||||
val availableWidth = context.resources.displayMetrics.widthPixels - (155 * density).toInt()
|
||||
return minOf(requestedWidth, availableWidth.coerceAtLeast(1))
|
||||
}
|
||||
|
||||
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()))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val REQUEST_CAMERA_PERMISSION = 1001
|
||||
private const val REQUEST_PHOTO_PERMISSION = 1002
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.ck.ckcollar.app.ui.act.customer
|
||||
|
||||
import android.Manifest
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
@@ -36,6 +37,7 @@ 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.LubanCompressUtil
|
||||
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
|
||||
@@ -64,6 +66,7 @@ class MineCustomerActivity : CKBaseActivity() {
|
||||
|
||||
var path = ""
|
||||
var url = ""
|
||||
private var imageSendDraft = ""
|
||||
|
||||
var lock = true
|
||||
var webSocket: WebSocket? = null
|
||||
@@ -98,6 +101,13 @@ class MineCustomerActivity : CKBaseActivity() {
|
||||
|
||||
binding.editMessage.setHorizontallyScrolling(false);
|
||||
|
||||
binding.editMessage.setOnClickListener {
|
||||
binding.contentBottom.visibility = View.GONE
|
||||
}
|
||||
binding.editMessage.onFocusChangeListener = View.OnFocusChangeListener { _, hasFocus ->
|
||||
if (hasFocus) binding.contentBottom.visibility = View.GONE
|
||||
}
|
||||
|
||||
binding.editMessage.setOnEditorActionListener(object : TextView.OnEditorActionListener {
|
||||
override fun onEditorAction(
|
||||
p0: TextView?,
|
||||
@@ -120,6 +130,7 @@ class MineCustomerActivity : CKBaseActivity() {
|
||||
sendMessage(text)
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
@@ -157,7 +168,9 @@ class MineCustomerActivity : CKBaseActivity() {
|
||||
})
|
||||
binding.btnMore.setOnClickListener {
|
||||
if (binding.contentBottom.visibility == View.GONE) {
|
||||
KeyboardUtils.hideKeyboard(this@MineCustomerActivity)
|
||||
val inputMethodManager = getSystemService(Context.INPUT_METHOD_SERVICE) as android.view.inputmethod.InputMethodManager
|
||||
inputMethodManager.hideSoftInputFromWindow(binding.editMessage.windowToken, 0)
|
||||
binding.editMessage.clearFocus()
|
||||
binding.contentBottom.visibility = View.VISIBLE
|
||||
} else {
|
||||
binding.contentBottom.visibility = View.GONE
|
||||
@@ -167,13 +180,17 @@ class MineCustomerActivity : CKBaseActivity() {
|
||||
}
|
||||
|
||||
binding.btnSmile.setOnClickListener {
|
||||
binding.contentBottom.visibility = View.GONE
|
||||
binding.editMessage.requestFocus()
|
||||
KeyboardUtils.showKeyboard(binding.editMessage)
|
||||
}
|
||||
|
||||
binding.conetnt1.setOnClickListener {
|
||||
if (TextUtils.isEmpty(path)) {
|
||||
takePhoto()
|
||||
getPermissionRequst(
|
||||
Manifest.permission.CAMERA,
|
||||
REQUEST_CAMERA_PERMISSION
|
||||
)
|
||||
} else {
|
||||
toast(getString(R.string.only_one_photo))
|
||||
}
|
||||
@@ -181,12 +198,12 @@ class MineCustomerActivity : CKBaseActivity() {
|
||||
}
|
||||
binding.conetnt2.setOnClickListener {
|
||||
if (TextUtils.isEmpty(path)) {
|
||||
//相册
|
||||
val i = Intent(
|
||||
Intent.ACTION_PICK,
|
||||
MediaStore.Images.Media.EXTERNAL_CONTENT_URI
|
||||
)
|
||||
startActivityForResult(i, 56)
|
||||
val permission = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
Manifest.permission.READ_MEDIA_IMAGES
|
||||
} else {
|
||||
Manifest.permission.READ_EXTERNAL_STORAGE
|
||||
}
|
||||
getPermissionRequst(permission, REQUEST_PHOTO_PERMISSION)
|
||||
} else {
|
||||
toast(getString(R.string.only_one_photo))
|
||||
}
|
||||
@@ -195,6 +212,23 @@ class MineCustomerActivity : CKBaseActivity() {
|
||||
|
||||
}
|
||||
|
||||
override fun onPermissionsGranted(requestCode: Int, permissions: Array<String>) {
|
||||
when (requestCode) {
|
||||
REQUEST_CAMERA_PERMISSION -> takePhoto()
|
||||
REQUEST_PHOTO_PERMISSION -> openPhotoAlbum()
|
||||
}
|
||||
}
|
||||
|
||||
private fun openPhotoAlbum() {
|
||||
val intent = Intent(
|
||||
Intent.ACTION_PICK,
|
||||
MediaStore.Images.Media.EXTERNAL_CONTENT_URI
|
||||
).apply {
|
||||
setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*")
|
||||
}
|
||||
startActivityForResult(intent, 56)
|
||||
}
|
||||
|
||||
override fun initData() {
|
||||
|
||||
//getList()
|
||||
@@ -262,7 +296,7 @@ class MineCustomerActivity : CKBaseActivity() {
|
||||
override fun onOpen(webSocket: WebSocket, response: Response) {
|
||||
TTLog.e("onOpen")
|
||||
runOnUiThread {
|
||||
toast(getString(R.string.connect_customer_success))
|
||||
// toast(getString(R.string.connect_customer_success))
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -280,7 +314,9 @@ class MineCustomerActivity : CKBaseActivity() {
|
||||
|
||||
fun sendMessage(content: String) {
|
||||
|
||||
showProgeassDialog(getString(R.string.send))
|
||||
if (!TextUtils.isEmpty(url)) {
|
||||
showProgeassDialog(getString(R.string.send))
|
||||
}
|
||||
TTHttpClient.postJson(this, "发送人工会话消息", TTRequestParam().apply {
|
||||
add(TTRequestData("content", content))
|
||||
add(TTRequestData("chatType", 2))
|
||||
@@ -309,7 +345,8 @@ class MineCustomerActivity : CKBaseActivity() {
|
||||
|
||||
|
||||
|
||||
binding.editMessage.setText("")
|
||||
binding.editMessage.setText(if (!TextUtils.isEmpty(url)) imageSendDraft else "")
|
||||
imageSendDraft = ""
|
||||
path = ""
|
||||
url = ""
|
||||
customerMessageAdapter.data = this@MineCustomerActivity.data
|
||||
@@ -341,7 +378,7 @@ class MineCustomerActivity : CKBaseActivity() {
|
||||
var model = Gson().fromJson<UploadModel>(data, UploadModel::class.java)
|
||||
|
||||
url = model.urls
|
||||
|
||||
imageSendDraft = binding.editMessage.text.toString().replace("$$$$$", "")
|
||||
sendMessage(url)
|
||||
}
|
||||
|
||||
@@ -428,17 +465,35 @@ class MineCustomerActivity : CKBaseActivity() {
|
||||
|
||||
if (requestCode == 55 && resultCode == RESULT_OK) {
|
||||
path = PreferencesUtils.getString(this@MineCustomerActivity, Const.IMAGE_PATH, "")!!
|
||||
|
||||
//addImage(path!!)
|
||||
uploadImage()
|
||||
compressAndUploadImage()
|
||||
} else if (requestCode == 56 && resultCode == RESULT_OK) {
|
||||
path = TTUtils.getImageUrl(this, data!!.getData());
|
||||
// addImage(path)
|
||||
uploadImage()
|
||||
compressAndUploadImage()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private fun compressAndUploadImage() {
|
||||
if (TextUtils.isEmpty(path)) return
|
||||
LubanCompressUtil.getCompressFile(
|
||||
this,
|
||||
File(path),
|
||||
object : LubanCompressUtil.CompressCallback {
|
||||
override fun success(file: File) {
|
||||
if (isFinishing || isDestroyed) return
|
||||
path = file.absolutePath
|
||||
uploadImage()
|
||||
}
|
||||
|
||||
override fun fail(failMsg: String) {
|
||||
if (isFinishing || isDestroyed) return
|
||||
path = ""
|
||||
toast(failMsg)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
|
||||
@@ -476,6 +531,11 @@ class MineCustomerActivity : CKBaseActivity() {
|
||||
startActivityForResult(openCameraIntent, 55)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val REQUEST_CAMERA_PERMISSION = 1201
|
||||
private const val REQUEST_PHOTO_PERMISSION = 1202
|
||||
}
|
||||
|
||||
class CustomerMessageAdapter(
|
||||
var context: Context,
|
||||
var data: List<CustomerMessageModel.MessageItemModel>,
|
||||
@@ -528,10 +588,11 @@ class MineCustomerActivity : CKBaseActivity() {
|
||||
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)
|
||||
ChatImageLoader.load(
|
||||
context,
|
||||
holder.binding.imageContentTo,
|
||||
ActionCode.BASE_URL + model.url
|
||||
)
|
||||
} else {
|
||||
holder.binding.textTo.visibility = View.VISIBLE
|
||||
holder.binding.imageContentTo.visibility = View.GONE
|
||||
@@ -556,4 +617,4 @@ class MineCustomerActivity : CKBaseActivity() {
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.ck.ckcollar.app.ui.act.customer
|
||||
|
||||
import android.Manifest
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.graphics.Rect
|
||||
@@ -45,6 +46,7 @@ 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.LubanCompressUtil
|
||||
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
|
||||
@@ -76,6 +78,7 @@ class PeopleCustomerActivity : CKBaseActivity() {
|
||||
|
||||
var path = ""
|
||||
var url = ""
|
||||
private var imageSendDraft = ""
|
||||
|
||||
var lock = true
|
||||
var webSocket: WebSocket? = null
|
||||
@@ -154,6 +157,7 @@ class PeopleCustomerActivity : CKBaseActivity() {
|
||||
sendMessage(text)
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
@@ -191,7 +195,9 @@ class PeopleCustomerActivity : CKBaseActivity() {
|
||||
})
|
||||
binding.btnMore.setOnClickListener {
|
||||
if (binding.contentBottom.visibility == View.GONE) {
|
||||
KeyboardUtils.hideKeyboard(this@PeopleCustomerActivity)
|
||||
val inputMethodManager = getSystemService(Context.INPUT_METHOD_SERVICE) as android.view.inputmethod.InputMethodManager
|
||||
inputMethodManager.hideSoftInputFromWindow(binding.editMessage.windowToken, 0)
|
||||
binding.editMessage.clearFocus()
|
||||
binding.contentBottom.visibility = View.VISIBLE
|
||||
} else {
|
||||
binding.contentBottom.visibility = View.GONE
|
||||
@@ -203,6 +209,7 @@ class PeopleCustomerActivity : CKBaseActivity() {
|
||||
}
|
||||
|
||||
binding.btnSmile.setOnClickListener {
|
||||
binding.contentBottom.visibility = View.GONE
|
||||
binding.editMessage.requestFocus()
|
||||
KeyboardUtils.showKeyboard(binding.editMessage)
|
||||
handler2.sendEmptyMessageDelayed(0,300)
|
||||
@@ -211,16 +218,10 @@ class PeopleCustomerActivity : CKBaseActivity() {
|
||||
|
||||
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()
|
||||
getPermissionRequst(
|
||||
Manifest.permission.CAMERA,
|
||||
REQUEST_CAMERA_PERMISSION
|
||||
)
|
||||
} else {
|
||||
toast(getString(R.string.only_one_photo))
|
||||
}
|
||||
@@ -228,12 +229,12 @@ class PeopleCustomerActivity : CKBaseActivity() {
|
||||
}
|
||||
binding.conetnt2.setOnClickListener {
|
||||
if (TextUtils.isEmpty(path)) {
|
||||
//相册
|
||||
val i = Intent(
|
||||
Intent.ACTION_PICK,
|
||||
MediaStore.Images.Media.EXTERNAL_CONTENT_URI
|
||||
)
|
||||
startActivityForResult(i, 56)
|
||||
val permission = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
Manifest.permission.READ_MEDIA_IMAGES
|
||||
} else {
|
||||
Manifest.permission.READ_EXTERNAL_STORAGE
|
||||
}
|
||||
getPermissionRequst(permission, REQUEST_PHOTO_PERMISSION)
|
||||
} else {
|
||||
toast(getString(R.string.only_one_photo))
|
||||
}
|
||||
@@ -243,6 +244,23 @@ class PeopleCustomerActivity : CKBaseActivity() {
|
||||
|
||||
}
|
||||
|
||||
override fun onPermissionsGranted(requestCode: Int, permissions: Array<String>) {
|
||||
when (requestCode) {
|
||||
REQUEST_CAMERA_PERMISSION -> takePhoto()
|
||||
REQUEST_PHOTO_PERMISSION -> openPhotoAlbum()
|
||||
}
|
||||
}
|
||||
|
||||
private fun openPhotoAlbum() {
|
||||
val intent = Intent(
|
||||
Intent.ACTION_PICK,
|
||||
MediaStore.Images.Media.EXTERNAL_CONTENT_URI
|
||||
).apply {
|
||||
setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*")
|
||||
}
|
||||
startActivityForResult(intent, 56)
|
||||
}
|
||||
|
||||
override fun initData() {
|
||||
|
||||
|
||||
@@ -353,7 +371,7 @@ class PeopleCustomerActivity : CKBaseActivity() {
|
||||
override fun onOpen(webSocket: WebSocket, response: Response) {
|
||||
TTLog.e("onOpen")
|
||||
runOnUiThread {
|
||||
toast(getString(R.string.connect_customer_success))
|
||||
// toast(getString(R.string.connect_customer_success))
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -394,7 +412,9 @@ class PeopleCustomerActivity : CKBaseActivity() {
|
||||
"<img src=\"$content\"/>"
|
||||
}
|
||||
|
||||
showProgeassDialog(getString(R.string.send))
|
||||
if (!TextUtils.isEmpty(url)) {
|
||||
showProgeassDialog(getString(R.string.send))
|
||||
}
|
||||
TTHttpClient.postJson(this, "发送人工会话消息", TTRequestParam().apply {
|
||||
add(TTRequestData("content", sendContent))
|
||||
add(TTRequestData("chatType", chatType))
|
||||
@@ -422,7 +442,8 @@ class PeopleCustomerActivity : CKBaseActivity() {
|
||||
|
||||
|
||||
|
||||
binding.editMessage.setText("")
|
||||
binding.editMessage.setText(if (!TextUtils.isEmpty(url)) imageSendDraft else "")
|
||||
imageSendDraft = ""
|
||||
path = ""
|
||||
url = ""
|
||||
customerMessageAdapter.data = this@PeopleCustomerActivity.data
|
||||
@@ -454,7 +475,7 @@ class PeopleCustomerActivity : CKBaseActivity() {
|
||||
var model = Gson().fromJson<UploadModel>(data, UploadModel::class.java)
|
||||
|
||||
url = model.urls
|
||||
|
||||
imageSendDraft = binding.editMessage.text.toString().replace("$$$$$", "")
|
||||
sendMessage(url)
|
||||
}
|
||||
|
||||
@@ -559,17 +580,35 @@ class PeopleCustomerActivity : CKBaseActivity() {
|
||||
|
||||
if (requestCode == 55 && resultCode == RESULT_OK) {
|
||||
path = PreferencesUtils.getString(this@PeopleCustomerActivity, Const.IMAGE_PATH, "")!!
|
||||
|
||||
//addImage(path!!)
|
||||
uploadImage()
|
||||
compressAndUploadImage()
|
||||
} else if (requestCode == 56 && resultCode == RESULT_OK) {
|
||||
path = TTUtils.getImageUrl(this, data!!.getData());
|
||||
//addImage(path)
|
||||
uploadImage()
|
||||
compressAndUploadImage()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private fun compressAndUploadImage() {
|
||||
if (TextUtils.isEmpty(path)) return
|
||||
LubanCompressUtil.getCompressFile(
|
||||
this,
|
||||
File(path),
|
||||
object : LubanCompressUtil.CompressCallback {
|
||||
override fun success(file: File) {
|
||||
if (isFinishing || isDestroyed) return
|
||||
path = file.absolutePath
|
||||
uploadImage()
|
||||
}
|
||||
|
||||
override fun fail(failMsg: String) {
|
||||
if (isFinishing || isDestroyed) return
|
||||
path = ""
|
||||
toast(failMsg)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
|
||||
@@ -607,6 +646,11 @@ class PeopleCustomerActivity : CKBaseActivity() {
|
||||
startActivityForResult(openCameraIntent, 55)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val REQUEST_CAMERA_PERMISSION = 1301
|
||||
private const val REQUEST_PHOTO_PERMISSION = 1302
|
||||
}
|
||||
|
||||
class CustomerMessageAdapter(
|
||||
var context: TTBaseActivity,
|
||||
var data: List<CustomerMessageModel.MessageItemModel>,
|
||||
@@ -675,10 +719,7 @@ class PeopleCustomerActivity : CKBaseActivity() {
|
||||
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)
|
||||
ChatImageLoader.load(context, holder.binding.imageContentTo, model.url!!)
|
||||
|
||||
holder.binding.imageContentTo.setTag(model.url)
|
||||
|
||||
@@ -733,4 +774,4 @@ class PeopleCustomerActivity : CKBaseActivity() {
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.ck.ckcollar.app.ui.act.customer
|
||||
|
||||
import android.Manifest
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
@@ -36,6 +37,7 @@ 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.LubanCompressUtil
|
||||
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
|
||||
@@ -58,12 +60,15 @@ import java.util.concurrent.TimeUnit
|
||||
|
||||
class ShopCustomerActivity : CKBaseActivity() {
|
||||
|
||||
private val requestPhotoPermission = 1402
|
||||
|
||||
lateinit var binding: ActivityCustomerBinding
|
||||
lateinit var customerMessageAdapter: CustomerMessageAdapter
|
||||
var data = mutableListOf<CustomerMessageModel.MessageItemModel>()
|
||||
|
||||
var path = ""
|
||||
var url = ""
|
||||
private var imageSendDraft = ""
|
||||
|
||||
var lock = true
|
||||
var webSocket: WebSocket? = null
|
||||
@@ -97,6 +102,13 @@ class ShopCustomerActivity : CKBaseActivity() {
|
||||
|
||||
binding.editMessage.setHorizontallyScrolling(false);
|
||||
|
||||
binding.editMessage.setOnClickListener {
|
||||
binding.contentBottom.visibility = View.GONE
|
||||
}
|
||||
binding.editMessage.onFocusChangeListener = View.OnFocusChangeListener { _, hasFocus ->
|
||||
if (hasFocus) binding.contentBottom.visibility = View.GONE
|
||||
}
|
||||
|
||||
binding.editMessage.setOnEditorActionListener(object : TextView.OnEditorActionListener {
|
||||
override fun onEditorAction(
|
||||
p0: TextView?,
|
||||
@@ -119,6 +131,7 @@ class ShopCustomerActivity : CKBaseActivity() {
|
||||
sendMessage(text)
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
@@ -156,7 +169,9 @@ class ShopCustomerActivity : CKBaseActivity() {
|
||||
})
|
||||
binding.btnMore.setOnClickListener {
|
||||
if (binding.contentBottom.visibility == View.GONE) {
|
||||
KeyboardUtils.hideKeyboard(this@ShopCustomerActivity)
|
||||
val inputMethodManager = getSystemService(Context.INPUT_METHOD_SERVICE) as android.view.inputmethod.InputMethodManager
|
||||
inputMethodManager.hideSoftInputFromWindow(binding.editMessage.windowToken, 0)
|
||||
binding.editMessage.clearFocus()
|
||||
binding.contentBottom.visibility = View.VISIBLE
|
||||
} else {
|
||||
binding.contentBottom.visibility = View.GONE
|
||||
@@ -166,6 +181,7 @@ class ShopCustomerActivity : CKBaseActivity() {
|
||||
}
|
||||
|
||||
binding.btnSmile.setOnClickListener {
|
||||
binding.contentBottom.visibility = View.GONE
|
||||
binding.editMessage.requestFocus()
|
||||
KeyboardUtils.showKeyboard(binding.editMessage)
|
||||
}
|
||||
@@ -181,11 +197,12 @@ class ShopCustomerActivity : CKBaseActivity() {
|
||||
binding.conetnt2.setOnClickListener {
|
||||
if (TextUtils.isEmpty(path)) {
|
||||
//相册
|
||||
val i = Intent(
|
||||
Intent.ACTION_PICK,
|
||||
MediaStore.Images.Media.EXTERNAL_CONTENT_URI
|
||||
)
|
||||
startActivityForResult(i, 56)
|
||||
val permission = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
Manifest.permission.READ_MEDIA_IMAGES
|
||||
} else {
|
||||
Manifest.permission.READ_EXTERNAL_STORAGE
|
||||
}
|
||||
getPermissionRequst(permission, requestPhotoPermission)
|
||||
} else {
|
||||
toast(getString(R.string.only_one_photo))
|
||||
}
|
||||
@@ -194,6 +211,22 @@ class ShopCustomerActivity : CKBaseActivity() {
|
||||
|
||||
}
|
||||
|
||||
override fun onPermissionsGranted(requestCode: Int, permissions: Array<String>) {
|
||||
if (requestCode == requestPhotoPermission) {
|
||||
openPhotoAlbum()
|
||||
}
|
||||
}
|
||||
|
||||
private fun openPhotoAlbum() {
|
||||
val intent = Intent(
|
||||
Intent.ACTION_PICK,
|
||||
MediaStore.Images.Media.EXTERNAL_CONTENT_URI
|
||||
).apply {
|
||||
setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*")
|
||||
}
|
||||
startActivityForResult(intent, 56)
|
||||
}
|
||||
|
||||
override fun initData() {
|
||||
|
||||
//getList()
|
||||
@@ -261,7 +294,7 @@ class ShopCustomerActivity : CKBaseActivity() {
|
||||
override fun onOpen(webSocket: WebSocket, response: Response) {
|
||||
TTLog.e("onOpen")
|
||||
runOnUiThread {
|
||||
toast(getString(R.string.connect_customer_success))
|
||||
// toast(getString(R.string.connect_customer_success))
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -295,7 +328,9 @@ class ShopCustomerActivity : CKBaseActivity() {
|
||||
// e.printStackTrace()
|
||||
// }
|
||||
|
||||
showProgeassDialog(getString(R.string.send))
|
||||
if (!TextUtils.isEmpty(url)) {
|
||||
showProgeassDialog(getString(R.string.send))
|
||||
}
|
||||
TTHttpClient.postJson(this, "发送人工会话消息", TTRequestParam().apply {
|
||||
add(TTRequestData("content", content))
|
||||
add(TTRequestData("chatType", 1))
|
||||
@@ -323,7 +358,8 @@ class ShopCustomerActivity : CKBaseActivity() {
|
||||
|
||||
|
||||
|
||||
binding.editMessage.setText("")
|
||||
binding.editMessage.setText(if (!TextUtils.isEmpty(url)) imageSendDraft else "")
|
||||
imageSendDraft = ""
|
||||
path = ""
|
||||
url = ""
|
||||
customerMessageAdapter.data = this@ShopCustomerActivity.data
|
||||
@@ -355,6 +391,7 @@ class ShopCustomerActivity : CKBaseActivity() {
|
||||
var model = Gson().fromJson<UploadModel>(data, UploadModel::class.java)
|
||||
|
||||
url = model.urls
|
||||
imageSendDraft = binding.editMessage.text.toString().replace("$$$$$", "")
|
||||
sendMessage(url)
|
||||
}
|
||||
|
||||
@@ -441,17 +478,35 @@ class ShopCustomerActivity : CKBaseActivity() {
|
||||
|
||||
if (requestCode == 55 && resultCode == RESULT_OK) {
|
||||
path = PreferencesUtils.getString(this@ShopCustomerActivity, Const.IMAGE_PATH, "")!!
|
||||
|
||||
//addImage(path!!)
|
||||
uploadImage()
|
||||
compressAndUploadImage()
|
||||
} else if (requestCode == 56 && resultCode == RESULT_OK) {
|
||||
path = TTUtils.getImageUrl(this, data!!.getData());
|
||||
//addImage(path)
|
||||
uploadImage()
|
||||
compressAndUploadImage()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private fun compressAndUploadImage() {
|
||||
if (TextUtils.isEmpty(path)) return
|
||||
LubanCompressUtil.getCompressFile(
|
||||
this,
|
||||
File(path),
|
||||
object : LubanCompressUtil.CompressCallback {
|
||||
override fun success(file: File) {
|
||||
if (isFinishing || isDestroyed) return
|
||||
path = file.absolutePath
|
||||
uploadImage()
|
||||
}
|
||||
|
||||
override fun fail(failMsg: String) {
|
||||
if (isFinishing || isDestroyed) return
|
||||
path = ""
|
||||
toast(failMsg)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
|
||||
@@ -541,10 +596,7 @@ class ShopCustomerActivity : CKBaseActivity() {
|
||||
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)
|
||||
ChatImageLoader.load(context, holder.binding.imageContentTo, model.url!!)
|
||||
} else {
|
||||
holder.binding.textTo.visibility = View.VISIBLE
|
||||
holder.binding.imageContentTo.visibility = View.GONE
|
||||
@@ -569,4 +621,4 @@ class ShopCustomerActivity : CKBaseActivity() {
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,40 +1,64 @@
|
||||
package com.ck.ckcollar.app.ui.act.home
|
||||
|
||||
import android.graphics.Color
|
||||
import android.Manifest
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageManager
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.view.MenuItem
|
||||
import android.os.SystemClock
|
||||
import android.provider.Settings
|
||||
import android.view.View
|
||||
import android.view.WindowInsets
|
||||
import android.widget.TextView
|
||||
import androidx.viewpager2.widget.ViewPager2
|
||||
import androidx.viewpager2.widget.ViewPager2.OnPageChangeCallback
|
||||
import androidx.activity.OnBackPressedCallback
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.content.FileProvider
|
||||
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.AppUpdateDownloader
|
||||
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
|
||||
import java.io.File
|
||||
|
||||
|
||||
class MainActivity : CKLHBaseActivity(),View.OnClickListener {
|
||||
private var lastBackPressedAt = 0L
|
||||
private var pendingUpdate: UpdateModel? = null
|
||||
private var updateDialog: CKUpdateAlertDialog? = null
|
||||
private var pendingApk: File? = null
|
||||
|
||||
private val notificationPermissionLauncher = registerForActivityResult(
|
||||
ActivityResultContracts.RequestPermission()
|
||||
) { granted ->
|
||||
if (granted) {
|
||||
pendingUpdate?.let(::startUpdateDownload)
|
||||
} else {
|
||||
toast(getString(R.string.notification_permission_required))
|
||||
}
|
||||
}
|
||||
|
||||
private val installPermissionLauncher = registerForActivityResult(
|
||||
ActivityResultContracts.StartActivityForResult()
|
||||
) {
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O || packageManager.canRequestPackageInstalls()) {
|
||||
pendingApk?.let(::installApk)
|
||||
} else {
|
||||
toast(getString(R.string.install_permission_required))
|
||||
}
|
||||
}
|
||||
|
||||
lateinit var mainBinding: ActivityMainBinding
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
|
||||
@@ -43,6 +67,18 @@ class MainActivity : CKLHBaseActivity(),View.OnClickListener {
|
||||
setContentView(mainBinding.root)
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
onBackPressedDispatcher.addCallback(this, object : OnBackPressedCallback(true) {
|
||||
override fun handleOnBackPressed() {
|
||||
val now = SystemClock.elapsedRealtime()
|
||||
if (lastBackPressedAt != 0L && now - lastBackPressedAt <= EXIT_INTERVAL_MS) {
|
||||
finish()
|
||||
} else {
|
||||
lastBackPressedAt = now
|
||||
toast(getString(R.string.press_again_to_exit))
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
// if (Build.VERSION.SDK_INT >= 36){
|
||||
//
|
||||
@@ -100,6 +136,22 @@ class MainActivity : CKLHBaseActivity(),View.OnClickListener {
|
||||
|
||||
mainBinding.viewPager.setPagingEnabled(false)
|
||||
|
||||
if (intent.getBooleanExtra(EXTRA_SHOW_HOME, false)) {
|
||||
showHomeTab()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override fun onNewIntent(intent: Intent) {
|
||||
super.onNewIntent(intent)
|
||||
setIntent(intent)
|
||||
if (intent.getBooleanExtra(EXTRA_SHOW_HOME, false)) {
|
||||
showHomeTab()
|
||||
}
|
||||
}
|
||||
|
||||
private fun showHomeTab() {
|
||||
mainBinding.content1.performClick()
|
||||
}
|
||||
|
||||
fun resetItemIcon() {
|
||||
@@ -170,19 +222,28 @@ class MainActivity : CKLHBaseActivity(),View.OnClickListener {
|
||||
}
|
||||
|
||||
fun checkUpdate(){
|
||||
if (hasCheckedUpdate) return
|
||||
hasCheckedUpdate = true
|
||||
|
||||
TTHttpClient.get(this,"更新", TTRequestParam(),object : ICallback{
|
||||
override fun onSuccess(data: String) {
|
||||
|
||||
var mode = Gson().fromJson<UpdateModel>(data,UpdateModel::class.java)
|
||||
val model = Gson().fromJson<UpdateModel>(data, UpdateModel::class.java)
|
||||
|
||||
if (mode.androidVersion != TTUtils.getVersionCode(this@MainActivity)){
|
||||
CKUpdateAlertDialog(this@MainActivity,mode
|
||||
.content!!,mode.isForce,object : CKUpdateAlertDialog.AlertClickListener{
|
||||
val currentVersionCode = TTUtils.getVersionCode(this@MainActivity)
|
||||
if (model.versionCode > currentVersionCode) {
|
||||
val updateContent = model.content.orEmpty().replace("\\n", "\n")
|
||||
updateDialog = CKUpdateAlertDialog(this@MainActivity, updateContent,
|
||||
model.isForce, object : CKUpdateAlertDialog.AlertClickListener{
|
||||
override fun onBack(isConfirm: Boolean) {
|
||||
|
||||
if (isConfirm) {
|
||||
if (!model.isForce) {
|
||||
toast("更新下载进度可在任务栏中查看")
|
||||
}
|
||||
requestUpdateDownload(model)
|
||||
}
|
||||
}
|
||||
}).show()
|
||||
}).also { it.show() }
|
||||
}
|
||||
|
||||
}
|
||||
@@ -192,4 +253,91 @@ class MainActivity : CKLHBaseActivity(),View.OnClickListener {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private fun requestUpdateDownload(model: UpdateModel) {
|
||||
if (model.downloadUrl.isNullOrBlank()) {
|
||||
toast(getString(R.string.update_url_invalid))
|
||||
return
|
||||
}
|
||||
pendingUpdate = model
|
||||
if (!model.isForce && Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU &&
|
||||
ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) !=
|
||||
PackageManager.PERMISSION_GRANTED
|
||||
) {
|
||||
notificationPermissionLauncher.launch(Manifest.permission.POST_NOTIFICATIONS)
|
||||
return
|
||||
}
|
||||
startUpdateDownload(model)
|
||||
}
|
||||
|
||||
private fun startUpdateDownload(model: UpdateModel) {
|
||||
pendingUpdate = null
|
||||
if (model.isForce) {
|
||||
updateDialog?.showDownloadProgress()
|
||||
} else {
|
||||
updateDialog?.dismiss()
|
||||
updateDialog = null
|
||||
}
|
||||
AppUpdateDownloader(applicationContext).download(
|
||||
model.downloadUrl.orEmpty(),
|
||||
showNotification = !model.isForce,
|
||||
callback = object : AppUpdateDownloader.Callback {
|
||||
override fun onProgress(percent: Int) {
|
||||
runOnUiThread { updateDialog?.updateProgress(percent) }
|
||||
}
|
||||
|
||||
override fun onComplete(apkFile: File) {
|
||||
runOnUiThread {
|
||||
if (model.isForce) {
|
||||
updateDialog?.dismiss()
|
||||
updateDialog = null
|
||||
}
|
||||
pendingApk = apkFile
|
||||
installApk(apkFile)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onError(message: String) {
|
||||
runOnUiThread {
|
||||
updateDialog?.showDownloadError()
|
||||
toast(getString(R.string.update_download_failed, message))
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
private fun installApk(apkFile: File) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O &&
|
||||
!packageManager.canRequestPackageInstalls()
|
||||
) {
|
||||
toast(getString(R.string.install_permission_required))
|
||||
installPermissionLauncher.launch(
|
||||
Intent(
|
||||
Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES,
|
||||
Uri.parse("package:$packageName")
|
||||
)
|
||||
)
|
||||
return
|
||||
}
|
||||
pendingApk = null
|
||||
val apkUri = FileProvider.getUriForFile(
|
||||
this,
|
||||
"$packageName.fileprovider",
|
||||
apkFile
|
||||
)
|
||||
startActivity(
|
||||
Intent(Intent.ACTION_VIEW).apply {
|
||||
setDataAndType(apkUri, "application/vnd.android.package-archive")
|
||||
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
||||
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val EXTRA_SHOW_HOME = "extra_show_home"
|
||||
private const val EXIT_INTERVAL_MS = 2_000L
|
||||
private var hasCheckedUpdate = false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import android.view.ViewGroup
|
||||
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.databinding.FragmentHealthBinding
|
||||
import com.ck.ckcollar.app.databinding.LayoutItemNoteBinding
|
||||
@@ -16,6 +17,7 @@ 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.login.LoginActivity
|
||||
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
|
||||
@@ -24,9 +26,6 @@ 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
|
||||
@@ -64,26 +63,37 @@ class HealthFragment: CKBaseFragment() {
|
||||
binding.recyclerView.adapter = noteAdapter
|
||||
|
||||
binding.btnAIText.setOnClickListener {
|
||||
if (!requireLogin()) return@setOnClickListener
|
||||
|
||||
toActivity(CustomerActivity::class.java, DataCollection())
|
||||
}
|
||||
binding.btnAIPhoto.setOnClickListener {
|
||||
if (!requireLogin()) return@setOnClickListener
|
||||
toActivity(CustomerActivity::class.java, DataCollection())
|
||||
}
|
||||
binding.contentCustomer.setOnClickListener {
|
||||
if (!requireLogin()) return@setOnClickListener
|
||||
checkCustomerStatus()
|
||||
}
|
||||
binding.refreshLayout.setEnableLoadMore(false)
|
||||
binding.refreshLayout.setOnRefreshListener {
|
||||
page = 1
|
||||
getData()
|
||||
getCustomerTime()
|
||||
if (CKApp.app.isUserLoggedIn) {
|
||||
getCustomerTime()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
private fun requireLogin(): Boolean {
|
||||
if (CKApp.app.isUserLoggedIn) return true
|
||||
toActivity(LoginActivity::class.java, DataCollection())
|
||||
return false
|
||||
}
|
||||
|
||||
override fun initData() {
|
||||
|
||||
|
||||
@@ -93,6 +103,7 @@ class HealthFragment: CKBaseFragment() {
|
||||
|
||||
|
||||
fun getCustomerTime(){
|
||||
if (!CKApp.app.isUserLoggedIn) return
|
||||
|
||||
TTHttpClient.get(activity as TTBaseActivity,"客服在线状态", TTRequestParam(),object : ICallback{
|
||||
override fun onSuccess(data: String) {
|
||||
@@ -101,7 +112,19 @@ class HealthFragment: CKBaseFragment() {
|
||||
|
||||
|
||||
binding.textDate.text = getString(R.string.pet_advisor2)
|
||||
binding.textDate2.text = "("+customerStatusModel.serviceStartTime +","+customerStatusModel.serviceEndTime+")"
|
||||
val serviceTimes = listOfNotNull(
|
||||
customerStatusModel.serviceStartTime?.takeIf { it.isNotBlank() },
|
||||
customerStatusModel.serviceEndTime?.takeIf { it.isNotBlank() }
|
||||
)
|
||||
binding.textDate2.text = when (serviceTimes.size) {
|
||||
0 -> getString(R.string.pet_advisor_time_default)
|
||||
1 -> serviceTimes.first()
|
||||
else -> getString(
|
||||
R.string.pet_advisor_time_format,
|
||||
serviceTimes[0],
|
||||
serviceTimes[1]
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onFailed(code: String, msg: String) {
|
||||
@@ -116,6 +139,8 @@ class HealthFragment: CKBaseFragment() {
|
||||
|
||||
}
|
||||
fun getData(){
|
||||
// if (!CKApp.app.isUserLoggedIn) return
|
||||
|
||||
TTHttpClient.get(activity as TTBaseActivity,"宠物知识列表", TTRequestParam().apply {
|
||||
add(
|
||||
TTRequestData("pageNum", page)
|
||||
@@ -144,7 +169,8 @@ class HealthFragment: CKBaseFragment() {
|
||||
override fun onFailed(code: String, msg: String) {
|
||||
try {
|
||||
toast(msg)
|
||||
binding.refreshLayout.finishLoadMore(true)
|
||||
binding.refreshLayout.finishLoadMore(false)
|
||||
binding.refreshLayout.finishRefresh(false)
|
||||
|
||||
}catch (e : Exception){
|
||||
e.printStackTrace()
|
||||
@@ -189,4 +215,4 @@ class HealthFragment: CKBaseFragment() {
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,26 +1,36 @@
|
||||
package com.ck.ckcollar.app.ui.act.home.fragment
|
||||
|
||||
import android.Manifest
|
||||
import android.app.Activity.RESULT_OK
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.graphics.drawable.ColorDrawable
|
||||
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.provider.Settings
|
||||
import android.text.TextUtils
|
||||
import android.view.Gravity
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.WindowManager
|
||||
import android.widget.ImageView
|
||||
import android.widget.PopupWindow
|
||||
import android.widget.TextView
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.core.app.ActivityCompat
|
||||
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.CKApp
|
||||
import com.ck.ckcollar.app.R
|
||||
import com.ck.ckcollar.app.databinding.FragmentHomeBinding
|
||||
import com.ck.ckcollar.app.listenner.OnItemClickListenner
|
||||
@@ -35,12 +45,14 @@ 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.act.login.LoginActivity
|
||||
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.LubanCompressUtil
|
||||
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
|
||||
@@ -67,6 +79,38 @@ import kotlin.random.Random
|
||||
|
||||
class HomeFragment : CKBaseFragment() {
|
||||
|
||||
private enum class CameraAction { SCAN, TAKE_PHOTO }
|
||||
|
||||
private var pendingCameraAction: CameraAction? = null
|
||||
private var imageUploadInProgress = false
|
||||
private var permissionTopDialog: AlertDialog? = null
|
||||
private val cameraSettingsLauncher = registerForActivityResult(
|
||||
ActivityResultContracts.StartActivityForResult()
|
||||
) {
|
||||
val action = pendingCameraAction
|
||||
pendingCameraAction = null
|
||||
if (checkCameraPermissions()) {
|
||||
performCameraAction(action)
|
||||
}
|
||||
}
|
||||
private val cameraPermissionLauncher = registerForActivityResult(
|
||||
ActivityResultContracts.RequestPermission()
|
||||
) { granted ->
|
||||
hideCameraPermissionTopDialog()
|
||||
val action = pendingCameraAction
|
||||
if (granted) {
|
||||
pendingCameraAction = null
|
||||
performCameraAction(action)
|
||||
} else if (!ActivityCompat.shouldShowRequestPermissionRationale(
|
||||
requireActivity(),
|
||||
Manifest.permission.CAMERA
|
||||
)) {
|
||||
showCameraSettingsDialog()
|
||||
} else {
|
||||
pendingCameraAction = null
|
||||
}
|
||||
}
|
||||
|
||||
lateinit var homeBinding: FragmentHomeBinding
|
||||
var collarDatas = listOf<CollarTypeModel.TypeDataModel>()
|
||||
|
||||
@@ -75,6 +119,9 @@ class HomeFragment : CKBaseFragment() {
|
||||
var dataModel: CollarTypeModel.TypeDataModel? = null
|
||||
var homeModel: HomeModel? = null
|
||||
var isFirstShow = false
|
||||
private var waitingForLoginResult = false
|
||||
private var loadedLoginToken: String? = null
|
||||
private var shouldRefreshPetListOnResume = false
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
@@ -99,10 +146,13 @@ class HomeFragment : CKBaseFragment() {
|
||||
|
||||
|
||||
homeBinding.textName?.setOnClickListener {
|
||||
getPetList()
|
||||
if (!requireLogin()) return@setOnClickListener
|
||||
if (collarDatas.size <= 1) return@setOnClickListener
|
||||
showPetSelector()
|
||||
}
|
||||
//扫一扫
|
||||
homeBinding.btnScan?.setOnClickListener {
|
||||
if (!requireLogin()) return@setOnClickListener
|
||||
if (dataModel == null) {
|
||||
toast(getString(R.string.choose_pet_alert))
|
||||
return@setOnClickListener
|
||||
@@ -111,6 +161,11 @@ class HomeFragment : CKBaseFragment() {
|
||||
if (!checkCameraPermissions()){
|
||||
CKAlertDialog(activity!!,getString(R.string.alert),getString(R.string.camera_alert),object : CKAlertDialog.AlertClickListener{
|
||||
override fun onBack(isConfirm: Boolean) {
|
||||
if(isConfirm){
|
||||
requestCameraPermission(CameraAction.SCAN)
|
||||
}else{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}).show()
|
||||
@@ -120,13 +175,14 @@ class HomeFragment : CKBaseFragment() {
|
||||
startScan()
|
||||
}
|
||||
homeBinding.btnCamera?.setOnClickListener {
|
||||
if (!requireLogin()) return@setOnClickListener
|
||||
try {
|
||||
|
||||
if (!checkCameraPermissions()){
|
||||
CKAlertDialog(activity!!,getString(R.string.alert),getString(R.string.camera_alert),object : CKAlertDialog.AlertClickListener{
|
||||
|
||||
override fun onBack(isConfirm: Boolean) {
|
||||
|
||||
if (isConfirm) requestCameraPermission(CameraAction.TAKE_PHOTO)
|
||||
}
|
||||
}).show()
|
||||
return@setOnClickListener
|
||||
@@ -139,9 +195,11 @@ class HomeFragment : CKBaseFragment() {
|
||||
}
|
||||
}
|
||||
homeBinding.btnManager?.setOnClickListener {
|
||||
if (!requireLogin()) return@setOnClickListener
|
||||
toActivity(PetManagerActivity::class.java, DataCollection())
|
||||
}
|
||||
homeBinding.btnAddPet?.setOnClickListener {
|
||||
if (!requireLogin()) return@setOnClickListener
|
||||
toActivity(AddPetActivity::class.java, DataCollection())
|
||||
}
|
||||
|
||||
@@ -167,6 +225,11 @@ class HomeFragment : CKBaseFragment() {
|
||||
|
||||
}
|
||||
homeBinding.btnViewPostion?.setOnClickListener {
|
||||
if (!requireLogin()) return@setOnClickListener
|
||||
if(homeModel?.equipment?.collNum == null){
|
||||
toast("请为您的爱宠绑定项圈")
|
||||
return@setOnClickListener
|
||||
}
|
||||
getData(dataModel?.id.toString())
|
||||
|
||||
// toActivity(MapLocationActivity::class.java, DataCollection().apply {
|
||||
@@ -185,6 +248,10 @@ class HomeFragment : CKBaseFragment() {
|
||||
})
|
||||
}
|
||||
homeBinding.refreshLayout?.setOnRefreshListener {
|
||||
if (!CKApp.app.isUserLoggedIn) {
|
||||
homeBinding.refreshLayout?.finishRefresh()
|
||||
return@setOnRefreshListener
|
||||
}
|
||||
|
||||
if (dataModel == null) {
|
||||
getData("")
|
||||
@@ -199,10 +266,75 @@ class HomeFragment : CKBaseFragment() {
|
||||
homeBinding.btnTraining?.setOnClickListener {
|
||||
toast(getString(R.string.waitting_open_area))
|
||||
}
|
||||
|
||||
LiveDataBus.get().with("FIRST", Int::class.java)
|
||||
.observe(viewLifecycleOwner, object : Observer<Int?> {
|
||||
override fun onChanged(result: Int?) {
|
||||
shouldRefreshPetListOnResume = true
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private fun requireLogin(): Boolean {
|
||||
if (CKApp.app.isUserLoggedIn) return true
|
||||
waitingForLoginResult = true
|
||||
toActivity(LoginActivity::class.java, DataCollection())
|
||||
return false
|
||||
}
|
||||
|
||||
private fun requestCameraPermission(action: CameraAction) {
|
||||
pendingCameraAction = action
|
||||
showCameraPermissionTopDialog()
|
||||
permissionTopDialog?.window?.decorView?.post {
|
||||
if (isAdded && pendingCameraAction == action) {
|
||||
cameraPermissionLauncher.launch(Manifest.permission.CAMERA)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun showCameraPermissionTopDialog() {
|
||||
permissionTopDialog?.dismiss()
|
||||
val view = layoutInflater.inflate(R.layout.permission_top_dialog, null)
|
||||
view.findViewById<TextView>(R.id.permissionTopTitle).text = getString(R.string.camera)
|
||||
view.findViewById<TextView>(R.id.permissionTopContent).text = getString(R.string.camera_alert)
|
||||
permissionTopDialog = AlertDialog.Builder(requireContext())
|
||||
.setView(view)
|
||||
.create()
|
||||
.also { dialog ->
|
||||
dialog.setCanceledOnTouchOutside(false)
|
||||
dialog.setCancelable(false)
|
||||
dialog.show()
|
||||
dialog.window?.apply {
|
||||
setBackgroundDrawable(ColorDrawable(android.graphics.Color.TRANSPARENT))
|
||||
setGravity(Gravity.TOP)
|
||||
setLayout(
|
||||
WindowManager.LayoutParams.MATCH_PARENT,
|
||||
WindowManager.LayoutParams.WRAP_CONTENT
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun hideCameraPermissionTopDialog() {
|
||||
permissionTopDialog?.dismiss()
|
||||
permissionTopDialog = null
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
hideCameraPermissionTopDialog()
|
||||
pendingCameraAction = null
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
override fun initData() {
|
||||
|
||||
if (!CKApp.app.isUserLoggedIn) {
|
||||
resetLoggedOutState()
|
||||
return
|
||||
}
|
||||
|
||||
loadedLoginToken = CKApp.app.token
|
||||
|
||||
var data = PreferencesUtils.getString(activity!!, Const.PET_DATA, "")
|
||||
|
||||
if (!TextUtils.isEmpty(data)) {
|
||||
@@ -222,18 +354,9 @@ class HomeFragment : CKBaseFragment() {
|
||||
}
|
||||
|
||||
|
||||
if (isFirstShow) {
|
||||
getPetList()
|
||||
}
|
||||
getPetList()
|
||||
|
||||
|
||||
LiveDataBus.get().with("FIRST", Int::class.java)
|
||||
.observe(viewLifecycleOwner, object : Observer<Int?> {
|
||||
override fun onChanged(result: Int?) {
|
||||
getPetList2()
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
fun takePhoto() {
|
||||
@@ -275,22 +398,15 @@ class HomeFragment : CKBaseFragment() {
|
||||
}
|
||||
|
||||
fun getData(id: String) {
|
||||
if (!CKApp.app.isUserLoggedIn) return
|
||||
TTHttpClient.get(activity as TTBaseActivity, "首页", TTRequestParam().apply {
|
||||
add(TTRequestData("patId", id))
|
||||
}, object : ICallback {
|
||||
override fun onSuccess(data: String) {
|
||||
if (!CKApp.app.isUserLoggedIn) return
|
||||
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));
|
||||
setBannerData(homeModel?.banners.orEmpty())
|
||||
|
||||
}
|
||||
|
||||
@@ -299,9 +415,9 @@ class HomeFragment : CKBaseFragment() {
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
TTHttpClient.get(activity as TTBaseActivity, "设备信息", TTRequestParam().apply { add(TTRequestData("patId",id)) },object : ICallback{
|
||||
override fun onSuccess(data: String) {
|
||||
if (!CKApp.app.isUserLoggedIn) return
|
||||
var model = Gson().fromJson<HomeModel.EquipmentModel>(data, HomeModel.EquipmentModel::class.java)
|
||||
|
||||
homeModel?.equipment = model
|
||||
@@ -395,7 +511,53 @@ class HomeFragment : CKBaseFragment() {
|
||||
})
|
||||
}
|
||||
|
||||
private fun performCameraAction(action: CameraAction?) {
|
||||
when (action) {
|
||||
CameraAction.SCAN -> startScan()
|
||||
CameraAction.TAKE_PHOTO -> takePhoto()
|
||||
null -> Unit
|
||||
}
|
||||
}
|
||||
|
||||
private fun showCameraSettingsDialog() {
|
||||
CKAlertDialog(
|
||||
requireActivity(),
|
||||
getString(R.string.settting_permissions),
|
||||
getString(R.string.camera_permission_settings_alert),
|
||||
object : CKAlertDialog.AlertClickListener {
|
||||
override fun onBack(isConfirm: Boolean) {
|
||||
if (isConfirm) {
|
||||
val intent = Intent(
|
||||
Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
|
||||
Uri.parse("package:${requireContext().packageName}")
|
||||
)
|
||||
cameraSettingsLauncher.launch(intent)
|
||||
} else {
|
||||
pendingCameraAction = null
|
||||
}
|
||||
}
|
||||
}
|
||||
).show()
|
||||
}
|
||||
|
||||
private fun setBannerData(data: List<BannarModel>) {
|
||||
bannarData = data
|
||||
if (::imageAdapter.isInitialized) {
|
||||
imageAdapter.mDatas = bannarData
|
||||
homeBinding.banner.setDatas(bannarData)
|
||||
return
|
||||
}
|
||||
|
||||
imageAdapter = ImageAdapter(activity!!, bannarData, object : OnItemClickListenner {
|
||||
override fun onClick(pos: Int, model: Any) = Unit
|
||||
})
|
||||
homeBinding.banner.addBannerLifecycleObserver(this@HomeFragment)
|
||||
.setAdapter(imageAdapter)
|
||||
.setIndicator(CircleIndicator(activity))
|
||||
}
|
||||
|
||||
fun switchPet() {
|
||||
if (!CKApp.app.isUserLoggedIn) return
|
||||
|
||||
|
||||
LiveDataBus.get().with("BOUND" + dataModel!!.id, Int::class.java)
|
||||
@@ -431,6 +593,7 @@ class HomeFragment : CKBaseFragment() {
|
||||
}
|
||||
|
||||
fun getPetInfo(id: String) {
|
||||
if (!CKApp.app.isUserLoggedIn) return
|
||||
TTHttpClient.get(activity as TTBaseActivity, "宠物档案", id, object : ICallback {
|
||||
override fun onSuccess(data: String) {
|
||||
var model = Gson().fromJson<CollarTypeModel.TypeDataModel>(
|
||||
@@ -517,6 +680,7 @@ class HomeFragment : CKBaseFragment() {
|
||||
|
||||
|
||||
fun getPetList() {
|
||||
if (!CKApp.app.isUserLoggedIn) return
|
||||
showProgeassDialog(getString(R.string.search))
|
||||
TTHttpClient.get(activity as TTBaseActivity, "宠物列表", TTRequestParam().apply {
|
||||
add(
|
||||
@@ -529,43 +693,31 @@ class HomeFragment : CKBaseFragment() {
|
||||
override fun onSuccess(data: String) {
|
||||
|
||||
hiddenProgeassDialog()
|
||||
if (!CKApp.app.isUserLoggedIn) return
|
||||
var model = Gson().fromJson<CollarTypeModel>(data, CollarTypeModel::class.java)
|
||||
collarDatas = model.rows
|
||||
|
||||
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 {
|
||||
if (model.rows.isEmpty()) {
|
||||
isFirstShow = false
|
||||
if (model.rows.size > 0) {
|
||||
dataModel = model.rows.get(0)
|
||||
homeBinding.textName?.setText(dataModel?.patName)
|
||||
dataModel = null
|
||||
homeBinding.textName?.text = getString(R.string.choost_pet)
|
||||
PreferencesUtils.putString(activity!!, Const.PET_DATA, "")
|
||||
return
|
||||
}
|
||||
|
||||
if (isFirstShow) {
|
||||
isFirstShow = false
|
||||
dataModel = model.rows.first()
|
||||
homeBinding.textName?.text = dataModel?.patName
|
||||
switchPet()
|
||||
} else {
|
||||
val currentPet = model.rows.firstOrNull { it.id == dataModel?.id }
|
||||
if (currentPet != null) {
|
||||
dataModel = currentPet
|
||||
homeBinding.textName?.text = currentPet.patName
|
||||
} else if (model.rows.isNotEmpty()) {
|
||||
dataModel = model.rows.first()
|
||||
homeBinding.textName?.text = dataModel?.patName
|
||||
switchPet()
|
||||
}
|
||||
}
|
||||
@@ -579,8 +731,36 @@ class HomeFragment : CKBaseFragment() {
|
||||
})
|
||||
}
|
||||
|
||||
private fun showPetSelector() {
|
||||
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?.text = model.patName
|
||||
switchPet()
|
||||
PreferencesUtils.putString(
|
||||
activity!!,
|
||||
Const.PET_DATA,
|
||||
Gson().toJson(dataModel)
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
fun getPetList2() {
|
||||
if (!CKApp.app.isUserLoggedIn) return
|
||||
showProgeassDialog(getString(R.string.search))
|
||||
TTHttpClient.get(activity as TTBaseActivity, "宠物列表", TTRequestParam().apply {
|
||||
add(
|
||||
@@ -593,6 +773,7 @@ class HomeFragment : CKBaseFragment() {
|
||||
override fun onSuccess(data: String) {
|
||||
|
||||
hiddenProgeassDialog()
|
||||
if (!CKApp.app.isUserLoggedIn) return
|
||||
var model = Gson().fromJson<CollarTypeModel>(data, CollarTypeModel::class.java)
|
||||
|
||||
if (model.rows.size == 1) {
|
||||
@@ -615,12 +796,31 @@ class HomeFragment : CKBaseFragment() {
|
||||
super.onActivityResult(requestCode, resultCode, data)
|
||||
|
||||
if (requestCode == 55 && resultCode == RESULT_OK) {
|
||||
var path = PreferencesUtils.getString(activity!!, Const.IMAGE_PATH, "")
|
||||
uploadImage(path!!)
|
||||
val path = PreferencesUtils.getString(activity!!, Const.IMAGE_PATH, "")
|
||||
if (!path.isNullOrBlank()) {
|
||||
imageUploadInProgress = true
|
||||
LubanCompressUtil.getCompressFile(
|
||||
requireContext(),
|
||||
File(path),
|
||||
object : LubanCompressUtil.CompressCallback {
|
||||
override fun success(file: File) {
|
||||
if (!isAdded) return
|
||||
uploadImage(file.absolutePath)
|
||||
}
|
||||
|
||||
override fun fail(failMsg: String) {
|
||||
if (!isAdded) return
|
||||
imageUploadInProgress = false
|
||||
toast(failMsg)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun uploadImage(path: String) {
|
||||
if (!CKApp.app.isUserLoggedIn) return
|
||||
|
||||
var param = TTRequestParam()
|
||||
param.files.add(File(path))
|
||||
@@ -628,6 +828,11 @@ class HomeFragment : CKBaseFragment() {
|
||||
showProgeassDialog(getString(R.string.see))
|
||||
TTHttpClient.postFile(activity as TTBaseActivity, "上传照片s", param, object : ICallback {
|
||||
override fun onSuccess(data: String) {
|
||||
if (!CKApp.app.isUserLoggedIn) {
|
||||
imageUploadInProgress = false
|
||||
hiddenProgeassDialog()
|
||||
return
|
||||
}
|
||||
var model = Gson().fromJson<UploadModel>(data, UploadModel::class.java)
|
||||
|
||||
//aiPhoto(ActionCode.BASE_URL + "/" + model.fileNames)
|
||||
@@ -635,6 +840,7 @@ class HomeFragment : CKBaseFragment() {
|
||||
}
|
||||
|
||||
override fun onFailed(code: String, msg: String) {
|
||||
imageUploadInProgress = false
|
||||
hiddenProgeassDialog()
|
||||
toast(msg)
|
||||
}
|
||||
@@ -642,12 +848,15 @@ class HomeFragment : CKBaseFragment() {
|
||||
}
|
||||
|
||||
fun aiPhoto(imageUrl: String) {
|
||||
if (!CKApp.app.isUserLoggedIn) return
|
||||
|
||||
TTHttpClient.postJson(activity as TTBaseActivity, "AI拍照识别", TTRequestParam().apply {
|
||||
add(TTRequestData("imageUrl", imageUrl))
|
||||
}, object : ICallback {
|
||||
override fun onSuccess(data: String) {
|
||||
imageUploadInProgress = false
|
||||
hiddenProgeassDialog()
|
||||
if (!CKApp.app.isUserLoggedIn) return
|
||||
|
||||
var model = Gson().fromJson<AIPhotoModel>(data, AIPhotoModel::class.java)
|
||||
if ("狗".equals(model.species) || "猫".equals(model.species)) {
|
||||
@@ -665,6 +874,7 @@ class HomeFragment : CKBaseFragment() {
|
||||
}
|
||||
|
||||
override fun onFailed(code: String, msg: String) {
|
||||
imageUploadInProgress = false
|
||||
hiddenProgeassDialog()
|
||||
toast(msg)
|
||||
}
|
||||
@@ -705,11 +915,62 @@ class HomeFragment : CKBaseFragment() {
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
homeBinding.banner.start();
|
||||
if (!CKApp.app.isUserLoggedIn) {
|
||||
waitingForLoginResult = false
|
||||
resetLoggedOutState()
|
||||
return
|
||||
}
|
||||
if (waitingForLoginResult) {
|
||||
waitingForLoginResult = false
|
||||
if (CKApp.app.isUserLoggedIn) {
|
||||
getPetList()
|
||||
}
|
||||
}
|
||||
dataModel?.let {
|
||||
getData(dataModel!!.id.toString())
|
||||
}
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
if (CKApp.app.isUserLoggedIn && loadedLoginToken != CKApp.app.token) {
|
||||
initData()
|
||||
} else if (CKApp.app.isUserLoggedIn && shouldRefreshPetListOnResume && !imageUploadInProgress) {
|
||||
getPetList()
|
||||
}
|
||||
shouldRefreshPetListOnResume = false
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
shouldRefreshPetListOnResume = true
|
||||
}
|
||||
|
||||
private fun resetLoggedOutState() {
|
||||
loadedLoginToken = null
|
||||
collarDatas = emptyList()
|
||||
bannarData = emptyList()
|
||||
dataModel = null
|
||||
homeModel = null
|
||||
isFirstShow = false
|
||||
|
||||
homeBinding.textName?.text = getString(R.string.choost_pet)
|
||||
homeBinding.btnBound?.text = getString(R.string.unbound)
|
||||
homeBinding.textHealthPoints?.text = "--"
|
||||
homeBinding.points?.visibility = View.GONE
|
||||
homeBinding.textStep?.text = "-"
|
||||
homeBinding.textAddress?.text = getString(R.string.no_position)
|
||||
homeBinding.textDistance?.text = "-"
|
||||
homeBinding.textPowerValue?.text = "%"
|
||||
homeBinding.imagePower?.setImageResource(R.mipmap.image_power_0)
|
||||
homeBinding.contentPower?.visibility = View.GONE
|
||||
setNoDeviceUI()
|
||||
setBannerData(listOf(BannarModel().apply {
|
||||
localImageRes = R.mipmap.index_banner1
|
||||
}))
|
||||
homeBinding.refreshLayout?.finishRefresh()
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
super.onStop()
|
||||
homeBinding.banner.stop();
|
||||
@@ -749,8 +1010,11 @@ class HomeFragment : CKBaseFragment() {
|
||||
position: Int,
|
||||
size: Int
|
||||
) {
|
||||
val imageSource: Any? = data?.localImageRes
|
||||
?.takeIf { it != 0 }
|
||||
?: data?.bannerUrl
|
||||
Glide.with(context)
|
||||
.load(data?.bannerUrl)
|
||||
.load(imageSource)
|
||||
.apply(RequestOptions.bitmapTransform(RoundedCorners(12)))
|
||||
.placeholder(R.mipmap.image_bannar_item)
|
||||
.into(holder!!.imageView)
|
||||
@@ -768,4 +1032,4 @@ class HomeFragment : CKBaseFragment() {
|
||||
imageView
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ 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.login.LoginActivity
|
||||
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
|
||||
@@ -51,19 +52,24 @@ class MineFragment : CKBaseFragment() {
|
||||
override fun initView() {
|
||||
|
||||
binding.contentBalance.setOnClickListener {
|
||||
if (!requireLogin()) return@setOnClickListener
|
||||
toActivity(BalanceActivity::class.java, DataCollection())
|
||||
}
|
||||
binding.conetntPoints.setOnClickListener {
|
||||
if (!requireLogin()) return@setOnClickListener
|
||||
toActivity(PointsActivity::class.java, DataCollection())
|
||||
}
|
||||
binding.imageUser.setOnClickListener {
|
||||
if (!requireLogin()) return@setOnClickListener
|
||||
toActivity(UserInfoActivity::class.java, DataCollection())
|
||||
}
|
||||
binding.btnUserInfo.setOnClickListener {
|
||||
if (!requireLogin()) return@setOnClickListener
|
||||
toActivity(UserInfoActivity::class.java, DataCollection())
|
||||
}
|
||||
|
||||
binding.btnMessage.setOnClickListener {
|
||||
if (!requireLogin()) return@setOnClickListener
|
||||
toActivity(MessageCenterActivity::class.java, DataCollection())
|
||||
}
|
||||
|
||||
@@ -71,19 +77,24 @@ class MineFragment : CKBaseFragment() {
|
||||
toActivity(SettingActivity::class.java, DataCollection())
|
||||
}
|
||||
binding.btnOpen.setOnClickListener {
|
||||
if (!requireLogin()) return@setOnClickListener
|
||||
toActivity(MemberActivity::class.java, DataCollection())
|
||||
}
|
||||
|
||||
binding.btnReturnDevice.setOnClickListener {
|
||||
if (!requireLogin()) return@setOnClickListener
|
||||
toActivity(ReturnDeviceActivity::class.java, DataCollection())
|
||||
}
|
||||
binding.btnFeedback.setOnClickListener {
|
||||
if (!requireLogin()) return@setOnClickListener
|
||||
toActivity(FeedBackActivity::class.java, DataCollection())
|
||||
}
|
||||
binding.btnCustomerService.setOnClickListener {
|
||||
if (!requireLogin()) return@setOnClickListener
|
||||
toActivity(PeopleCustomerActivity::class.java, DataCollection().apply { add(Data("chatType","2")) })
|
||||
}
|
||||
binding.textDeposit.setOnClickListener {
|
||||
if (!requireLogin()) return@setOnClickListener
|
||||
if ("0".equals(CKApp.app.userInfo!!.depositStatus)){
|
||||
toActivity(DepositActivity::class.java, DataCollection())
|
||||
}else{
|
||||
@@ -92,18 +103,23 @@ class MineFragment : CKBaseFragment() {
|
||||
}
|
||||
|
||||
binding.btnAllOrder.setOnClickListener {
|
||||
if (!requireLogin()) return@setOnClickListener
|
||||
toActivity(MyOrderActivity::class.java, DataCollection().apply { add(Data("pos","0")) })
|
||||
}
|
||||
binding.btnOrderPayment.setOnClickListener {
|
||||
if (!requireLogin()) return@setOnClickListener
|
||||
toActivity(MyOrderActivity::class.java, DataCollection().apply { add(Data("pos","1")) })
|
||||
}
|
||||
binding.btnOrderDelivery.setOnClickListener {
|
||||
if (!requireLogin()) return@setOnClickListener
|
||||
toActivity(MyOrderActivity::class.java, DataCollection().apply { add(Data("pos","2")) })
|
||||
}
|
||||
binding.btnOrderReceipt.setOnClickListener {
|
||||
if (!requireLogin()) return@setOnClickListener
|
||||
toActivity(MyOrderActivity::class.java, DataCollection().apply { add(Data("pos","3")) })
|
||||
}
|
||||
binding.btnOrderAfterSales.setOnClickListener {
|
||||
if (!requireLogin()) return@setOnClickListener
|
||||
toActivity(MyOrderActivity::class.java, DataCollection().apply { add(Data("pos","4")) })
|
||||
}
|
||||
|
||||
@@ -111,20 +127,39 @@ class MineFragment : CKBaseFragment() {
|
||||
|
||||
}
|
||||
|
||||
private fun requireLogin(): Boolean {
|
||||
if (CKApp.app.isUserLoggedIn) return true
|
||||
toActivity(LoginActivity::class.java, DataCollection())
|
||||
return false
|
||||
}
|
||||
|
||||
override fun initData() {
|
||||
|
||||
if (!CKApp.app.isUserLoggedIn) {
|
||||
renderLoggedOutState()
|
||||
binding.textNick.text = getString(R.string.guest)
|
||||
binding.textPhone.text = "用户未登录"
|
||||
binding.textPhone.visibility = View.VISIBLE
|
||||
binding.textBalance.text = "0"
|
||||
binding.textPoints.text = "0"
|
||||
binding.textCount.visibility = View.INVISIBLE
|
||||
binding.imageUser.setImageResource(R.mipmap.icon_unlogin_defaul)
|
||||
return
|
||||
}
|
||||
|
||||
binding.textNick.text = CKApp.app.userInfo?.custName
|
||||
binding.textPhone.text = CKApp.app.userInfo?.phonenumber
|
||||
binding.textPhone.visibility = View.VISIBLE
|
||||
|
||||
if (!TextUtils.isEmpty(CKApp.app.userInfo?.avatar)){
|
||||
Glide.with(this@MineFragment)
|
||||
.load( CKApp.app.userInfo?.avatar)
|
||||
.placeholder(R.mipmap.image_user_default)
|
||||
.placeholder(R.mipmap.icon_unlogin_defaul)
|
||||
.into(binding.imageUser)
|
||||
}
|
||||
|
||||
binding.textBalance.text = CKApp.app.userInfo?.balance.toString()
|
||||
binding.textPoints.text = CKApp.app.userInfo?.points.toString()
|
||||
binding.textBalance.text = CKApp.app.userInfo?.balance?.toString() ?: "0"
|
||||
binding.textPoints.text = CKApp.app.userInfo?.points?.toString() ?: "0"
|
||||
|
||||
if (CKApp.app.userInfo?.isMember == true){
|
||||
binding.btnOpen.setText(getString(R.string.auto_renewal2))
|
||||
@@ -135,6 +170,7 @@ class MineFragment : CKBaseFragment() {
|
||||
}else{
|
||||
binding.btnOpen.setText(getString(R.string.open_member))
|
||||
binding.textMemberTitle.text = getString(R.string.pet_member)
|
||||
binding.textMemberDate.text = getString(R.string.pet_member_rewards)
|
||||
}
|
||||
|
||||
|
||||
@@ -147,11 +183,36 @@ class MineFragment : CKBaseFragment() {
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
getUserInfo()
|
||||
initData()
|
||||
if (CKApp.app.isUserLoggedIn) {
|
||||
getUserInfo()
|
||||
}
|
||||
}
|
||||
fun getUserInfo(){
|
||||
|
||||
private fun renderLoggedOutState() {
|
||||
binding.textNick.text = getString(R.string.guest)
|
||||
binding.textPhone.text = getString(R.string.user_not_logged_in)
|
||||
binding.textPhone.visibility = View.VISIBLE
|
||||
binding.textBalance.text = "0"
|
||||
binding.textPoints.text = "0"
|
||||
binding.textCount.text = "0"
|
||||
binding.textCount.visibility = View.INVISIBLE
|
||||
binding.btnOpen.text = getString(R.string.open_member)
|
||||
binding.textMemberTitle.text = getString(R.string.pet_member)
|
||||
binding.textMemberDate.text = getString(R.string.pet_member_rewards)
|
||||
Glide.with(this).clear(binding.imageUser)
|
||||
binding.imageUser.setImageResource(R.mipmap.icon_unlogin_defaul)
|
||||
}
|
||||
|
||||
private fun getUserInfo(){
|
||||
if (!CKApp.app.isUserLoggedIn) {
|
||||
binding.textCount.visibility = View.INVISIBLE
|
||||
return
|
||||
}
|
||||
|
||||
TTHttpClient.get(activity as TTBaseActivity,"个人资料", TTRequestParam(),object : ICallback{
|
||||
override fun onSuccess(data: String) {
|
||||
if (!CKApp.app.isUserLoggedIn) return
|
||||
CKApp.app.userInfo = Gson().fromJson<UserInfoModel>(data, UserInfoModel::class.java)
|
||||
PreferencesUtils.putString(activity!!, Const.USER_DATA,data)
|
||||
|
||||
@@ -168,6 +229,7 @@ class MineFragment : CKBaseFragment() {
|
||||
add(TTRequestData("accept","true"))
|
||||
},object : ICallback{
|
||||
override fun onSuccess(data: String) {
|
||||
if (!CKApp.app.isUserLoggedIn) return
|
||||
var model = Gson().fromJson<UnReadModel>(data, UnReadModel::class.java)
|
||||
|
||||
binding.textCount.text = model.unreadCount.toString()
|
||||
@@ -187,4 +249,4 @@ class MineFragment : CKBaseFragment() {
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ 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.CKApp
|
||||
import com.ck.ckcollar.app.R
|
||||
import com.ck.ckcollar.app.action.ActionCode
|
||||
import com.ck.ckcollar.app.databinding.FragmentShopBinding
|
||||
@@ -134,10 +135,12 @@ class ShopFragment : CKBaseFragment() {
|
||||
}
|
||||
|
||||
binding.btnShopCar.setOnClickListener {
|
||||
if (!isUserLogin()) return@setOnClickListener
|
||||
toActivity(ShopCarActivity::class.java, DataCollection())
|
||||
}
|
||||
|
||||
binding.btnShopOrder.setOnClickListener {
|
||||
if (!isUserLogin()) return@setOnClickListener
|
||||
toActivity(MyOrderActivity::class.java, DataCollection().apply { add(Data("pos","0")) })
|
||||
}
|
||||
|
||||
@@ -154,7 +157,7 @@ class ShopFragment : CKBaseFragment() {
|
||||
getHot()
|
||||
page = 1
|
||||
getData()
|
||||
getBannar()
|
||||
// getBannar()
|
||||
}
|
||||
|
||||
override fun onLoadMore(refreshLayout: RefreshLayout) {
|
||||
@@ -299,6 +302,11 @@ class ShopFragment : CKBaseFragment() {
|
||||
}
|
||||
|
||||
fun getCarCount() {
|
||||
if (!CKApp.app.isUserLoggedIn) {
|
||||
binding.textCount.visibility = View.GONE
|
||||
return
|
||||
}
|
||||
|
||||
TTHttpClient.get(
|
||||
activity as TTBaseActivity,
|
||||
"购物车数量和合计",
|
||||
@@ -546,4 +554,4 @@ class ShopFragment : CKBaseFragment() {
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,11 +91,7 @@ class BoundPhoneActivity : CKBaseActivity() {
|
||||
override fun onSuccess(data: String) {
|
||||
|
||||
var token = JSONObject(data).getString("token")
|
||||
PreferencesUtils.putString(
|
||||
this@BoundPhoneActivity,
|
||||
Const.TOKEN, token
|
||||
)
|
||||
CKApp.app.token = token
|
||||
CKApp.app.setLoginToken(token)
|
||||
|
||||
|
||||
|
||||
@@ -140,4 +136,4 @@ class BoundPhoneActivity : CKBaseActivity() {
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,10 +12,12 @@ 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.config.Config
|
||||
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.act.setting.SettingWebViewActivity
|
||||
import com.ck.ckcollar.app.ui.base.CKBaseActivity
|
||||
import com.ck.ckcollar.app.utils.Const
|
||||
import com.ck.ckcollar.app.utils.networkone.ICallback
|
||||
@@ -32,7 +34,7 @@ import com.tt.kit.model.DataCollection
|
||||
import com.tt.kit.utils.TTUtils
|
||||
|
||||
/**
|
||||
* 登录
|
||||
* 登录..
|
||||
*/
|
||||
class LoginActivity : CKBaseActivity() {
|
||||
|
||||
@@ -51,7 +53,7 @@ class LoginActivity : CKBaseActivity() {
|
||||
// api = WXAPIFactory.createWXAPI(this, Const.WX_APP_ID, false);
|
||||
setStatusBarColor(R.attr.mainBackground)
|
||||
//检测权限
|
||||
checkAppPermissions()
|
||||
// checkAppPermissions()
|
||||
|
||||
}
|
||||
|
||||
@@ -67,6 +69,9 @@ class LoginActivity : CKBaseActivity() {
|
||||
binding.btnLogin.setOnClickListener {
|
||||
login()
|
||||
}
|
||||
binding.btnQuickLogin.setOnClickListener {
|
||||
quickLogin()
|
||||
}
|
||||
|
||||
binding.btnCodeLogin.setOnClickListener {
|
||||
binding.btnCodeLogin.setTextColor(getColor2(R.attr.appTextColor))
|
||||
@@ -124,8 +129,11 @@ class LoginActivity : CKBaseActivity() {
|
||||
var clickableSpan2 = object : ClickableSpan() {
|
||||
override fun onClick(v: View) {
|
||||
toActivity(
|
||||
AgreementActivity::class.java,
|
||||
DataCollection().apply { add(Data("title", "隐私政策")) })
|
||||
SettingWebViewActivity::class.java,
|
||||
DataCollection().apply {
|
||||
add(Data("url", Config.PRIVACY_POLICY))
|
||||
add(Data("title", getString(R.string.privacy_agreement)))
|
||||
})
|
||||
}
|
||||
|
||||
override fun updateDrawState(ds: TextPaint) {
|
||||
@@ -146,7 +154,6 @@ class LoginActivity : CKBaseActivity() {
|
||||
binding.btnCheck.setOnClickListener {
|
||||
isCheck = !isCheck
|
||||
setCheckUI()
|
||||
PreferencesUtils.putBoolean(this@LoginActivity, Const.AGREEMENT_CHECK, isCheck)
|
||||
}
|
||||
|
||||
binding.btnSendCode.setOnClickListener {
|
||||
@@ -154,6 +161,10 @@ class LoginActivity : CKBaseActivity() {
|
||||
sendCode()
|
||||
}
|
||||
binding.btnWX.setOnClickListener {
|
||||
if (!isCheck) {
|
||||
toast(getString(R.string.alert_agreement))
|
||||
return@setOnClickListener
|
||||
}
|
||||
val req = SendAuth.Req()
|
||||
req.scope = "snsapi_userinfo" // 只能填 snsapi_userinfo
|
||||
req.state = "wechat_sdk_demo_test"
|
||||
@@ -232,11 +243,7 @@ class LoginActivity : CKBaseActivity() {
|
||||
|
||||
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()
|
||||
CKApp.app.setLoginToken(model.token.orEmpty())
|
||||
|
||||
getUserInfo()
|
||||
} catch (e: Exception) {
|
||||
@@ -262,11 +269,7 @@ class LoginActivity : CKBaseActivity() {
|
||||
|
||||
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()
|
||||
CKApp.app.setLoginToken(model.token.orEmpty())
|
||||
|
||||
getUserInfo()
|
||||
} catch (e: Exception) {
|
||||
@@ -285,15 +288,44 @@ class LoginActivity : CKBaseActivity() {
|
||||
|
||||
}
|
||||
|
||||
private fun quickLogin() {
|
||||
showProgeassDialog(getString(R.string.login))
|
||||
TTHttpClient.postJson(this, "登录", TTRequestParam().apply {
|
||||
add(TTRequestData("username", "13305376054"))
|
||||
add(TTRequestData("password", "000000"))
|
||||
add(TTRequestData("code", ""))
|
||||
add(TTRequestData("uuid", TTUtils.getDeviceId(this@LoginActivity).toString()))
|
||||
}, object : ICallback {
|
||||
override fun onSuccess(data: String) {
|
||||
try {
|
||||
val model = Gson().fromJson<LoginModel>(data, LoginModel::class.java)
|
||||
CKApp.app.setLoginToken(model.token.orEmpty())
|
||||
getUserInfo()
|
||||
} catch (e: Exception) {
|
||||
hiddenProgeassDialog()
|
||||
toast(e.message.orEmpty())
|
||||
}
|
||||
}
|
||||
|
||||
override fun onFailed(code: String, msg: String) {
|
||||
hiddenProgeassDialog()
|
||||
toast(msg)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fun getUserInfo(){
|
||||
TTHttpClient.get(this,"个人资料", TTRequestParam(),object : ICallback{
|
||||
override fun onSuccess(data: String) {
|
||||
CKApp.app.userInfo = Gson().fromJson<UserInfoModel>(data, UserInfoModel::class.java)
|
||||
PreferencesUtils.putString(this@LoginActivity, Const.USER_DATA,data)
|
||||
|
||||
toActivity(MainActivity::class.java, DataCollection())
|
||||
|
||||
|
||||
startActivity(
|
||||
Intent(this@LoginActivity, MainActivity::class.java).apply {
|
||||
addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP)
|
||||
putExtra(MainActivity.EXTRA_SHOW_HOME, true)
|
||||
}
|
||||
)
|
||||
finish()
|
||||
}
|
||||
|
||||
@@ -308,7 +340,9 @@ class LoginActivity : CKBaseActivity() {
|
||||
|
||||
binding.editLoginName.setText(PreferencesUtils.getString(this, Const.LOGIN_NAME, ""))
|
||||
|
||||
isCheck = PreferencesUtils.getBolean(this, Const.AGREEMENT_CHECK, false) as Boolean
|
||||
// Agreement consent is intentionally session-local: users must confirm it on every login.
|
||||
isCheck = false
|
||||
setCheckUI()
|
||||
|
||||
}
|
||||
|
||||
@@ -324,6 +358,12 @@ class LoginActivity : CKBaseActivity() {
|
||||
}
|
||||
|
||||
fun wxLogin(code : String){
|
||||
|
||||
if (!isCheck) {
|
||||
toast(getString(R.string.alert_agreement))
|
||||
return
|
||||
}
|
||||
|
||||
showProgeassDialog(getString(R.string.login))
|
||||
TTHttpClient.postJson(this,"微信登录", TTRequestParam().apply { add(TTRequestData("code",code)) },object : ICallback{
|
||||
override fun onSuccess(data: String) {
|
||||
@@ -338,11 +378,7 @@ class LoginActivity : CKBaseActivity() {
|
||||
finish()
|
||||
|
||||
}else{
|
||||
PreferencesUtils.putString(
|
||||
this@LoginActivity,
|
||||
Const.TOKEN, model.token.toString()
|
||||
)
|
||||
CKApp.app.token = model.token.toString()
|
||||
CKApp.app.setLoginToken(model.token.orEmpty())
|
||||
|
||||
getUserInfo()
|
||||
}
|
||||
@@ -360,4 +396,4 @@ class LoginActivity : CKBaseActivity() {
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -122,11 +122,7 @@ class RegisterActivity : CKBaseActivity() {
|
||||
|
||||
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()
|
||||
CKApp.app.setLoginToken(model.token.orEmpty())
|
||||
|
||||
getUserInfo()
|
||||
} catch (e: Exception) {
|
||||
@@ -171,4 +167,4 @@ class RegisterActivity : CKBaseActivity() {
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,45 +8,42 @@ 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.Const
|
||||
import com.ck.ckcollar.app.utils.MemberPriceCache
|
||||
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.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.DataCollection
|
||||
|
||||
class MemberActivity : CKBaseActivity() {
|
||||
|
||||
override val useDarkStatusBarIcons: Boolean = false
|
||||
|
||||
lateinit var binding: ActivityMemberBinding
|
||||
private var priceRequestInFlight = false
|
||||
|
||||
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)
|
||||
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())
|
||||
}
|
||||
@@ -56,8 +53,7 @@ class MemberActivity : CKBaseActivity() {
|
||||
}
|
||||
|
||||
override fun initData() {
|
||||
|
||||
|
||||
renderMemberInfo(CKApp.app.userInfo)
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
@@ -65,45 +61,78 @@ class MemberActivity : CKBaseActivity() {
|
||||
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)
|
||||
private fun loadMemberPrice() {
|
||||
val cachedPrice = MemberPriceCache.getPrice(this)
|
||||
if (cachedPrice != null) {
|
||||
showMemberPrice(cachedPrice)
|
||||
}
|
||||
|
||||
if (model.size > 0){
|
||||
binding.textMoney.text = model.get(0).actualPrice.toString()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override fun onFailed(code: String, msg: String) {
|
||||
toast(msg)
|
||||
}
|
||||
})
|
||||
if (cachedPrice == null || MemberPriceCache.isExpired(this)) {
|
||||
getInfo(cachedPrice != null)
|
||||
}
|
||||
}
|
||||
|
||||
fun getMemberInfo(){
|
||||
TTHttpClient.get(this,"个人资料", TTRequestParam(),object : ICallback{
|
||||
private fun getInfo(hasCachedPrice: Boolean) {
|
||||
if (priceRequestInFlight) return
|
||||
priceRequestInFlight = true
|
||||
TTHttpClient.get(this, "会员套餐列表", TTRequestParam(), object : ICallback {
|
||||
override fun onSuccess(data: String) {
|
||||
var model = Gson().fromJson<UserInfoModel>(data, UserInfoModel::class.java)
|
||||
priceRequestInFlight = false
|
||||
val model = Gson().fromJson<List<MemberPriceModel>>(
|
||||
data,
|
||||
object : TypeToken<List<MemberPriceModel>>() {}.type
|
||||
)
|
||||
|
||||
|
||||
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()
|
||||
if (model.isNotEmpty()) {
|
||||
val price = model.first().actualPrice
|
||||
MemberPriceCache.save(this@MemberActivity, price)
|
||||
showMemberPrice(price)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onFailed(code: String, msg: String) {
|
||||
priceRequestInFlight = false
|
||||
if (!hasCachedPrice) toast(msg)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private fun showMemberPrice(price: Double) {
|
||||
binding.textMoney.text = price.toString()
|
||||
binding.priceContent.visibility = View.VISIBLE
|
||||
}
|
||||
|
||||
private fun getMemberInfo() {
|
||||
TTHttpClient.get(this, "个人资料", TTRequestParam(), object : ICallback {
|
||||
override fun onSuccess(data: String) {
|
||||
val model = Gson().fromJson<UserInfoModel>(data, UserInfoModel::class.java)
|
||||
CKApp.app.userInfo = model
|
||||
PreferencesUtils.putString(this@MemberActivity, Const.USER_DATA, data)
|
||||
renderMemberInfo(model)
|
||||
}
|
||||
|
||||
override fun onFailed(code: String, msg: String) {
|
||||
toast(msg)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
private fun renderMemberInfo(model: UserInfoModel?) {
|
||||
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
|
||||
loadMemberPrice()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.ck.ckcollar.app.ui.act.member
|
||||
|
||||
import android.content.pm.ApplicationInfo
|
||||
import android.content.res.ColorStateList
|
||||
import android.graphics.Color
|
||||
import android.os.Bundle
|
||||
@@ -8,6 +9,7 @@ import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.TextView
|
||||
import com.alipay.sdk.app.EnvUtils
|
||||
import com.alipay.sdk.app.PayTask
|
||||
import com.ck.ckcollar.app.R
|
||||
import com.ck.ckcollar.app.databinding.ActivityMemberBinding
|
||||
@@ -19,14 +21,19 @@ 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.ui.act.balance.RechargeActivity
|
||||
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.google.gson.Gson
|
||||
import com.google.gson.reflect.TypeToken
|
||||
import com.tencent.mm.opensdk.modelpay.PayReq
|
||||
import com.tencent.mm.opensdk.openapi.WXAPIFactory
|
||||
import com.gyf.immersionbar.ImmersionBar
|
||||
import com.tt.kit.utils.TTUtils
|
||||
import com.tt.kit.utils.LiveDataBus
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.launch
|
||||
@@ -38,7 +45,7 @@ class OpenMemberActivity : CKLHBaseActionBarActivity() {
|
||||
var data = listOf<MemberPriceModel>()
|
||||
var pos = -1
|
||||
var isAuto = false
|
||||
var payType = "1"
|
||||
var payType = "0"
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
binding = ActivityOpenMemberBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
@@ -53,6 +60,17 @@ class OpenMemberActivity : CKLHBaseActionBarActivity() {
|
||||
|
||||
override fun initView() {
|
||||
|
||||
LiveDataBus.get().with(RechargeActivity.WX_PAY_RESULT, Int::class.java).observe(this) { result ->
|
||||
when (result) {
|
||||
0 -> {
|
||||
toast(getString(R.string.payment_success))
|
||||
finish()
|
||||
}
|
||||
-2 -> toast("已取消微信支付")
|
||||
else -> toast(getString(R.string.payment_faild))
|
||||
}
|
||||
}
|
||||
|
||||
//setPriceUI()
|
||||
|
||||
binding.btnAli.setOnClickListener {
|
||||
@@ -134,6 +152,8 @@ class OpenMemberActivity : CKLHBaseActionBarActivity() {
|
||||
var model = Gson().fromJson<MemberModel>(data, MemberModel::class.java)
|
||||
if ("1".equals(payType)){
|
||||
aliPay(model.orderStr!!)
|
||||
}else if ("0".equals(payType)) {
|
||||
wxPay(model)
|
||||
}else{
|
||||
toast(getString(R.string.payment_success))
|
||||
finish()
|
||||
@@ -220,7 +240,10 @@ class OpenMemberActivity : CKLHBaseActionBarActivity() {
|
||||
|
||||
fun aliPay(orderStr : String){
|
||||
GlobalScope.launch(Dispatchers.IO){
|
||||
|
||||
// [支付宝沙箱测试] 仅 Debug 包启用,Release 包继续使用正式环境。
|
||||
if (applicationInfo.flags and ApplicationInfo.FLAG_DEBUGGABLE != 0) {
|
||||
// EnvUtils.setEnv(EnvUtils.EnvEnum.SANDBOX)
|
||||
}
|
||||
val alipay = PayTask(this@OpenMemberActivity)
|
||||
val result = alipay.payV2(orderStr, true)
|
||||
|
||||
@@ -239,4 +262,49 @@ class OpenMemberActivity : CKLHBaseActionBarActivity() {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun wxPay(model: MemberModel) {
|
||||
val requiredValues = listOf(
|
||||
model.appId,
|
||||
model.partnerId,
|
||||
model.prepayId,
|
||||
model.packageVal,
|
||||
model.nonceStr,
|
||||
model.timeStamp,
|
||||
model.paySign
|
||||
)
|
||||
if (requiredValues.any { it.isNullOrBlank() }) {
|
||||
hiddenProgeassDialog()
|
||||
toast("微信支付参数不完整,请检查商户号等支付参数")
|
||||
return
|
||||
}
|
||||
if (model.appId != Const.WX_APP_ID) {
|
||||
hiddenProgeassDialog()
|
||||
toast("微信支付 AppID 不匹配")
|
||||
return
|
||||
}
|
||||
|
||||
val api = WXAPIFactory.createWXAPI(this, Const.WX_APP_ID, true)
|
||||
api.registerApp(Const.WX_APP_ID)
|
||||
if (!api.isWXAppInstalled) {
|
||||
hiddenProgeassDialog()
|
||||
toast("请先安装微信")
|
||||
return
|
||||
}
|
||||
|
||||
val request = PayReq().apply {
|
||||
appId = model.appId
|
||||
partnerId = model.partnerId
|
||||
prepayId = model.prepayId
|
||||
packageValue = model.packageVal
|
||||
nonceStr = model.nonceStr
|
||||
timeStamp = model.timeStamp
|
||||
sign = model.paySign
|
||||
extData = model.orderNo
|
||||
}
|
||||
hiddenProgeassDialog()
|
||||
if (!api.sendReq(request)) {
|
||||
toast("微信支付拉起失败")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.ck.ckcollar.app.ui.act.mine
|
||||
|
||||
import android.Manifest
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
@@ -10,24 +11,23 @@ import android.text.TextUtils
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.webkit.MimeTypeMap
|
||||
import android.widget.AdapterView
|
||||
import android.widget.BaseAdapter
|
||||
import android.widget.ImageView
|
||||
import androidx.core.content.FileProvider
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.ck.ckcollar.app.R
|
||||
import com.ck.ckcollar.app.databinding.ActivityFeedBackBinding
|
||||
import com.ck.ckcollar.app.databinding.LayoutItemImage2Binding
|
||||
import com.ck.ckcollar.app.databinding.LayoutItemImageBinding
|
||||
import com.ck.ckcollar.app.model.ImageModel
|
||||
import com.ck.ckcollar.app.model.UploadModel
|
||||
import com.ck.ckcollar.app.ui.act.petmanager.AddPetActivity
|
||||
import com.ck.ckcollar.app.ui.act.petmanager.AddPetActivity.ImageAdapter
|
||||
import com.ck.ckcollar.app.ui.act.petmanager.ImageViewActivity
|
||||
import com.ck.ckcollar.app.ui.base.CKBaseActivity
|
||||
import com.ck.ckcollar.app.ui.dialog.CKAlertDialog
|
||||
import com.ck.ckcollar.app.ui.dialog.CKPhotoDialog
|
||||
import com.ck.ckcollar.app.utils.CKUtils
|
||||
import com.ck.ckcollar.app.utils.Const
|
||||
import com.ck.ckcollar.app.utils.LubanCompressUtil
|
||||
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
|
||||
@@ -36,8 +36,10 @@ import com.cyclone.shadowsocks.utils.PreferencesUtils
|
||||
import com.google.gson.Gson
|
||||
import com.tt.kit.model.Data
|
||||
import com.tt.kit.model.DataCollection
|
||||
import com.tt.kit.utils.TTLog
|
||||
import com.tt.kit.utils.TTUtils
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.io.File
|
||||
|
||||
class FeedBackActivity : CKBaseActivity() {
|
||||
@@ -50,7 +52,7 @@ class FeedBackActivity : CKBaseActivity() {
|
||||
binding = ActivityFeedBackBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
super.onCreate(savedInstanceState)
|
||||
checkAppPermissions()
|
||||
// checkAppPermissions()
|
||||
setTitleText(getString(R.string.feedback))
|
||||
}
|
||||
|
||||
@@ -84,13 +86,30 @@ class FeedBackActivity : CKBaseActivity() {
|
||||
})
|
||||
return
|
||||
}
|
||||
//相册
|
||||
val i = Intent(
|
||||
Intent.ACTION_PICK,
|
||||
MediaStore.Images.Media.EXTERNAL_CONTENT_URI
|
||||
)
|
||||
i.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,"image/*");
|
||||
startActivityForResult(i, 56)
|
||||
CKPhotoDialog(
|
||||
this@FeedBackActivity,
|
||||
object : CKPhotoDialog.PhotoClickListener {
|
||||
override fun onBack(mark: Int, position: Int) {
|
||||
try {
|
||||
if (mark == 0) {
|
||||
if (!checkCameraPermissions()) {
|
||||
getPermissionRequst(
|
||||
Manifest.permission.CAMERA,
|
||||
REQUEST_CAMERA_PERMISSION
|
||||
)
|
||||
return
|
||||
}
|
||||
takePhoto()
|
||||
} else {
|
||||
openAlbum()
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
toast(getString(R.string.read_photo_failed))
|
||||
}
|
||||
}
|
||||
}
|
||||
).show()
|
||||
}
|
||||
|
||||
}
|
||||
@@ -105,6 +124,12 @@ class FeedBackActivity : CKBaseActivity() {
|
||||
|
||||
}
|
||||
|
||||
override fun onPermissionsGranted(requestCode: Int, permissions: Array<String>) {
|
||||
if (requestCode == REQUEST_CAMERA_PERMISSION) {
|
||||
takePhoto()
|
||||
}
|
||||
}
|
||||
|
||||
fun upload(){
|
||||
|
||||
if (binding.editConten.isEmpty()){
|
||||
@@ -162,11 +187,120 @@ class FeedBackActivity : CKBaseActivity() {
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
super.onActivityResult(requestCode, resultCode, data)
|
||||
|
||||
if (requestCode == 56 && resultCode == RESULT_OK) {
|
||||
var path = TTUtils.getImageUrl(this, data!!.getData());
|
||||
this.data.add(this.data.size - 1,ImageModel().apply { this.path = path })
|
||||
imageAdapter.data = this.data
|
||||
imageAdapter.notifyDataSetChanged()
|
||||
if (requestCode == REQUEST_CAMERA && resultCode == RESULT_OK) {
|
||||
val path = PreferencesUtils.getString(this, Const.IMAGE_PATH, "").orEmpty()
|
||||
compressAndAddImage(path)
|
||||
} else if (requestCode == REQUEST_ALBUM && resultCode == RESULT_OK) {
|
||||
data?.data?.let(::handleSelectedImage)
|
||||
?: toast(getString(R.string.read_photo_failed))
|
||||
}
|
||||
}
|
||||
|
||||
private fun openAlbum() {
|
||||
val intent = Intent(
|
||||
Intent.ACTION_PICK,
|
||||
MediaStore.Images.Media.EXTERNAL_CONTENT_URI
|
||||
).apply {
|
||||
setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*")
|
||||
}
|
||||
startActivityForResult(intent, REQUEST_ALBUM)
|
||||
}
|
||||
|
||||
private fun handleSelectedImage(uri: Uri) {
|
||||
lifecycleScope.launch {
|
||||
val path = withContext(Dispatchers.IO) {
|
||||
copySelectedImageToCache(uri)
|
||||
}
|
||||
if (path == null) {
|
||||
toast(getString(R.string.read_photo_failed))
|
||||
return@launch
|
||||
}
|
||||
compressAndAddImage(path)
|
||||
}
|
||||
}
|
||||
|
||||
private fun compressAndAddImage(path: String) {
|
||||
if (path.isBlank()) {
|
||||
toast(getString(R.string.read_photo_failed))
|
||||
return
|
||||
}
|
||||
|
||||
LubanCompressUtil.getCompressFile(
|
||||
this,
|
||||
File(path),
|
||||
object : LubanCompressUtil.CompressCallback {
|
||||
override fun success(file: File) {
|
||||
if (isFinishing || isDestroyed) return
|
||||
data.add(data.size - 1, ImageModel().apply {
|
||||
this.path = file.absolutePath
|
||||
})
|
||||
imageAdapter.data = data
|
||||
imageAdapter.notifyDataSetChanged()
|
||||
}
|
||||
|
||||
override fun fail(failMsg: String) {
|
||||
if (isFinishing || isDestroyed) return
|
||||
toast(failMsg)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
private fun copySelectedImageToCache(uri: Uri): String? {
|
||||
val extension = contentResolver.getType(uri)
|
||||
?.let(MimeTypeMap.getSingleton()::getExtensionFromMimeType)
|
||||
?.takeIf { it.isNotBlank() }
|
||||
?: "jpg"
|
||||
val imageDir = File(cacheDir, "feedback_images")
|
||||
if (!imageDir.exists() && !imageDir.mkdirs()) return null
|
||||
|
||||
val target = File(imageDir, System.currentTimeMillis().toString() + "." + extension)
|
||||
return try {
|
||||
val input = contentResolver.openInputStream(uri) ?: return null
|
||||
input.use { source ->
|
||||
target.outputStream().use { output -> source.copyTo(output) }
|
||||
}
|
||||
target.absolutePath.takeIf { target.length() > 0L }
|
||||
?: run {
|
||||
target.delete()
|
||||
null
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
target.delete()
|
||||
e.printStackTrace()
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
private fun takePhoto() {
|
||||
try {
|
||||
val cameraIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
|
||||
val imageFile = File(
|
||||
getExternalFilesDir(Environment.DIRECTORY_PICTURES),
|
||||
System.currentTimeMillis().toString() + ".png"
|
||||
)
|
||||
imageFile.parentFile?.let { parent ->
|
||||
if (!parent.exists()) parent.mkdirs()
|
||||
}
|
||||
PreferencesUtils.putString(this, Const.IMAGE_PATH, imageFile.absolutePath)
|
||||
|
||||
val cameraUri = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
FileProvider.getUriForFile(
|
||||
this,
|
||||
packageName + ".fileprovider",
|
||||
imageFile
|
||||
)
|
||||
} else {
|
||||
Uri.fromFile(imageFile)
|
||||
}
|
||||
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, cameraUri)
|
||||
cameraIntent.addFlags(
|
||||
Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION
|
||||
)
|
||||
startActivityForResult(cameraIntent, REQUEST_CAMERA)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
toast(getString(R.string.read_photo_failed))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -234,4 +368,10 @@ class FeedBackActivity : CKBaseActivity() {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
companion object {
|
||||
private const val REQUEST_CAMERA = 55
|
||||
private const val REQUEST_ALBUM = 56
|
||||
private const val REQUEST_CAMERA_PERMISSION = 1301
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ class ReturnDeviceActivity : CKBaseActivity() {
|
||||
binding = ActivityReturnDeviceBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
super.onCreate(savedInstanceState)
|
||||
checkAppPermissions()
|
||||
// checkAppPermissions()
|
||||
setTitleText(getString(R.string.device_return))
|
||||
|
||||
setActionBarColor(getColor(R.color.white))
|
||||
@@ -97,6 +97,12 @@ class ReturnDeviceActivity : CKBaseActivity() {
|
||||
return
|
||||
}
|
||||
|
||||
val phone = binding.textPhone.text.toString().trim()
|
||||
if (!PHONE_PATTERN.matches(phone)) {
|
||||
toast(getString(R.string.invalid_phone_format))
|
||||
return
|
||||
}
|
||||
|
||||
if (binding.textReason.isEmpty()){
|
||||
toast(getString(R.string.input_return_reason))
|
||||
return
|
||||
@@ -124,4 +130,8 @@ class ReturnDeviceActivity : CKBaseActivity() {
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val PHONE_PATTERN = Regex("^1[3-9]\\d{9}$")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -137,8 +137,8 @@ class LogisticsInfoActivity : CKBaseActivity() {
|
||||
model = Gson().fromJson<OrderModel.Order>(getReceiveParam().get("data")!!.stringValue.toString(),
|
||||
OrderModel.Order::class.java)
|
||||
|
||||
binding.textReceiveName.text = model.receiverName + " " + model.receiverPhone
|
||||
getData()
|
||||
binding.textReceiveName.text = model.receiverAddress + "\n" + model.receiverName + " " + model.receiverPhone
|
||||
getData()
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -160,6 +160,7 @@ class MyOrderActivity : CKBaseActivity() , View.OnClickListener{
|
||||
|
||||
|
||||
fun getData() {
|
||||
showProgeassDialog()
|
||||
TTHttpClient.get(this, "我的订单", TTRequestParam().apply {
|
||||
add(
|
||||
TTRequestData("pageNum", page)
|
||||
@@ -172,10 +173,10 @@ class MyOrderActivity : CKBaseActivity() , View.OnClickListener{
|
||||
override fun onSuccess(data: String) {
|
||||
var model = Gson().fromJson<OrderModel>(data, OrderModel::class.java)
|
||||
|
||||
if (page == 1) {
|
||||
this@MyOrderActivity.data.clear()
|
||||
}
|
||||
model.rows?.let{
|
||||
if (page ==1){
|
||||
this@MyOrderActivity.data.clear()
|
||||
}
|
||||
if (this@MyOrderActivity.data.size != model.total){
|
||||
this@MyOrderActivity.data.addAll(model.rows!!)
|
||||
}
|
||||
@@ -184,11 +185,17 @@ class MyOrderActivity : CKBaseActivity() , View.OnClickListener{
|
||||
orderAdapter.data = this@MyOrderActivity.data
|
||||
orderAdapter.notifyDataSetChanged()
|
||||
|
||||
val isEmpty = this@MyOrderActivity.data.isEmpty()
|
||||
binding.relNoresult.visibility = if (isEmpty) View.VISIBLE else View.GONE
|
||||
binding.recyclerView.visibility = if (isEmpty) View.GONE else View.VISIBLE
|
||||
|
||||
binding.refreshLayout.finishRefresh()
|
||||
binding.refreshLayout.finishLoadMore(true)
|
||||
}
|
||||
|
||||
override fun onFailed(code: String, msg: String) {
|
||||
binding.refreshLayout.finishRefresh()
|
||||
binding.refreshLayout.finishLoadMore(false)
|
||||
toast(msg)
|
||||
}
|
||||
})
|
||||
@@ -445,4 +452,4 @@ class MyOrderActivity : CKBaseActivity() , View.OnClickListener{
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.ck.ckcollar.app.ui.act.order
|
||||
|
||||
import android.content.Context
|
||||
import android.content.pm.ApplicationInfo
|
||||
import android.os.Bundle
|
||||
import android.text.TextUtils
|
||||
import android.view.LayoutInflater
|
||||
@@ -8,6 +9,7 @@ import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.alipay.sdk.app.EnvUtils
|
||||
import com.alipay.sdk.app.PayTask
|
||||
import com.bumptech.glide.Glide
|
||||
import com.ck.ckcollar.app.CKApp
|
||||
@@ -20,27 +22,34 @@ import com.ck.ckcollar.app.model.AddressModel
|
||||
import com.ck.ckcollar.app.model.ConfirmOrderModel
|
||||
import com.ck.ckcollar.app.model.MemberModel
|
||||
import com.ck.ckcollar.app.model.OrderModel
|
||||
import com.ck.ckcollar.app.model.OrderPaymentModel
|
||||
import com.ck.ckcollar.app.model.PayOrderModel
|
||||
import com.ck.ckcollar.app.model.PayPasswordStatus
|
||||
import com.ck.ckcollar.app.model.PayResult
|
||||
import com.ck.ckcollar.app.model.UserInfoModel
|
||||
import com.ck.ckcollar.app.ui.act.setting.PayPsswordActivity
|
||||
import com.ck.ckcollar.app.ui.act.balance.RechargeActivity
|
||||
import com.ck.ckcollar.app.ui.act.shop.OrderSuccessActivity
|
||||
import com.ck.ckcollar.app.ui.act.shop.PayPasswordBottomFragment
|
||||
import com.ck.ckcollar.app.ui.base.CKBaseActivity
|
||||
import com.ck.ckcollar.app.utils.CKUtils
|
||||
import com.ck.ckcollar.app.utils.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.google.gson.Gson
|
||||
import com.tencent.mm.opensdk.modelpay.PayReq
|
||||
import com.tencent.mm.opensdk.openapi.WXAPIFactory
|
||||
import com.tt.kit.model.Data
|
||||
import com.tt.kit.model.DataCollection
|
||||
import com.tt.kit.utils.LiveDataBus
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.math.BigDecimal
|
||||
import java.math.RoundingMode
|
||||
|
||||
class PayOrderActivity : CKBaseActivity() {
|
||||
|
||||
@@ -54,12 +63,15 @@ class PayOrderActivity : CKBaseActivity() {
|
||||
|
||||
var memberModel: UserInfoModel? = null
|
||||
|
||||
var payType = "1"
|
||||
var payType = "0"
|
||||
|
||||
var selectBalance = false
|
||||
var selectPoints = false
|
||||
var confirmOrderModel : ConfirmOrderModel? = null
|
||||
lateinit var orderSource: String
|
||||
|
||||
private var isCancellingOrder = false
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
binding = ActivityPayOrderBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
@@ -68,6 +80,14 @@ class PayOrderActivity : CKBaseActivity() {
|
||||
}
|
||||
|
||||
override fun initView() {
|
||||
LiveDataBus.get().with(RechargeActivity.WX_PAY_RESULT, Int::class.java).observe(this) { result ->
|
||||
if (result == 0) {
|
||||
handleWeChatPaymentSuccess()
|
||||
} else {
|
||||
handleWeChatPaymentFailed(result == -2)
|
||||
}
|
||||
}
|
||||
|
||||
productAdapter =
|
||||
ProductAdapter(this@PayOrderActivity, productDatas, object : OnItemClickListenner {
|
||||
override fun onClick(pos: Int, model: Any) {
|
||||
@@ -82,13 +102,14 @@ class PayOrderActivity : CKBaseActivity() {
|
||||
|
||||
binding.btnAli.setOnClickListener(payClick)
|
||||
binding.btnWX.setOnClickListener(payClick)
|
||||
binding.btnBalance.setOnClickListener(payClick)
|
||||
binding.btnPoints.setOnClickListener(payClick)
|
||||
|
||||
|
||||
binding.btnBalance.setOnClickListener {
|
||||
|
||||
if (memberModel?.balance == 0.0){
|
||||
if (clearBalanceIfPointsSufficient()) {
|
||||
toast("积分足够无需使用余额")
|
||||
return@setOnClickListener
|
||||
}
|
||||
if ((memberModel?.balance ?: 0.0) <= 0.0){
|
||||
toast(getString(R.string.balance_over))
|
||||
return@setOnClickListener
|
||||
}
|
||||
@@ -99,21 +120,28 @@ class PayOrderActivity : CKBaseActivity() {
|
||||
}else{
|
||||
binding.image3.setImageResource(R.mipmap.image_address_check_narmal)
|
||||
}
|
||||
clearExternalPaymentIfNotNeeded()
|
||||
}
|
||||
binding.btnPoints.setOnClickListener {
|
||||
if ((memberModel?.points ?: 0.0) <= 0.0) {
|
||||
toast(getString(R.string.points_over))
|
||||
return@setOnClickListener
|
||||
}
|
||||
|
||||
selectPoints = !selectPoints
|
||||
if (selectPoints){
|
||||
binding.image4.setImageResource(R.mipmap.image_address_check_select)
|
||||
}else{
|
||||
binding.image4.setImageResource(R.mipmap.image_address_check_narmal)
|
||||
}
|
||||
clearBalanceIfPointsSufficient()
|
||||
clearExternalPaymentIfNotNeeded()
|
||||
}
|
||||
|
||||
|
||||
binding.btnBuyNow.setOnClickListener {
|
||||
|
||||
|
||||
if (selectBalance){
|
||||
if (selectBalance && !canPointsCoverPayAmount()){
|
||||
getPayPassword()
|
||||
}else{
|
||||
order("")
|
||||
@@ -170,7 +198,7 @@ class PayOrderActivity : CKBaseActivity() {
|
||||
|
||||
|
||||
if (TextUtils.isEmpty(payType) && memberModel?.balance == 0.0){
|
||||
if (!selectPoints || "1".equals(confirmOrderModel?.isPoint)){
|
||||
if (!selectPoints || "1".equals(confirmOrderModel?.isPoint.toString())){
|
||||
toast(getString(R.string.balance_over))
|
||||
return
|
||||
}
|
||||
@@ -204,17 +232,18 @@ class PayOrderActivity : CKBaseActivity() {
|
||||
|
||||
fun showPayBottomView(){
|
||||
|
||||
var showBalance = model.payAmount
|
||||
var showBalance = BigDecimal.valueOf(model.payAmount).setScale(2, RoundingMode.HALF_UP)
|
||||
if (selectPoints){
|
||||
CKApp.app.userInfo?.intoAmounts?.let {
|
||||
showBalance = showBalance - BigDecimal(memberModel?.points!!).multiply(
|
||||
BigDecimal(memberModel!!.intoAmounts!!)).setScale(2).toDouble()
|
||||
if (showBalance < 0.0){
|
||||
showBalance = 0.00
|
||||
}
|
||||
calculatePointsDeduction()?.let { pointsDeduction ->
|
||||
showBalance = showBalance.subtract(pointsDeduction)
|
||||
.max(BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP))
|
||||
}
|
||||
}
|
||||
|
||||
val userBalance = BigDecimal.valueOf(memberModel?.balance ?: 0.0)
|
||||
.setScale(2, RoundingMode.HALF_UP)
|
||||
showBalance = showBalance.min(userBalance)
|
||||
|
||||
var passwordBottomFragment = PayPasswordBottomFragment(showBalance.toString(), "余额",object : PayPasswordBottomFragment.PasswordCallBack{
|
||||
override fun callBack(password: String) {
|
||||
|
||||
@@ -229,6 +258,11 @@ class PayOrderActivity : CKBaseActivity() {
|
||||
|
||||
var payType = payType
|
||||
if(selectBalance){
|
||||
if (TextUtils.isEmpty(payType) && memberModel?.balance == 0.0){
|
||||
toast(getString(R.string.balance_over))
|
||||
return
|
||||
}
|
||||
|
||||
if (TextUtils.isEmpty(payType)){
|
||||
payType = "2"
|
||||
}else{
|
||||
@@ -236,6 +270,11 @@ class PayOrderActivity : CKBaseActivity() {
|
||||
}
|
||||
}
|
||||
if(selectPoints){
|
||||
if (TextUtils.isEmpty(payType) && memberModel?.points == 0.0){
|
||||
toast(getString(R.string.points_over))
|
||||
return
|
||||
}
|
||||
|
||||
if (TextUtils.isEmpty(payType)){
|
||||
payType = "3"
|
||||
}else{
|
||||
@@ -271,16 +310,25 @@ class PayOrderActivity : CKBaseActivity() {
|
||||
)
|
||||
}, object : ICallback {
|
||||
override fun onSuccess(data: String) {
|
||||
var model = Gson().fromJson<PayOrderModel>(data, PayOrderModel::class.java)
|
||||
val paymentModel = Gson().fromJson(data, OrderPaymentModel::class.java)
|
||||
|
||||
if ("0".equals(this@PayOrderActivity.payType)) {
|
||||
//微信
|
||||
val weChatPayParams = paymentModel.wxMap
|
||||
if (weChatPayParams == null || !weChatPayParams.isJsonObject) {
|
||||
hiddenProgeassDialog()
|
||||
toast("微信支付参数格式错误")
|
||||
return
|
||||
}
|
||||
wxPay(Gson().fromJson(weChatPayParams, PayOrderModel::class.java))
|
||||
}else if ("1".equals(this@PayOrderActivity.payType)) {
|
||||
if (TextUtils.isEmpty(model.orderStr)){
|
||||
val aliPayOrderStr = paymentModel.orderStr
|
||||
?.takeIf { it.isJsonPrimitive && it.asJsonPrimitive.isString }
|
||||
?.asString
|
||||
if (TextUtils.isEmpty(aliPayOrderStr)){
|
||||
toActivity(OrderSuccessActivity::class.java, DataCollection())
|
||||
finish(DataCollection(),1002)
|
||||
}else{
|
||||
aliPay(model.orderStr!!)
|
||||
aliPay(aliPayOrderStr!!)
|
||||
}
|
||||
}else{
|
||||
toast(getString(R.string.order_success))
|
||||
@@ -299,9 +347,143 @@ class PayOrderActivity : CKBaseActivity() {
|
||||
})
|
||||
}
|
||||
|
||||
fun aliPay(orderStr: String) {
|
||||
GlobalScope.launch(Dispatchers.IO) {
|
||||
private fun wxPay(model: PayOrderModel) {
|
||||
val requiredValues = listOf(
|
||||
model.appId,
|
||||
model.partnerId,
|
||||
model.prepayId,
|
||||
model.packageVal,
|
||||
model.nonceStr,
|
||||
model.timeStamp,
|
||||
model.paySign
|
||||
)
|
||||
if (requiredValues.any { it.isNullOrBlank() }) {
|
||||
hiddenProgeassDialog()
|
||||
toast("微信支付参数不完整,请检查商户号等支付参数")
|
||||
return
|
||||
}
|
||||
if (model.appId != Const.WX_APP_ID) {
|
||||
hiddenProgeassDialog()
|
||||
toast("微信支付 AppID 不匹配")
|
||||
return
|
||||
}
|
||||
|
||||
val api = WXAPIFactory.createWXAPI(this, Const.WX_APP_ID, true)
|
||||
api.registerApp(Const.WX_APP_ID)
|
||||
if (!api.isWXAppInstalled) {
|
||||
hiddenProgeassDialog()
|
||||
toast("请先安装微信")
|
||||
return
|
||||
}
|
||||
|
||||
val request = PayReq().apply {
|
||||
appId = model.appId
|
||||
partnerId = model.partnerId
|
||||
prepayId = model.prepayId
|
||||
packageValue = model.packageVal
|
||||
nonceStr = model.nonceStr
|
||||
timeStamp = model.timeStamp
|
||||
sign = model.paySign
|
||||
extData = model.orderNo
|
||||
}
|
||||
hiddenProgeassDialog()
|
||||
if (!api.sendReq(request)) {
|
||||
toast("微信支付拉起失败")
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleWeChatPaymentSuccess() {
|
||||
toast(getString(R.string.payment_success))
|
||||
finish(DataCollection(), 1002)
|
||||
}
|
||||
|
||||
private fun handleWeChatPaymentFailed(cancelled: Boolean) {
|
||||
if (cancelled) {
|
||||
cancelPendingOrder()
|
||||
} else {
|
||||
toast(getString(R.string.payment_faild))
|
||||
}
|
||||
}
|
||||
|
||||
private fun cancelPendingOrder() {
|
||||
if (isCancellingOrder) return
|
||||
|
||||
isCancellingOrder = true
|
||||
showProgeassDialog(getString(R.string.cancel))
|
||||
TTHttpClient.post(this, "取消待支付订单", TTRequestParam().apply {
|
||||
add(TTRequestData("orderId", model.id))
|
||||
}, object : ICallback {
|
||||
override fun onSuccess(data: String) {
|
||||
hiddenProgeassDialog()
|
||||
toast(getString(R.string.cancel_pay_cussess))
|
||||
finish(DataCollection(), 1002)
|
||||
}
|
||||
|
||||
override fun onFailed(code: String, msg: String) {
|
||||
isCancellingOrder = false
|
||||
hiddenProgeassDialog()
|
||||
toast(msg)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private fun canPointsCoverPayAmount(): Boolean {
|
||||
if (!selectPoints) return false
|
||||
val pointsDeduction = calculatePointsDeduction() ?: return false
|
||||
val payAmount = BigDecimal.valueOf(model.payAmount).setScale(2, RoundingMode.HALF_UP)
|
||||
return pointsDeduction >= payAmount
|
||||
}
|
||||
|
||||
private fun clearBalanceIfPointsSufficient(): Boolean {
|
||||
if (!canPointsCoverPayAmount()) return false
|
||||
|
||||
selectBalance = false
|
||||
binding.image3.setImageResource(R.mipmap.image_address_check_narmal)
|
||||
return true
|
||||
}
|
||||
|
||||
private fun calculatePointsDeduction(): BigDecimal? {
|
||||
val member = memberModel ?: return null
|
||||
val intoAmounts = member.intoAmounts?.toBigDecimalOrNull() ?: return null
|
||||
return BigDecimal.valueOf(member.points)
|
||||
.multiply(intoAmounts)
|
||||
.setScale(2, RoundingMode.HALF_UP)
|
||||
}
|
||||
|
||||
private fun isInternalPaymentSufficient(): Boolean {
|
||||
var internalAmount = BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP)
|
||||
if (selectBalance) {
|
||||
internalAmount = internalAmount.add(
|
||||
BigDecimal.valueOf(memberModel?.balance ?: 0.0)
|
||||
.setScale(2, RoundingMode.HALF_UP)
|
||||
)
|
||||
}
|
||||
if (selectPoints) {
|
||||
internalAmount = internalAmount.add(
|
||||
calculatePointsDeduction() ?: BigDecimal.ZERO
|
||||
)
|
||||
}
|
||||
|
||||
val payAmount = BigDecimal.valueOf(model.payAmount)
|
||||
.setScale(2, RoundingMode.HALF_UP)
|
||||
return internalAmount >= payAmount
|
||||
}
|
||||
|
||||
private fun clearExternalPaymentIfNotNeeded() {
|
||||
if (!isInternalPaymentSufficient()) return
|
||||
|
||||
payType = ""
|
||||
binding.image1.setImageResource(R.mipmap.image_address_check_narmal)
|
||||
binding.image2.setImageResource(R.mipmap.image_address_check_narmal)
|
||||
}
|
||||
|
||||
fun aliPay(orderStr: String) {
|
||||
|
||||
GlobalScope.launch(Dispatchers.IO) {
|
||||
// [支付宝沙箱测试] 仅 Debug 包启用,Release 包继续使用正式环境。
|
||||
if (applicationInfo.flags and ApplicationInfo.FLAG_DEBUGGABLE != 0) {
|
||||
// EnvUtils.setEnv(EnvUtils.EnvEnum.SANDBOX)
|
||||
}
|
||||
val alipay = PayTask(this@PayOrderActivity)
|
||||
val result = alipay.payV2(orderStr, true)
|
||||
|
||||
@@ -314,6 +496,8 @@ class PayOrderActivity : CKBaseActivity() {
|
||||
// 该笔订单是否真实支付成功,需要依赖服务端的异步通知。
|
||||
toast(getString(R.string.payment_success))
|
||||
finish(DataCollection(),1002)
|
||||
} else if (TextUtils.equals(resultStatus, "6001")) {
|
||||
cancelPendingOrder()
|
||||
} else {
|
||||
toast(getString(R.string.payment_faild))
|
||||
}
|
||||
@@ -342,13 +526,19 @@ class PayOrderActivity : CKBaseActivity() {
|
||||
}
|
||||
|
||||
override fun getResult(data: DataCollection, resultCode: Int) {
|
||||
if (resultCode == 10001){
|
||||
if (resultCode == 10001){
|
||||
showPayBottomView()
|
||||
}
|
||||
}
|
||||
|
||||
var payClick = object : View.OnClickListener {
|
||||
override fun onClick(v: View?) {
|
||||
if (isInternalPaymentSufficient()) {
|
||||
clearExternalPaymentIfNotNeeded()
|
||||
toast("当前支付方式无需使用三方支付")
|
||||
return
|
||||
}
|
||||
|
||||
binding.image1.setImageResource(R.mipmap.image_address_check_narmal)
|
||||
binding.image2.setImageResource(R.mipmap.image_address_check_narmal)
|
||||
when (v?.id) {
|
||||
@@ -432,4 +622,4 @@ class PayOrderActivity : CKBaseActivity() {
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -251,10 +251,12 @@ class RefundActivity: CKBaseActivity() {
|
||||
|
||||
|
||||
showProgeassDialog(getString(R.string.submit))
|
||||
var commodityState = if(model.orderStatus >= 3){
|
||||
"1"
|
||||
|
||||
var commodityState = -1;
|
||||
if ("0".equals(refundType)){
|
||||
commodityState = 0
|
||||
}else{
|
||||
"0"
|
||||
commodityState = 1
|
||||
}
|
||||
var param = TTRequestParam().apply {
|
||||
add(TTRequestData("orderId",model.id))
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package com.ck.ckcollar.app.ui.act.petmanager
|
||||
|
||||
import android.Manifest
|
||||
import android.content.Intent
|
||||
import android.graphics.Bitmap
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
@@ -11,10 +11,12 @@ import android.text.TextUtils
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.webkit.MimeTypeMap
|
||||
import android.widget.AdapterView
|
||||
import android.widget.BaseAdapter
|
||||
import android.widget.ImageView
|
||||
import androidx.core.content.FileProvider
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.bumptech.glide.Glide
|
||||
import com.ck.ckcollar.app.R
|
||||
import com.ck.ckcollar.app.databinding.ActivityAddPetBinding
|
||||
@@ -28,6 +30,7 @@ import com.ck.ckcollar.app.ui.dialog.CKPhotoDialog
|
||||
import com.ck.ckcollar.app.ui.dialog.CKPickViewDialog
|
||||
import com.ck.ckcollar.app.utils.CKUtils
|
||||
import com.ck.ckcollar.app.utils.Const
|
||||
import com.ck.ckcollar.app.utils.LubanCompressUtil
|
||||
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
|
||||
@@ -40,6 +43,9 @@ 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 kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.io.File
|
||||
|
||||
class AddPetActivity : CKBaseActivity() {
|
||||
@@ -97,12 +103,10 @@ class AddPetActivity : CKBaseActivity() {
|
||||
try {
|
||||
if (mark == 0){
|
||||
if (!checkCameraPermissions()){
|
||||
CKAlertDialog(this@AddPetActivity,getString(R.string.alert),getString(R.string.camera_alert),object : CKAlertDialog.AlertClickListener{
|
||||
override fun onBack(isConfirm: Boolean) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
}).show()
|
||||
getPermissionRequst(
|
||||
Manifest.permission.CAMERA,
|
||||
REQUEST_CAMERA_PERMISSION
|
||||
)
|
||||
return
|
||||
}
|
||||
takePhoto()
|
||||
@@ -189,11 +193,25 @@ class AddPetActivity : CKBaseActivity() {
|
||||
}
|
||||
|
||||
binding.tvAiRecognize.setOnClickListener {
|
||||
if (!checkCameraPermissions()) {
|
||||
getPermissionRequst(
|
||||
Manifest.permission.CAMERA,
|
||||
REQUEST_AI_CAMERA_PERMISSION
|
||||
)
|
||||
return@setOnClickListener
|
||||
}
|
||||
takePhoto2()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override fun onPermissionsGranted(requestCode: Int, permissions: Array<String>) {
|
||||
when (requestCode) {
|
||||
REQUEST_CAMERA_PERMISSION -> takePhoto()
|
||||
REQUEST_AI_CAMERA_PERMISSION -> takePhoto2()
|
||||
}
|
||||
}
|
||||
|
||||
override fun initData() {
|
||||
var data = getReceiveParam().get("data")
|
||||
data?.let {
|
||||
@@ -271,6 +289,7 @@ class AddPetActivity : CKBaseActivity() {
|
||||
}
|
||||
}
|
||||
showProgeassDialog()
|
||||
//先上传照片
|
||||
TTHttpClient.postFile(this,"上传照片s", param,object : ICallback{
|
||||
override fun onSuccess(data: String) {
|
||||
var model = Gson().fromJson<UploadModel>(data,UploadModel::class.java)
|
||||
@@ -317,21 +336,109 @@ class AddPetActivity : CKBaseActivity() {
|
||||
super.onActivityResult(requestCode, resultCode, data)
|
||||
|
||||
if (requestCode == 55 && resultCode == RESULT_OK) {
|
||||
var path = PreferencesUtils.getString(this@AddPetActivity, Const.IMAGE_PATH,"")
|
||||
this.data.add(this.data.size - 1,ImageModel().apply { this.path = path })
|
||||
imageAdapter.data = this.data
|
||||
imageAdapter.notifyDataSetChanged()
|
||||
val path = PreferencesUtils.getString(this@AddPetActivity, Const.IMAGE_PATH, "")
|
||||
compressAndAddImage(path.orEmpty())
|
||||
}else if (requestCode == 56 && resultCode == RESULT_OK) {
|
||||
var path = TTUtils.getImageUrl(this, data!!.getData());
|
||||
this.data.add(this.data.size - 1,ImageModel().apply { this.path = path })
|
||||
imageAdapter.data = this.data
|
||||
imageAdapter.notifyDataSetChanged()
|
||||
data?.data?.let(::handleSelectedImage)
|
||||
?: toast(getString(R.string.read_photo_failed))
|
||||
}else if (requestCode == 555 && resultCode == RESULT_OK) {
|
||||
var path = PreferencesUtils.getString(this@AddPetActivity, Const.IMAGE_PATH,"")
|
||||
uploadImage(path!!)
|
||||
val path = PreferencesUtils.getString(this@AddPetActivity, Const.IMAGE_PATH, "")
|
||||
compressAndUploadImage(path.orEmpty())
|
||||
}
|
||||
binding.textPhotoNum.setText((this.data.size - 1 ).toString() + "/3")
|
||||
}
|
||||
|
||||
private fun handleSelectedImage(uri: Uri) {
|
||||
lifecycleScope.launch {
|
||||
val path = withContext(Dispatchers.IO) {
|
||||
copySelectedImageToCache(uri)
|
||||
}
|
||||
if (path == null) {
|
||||
toast(getString(R.string.read_photo_failed))
|
||||
return@launch
|
||||
}
|
||||
compressAndAddImage(path)
|
||||
}
|
||||
}
|
||||
|
||||
private fun compressAndAddImage(path: String) {
|
||||
if (path.isBlank()) {
|
||||
toast(getString(R.string.read_photo_failed))
|
||||
return
|
||||
}
|
||||
|
||||
LubanCompressUtil.getCompressFile(
|
||||
this,
|
||||
File(path),
|
||||
object : LubanCompressUtil.CompressCallback {
|
||||
override fun success(file: File) {
|
||||
if (isFinishing || isDestroyed) return
|
||||
data.add(data.size - 1, ImageModel().apply {
|
||||
this.path = file.absolutePath
|
||||
})
|
||||
imageAdapter.data = data
|
||||
imageAdapter.notifyDataSetChanged()
|
||||
binding.textPhotoNum.text = "${data.size - 1}/3"
|
||||
}
|
||||
|
||||
override fun fail(failMsg: String) {
|
||||
if (isFinishing || isDestroyed) return
|
||||
toast(failMsg)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
private fun compressAndUploadImage(path: String) {
|
||||
if (path.isBlank()) {
|
||||
toast(getString(R.string.read_photo_failed))
|
||||
return
|
||||
}
|
||||
|
||||
LubanCompressUtil.getCompressFile(
|
||||
this,
|
||||
File(path),
|
||||
object : LubanCompressUtil.CompressCallback {
|
||||
override fun success(file: File) {
|
||||
if (isFinishing || isDestroyed) return
|
||||
uploadImage(file.absolutePath)
|
||||
}
|
||||
|
||||
override fun fail(failMsg: String) {
|
||||
if (isFinishing || isDestroyed) return
|
||||
toast(failMsg)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
private fun copySelectedImageToCache(uri: Uri): String? {
|
||||
val extension = contentResolver.getType(uri)
|
||||
?.let(MimeTypeMap.getSingleton()::getExtensionFromMimeType)
|
||||
?.takeIf { it.isNotBlank() }
|
||||
?: "jpg"
|
||||
val imageDir = File(cacheDir, "selected_images")
|
||||
if (!imageDir.exists() && !imageDir.mkdirs()) {
|
||||
return null
|
||||
}
|
||||
|
||||
val target = File(imageDir, "${System.currentTimeMillis()}.$extension")
|
||||
return try {
|
||||
val input = contentResolver.openInputStream(uri) ?: return null
|
||||
input.use { source ->
|
||||
target.outputStream().use { output -> source.copyTo(output) }
|
||||
}
|
||||
target.absolutePath.takeIf { target.length() > 0L }
|
||||
?: run {
|
||||
target.delete()
|
||||
null
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
target.delete()
|
||||
e.printStackTrace()
|
||||
null
|
||||
}
|
||||
}
|
||||
fun takePhoto() {
|
||||
try {
|
||||
val openCameraIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
|
||||
@@ -408,6 +515,11 @@ class AddPetActivity : CKBaseActivity() {
|
||||
}).show()
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val REQUEST_CAMERA_PERMISSION = 1201
|
||||
private const val REQUEST_AI_CAMERA_PERMISSION = 1202
|
||||
}
|
||||
|
||||
|
||||
fun uploadImage(path: String) {
|
||||
|
||||
@@ -491,13 +603,10 @@ class AddPetActivity : CKBaseActivity() {
|
||||
layoutItemImageBinding.imageDelete.visibility = View.GONE
|
||||
} else {
|
||||
layoutItemImageBinding.image.scaleType = ImageView.ScaleType.CENTER_CROP
|
||||
layoutItemImageBinding.image.setImageBitmap(
|
||||
TTUtils.getBitmap(
|
||||
model.path,
|
||||
200,
|
||||
200
|
||||
)
|
||||
)
|
||||
Glide.with(context)
|
||||
.load(model.path?.let(::File))
|
||||
.centerCrop()
|
||||
.into(layoutItemImageBinding.image)
|
||||
|
||||
layoutItemImageBinding.imageDelete.visibility = View.VISIBLE
|
||||
layoutItemImageBinding.imageDelete.setOnClickListener {
|
||||
|
||||
@@ -3,27 +3,19 @@ package com.ck.ckcollar.app.ui.act.petmanager
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.Window
|
||||
import android.view.WindowManager
|
||||
import androidx.viewpager.widget.PagerAdapter
|
||||
import com.bumptech.glide.Glide
|
||||
import com.ck.ckcollar.app.R
|
||||
import com.ck.ckcollar.app.databinding.ActivityImageViewBinding
|
||||
import com.ck.ckcollar.app.databinding.ActivityWelcomeBinding
|
||||
import com.ck.ckcollar.app.databinding.LayoutItemImageViewBinding
|
||||
import com.ck.ckcollar.app.databinding.LayoutItemWelcomeBinding
|
||||
import com.ck.ckcollar.app.ui.act.login.LoginActivity
|
||||
import com.ck.ckcollar.app.ui.act.welcome.PermisstionActivity
|
||||
import com.ck.ckcollar.app.ui.base.CKBaseActivity
|
||||
import com.ck.ckcollar.app.utils.Const
|
||||
import com.cyclone.shadowsocks.utils.PreferencesUtils
|
||||
import com.google.gson.Gson
|
||||
import com.google.gson.reflect.TypeToken
|
||||
import com.tt.kit.model.DataCollection
|
||||
|
||||
class ImageViewActivity : CKBaseActivity() {
|
||||
override val useDarkStatusBarIcons: Boolean = false
|
||||
|
||||
lateinit var binding: ActivityImageViewBinding
|
||||
var views = mutableListOf<View>()
|
||||
var data : List<String>? = null
|
||||
var pos = 0
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
@@ -36,17 +28,9 @@ class ImageViewActivity : CKBaseActivity() {
|
||||
}
|
||||
|
||||
override fun initView() {
|
||||
for (i in data!!) {
|
||||
var view = LayoutItemImageViewBinding.inflate(layoutInflater);
|
||||
Glide.with(this)
|
||||
.load(i)
|
||||
.placeholder(R.mipmap.image_default)
|
||||
.into(view.imageView)
|
||||
views.add(view.root)
|
||||
}
|
||||
binding.viewPager.adapter = object : PagerAdapter() {
|
||||
override fun getCount(): Int {
|
||||
return views.size
|
||||
return data.orEmpty().size
|
||||
}
|
||||
|
||||
override fun isViewFromObject(
|
||||
@@ -57,12 +41,21 @@ class ImageViewActivity : CKBaseActivity() {
|
||||
}
|
||||
|
||||
override fun destroyItem(container: ViewGroup, position: Int, `object`: Any) {
|
||||
container.removeView(views.get(position))
|
||||
container.removeView(`object` as View)
|
||||
}
|
||||
|
||||
override fun instantiateItem(container: ViewGroup, position: Int): Any {
|
||||
container.addView(views.get(position))
|
||||
return views.get(position)
|
||||
val itemBinding = LayoutItemImageViewBinding.inflate(
|
||||
layoutInflater,
|
||||
container,
|
||||
false
|
||||
)
|
||||
Glide.with(this@ImageViewActivity)
|
||||
.load(data.orEmpty()[position])
|
||||
.placeholder(R.mipmap.image_default)
|
||||
.into(itemBinding.imageView)
|
||||
container.addView(itemBinding.root)
|
||||
return itemBinding.root
|
||||
}
|
||||
|
||||
}
|
||||
@@ -81,4 +74,4 @@ class ImageViewActivity : CKBaseActivity() {
|
||||
pos = data.stringValue!!.toInt()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.ck.ckcollar.app.ui.act.petmanager
|
||||
|
||||
import android.net.wifi.ScanResult
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.PopupWindow
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
@@ -64,7 +65,7 @@ class PetManagerActivity : CKBaseActivity() {
|
||||
}
|
||||
|
||||
fun getData() {
|
||||
//showProgeassDialog(getString(R.string.search))
|
||||
showProgeassDialog(getString(R.string.search))
|
||||
TTHttpClient.get(this, "宠物列表", TTRequestParam().apply {
|
||||
add(
|
||||
TTRequestData("pageNum", 1)
|
||||
@@ -81,6 +82,10 @@ class PetManagerActivity : CKBaseActivity() {
|
||||
|
||||
petAdapter.data = this@PetManagerActivity.data
|
||||
petAdapter.notifyDataSetChanged()
|
||||
|
||||
val isEmpty = this@PetManagerActivity.data.isEmpty()
|
||||
binding.relNoresult.visibility = if (isEmpty) View.VISIBLE else View.GONE
|
||||
binding.recyclerView.visibility = if (isEmpty) View.GONE else View.VISIBLE
|
||||
}
|
||||
|
||||
override fun onFailed(code: String, msg: String) {
|
||||
|
||||
@@ -77,7 +77,10 @@ class ViewPetFileActivity: CKBaseActivity() {
|
||||
}
|
||||
|
||||
binding.btnViewPostion.setOnClickListener {
|
||||
|
||||
if(homeModel?.collNum == null){
|
||||
toast("请为您的爱宠绑定项圈")
|
||||
return@setOnClickListener
|
||||
}
|
||||
getData2(model?.id.toString())
|
||||
}
|
||||
binding.btnAdreessDetails.setOnClickListener {
|
||||
|
||||
@@ -33,6 +33,7 @@ import java.text.SimpleDateFormat
|
||||
import java.util.Date
|
||||
|
||||
class PointsActivity : CKLHBaseActionBarActivity() {
|
||||
override val shouldRequestPermissionsOnCreate: Boolean = false
|
||||
|
||||
lateinit var binding: ActivityPointsBinding
|
||||
var data = listOf<PointsModel.PointsRecordModel>()
|
||||
@@ -207,4 +208,4 @@ class PointsActivity : CKLHBaseActionBarActivity() {
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,6 +109,8 @@ class AccountCancellationActivity: CKBaseActivity() {
|
||||
},object : ICallback{
|
||||
override fun onSuccess(data: String) {
|
||||
PreferencesUtils.clear(this@AccountCancellationActivity)
|
||||
PreferencesUtils.putBoolean(this@AccountCancellationActivity, Const.FIRST, false)
|
||||
CKApp.app.clearLoginState()
|
||||
toActivityNewTaskClear(LoginActivity::class.java, DataCollection())
|
||||
finish()
|
||||
}
|
||||
@@ -176,4 +178,4 @@ class AccountCancellationActivity: CKBaseActivity() {
|
||||
binding.check.setImageResource(R.mipmap.image_check_unselect)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -168,7 +168,7 @@ class AddAddressActivity : CKBaseActivity() {
|
||||
add(TTRequestData("provinceName",provinceName))
|
||||
add(TTRequestData("cityName",cityName))
|
||||
add(TTRequestData("areaName",areaName))
|
||||
add(TTRequestData("detailAddress",binding.textDetailsAddress.text.toString()))
|
||||
add(TTRequestData("detailAddress",binding.textDetailsAddress.text.toString().trim()))
|
||||
add(TTRequestData("postalCode",""))
|
||||
add(TTRequestData("isDefault",check))
|
||||
add(TTRequestData("addressTag",tag))
|
||||
|
||||
@@ -195,12 +195,12 @@ class EditAddressActivity : CKBaseActivity() {
|
||||
}
|
||||
var param = TTRequestParam().apply {
|
||||
add(TTRequestData("id", model?.id.toString()))
|
||||
add(TTRequestData("receiverName", binding.textName.text.toString()))
|
||||
add(TTRequestData("receiverPhone", binding.textPhone.text.toString()))
|
||||
add(TTRequestData("receiverName", binding.textName.text.toString().trim()))
|
||||
add(TTRequestData("receiverPhone", binding.textPhone.text.toString().trim()))
|
||||
add(TTRequestData("provinceName", provinceName))
|
||||
add(TTRequestData("cityName", cityName))
|
||||
add(TTRequestData("areaName", areaName))
|
||||
add(TTRequestData("detailAddress", binding.textDetailsAddress.text.toString()))
|
||||
add(TTRequestData("detailAddress", binding.textDetailsAddress.text.toString().trim()))
|
||||
add(TTRequestData("postalCode", ""))
|
||||
add(TTRequestData("isDefault", check))
|
||||
add(TTRequestData("addressTag", tag))
|
||||
|
||||
@@ -3,81 +3,74 @@ package com.ck.ckcollar.app.ui.act.setting
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import com.ck.ckcollar.app.CKApp
|
||||
import com.ck.ckcollar.app.R
|
||||
import com.ck.ckcollar.app.config.Config
|
||||
import com.ck.ckcollar.app.databinding.ActivitySettingBinding
|
||||
import com.ck.ckcollar.app.ui.act.home.MainActivity
|
||||
import com.ck.ckcollar.app.ui.act.login.AgreementActivity
|
||||
import com.ck.ckcollar.app.ui.act.login.LoginActivity
|
||||
import com.ck.ckcollar.app.ui.base.CKBaseActivity
|
||||
import com.ck.ckcollar.app.ui.dialog.CKAlertDialog
|
||||
import com.ck.ckcollar.app.utils.Const
|
||||
import com.cyclone.shadowsocks.utils.PreferencesUtils
|
||||
import com.tt.kit.model.Data
|
||||
import com.tt.kit.model.DataCollection
|
||||
|
||||
class SettingActivity : CKBaseActivity(), View.OnClickListener {
|
||||
lateinit var binding: ActivitySettingBinding
|
||||
private lateinit var binding: ActivitySettingBinding
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
binding = ActivitySettingBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
setStatusBarColor(resources.getColor(R.color.white))
|
||||
setActionBarColor(resources.getColor(R.color.white))
|
||||
|
||||
setStatusBarColor(getColor(R.color.white))
|
||||
setActionBarColor(getColor(R.color.white))
|
||||
setTitleText(getString(R.string.setting))
|
||||
}
|
||||
|
||||
override fun initView() {
|
||||
binding.contentLoginPassword.setOnClickListener(this)
|
||||
binding.contentPaymentPassword.setOnClickListener(this)
|
||||
binding.contentAboutUs.setOnClickListener(this)
|
||||
binding.contentUserAgreement.setOnClickListener(this)
|
||||
binding.contentPrivacyAgreement.setOnClickListener(this)
|
||||
binding.contentShippingAddress.setOnClickListener(this)
|
||||
binding.contentCancellation.setOnClickListener(this)
|
||||
binding.btnLogout.setOnClickListener(this)
|
||||
binding.btnLogout.visibility = if (CKApp.app.isUserLoggedIn) View.VISIBLE else View.GONE
|
||||
listOf(binding.contentLoginPassword, binding.contentPaymentPassword, binding.contentAboutUs,
|
||||
binding.contentUserAgreement, binding.contentPrivacyAgreement, binding.contentShippingAddress,
|
||||
binding.contentCancellation, binding.btnLogout).forEach { it.setOnClickListener(this) }
|
||||
}
|
||||
override fun initData() {
|
||||
|
||||
}
|
||||
override fun initData() = Unit
|
||||
|
||||
override fun onClick(v: View?) {
|
||||
|
||||
when (v?.id){
|
||||
R.id.contentLoginPassword->{
|
||||
toActivity(PasswordManagerActivity::class.java, DataCollection())
|
||||
}
|
||||
R.id.contentPaymentPassword->{
|
||||
toActivity(PayPasswordManagerActivity::class.java, DataCollection())
|
||||
|
||||
}
|
||||
R.id.contentAboutUs->{
|
||||
toActivity(AgreementActivity::class.java, DataCollection().apply { add(Data("title","关于我们")) })
|
||||
}
|
||||
R.id.contentUserAgreement->{
|
||||
toActivity(AgreementActivity::class.java, DataCollection().apply { add(Data("title","用户协议")) })
|
||||
}
|
||||
R.id.contentPrivacyAgreement->{
|
||||
toActivity(AgreementActivity::class.java, DataCollection().apply { add(Data("title","隐私协议")) })
|
||||
}
|
||||
R.id.contentShippingAddress->{
|
||||
toActivity(AddressActivity::class.java, DataCollection().apply { add(Data("flag","1"))
|
||||
})
|
||||
}
|
||||
R.id.contentCancellation->{
|
||||
toActivity(AccountCancellationActivity::class.java, DataCollection())
|
||||
}
|
||||
R.id.btnLogout->{
|
||||
CKAlertDialog(this@SettingActivity,getString(R.string.logout),getString(R.string.logout_alert),object : CKAlertDialog.AlertClickListener{
|
||||
override fun onBack(isConfirm: Boolean) {
|
||||
if (isConfirm){
|
||||
PreferencesUtils.clear(this@SettingActivity)
|
||||
toActivityNewTaskClear(LoginActivity::class.java, DataCollection())
|
||||
finish()
|
||||
}
|
||||
when (v?.id) {
|
||||
R.id.contentLoginPassword -> if (requireLogin()) toActivity(PasswordManagerActivity::class.java, DataCollection())
|
||||
R.id.contentPaymentPassword -> if (requireLogin()) toActivity(PayPasswordManagerActivity::class.java, DataCollection())
|
||||
R.id.contentAboutUs -> toActivity(AgreementActivity::class.java, DataCollection().apply { add(Data("title", getString(R.string.about_us))) })
|
||||
R.id.contentUserAgreement -> toActivity(AgreementActivity::class.java, DataCollection().apply { add(Data("title", getString(R.string.user_agreement))) })
|
||||
R.id.contentPrivacyAgreement -> toActivity(SettingWebViewActivity::class.java, pageParams(Config.PRIVACY_POLICY, getString(R.string.privacy_agreement)))
|
||||
R.id.contentShippingAddress -> if (requireLogin()) toActivity(AddressActivity::class.java, DataCollection().apply { add(Data("flag", "1")) })
|
||||
R.id.contentCancellation -> if (requireLogin()) toActivity(AccountCancellationActivity::class.java, DataCollection())
|
||||
R.id.btnLogout -> CKAlertDialog(this, getString(R.string.logout), getString(R.string.logout_alert), object : CKAlertDialog.AlertClickListener {
|
||||
override fun onBack(isConfirm: Boolean) {
|
||||
if (isConfirm) {
|
||||
PreferencesUtils.putString(this@SettingActivity, Const.MESSAGE,"[]")
|
||||
CKApp.app.clearLoginState()
|
||||
startActivity(Intent(this@SettingActivity, MainActivity::class.java).apply {
|
||||
addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP)
|
||||
putExtra(MainActivity.EXTRA_SHOW_HOME, true)
|
||||
})
|
||||
finish()
|
||||
}
|
||||
}).show()
|
||||
|
||||
}
|
||||
}
|
||||
}).show()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun pageParams(url: String, title: String) = DataCollection().apply {
|
||||
add(Data("url", url))
|
||||
add(Data("title", title))
|
||||
}
|
||||
|
||||
private fun requireLogin(): Boolean {
|
||||
if (CKApp.app.isUserLoggedIn) return true
|
||||
toActivity(LoginActivity::class.java, DataCollection())
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
package com.ck.ckcollar.app.ui.act.setting
|
||||
|
||||
import android.os.Bundle
|
||||
import android.webkit.WebSettings
|
||||
import android.webkit.WebView
|
||||
import android.webkit.WebViewClient
|
||||
import android.net.Uri
|
||||
import com.ck.ckcollar.app.R
|
||||
import com.ck.ckcollar.app.databinding.ActivitySettingWebViewBinding
|
||||
import com.ck.ckcollar.app.ui.base.CKBaseActivity
|
||||
|
||||
/** Displays a setting document supplied by the caller. */
|
||||
class SettingWebViewActivity : CKBaseActivity() {
|
||||
private lateinit var binding: ActivitySettingWebViewBinding
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
binding = ActivitySettingWebViewBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
super.onCreate(savedInstanceState)
|
||||
setActionBarColor(getColor(R.color.white))
|
||||
setStatusBarColor(getColor(R.color.white))
|
||||
}
|
||||
|
||||
override fun initView() {
|
||||
binding.webView.settings.apply {
|
||||
javaScriptEnabled = true; domStorageEnabled = true
|
||||
useWideViewPort = true; loadWithOverviewMode = true
|
||||
setSupportZoom(true); builtInZoomControls = true; displayZoomControls = false
|
||||
layoutAlgorithm = WebSettings.LayoutAlgorithm.NARROW_COLUMNS
|
||||
}
|
||||
binding.webView.apply {
|
||||
isFocusableInTouchMode = true
|
||||
requestFocus()
|
||||
webViewClient = object : WebViewClient() {
|
||||
override fun onPageFinished(view: WebView?, url: String?) {
|
||||
super.onPageFinished(view, url)
|
||||
// Do this after the page's anchor/default restoration has run.
|
||||
view?.post {
|
||||
view.scrollTo(0, 0)
|
||||
view.evaluateJavascript("window.scrollTo(0, 0);", null)
|
||||
}
|
||||
view?.postDelayed({ view.scrollTo(0, 0) }, 300)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun initData() {
|
||||
val params = getReceiveParam()
|
||||
setTitleText(params.get("title")?.stringValue?.toString().orEmpty())
|
||||
val url = params.get("url")?.stringValue?.toString().orEmpty()
|
||||
if (url.isNotEmpty()) {
|
||||
// Fragment anchors (for example #a6 in the privacy URL) override the
|
||||
// initial position, while this screen always starts at the document top.
|
||||
val topUrl = runCatching { Uri.parse(url).buildUpon().fragment(null).build().toString() }
|
||||
.getOrDefault(url)
|
||||
binding.webView.loadUrl(topUrl)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
binding.webView.apply { stopLoading(); destroy() }
|
||||
super.onDestroy()
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.ck.ckcollar.app.ui.act.shop
|
||||
|
||||
import android.content.Context
|
||||
import android.content.pm.ApplicationInfo
|
||||
import android.os.Bundle
|
||||
import android.text.TextUtils
|
||||
import android.view.LayoutInflater
|
||||
@@ -8,6 +9,7 @@ import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.alipay.sdk.app.EnvUtils
|
||||
import com.alipay.sdk.app.PayTask
|
||||
import com.bumptech.glide.Glide
|
||||
import com.ck.ckcollar.app.CKApp
|
||||
@@ -21,6 +23,7 @@ import com.ck.ckcollar.app.model.AddressModel
|
||||
import com.ck.ckcollar.app.model.ConfirmOrderModel
|
||||
import com.ck.ckcollar.app.model.CreateOrderModel
|
||||
import com.ck.ckcollar.app.model.MemberModel
|
||||
import com.ck.ckcollar.app.model.OrderPaymentModel
|
||||
import com.ck.ckcollar.app.model.PayOrderModel
|
||||
import com.ck.ckcollar.app.model.PayPasswordStatus
|
||||
import com.ck.ckcollar.app.model.PayResult
|
||||
@@ -28,20 +31,25 @@ import com.ck.ckcollar.app.model.ShopCarModel
|
||||
import com.ck.ckcollar.app.model.ShopProductModel
|
||||
import com.ck.ckcollar.app.model.UserInfoModel
|
||||
import com.ck.ckcollar.app.ui.act.order.MyOrderActivity
|
||||
import com.ck.ckcollar.app.ui.act.balance.RechargeActivity
|
||||
import com.ck.ckcollar.app.ui.act.setting.AddAddressActivity
|
||||
import com.ck.ckcollar.app.ui.act.setting.AddressActivity
|
||||
import com.ck.ckcollar.app.ui.act.setting.PayPsswordActivity
|
||||
import com.ck.ckcollar.app.ui.act.shop.ShopCarActivity.ShopCarAdapter
|
||||
import com.ck.ckcollar.app.ui.base.CKBaseActivity
|
||||
import com.ck.ckcollar.app.utils.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.google.gson.Gson
|
||||
import com.google.gson.reflect.TypeToken
|
||||
import com.tencent.mm.opensdk.modelpay.PayReq
|
||||
import com.tencent.mm.opensdk.openapi.WXAPIFactory
|
||||
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 kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.launch
|
||||
@@ -49,6 +57,7 @@ import kotlinx.coroutines.withContext
|
||||
import org.json.JSONArray
|
||||
import org.json.JSONObject
|
||||
import java.math.BigDecimal
|
||||
import java.math.RoundingMode
|
||||
|
||||
class OrderActivity : CKBaseActivity() {
|
||||
|
||||
@@ -62,7 +71,7 @@ class OrderActivity : CKBaseActivity() {
|
||||
|
||||
var memberModel: UserInfoModel? = null
|
||||
|
||||
var payType = "1"
|
||||
var payType = "0"
|
||||
|
||||
var selectBalance = false
|
||||
var selectPoints = false
|
||||
@@ -70,6 +79,10 @@ class OrderActivity : CKBaseActivity() {
|
||||
lateinit var orderSource: String
|
||||
|
||||
var flag = 0
|
||||
|
||||
private var currentOrderId = 0
|
||||
private var isCancellingOrder = false
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
binding = ActivityOrderBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
@@ -78,7 +91,20 @@ class OrderActivity : CKBaseActivity() {
|
||||
setTitleText(getString(R.string.confirm_order))
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
var abc = 0;
|
||||
}
|
||||
|
||||
override fun initView() {
|
||||
LiveDataBus.get().with(RechargeActivity.WX_PAY_RESULT, Int::class.java).observe(this) { result ->
|
||||
if (result == 0) {
|
||||
handlePaymentSuccess()
|
||||
} else {
|
||||
handlePaymentFailed(result == -2)
|
||||
}
|
||||
}
|
||||
|
||||
productAdapter =
|
||||
ProductAdapter(this@OrderActivity, productDatas, object : OnItemClickListenner {
|
||||
override fun onClick(pos: Int, model: Any) {
|
||||
@@ -95,7 +121,11 @@ class OrderActivity : CKBaseActivity() {
|
||||
binding.btnWX.setOnClickListener(payClick)
|
||||
binding.btnBalance.setOnClickListener {
|
||||
|
||||
if (memberModel?.balance == 0.0){
|
||||
if (clearBalanceIfPointsSufficient()) {
|
||||
toast("积分足够无需使用余额")
|
||||
return@setOnClickListener
|
||||
}
|
||||
if ((memberModel?.balance ?: 0.0) <= 0.0){
|
||||
toast(getString(R.string.balance_over))
|
||||
return@setOnClickListener
|
||||
}
|
||||
@@ -106,14 +136,22 @@ class OrderActivity : CKBaseActivity() {
|
||||
}else{
|
||||
binding.image3.setImageResource(R.mipmap.image_address_check_narmal)
|
||||
}
|
||||
clearExternalPaymentIfNotNeeded()
|
||||
}
|
||||
binding.btnPoints.setOnClickListener {
|
||||
if ((memberModel?.points ?: 0.0) <= 0.0) {
|
||||
toast(getString(R.string.points_over))
|
||||
return@setOnClickListener
|
||||
}
|
||||
|
||||
selectPoints = !selectPoints
|
||||
if (selectPoints){
|
||||
binding.image4.setImageResource(R.mipmap.image_address_check_select)
|
||||
}else{
|
||||
binding.image4.setImageResource(R.mipmap.image_address_check_narmal)
|
||||
}
|
||||
clearBalanceIfPointsSufficient()
|
||||
clearExternalPaymentIfNotNeeded()
|
||||
}
|
||||
|
||||
binding.contentAddress.setOnClickListener {
|
||||
@@ -123,7 +161,7 @@ class OrderActivity : CKBaseActivity() {
|
||||
}
|
||||
binding.btnBuyNow.setOnClickListener {
|
||||
|
||||
if (selectBalance){
|
||||
if (selectBalance && !canPointsCoverPayAmount()){
|
||||
getPayPassword()
|
||||
}else{
|
||||
order("")
|
||||
@@ -287,38 +325,54 @@ class OrderActivity : CKBaseActivity() {
|
||||
param.put("buyerNote", "")
|
||||
param.put("items", items)
|
||||
param.put("payPassword", payPassword)
|
||||
param.put("orderId", model.orderId)
|
||||
showProgeassDialog(getString(R.string.order))
|
||||
|
||||
TTHttpClient.postJson(this, "下单", param.toString(), object : ICallback {
|
||||
override fun onSuccess(data: String) {
|
||||
var model = Gson().fromJson<PayOrderModel>(data, PayOrderModel::class.java)
|
||||
val paymentModel = Gson().fromJson(data, OrderPaymentModel::class.java)
|
||||
currentOrderId = paymentModel.orderId
|
||||
if ("0".equals(this@OrderActivity.payType)) {
|
||||
//微信
|
||||
val weChatPayParams = paymentModel.wxMap
|
||||
if (weChatPayParams == null || !weChatPayParams.isJsonObject) {
|
||||
hiddenProgeassDialog()
|
||||
toast("微信支付参数格式错误")
|
||||
return
|
||||
}
|
||||
wxPay(Gson().fromJson(weChatPayParams, PayOrderModel::class.java))
|
||||
}else if ("1".equals(this@OrderActivity.payType)) {
|
||||
if (TextUtils.isEmpty(model.orderStr)){
|
||||
val aliPayOrderStr = paymentModel.orderStr
|
||||
?.takeIf { it.isJsonPrimitive && it.asJsonPrimitive.isString }
|
||||
?.asString
|
||||
if (TextUtils.isEmpty(aliPayOrderStr)){
|
||||
toActivity(OrderSuccessActivity::class.java, DataCollection())
|
||||
finish()
|
||||
}else{
|
||||
aliPay(model.orderStr!!)
|
||||
aliPay(aliPayOrderStr!!)
|
||||
}
|
||||
}else{
|
||||
toast(getString(R.string.order_success))
|
||||
|
||||
toActivity(OrderSuccessActivity::class.java, DataCollection())
|
||||
finish()
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
override fun onFailed(code: String, msg: String) {
|
||||
|
||||
toast(msg)
|
||||
if (msg.indexOf("不足")>=0){
|
||||
toActivity(
|
||||
MyOrderActivity::class.java,
|
||||
DataCollection().apply { add(Data("pos", "1")) })
|
||||
finish()
|
||||
}
|
||||
|
||||
override fun onFailed(code: String, msg: String, data: String) {
|
||||
onFailed(code, msg)
|
||||
//原有【不足】的字符串判断条件
|
||||
if (code == "502") {
|
||||
val orderId = JSONObject(data).optInt("orderId")
|
||||
if (orderId > 0) {
|
||||
model.orderId = orderId
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -327,6 +381,10 @@ class OrderActivity : CKBaseActivity() {
|
||||
fun aliPay(orderStr: String) {
|
||||
GlobalScope.launch(Dispatchers.IO) {
|
||||
|
||||
// [支付宝沙箱测试] 仅 Debug 包启用,Release 包继续使用正式环境。
|
||||
if (applicationInfo.flags and ApplicationInfo.FLAG_DEBUGGABLE != 0) {
|
||||
// EnvUtils.setEnv(EnvUtils.EnvEnum.SANDBOX)
|
||||
}
|
||||
val alipay = PayTask(this@OrderActivity)
|
||||
val result = alipay.payV2(orderStr, true)
|
||||
|
||||
@@ -337,20 +395,111 @@ class OrderActivity : CKBaseActivity() {
|
||||
// 判断resultStatus 为9000则代表支付成功
|
||||
if (TextUtils.equals(resultStatus, "9000")) {
|
||||
// 该笔订单是否真实支付成功,需要依赖服务端的异步通知。
|
||||
toast(getString(R.string.payment_success))
|
||||
toActivity(OrderSuccessActivity::class.java, DataCollection())
|
||||
finish()
|
||||
handlePaymentSuccess()
|
||||
} else {
|
||||
toast(getString(R.string.payment_faild))
|
||||
toActivity(
|
||||
MyOrderActivity::class.java,
|
||||
DataCollection().apply { add(Data("pos", "1")) })
|
||||
finish()
|
||||
handlePaymentFailed(TextUtils.equals(resultStatus, "6001"))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun wxPay(model: PayOrderModel) {
|
||||
val requiredValues = listOf(
|
||||
model.appId,
|
||||
model.partnerId,
|
||||
model.prepayId,
|
||||
model.packageVal,
|
||||
model.nonceStr,
|
||||
model.timeStamp,
|
||||
model.paySign
|
||||
)
|
||||
if (requiredValues.any { it.isNullOrBlank() }) {
|
||||
hiddenProgeassDialog()
|
||||
toast("微信支付参数不完整,请检查商户号等支付参数")
|
||||
return
|
||||
}
|
||||
if (model.appId != Const.WX_APP_ID) {
|
||||
hiddenProgeassDialog()
|
||||
toast("微信支付 AppID 不匹配")
|
||||
return
|
||||
}
|
||||
|
||||
val api = WXAPIFactory.createWXAPI(this, Const.WX_APP_ID, true)
|
||||
api.registerApp(Const.WX_APP_ID)
|
||||
if (!api.isWXAppInstalled) {
|
||||
hiddenProgeassDialog()
|
||||
toast("请先安装微信")
|
||||
return
|
||||
}
|
||||
|
||||
val request = PayReq().apply {
|
||||
appId = model.appId
|
||||
partnerId = model.partnerId
|
||||
prepayId = model.prepayId
|
||||
packageValue = model.packageVal
|
||||
nonceStr = model.nonceStr
|
||||
timeStamp = model.timeStamp
|
||||
sign = model.paySign
|
||||
extData = model.orderNo
|
||||
}
|
||||
hiddenProgeassDialog()
|
||||
if (!api.sendReq(request)) {
|
||||
toast("微信支付拉起失败")
|
||||
}
|
||||
}
|
||||
|
||||
private fun handlePaymentSuccess() {
|
||||
toast(getString(R.string.payment_success))
|
||||
toActivity(OrderSuccessActivity::class.java, DataCollection())
|
||||
finish()
|
||||
}
|
||||
|
||||
private fun handlePaymentFailed(cancelled: Boolean) {
|
||||
if (cancelled) {
|
||||
cancelPendingOrder()
|
||||
return
|
||||
}
|
||||
|
||||
toast(getString(R.string.payment_faild))
|
||||
openPendingOrderList()
|
||||
}
|
||||
|
||||
private fun cancelPendingOrder() {
|
||||
if (isCancellingOrder) return
|
||||
|
||||
if (currentOrderId <= 0) {
|
||||
toast(getString(R.string.payment_faild))
|
||||
openPendingOrderList()
|
||||
return
|
||||
}
|
||||
|
||||
isCancellingOrder = true
|
||||
showProgeassDialog(getString(R.string.cancel))
|
||||
TTHttpClient.post(this, "取消待支付订单", TTRequestParam().apply {
|
||||
add(TTRequestData("orderId", currentOrderId))
|
||||
}, object : ICallback {
|
||||
override fun onSuccess(data: String) {
|
||||
hiddenProgeassDialog()
|
||||
toast(getString(R.string.cancel_pay_cussess))
|
||||
openPendingOrderList()
|
||||
}
|
||||
|
||||
override fun onFailed(code: String, msg: String) {
|
||||
hiddenProgeassDialog()
|
||||
toast(msg)
|
||||
openPendingOrderList()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private fun openPendingOrderList() {
|
||||
toActivity(
|
||||
MyOrderActivity::class.java,
|
||||
DataCollection().apply { add(Data("pos", "1")) }
|
||||
)
|
||||
finish()
|
||||
}
|
||||
|
||||
fun getMemberInfo() {
|
||||
TTHttpClient.get(this, "个人资料", TTRequestParam(), object : ICallback {
|
||||
override fun onSuccess(data: String) {
|
||||
@@ -393,16 +542,18 @@ class OrderActivity : CKBaseActivity() {
|
||||
|
||||
|
||||
fun showPayBottomView(){
|
||||
var showBalance = model.payAmount
|
||||
var showBalance = BigDecimal.valueOf(model.payAmount).setScale(2, RoundingMode.HALF_UP)
|
||||
if (selectPoints){
|
||||
CKApp.app.userInfo?.intoAmounts?.let {
|
||||
showBalance = showBalance - BigDecimal(memberModel?.points!!).multiply(
|
||||
BigDecimal(memberModel!!.intoAmounts!!)).setScale(2).toDouble()
|
||||
if (showBalance < 0.0){
|
||||
showBalance = 0.00
|
||||
}
|
||||
calculatePointsDeduction()?.let { pointsDeduction ->
|
||||
showBalance = showBalance.subtract(pointsDeduction)
|
||||
.max(BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP))
|
||||
}
|
||||
}
|
||||
|
||||
val userBalance = BigDecimal.valueOf(memberModel?.balance ?: 0.0)
|
||||
.setScale(2, RoundingMode.HALF_UP)
|
||||
showBalance = showBalance.min(userBalance)
|
||||
|
||||
var passwordBottomFragment = PayPasswordBottomFragment(showBalance.toString(), "余额",object : PayPasswordBottomFragment.PasswordCallBack{
|
||||
override fun callBack(password: String) {
|
||||
|
||||
@@ -413,8 +564,64 @@ class OrderActivity : CKBaseActivity() {
|
||||
passwordBottomFragment.show(supportFragmentManager, "PayPasswordBottomFragment")
|
||||
}
|
||||
|
||||
private fun canPointsCoverPayAmount(): Boolean {
|
||||
if (!selectPoints) return false
|
||||
val pointsDeduction = calculatePointsDeduction() ?: return false
|
||||
val payAmount = BigDecimal.valueOf(model.payAmount).setScale(2, RoundingMode.HALF_UP)
|
||||
return pointsDeduction >= payAmount
|
||||
}
|
||||
|
||||
private fun clearBalanceIfPointsSufficient(): Boolean {
|
||||
if (!canPointsCoverPayAmount()) return false
|
||||
|
||||
selectBalance = false
|
||||
binding.image3.setImageResource(R.mipmap.image_address_check_narmal)
|
||||
return true
|
||||
}
|
||||
|
||||
private fun calculatePointsDeduction(): BigDecimal? {
|
||||
val member = memberModel ?: return null
|
||||
val intoAmounts = member.intoAmounts?.toBigDecimalOrNull() ?: return null
|
||||
return BigDecimal.valueOf(member.points)
|
||||
.multiply(intoAmounts)
|
||||
.setScale(2, RoundingMode.HALF_UP)
|
||||
}
|
||||
|
||||
private fun isInternalPaymentSufficient(): Boolean {
|
||||
var internalAmount = BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP)
|
||||
if (selectBalance) {
|
||||
internalAmount = internalAmount.add(
|
||||
BigDecimal.valueOf(memberModel?.balance ?: 0.0)
|
||||
.setScale(2, RoundingMode.HALF_UP)
|
||||
)
|
||||
}
|
||||
if (selectPoints) {
|
||||
internalAmount = internalAmount.add(
|
||||
calculatePointsDeduction() ?: BigDecimal.ZERO
|
||||
)
|
||||
}
|
||||
|
||||
val payAmount = BigDecimal.valueOf(model.payAmount)
|
||||
.setScale(2, RoundingMode.HALF_UP)
|
||||
return internalAmount >= payAmount
|
||||
}
|
||||
|
||||
private fun clearExternalPaymentIfNotNeeded() {
|
||||
if (!isInternalPaymentSufficient()) return
|
||||
|
||||
payType = ""
|
||||
binding.image1.setImageResource(R.mipmap.image_address_check_narmal)
|
||||
binding.image2.setImageResource(R.mipmap.image_address_check_narmal)
|
||||
}
|
||||
|
||||
var payClick = object : View.OnClickListener {
|
||||
override fun onClick(v: View?) {
|
||||
if (isInternalPaymentSufficient()) {
|
||||
clearExternalPaymentIfNotNeeded()
|
||||
toast("当前支付方式无需使用三方支付")
|
||||
return
|
||||
}
|
||||
|
||||
binding.image1.setImageResource(R.mipmap.image_address_check_narmal)
|
||||
binding.image2.setImageResource(R.mipmap.image_address_check_narmal)
|
||||
when (v?.id) {
|
||||
@@ -517,4 +724,4 @@ class OrderActivity : CKBaseActivity() {
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ 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.CKApp
|
||||
import com.ck.ckcollar.app.R
|
||||
import com.ck.ckcollar.app.action.ActionCode
|
||||
import com.ck.ckcollar.app.databinding.ActivityProductDetailsBinding
|
||||
@@ -23,6 +24,7 @@ import com.ck.ckcollar.app.ui.act.customer.PeopleCustomerActivity
|
||||
import com.ck.ckcollar.app.ui.act.customer.ShopCustomerActivity
|
||||
import com.ck.ckcollar.app.ui.act.home.fragment.HomeFragment
|
||||
import com.ck.ckcollar.app.ui.act.home.fragment.HomeFragment.ImageAdapter
|
||||
import com.ck.ckcollar.app.ui.act.login.LoginActivity
|
||||
import com.ck.ckcollar.app.ui.act.petmanager.ImageViewActivity
|
||||
import com.ck.ckcollar.app.ui.base.CKBaseActivity
|
||||
import com.ck.ckcollar.app.ui.base.CKLHBaseActionBarActivity
|
||||
@@ -63,20 +65,30 @@ class ProductDetailsActivity : CKBaseActivity() {
|
||||
setupWebView(binding.textContent)
|
||||
|
||||
binding.btnAddCar.setOnClickListener {
|
||||
if (!requireLogin()) return@setOnClickListener
|
||||
showProductTypeFragment()
|
||||
}
|
||||
binding.btnBuyNow.setOnClickListener {
|
||||
if (!requireLogin()) return@setOnClickListener
|
||||
showProductTypeFragment()
|
||||
}
|
||||
|
||||
binding.contentShopCar.setOnClickListener {
|
||||
if (!requireLogin()) return@setOnClickListener
|
||||
toActivity(ShopCarActivity::class.java, DataCollection())
|
||||
}
|
||||
binding.contentCustomer.setOnClickListener {
|
||||
if (!requireLogin()) return@setOnClickListener
|
||||
toActivity(PeopleCustomerActivity::class.java, DataCollection().apply { add(Data("chatType","1")) })
|
||||
}
|
||||
}
|
||||
|
||||
private fun requireLogin(): Boolean {
|
||||
if (CKApp.app.isUserLoggedIn) return true
|
||||
toActivity(LoginActivity::class.java, DataCollection())
|
||||
return false
|
||||
}
|
||||
|
||||
override fun initData() {
|
||||
model = Gson().fromJson<ShopProductModel.ProductModel>(getReceiveParam().get("data")!!.stringValue,
|
||||
ShopProductModel.ProductModel::class.java)
|
||||
@@ -148,7 +160,7 @@ class ProductDetailsActivity : CKBaseActivity() {
|
||||
ViewGroup.LayoutParams.MATCH_PARENT
|
||||
)
|
||||
)
|
||||
imageView.setScaleType(ImageView.ScaleType.FIT_XY)
|
||||
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP)
|
||||
return BannerViewHolder(imageView)
|
||||
}
|
||||
|
||||
@@ -313,4 +325,4 @@ class ProductDetailsActivity : CKBaseActivity() {
|
||||
// 使用 loadDataWithBaseURL 加载
|
||||
webView.loadDataWithBaseURL(null, styledHtml, "text/html", "UTF-8", null)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import android.content.Context
|
||||
import android.os.Bundle
|
||||
import android.text.TextUtils
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.inputmethod.EditorInfo
|
||||
import android.view.inputmethod.InputMethodManager
|
||||
@@ -91,6 +92,10 @@ class ShopCarActivity : CKLHBaseActionBarActivity() {
|
||||
|
||||
|
||||
binding.checkbox.setOnClickListener {
|
||||
if (productDatas.isEmpty()) {
|
||||
toast(getString(R.string.shop_car_empty))
|
||||
return@setOnClickListener
|
||||
}
|
||||
|
||||
selectAll = !selectAll
|
||||
if (selectAll){
|
||||
@@ -154,6 +159,11 @@ class ShopCarActivity : CKLHBaseActionBarActivity() {
|
||||
|
||||
|
||||
override fun rightButton1OnClick() {
|
||||
if (productDatas.isEmpty()) {
|
||||
toast(getString(R.string.shop_car_empty))
|
||||
return
|
||||
}
|
||||
|
||||
isShowDelete = !isShowDelete
|
||||
|
||||
if (isShowDelete){
|
||||
@@ -214,6 +224,7 @@ class ShopCarActivity : CKLHBaseActionBarActivity() {
|
||||
})
|
||||
}
|
||||
fun getData(){
|
||||
showProgeassDialog()
|
||||
TTHttpClient.get(this,"购物车列表", TTRequestParam(),object : ICallback{
|
||||
override fun onSuccess(data: String) {
|
||||
this@ShopCarActivity.productDatas = Gson().fromJson<List<ShopCarModel>>(data, object : TypeToken<List<ShopCarModel>>(){}.type)
|
||||
@@ -221,6 +232,10 @@ class ShopCarActivity : CKLHBaseActionBarActivity() {
|
||||
shopCarAdapter.data = this@ShopCarActivity.productDatas
|
||||
shopCarAdapter.notifyDataSetChanged()
|
||||
|
||||
val isEmpty = this@ShopCarActivity.productDatas.isEmpty()
|
||||
binding.relNoresult.visibility = if (isEmpty) View.VISIBLE else View.GONE
|
||||
binding.recyclerView.visibility = if (isEmpty) View.GONE else View.VISIBLE
|
||||
|
||||
var flag = true
|
||||
for (model in productDatas){
|
||||
if ("0".equals(model.selected)){
|
||||
@@ -242,7 +257,7 @@ class ShopCarActivity : CKLHBaseActionBarActivity() {
|
||||
}
|
||||
|
||||
override fun onFailed(code: String, msg: String) {
|
||||
|
||||
toast(msg)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -296,14 +311,15 @@ class ShopCarActivity : CKLHBaseActionBarActivity() {
|
||||
}
|
||||
|
||||
fun sendSelectAll(select : String){
|
||||
|
||||
showProgeassDialog()
|
||||
TTHttpClient.putJson(this,"购物车全部选中", TTRequestParam().apply { add(TTRequestData("selected",select)) },object : ICallback{
|
||||
override fun onSuccess(data: String) {
|
||||
hiddenProgeassDialog()
|
||||
getData()
|
||||
}
|
||||
|
||||
override fun onFailed(code: String, msg: String) {
|
||||
|
||||
hiddenProgeassDialog()
|
||||
toast(msg)
|
||||
getData()
|
||||
}
|
||||
@@ -433,4 +449,4 @@ class ShopCarActivity : CKLHBaseActionBarActivity() {
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.ck.ckcollar.app.ui.act.shop
|
||||
import android.content.Context
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.inputmethod.EditorInfo
|
||||
import android.view.inputmethod.InputMethodManager
|
||||
@@ -33,6 +34,8 @@ import com.tt.kit.model.DataCollection
|
||||
import com.tt.kit.utils.KeyboardUtils
|
||||
|
||||
class TypeActivity : CKLHBaseActionBarActivity() {
|
||||
override val shouldRequestPermissionsOnCreate: Boolean = false
|
||||
|
||||
lateinit var binding: ActivityShopTypeBinding
|
||||
lateinit var productAdapter: ProductAdapter
|
||||
|
||||
@@ -86,6 +89,7 @@ class TypeActivity : CKLHBaseActionBarActivity() {
|
||||
|
||||
|
||||
fun getData() {
|
||||
showProgeassDialog()
|
||||
TTHttpClient.get(this, "商品列表", TTRequestParam().apply {
|
||||
add(
|
||||
TTRequestData("pageNum", page)
|
||||
@@ -107,12 +111,18 @@ class TypeActivity : CKLHBaseActionBarActivity() {
|
||||
productAdapter.data = productDatas
|
||||
productAdapter.notifyDataSetChanged()
|
||||
|
||||
val isEmpty = productDatas.isEmpty()
|
||||
binding.relNoresult.visibility = if (isEmpty) View.VISIBLE else View.GONE
|
||||
binding.recyclerView.visibility = if (isEmpty) View.GONE else View.VISIBLE
|
||||
|
||||
binding.refreshLayout.finishLoadMore(true)
|
||||
binding.refreshLayout.finishRefresh()
|
||||
}
|
||||
|
||||
override fun onFailed(code: String, msg: String) {
|
||||
binding.refreshLayout.finishLoadMore(true)
|
||||
binding.refreshLayout.finishLoadMore(false)
|
||||
binding.refreshLayout.finishRefresh()
|
||||
toast(msg)
|
||||
|
||||
}
|
||||
})
|
||||
@@ -172,4 +182,4 @@ class TypeActivity : CKLHBaseActionBarActivity() {
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.ck.ckcollar.app.ui.act.user
|
||||
|
||||
import android.Manifest
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
@@ -20,12 +21,12 @@ import com.ck.ckcollar.app.model.UserInfoModel
|
||||
import com.ck.ckcollar.app.ui.act.home.MainActivity
|
||||
import com.ck.ckcollar.app.ui.act.login.BoundPhoneActivity
|
||||
import com.ck.ckcollar.app.ui.base.CKBaseActivity
|
||||
import com.ck.ckcollar.app.ui.dialog.CKAlertDialog
|
||||
import com.ck.ckcollar.app.ui.dialog.CKEditDialog
|
||||
import com.ck.ckcollar.app.ui.dialog.CKEditNameDialog
|
||||
import com.ck.ckcollar.app.ui.dialog.CKEditPhoneDialog
|
||||
import com.ck.ckcollar.app.ui.dialog.CKPhotoDialog
|
||||
import com.ck.ckcollar.app.utils.Const
|
||||
import com.ck.ckcollar.app.utils.IDCardValidate
|
||||
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
|
||||
@@ -55,7 +56,7 @@ class UserInfoActivity: CKBaseActivity() {
|
||||
api = WXAPIFactory.createWXAPI(this, Const.WX_APP_ID)
|
||||
CKApp.app.wxJump = 1
|
||||
|
||||
checkAppPermissions()
|
||||
// checkAppPermissions()
|
||||
setStatusBarColor(resources.getColor(R.color.white))
|
||||
setActionBarColor(resources.getColor(R.color.white))
|
||||
|
||||
@@ -86,7 +87,7 @@ class UserInfoActivity: CKBaseActivity() {
|
||||
binding.textPhone.setOnClickListener {
|
||||
CKEditPhoneDialog(
|
||||
this@UserInfoActivity,
|
||||
getString(R.string.bind_phone),
|
||||
getString(R.string.modify_phone_number),
|
||||
object : CKEditPhoneDialog.AlertClickListener {
|
||||
override fun onBack(text: String) {
|
||||
binding.textPhone.text = text
|
||||
@@ -99,7 +100,12 @@ class UserInfoActivity: CKBaseActivity() {
|
||||
binding.textIdCard.setOnClickListener {
|
||||
CKEditDialog(this@UserInfoActivity,getString(R.string.id_card),binding.textIdCard.text.toString(),object : CKEditDialog.AlertClickListener{
|
||||
override fun onBack(text: String) {
|
||||
binding.textIdCard.text = text
|
||||
val idCard = text.trim().uppercase()
|
||||
if (!IDCardValidate.validateEffective(idCard)) {
|
||||
toast("请输入正确的身份证号码")
|
||||
return
|
||||
}
|
||||
binding.textIdCard.text = idCard
|
||||
save()
|
||||
}
|
||||
}).show()
|
||||
@@ -111,16 +117,10 @@ class UserInfoActivity: CKBaseActivity() {
|
||||
override fun onBack(mark: Int, position: Int) {
|
||||
try {
|
||||
if (mark == 0){
|
||||
if (!checkCameraPermissions()){
|
||||
CKAlertDialog(this@UserInfoActivity,getString(R.string.alert),getString(R.string.camera_alert),object : CKAlertDialog.AlertClickListener{
|
||||
override fun onBack(isConfirm: Boolean) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
}).show()
|
||||
return
|
||||
}
|
||||
takePhoto()
|
||||
getPermissionRequst(
|
||||
Manifest.permission.CAMERA,
|
||||
REQUEST_CAMERA_PERMISSION
|
||||
)
|
||||
}else{
|
||||
//相册
|
||||
val i = Intent(
|
||||
@@ -148,6 +148,12 @@ class UserInfoActivity: CKBaseActivity() {
|
||||
}
|
||||
}
|
||||
|
||||
override fun onPermissionsGranted(requestCode: Int, permissions: Array<String>) {
|
||||
if (requestCode == REQUEST_CAMERA_PERMISSION) {
|
||||
takePhoto()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onNewIntent(intent: Intent) {
|
||||
super.onNewIntent(intent)
|
||||
|
||||
@@ -242,6 +248,10 @@ class UserInfoActivity: CKBaseActivity() {
|
||||
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val REQUEST_CAMERA_PERMISSION = 1101
|
||||
}
|
||||
|
||||
override fun initData() {
|
||||
|
||||
binding.textNick.text= CKApp.app.userInfo?.custName
|
||||
@@ -322,4 +332,4 @@ class UserInfoActivity: CKBaseActivity() {
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,11 +4,27 @@ import android.os.Bundle
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.os.Message
|
||||
import android.text.TextUtils
|
||||
import android.app.AlertDialog
|
||||
import android.graphics.Color
|
||||
import android.graphics.drawable.GradientDrawable
|
||||
import android.text.SpannableString
|
||||
import android.text.Spanned
|
||||
import android.text.method.LinkMovementMethod
|
||||
import android.text.style.ClickableSpan
|
||||
import android.view.View
|
||||
import android.view.Gravity
|
||||
import android.view.ViewGroup
|
||||
import android.view.WindowManager
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.TextView
|
||||
import android.widget.ScrollView
|
||||
import com.ck.ckcollar.app.CKApp
|
||||
import com.ck.ckcollar.app.R
|
||||
import com.ck.ckcollar.app.databinding.ActivityIndexBinding
|
||||
import com.ck.ckcollar.app.ui.act.home.MainActivity
|
||||
import com.ck.ckcollar.app.ui.act.login.LoginActivity
|
||||
import com.ck.ckcollar.app.ui.act.login.AgreementActivity
|
||||
import com.ck.ckcollar.app.ui.act.setting.SettingWebViewActivity
|
||||
import com.ck.ckcollar.app.config.Config
|
||||
import com.ck.ckcollar.app.ui.base.CKBaseActivity
|
||||
import com.ck.ckcollar.app.utils.Const
|
||||
import com.cyclone.shadowsocks.utils.PreferencesUtils
|
||||
@@ -25,19 +41,89 @@ class IndexActivity : CKBaseActivity() {
|
||||
}
|
||||
var handler = object : Handler(Looper.getMainLooper()){
|
||||
override fun handleMessage(msg: Message) {
|
||||
if (TextUtils.isEmpty(CKApp.app.token)){
|
||||
var isFirst = PreferencesUtils.getBolean(this@IndexActivity, Const.FIRST,true) as Boolean
|
||||
if (isFirst){
|
||||
toActivity(WelcomeActivity::class.java, DataCollection())
|
||||
}else{
|
||||
toActivity(LoginActivity::class.java, DataCollection())
|
||||
}
|
||||
}else{
|
||||
toActivity(MainActivity::class.java, DataCollection())
|
||||
}
|
||||
continueAfterAgreement()
|
||||
}
|
||||
}
|
||||
|
||||
private fun continueAfterAgreement() {
|
||||
val agreed = PreferencesUtils.getBolean(this, Const.AGREEMENT_CHECK, false) as Boolean
|
||||
if (!agreed) {
|
||||
showUserNotice()
|
||||
return
|
||||
}
|
||||
val isFirst = PreferencesUtils.getBolean(this, Const.FIRST, true) as Boolean
|
||||
toActivity(if (isFirst) WelcomeActivity::class.java else MainActivity::class.java, DataCollection())
|
||||
finish()
|
||||
}
|
||||
|
||||
finish()
|
||||
private fun showUserNotice() {
|
||||
fun dp(value: Int) = (value * resources.displayMetrics.density).toInt()
|
||||
val title = TextView(this).apply {
|
||||
text = "用户须知"
|
||||
setTextColor(Color.rgb(35, 39, 55))
|
||||
textSize = 20f
|
||||
gravity = Gravity.CENTER
|
||||
setTypeface(typeface, android.graphics.Typeface.BOLD)
|
||||
}
|
||||
val content = TextView(this).apply {
|
||||
setTextColor(Color.rgb(95, 99, 115))
|
||||
textSize = 14f
|
||||
setLineSpacing(0f, 1.35f)
|
||||
movementMethod = LinkMovementMethod.getInstance()
|
||||
val text = "感谢您使用宠盾!我们非常重视您的个人信息和隐私保护。请阅读并同意《用户协议》和《隐私协议》后继续使用。\n\n1. 为提供宠物管理、设备连接、消息通知和 AI 识别等服务,我们可能会收集必要的账号、设备及使用信息。\n\n2. 在您使用拍照、扫码、地图定位、蓝牙或相册等功能时,我们会在获得授权后申请相应权限;您可以随时在系统设置中关闭权限,但可能无法使用对应功能。\n\n3. 我们会采取合理的安全措施保护您的信息,不会将信息用于协议约定以外的用途,也不会向无关方出售或出租您的信息。\n\n4. 为保障服务稳定运行,部分功能可能由第三方服务提供商协助完成,我们会要求其按照法律法规和隐私政策保护您的信息。\n\n5. 当协议内容或服务发生重要变化时,我们会通过弹窗或其他适当方式提醒您。您可以通过应用内相关入口再次查看完整协议。"
|
||||
val spannable = SpannableString(text)
|
||||
val userStart = text.indexOf("《用户协议》")
|
||||
val privacyStart = text.indexOf("《隐私协议》")
|
||||
spannable.setSpan(object : ClickableSpan() {
|
||||
override fun onClick(widget: View) = toActivity(AgreementActivity::class.java, DataCollection().apply { add(com.tt.kit.model.Data("title", getString(R.string.user_agreement))) })
|
||||
}, userStart, userStart + 6, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||
spannable.setSpan(object : ClickableSpan() {
|
||||
override fun onClick(widget: View) = toActivity(SettingWebViewActivity::class.java, DataCollection().apply {
|
||||
add(com.tt.kit.model.Data("url", Config.PRIVACY_POLICY)); add(com.tt.kit.model.Data("title", getString(R.string.privacy_agreement)))
|
||||
})
|
||||
}, privacyStart, privacyStart + 6, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||
setText(spannable)
|
||||
}
|
||||
val contentScroll = ScrollView(this).apply {
|
||||
isFillViewport = true
|
||||
isVerticalScrollBarEnabled = false
|
||||
addView(content, ViewGroup.LayoutParams(-1, -2))
|
||||
}
|
||||
lateinit var dialog: AlertDialog
|
||||
val buttons = LinearLayout(this).apply {
|
||||
orientation = LinearLayout.HORIZONTAL
|
||||
gravity = Gravity.CENTER
|
||||
}
|
||||
fun action(text: String, backgroundColor: Int, textColor: Int, onClick: () -> Unit) = TextView(this).apply {
|
||||
this.text = text; gravity = Gravity.CENTER; setTextColor(textColor); textSize = 15f
|
||||
setTypeface(typeface, android.graphics.Typeface.BOLD); setPadding(0, dp(13), 0, dp(13))
|
||||
background = GradientDrawable().apply { setColor(backgroundColor); cornerRadius = dp(10).toFloat() }
|
||||
setOnClickListener { onClick() }
|
||||
}
|
||||
val rejectButton = action("不同意", Color.rgb(245, 246, 250), Color.rgb(35, 39, 55), {
|
||||
dialog.dismiss(); finishAndRemoveTask()
|
||||
})
|
||||
val agreeButton = action("同意", getColor2(R.attr.buttonColor), Color.WHITE) {
|
||||
PreferencesUtils.putBoolean(this@IndexActivity, Const.AGREEMENT_CHECK, true)
|
||||
dialog.dismiss(); continueAfterAgreement()
|
||||
}
|
||||
buttons.addView(rejectButton, LinearLayout.LayoutParams(0, dp(52), 1f).apply { marginEnd = dp(7) })
|
||||
buttons.addView(agreeButton, LinearLayout.LayoutParams(0, dp(52), 1f).apply { marginStart = dp(7) })
|
||||
val panel = LinearLayout(this).apply {
|
||||
orientation = LinearLayout.VERTICAL
|
||||
setPadding(dp(24), dp(25), dp(24), dp(24))
|
||||
addView(title, LinearLayout.LayoutParams(-1, dp(40)))
|
||||
addView(contentScroll, LinearLayout.LayoutParams(-1, dp(390)).apply { topMargin = dp(12); bottomMargin = dp(20) })
|
||||
addView(buttons, LinearLayout.LayoutParams(-1, dp(52)))
|
||||
background = GradientDrawable().apply { setColor(Color.WHITE); cornerRadius = dp(22).toFloat() }
|
||||
}
|
||||
dialog = AlertDialog.Builder(this).setView(panel).setCancelable(false).create()
|
||||
dialog.show()
|
||||
dialog.window?.apply {
|
||||
setBackgroundDrawableResource(android.R.color.transparent)
|
||||
setDimAmount(0.55f)
|
||||
setGravity(Gravity.CENTER)
|
||||
setLayout((resources.displayMetrics.widthPixels * 0.82f).toInt(), WindowManager.LayoutParams.WRAP_CONTENT)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,4 +132,4 @@ class IndexActivity : CKBaseActivity() {
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ import androidx.viewpager.widget.PagerAdapter
|
||||
import com.ck.ckcollar.app.R
|
||||
import com.ck.ckcollar.app.databinding.ActivityWelcomeBinding
|
||||
import com.ck.ckcollar.app.databinding.LayoutItemWelcomeBinding
|
||||
import com.ck.ckcollar.app.ui.act.login.LoginActivity
|
||||
import com.ck.ckcollar.app.ui.act.home.MainActivity
|
||||
import com.ck.ckcollar.app.ui.base.CKBaseActivity
|
||||
import com.ck.ckcollar.app.utils.Const
|
||||
import com.cyclone.shadowsocks.utils.PreferencesUtils
|
||||
@@ -59,11 +59,12 @@ class WelcomeActivity : CKBaseActivity() {
|
||||
view.btnCome.setOnClickListener {
|
||||
val toPermisstionActivity = PreferencesUtils.getBolean(this@WelcomeActivity,
|
||||
Const.PERMISSIONS_FIRST,false) as Boolean
|
||||
if (!toPermisstionActivity){
|
||||
toActivity(PermisstionActivity::class.java, DataCollection())
|
||||
}else{
|
||||
toActivity(LoginActivity::class.java, DataCollection())
|
||||
}
|
||||
// if (!toPermisstionActivity){
|
||||
// toActivity(PermisstionActivity::class.java, DataCollection())
|
||||
// }else{
|
||||
// toActivity(LoginActivity::class.java, DataCollection())
|
||||
// }
|
||||
toActivity(MainActivity::class.java, DataCollection())
|
||||
finish()
|
||||
}
|
||||
|
||||
@@ -97,4 +98,4 @@ class WelcomeActivity : CKBaseActivity() {
|
||||
|
||||
PreferencesUtils.putBoolean(this, Const.FIRST, false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,8 +19,8 @@ import pub.devrel.easypermissions.EasyPermissions
|
||||
|
||||
open class CKBaseActionBarActivity : TTBaseActivity(){
|
||||
|
||||
var perms_= listOf<String>(Manifest.permission.CAMERA, Manifest.permission.READ_MEDIA_IMAGES,Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE)
|
||||
var perms_tiramisu = listOf<String>(Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.READ_EXTERNAL_STORAGE)
|
||||
var perms_= listOf<String>(Manifest.permission.CAMERA, Manifest.permission.READ_MEDIA_IMAGES,Manifest.permission.READ_EXTERNAL_STORAGE)
|
||||
var perms_tiramisu = listOf<String>(Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE)
|
||||
|
||||
lateinit var rootView : View
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
@@ -127,4 +127,4 @@ open class CKBaseActionBarActivity : TTBaseActivity(){
|
||||
super.onDestroy()
|
||||
CKApp.app.activitys.remove(this)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,23 +1,33 @@
|
||||
package com.ck.ckcollar.app.ui.base
|
||||
|
||||
import android.Manifest
|
||||
import android.content.pm.PackageManager
|
||||
import android.content.Intent
|
||||
import android.graphics.drawable.ColorDrawable
|
||||
import android.graphics.Color
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.provider.Settings
|
||||
import android.util.TypedValue
|
||||
import android.view.View
|
||||
import android.view.Gravity
|
||||
import android.view.WindowManager
|
||||
import android.widget.ImageButton
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.appcompat.app.AppCompatDelegate
|
||||
import androidx.core.app.ActivityCompat
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.view.ViewCompat
|
||||
import androidx.core.view.WindowCompat
|
||||
import androidx.core.view.WindowInsetsCompat
|
||||
import androidx.core.view.WindowInsetsControllerCompat
|
||||
import com.ck.ckcollar.app.CKApp
|
||||
import com.ck.ckcollar.app.R
|
||||
import com.ck.ckcollar.app.ui.dialog.CKAlertDialog
|
||||
import com.tt.kit.base.TTBaseActivity
|
||||
import com.tt.kit.utils.TTLog
|
||||
import com.tt.kit.utils.TTUtils
|
||||
@@ -26,8 +36,47 @@ import pub.devrel.easypermissions.EasyPermissions
|
||||
|
||||
open class CKBaseActivity : TTBaseActivity(){
|
||||
|
||||
var perms_= listOf<String>(Manifest.permission.CAMERA, Manifest.permission.READ_MEDIA_IMAGES,Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE)
|
||||
var perms_tiramisu = listOf<String>(Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.READ_EXTERNAL_STORAGE)
|
||||
protected open val useDarkStatusBarIcons: Boolean = true
|
||||
|
||||
private var permissionDialog: AlertDialog? = null
|
||||
private var pendingPermissionRequestCode: Int? = null
|
||||
private var pendingPermissions: Array<String> = emptyArray()
|
||||
private var settingsPermissionRequestCode: Int? = null
|
||||
private var settingsPermissions: Array<String> = emptyArray()
|
||||
private val permissionSettingsLauncher = registerForActivityResult(
|
||||
ActivityResultContracts.StartActivityForResult()
|
||||
) {
|
||||
val requestCode = settingsPermissionRequestCode
|
||||
val permissions = settingsPermissions
|
||||
settingsPermissionRequestCode = null
|
||||
settingsPermissions = emptyArray()
|
||||
|
||||
if (requestCode != null && hasRecordPermission(permissions)) {
|
||||
onPermissionsGranted(requestCode, permissions)
|
||||
}
|
||||
}
|
||||
private val permissionLauncher = registerForActivityResult(
|
||||
ActivityResultContracts.RequestMultiplePermissions()
|
||||
) { result ->
|
||||
hidePermissionDialog()
|
||||
val requestCode = pendingPermissionRequestCode ?: return@registerForActivityResult
|
||||
val requestedPermissions = pendingPermissions
|
||||
pendingPermissionRequestCode = null
|
||||
pendingPermissions = emptyArray()
|
||||
|
||||
val denied = result.filterValues { !it }.keys.toTypedArray()
|
||||
if (denied.isEmpty()) {
|
||||
onPermissionsGranted(requestCode, requestedPermissions)
|
||||
} else {
|
||||
val permanentlyDenied = denied.any {
|
||||
!ActivityCompat.shouldShowRequestPermissionRationale(this, it)
|
||||
}
|
||||
onPermissionsDenied(requestCode, denied, permanentlyDenied)
|
||||
}
|
||||
}
|
||||
|
||||
var perms_= listOf<String>(Manifest.permission.CAMERA, Manifest.permission.READ_MEDIA_IMAGES,Manifest.permission.READ_EXTERNAL_STORAGE)
|
||||
var perms_tiramisu = listOf<String>(Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE)
|
||||
|
||||
var perms_carmra = listOf<String>(Manifest.permission.CAMERA)
|
||||
|
||||
@@ -53,10 +102,15 @@ open class CKBaseActivity : TTBaseActivity(){
|
||||
|
||||
CKApp.app.activitys.add(this)
|
||||
setStatusBarColor(R.attr.actionBarBackground)
|
||||
setStatusBarTextDark(useDarkStatusBarIcons)
|
||||
|
||||
|
||||
}
|
||||
|
||||
fun setStatusBarTextDark(isDark: Boolean = true) {
|
||||
WindowInsetsControllerCompat(window, window.decorView).isAppearanceLightStatusBars = isDark
|
||||
}
|
||||
|
||||
fun checkAppPermissions(){
|
||||
if (!checkPermissions()){
|
||||
requstPermissions()
|
||||
@@ -208,10 +262,139 @@ open class CKBaseActivity : TTBaseActivity(){
|
||||
}
|
||||
|
||||
fun checkCameraPermissions() : Boolean{
|
||||
|
||||
var a = 0;
|
||||
return EasyPermissions.hasPermissions(this, *perms_carmra.toTypedArray())
|
||||
}
|
||||
|
||||
fun hasRecordPermission(permission: String): Boolean {
|
||||
return hasRecordPermission(arrayOf(permission))
|
||||
}
|
||||
|
||||
fun hasRecordPermission(permissions: Array<String>): Boolean {
|
||||
return permissions.all {
|
||||
ContextCompat.checkSelfPermission(this, it) == PackageManager.PERMISSION_GRANTED
|
||||
}
|
||||
}
|
||||
|
||||
fun getPermissionRequst(
|
||||
permission: String,
|
||||
requestCode: Int
|
||||
) {
|
||||
val isCameraPermission = permission == Manifest.permission.CAMERA
|
||||
getPermissionRequst(
|
||||
permission,
|
||||
getString(if (isCameraPermission) R.string.camera else R.string.photo),
|
||||
getString(if (isCameraPermission) R.string.camera_alert else R.string.photo_permission_alert),
|
||||
requestCode
|
||||
)
|
||||
}
|
||||
|
||||
fun getPermissionRequst(
|
||||
permission: String,
|
||||
title: String,
|
||||
content: String,
|
||||
requestCode: Int
|
||||
) {
|
||||
getMorePermissionRequst(arrayOf(permission), title, content, requestCode)
|
||||
}
|
||||
|
||||
fun getMorePermissionRequst(
|
||||
permissions: Array<String>,
|
||||
title: String,
|
||||
content: String,
|
||||
requestCode: Int
|
||||
) {
|
||||
if (hasRecordPermission(permissions)) {
|
||||
onPermissionsGranted(requestCode, permissions)
|
||||
return
|
||||
}
|
||||
|
||||
CKAlertDialog(this, getString(R.string.alert), content, object : CKAlertDialog.AlertClickListener {
|
||||
override fun onBack(isConfirm: Boolean) {
|
||||
if (isConfirm) {
|
||||
requestSystemPermissions(permissions, title, content, requestCode)
|
||||
} else {
|
||||
onPermissionsDenied(requestCode, permissions, false)
|
||||
}
|
||||
}
|
||||
}).show()
|
||||
}
|
||||
|
||||
private fun requestSystemPermissions(
|
||||
permissions: Array<String>,
|
||||
title: String,
|
||||
content: String,
|
||||
requestCode: Int
|
||||
) {
|
||||
pendingPermissionRequestCode = requestCode
|
||||
pendingPermissions = permissions
|
||||
showPermissionDialog(title, content)
|
||||
permissionDialog?.window?.decorView?.post {
|
||||
if (!isFinishing && pendingPermissionRequestCode == requestCode) {
|
||||
permissionLauncher.launch(permissions)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun showPermissionDialog(title: String, content: String) {
|
||||
hidePermissionDialog()
|
||||
val view = layoutInflater.inflate(R.layout.permission_top_dialog, null)
|
||||
view.findViewById<TextView>(R.id.permissionTopTitle).text = title
|
||||
view.findViewById<TextView>(R.id.permissionTopContent).text = content
|
||||
permissionDialog = AlertDialog.Builder(this)
|
||||
.setView(view)
|
||||
.create()
|
||||
.also { dialog ->
|
||||
dialog.setCanceledOnTouchOutside(false)
|
||||
dialog.setCancelable(false)
|
||||
dialog.show()
|
||||
dialog.window?.apply {
|
||||
setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
|
||||
setGravity(Gravity.TOP)
|
||||
setLayout(
|
||||
WindowManager.LayoutParams.MATCH_PARENT,
|
||||
WindowManager.LayoutParams.WRAP_CONTENT
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun hidePermissionDialog() {
|
||||
permissionDialog?.dismiss()
|
||||
permissionDialog = null
|
||||
}
|
||||
|
||||
protected open fun onPermissionsGranted(requestCode: Int, permissions: Array<String>) {
|
||||
}
|
||||
|
||||
protected open fun onPermissionsDenied(
|
||||
requestCode: Int,
|
||||
permissions: Array<String>,
|
||||
permanentlyDenied: Boolean
|
||||
) {
|
||||
if (!permanentlyDenied) return
|
||||
|
||||
CKAlertDialog(
|
||||
this,
|
||||
getString(R.string.settting_permissions),
|
||||
getString(R.string.permission_settings_alert),
|
||||
object : CKAlertDialog.AlertClickListener {
|
||||
override fun onBack(isConfirm: Boolean) {
|
||||
if (isConfirm) {
|
||||
settingsPermissionRequestCode = requestCode
|
||||
settingsPermissions = permissions
|
||||
permissionSettingsLauncher.launch(
|
||||
Intent(
|
||||
Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
|
||||
Uri.parse("package:$packageName")
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
).show()
|
||||
}
|
||||
|
||||
fun requstPermissions(){
|
||||
var perms = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
perms_
|
||||
@@ -228,6 +411,11 @@ open class CKBaseActivity : TTBaseActivity(){
|
||||
ActivityCompat.requestPermissions(this, perms.toTypedArray(), 1001)
|
||||
}
|
||||
override fun onDestroy() {
|
||||
hidePermissionDialog()
|
||||
pendingPermissionRequestCode = null
|
||||
pendingPermissions = emptyArray()
|
||||
settingsPermissionRequestCode = null
|
||||
settingsPermissions = emptyArray()
|
||||
super.onDestroy()
|
||||
CKApp.app.activitys.remove(this)
|
||||
}
|
||||
@@ -245,4 +433,4 @@ open class CKBaseActivity : TTBaseActivity(){
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,21 @@
|
||||
package com.ck.ckcollar.app.ui.base
|
||||
|
||||
import android.Manifest
|
||||
import com.ck.ckcollar.app.CKApp
|
||||
import com.ck.ckcollar.app.ui.act.login.LoginActivity
|
||||
import com.cyclone.shadowsocks.ui.frg.TTBaseFragment
|
||||
import com.tt.kit.model.DataCollection
|
||||
import pub.devrel.easypermissions.EasyPermissions
|
||||
|
||||
open class CKBaseFragment : TTBaseFragment() {
|
||||
|
||||
var perms_carmra = listOf<String>(Manifest.permission.CAMERA)
|
||||
|
||||
|
||||
fun isUserLogin(): Boolean {
|
||||
if (CKApp.app.isUserLoggedIn) return true
|
||||
toActivity(LoginActivity::class.java, DataCollection())
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
fun checkCameraPermissions() : Boolean{
|
||||
|
||||
@@ -28,8 +28,10 @@ import pub.devrel.easypermissions.EasyPermissions
|
||||
|
||||
open class CKLHBaseActionBarActivity : TTBaseActivity(){
|
||||
|
||||
var perms_= listOf<String>(Manifest.permission.CAMERA, Manifest.permission.READ_MEDIA_IMAGES,Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE)
|
||||
var perms_tiramisu = listOf<String>(Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.READ_EXTERNAL_STORAGE)
|
||||
protected open val shouldRequestPermissionsOnCreate: Boolean = false
|
||||
|
||||
var perms_= listOf<String>(Manifest.permission.CAMERA, Manifest.permission.READ_MEDIA_IMAGES,Manifest.permission.READ_EXTERNAL_STORAGE)
|
||||
var perms_tiramisu = listOf<String>(Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE)
|
||||
|
||||
lateinit var rootView : View
|
||||
|
||||
@@ -83,7 +85,7 @@ open class CKLHBaseActionBarActivity : TTBaseActivity(){
|
||||
// insets
|
||||
// }
|
||||
|
||||
if (!checkPermissions()){
|
||||
if (shouldRequestPermissionsOnCreate && !checkPermissions()){
|
||||
requstPermissions()
|
||||
}
|
||||
|
||||
@@ -202,4 +204,4 @@ open class CKLHBaseActionBarActivity : TTBaseActivity(){
|
||||
// insets
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,8 +28,8 @@ import pub.devrel.easypermissions.EasyPermissions
|
||||
|
||||
open class CKLHBaseActivity : TTBaseActivity(){
|
||||
|
||||
var perms_= listOf<String>(Manifest.permission.CAMERA, Manifest.permission.READ_MEDIA_IMAGES,Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE)
|
||||
var perms_tiramisu = listOf<String>(Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.READ_EXTERNAL_STORAGE)
|
||||
var perms_= listOf<String>(Manifest.permission.CAMERA, Manifest.permission.READ_MEDIA_IMAGES,Manifest.permission.READ_EXTERNAL_STORAGE)
|
||||
var perms_tiramisu = listOf<String>(Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE)
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
// AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
|
||||
|
||||
@@ -74,9 +74,9 @@ open class CKLHBaseActivity : TTBaseActivity(){
|
||||
// getWindow().setStatusBarColor(Color.TRANSPARENT);
|
||||
|
||||
|
||||
if (!checkPermissions()){
|
||||
requstPermissions()
|
||||
}
|
||||
// if (!checkPermissions()){
|
||||
// requstPermissions()
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
@@ -206,4 +206,4 @@ open class CKLHBaseActivity : TTBaseActivity(){
|
||||
MobclickAgent.onPageEnd("view")
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.ck.ckcollar.app.ui.dialog
|
||||
|
||||
import android.content.Context
|
||||
import android.content.res.ColorStateList
|
||||
import android.text.TextUtils
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
@@ -33,8 +34,15 @@ class CKEditPhoneDialog(
|
||||
dialogAlertBinding.title.text = title
|
||||
}
|
||||
dialogAlertBinding.btnSendCode.setOnClickListener { sendCode() }
|
||||
dialogAlertBinding.btnSendCode.setTextColor(
|
||||
ColorStateList(
|
||||
arrayOf(intArrayOf(-android.R.attr.state_enabled), intArrayOf()),
|
||||
intArrayOf(mContext.getColor(R.color.textSecondColor), mContext.getColor(R.color.appStyle))
|
||||
)
|
||||
)
|
||||
dialogAlertBinding.cancelButton.setOnClickListener(object : View.OnClickListener {
|
||||
override fun onClick(v: View?) {
|
||||
dialogAlertBinding.btnSendCode.stopCountDown()
|
||||
cancel()
|
||||
}
|
||||
})
|
||||
@@ -72,7 +80,7 @@ class CKEditPhoneDialog(
|
||||
add(TTRequestData("smsCode",dialogAlertBinding.textCode.text.toString()))
|
||||
},object : ICallback{
|
||||
override fun onSuccess(data: String) {
|
||||
mContext.toast(mContext.getString(R.string.send_success))
|
||||
mContext.toast(mContext.getString(R.string.edit_success))
|
||||
cancel()
|
||||
}
|
||||
|
||||
@@ -94,7 +102,8 @@ class CKEditPhoneDialog(
|
||||
add(TTRequestData("scene","changePhone"))
|
||||
},object : ICallback{
|
||||
override fun onSuccess(data: String) {
|
||||
mContext.toast(mContext.getString(R.string.edit_success))
|
||||
mContext.toast(mContext.getString(R.string.verification_code_sent))
|
||||
dialogAlertBinding.btnSendCode.startCountDown()
|
||||
alertClickListener.onBack(dialogAlertBinding.textPhone.text.toString())
|
||||
|
||||
}
|
||||
@@ -108,4 +117,4 @@ class CKEditPhoneDialog(
|
||||
interface AlertClickListener {
|
||||
fun onBack(text : String)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,6 +35,10 @@ class CKPhotoDialog(
|
||||
}
|
||||
})
|
||||
|
||||
dialogMakePhotoBinding.cancelButton.setOnClickListener {
|
||||
cancel()
|
||||
}
|
||||
|
||||
setContentView(dialogMakePhotoBinding.root,ViewGroup.LayoutParams(TTUtils.width, ViewGroup.LayoutParams.WRAP_CONTENT))
|
||||
|
||||
} catch (e: Exception) {
|
||||
@@ -48,4 +52,4 @@ class CKPhotoDialog(
|
||||
interface PhotoClickListener {
|
||||
fun onBack(mark: Int, position: Int)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,10 +19,13 @@ class CKUpdateAlertDialog(
|
||||
var alertClickListener: AlertClickListener
|
||||
) : TTBaseDialog(mContext){
|
||||
|
||||
private var binding: DialogUpdateAlertBinding? = null
|
||||
|
||||
override fun show() {
|
||||
try {
|
||||
var dialogAlertBinding =
|
||||
val dialogAlertBinding =
|
||||
DialogUpdateAlertBinding.inflate(LayoutInflater.from(mContext))
|
||||
binding = dialogAlertBinding
|
||||
|
||||
dialogAlertBinding.textAlert.text = alertText
|
||||
if (isForce){
|
||||
@@ -39,8 +42,6 @@ class CKUpdateAlertDialog(
|
||||
//dialogView.findViewById(R.id.photo).setVisibility(View.GONE);
|
||||
dialogAlertBinding.btnConfirm.setOnClickListener(object : View.OnClickListener {
|
||||
override fun onClick(v: View?) {
|
||||
// TODO Auto-generated method stub
|
||||
cancel()
|
||||
alertClickListener.onBack(true)
|
||||
}
|
||||
})
|
||||
@@ -55,8 +56,36 @@ class CKUpdateAlertDialog(
|
||||
setCancelable(false)
|
||||
}
|
||||
|
||||
fun showDownloadProgress() {
|
||||
binding?.apply {
|
||||
progressContainer.visibility = View.VISIBLE
|
||||
btnConfirm.visibility = View.GONE
|
||||
btnCenlel.visibility = View.GONE
|
||||
textAlert.visibility = View.GONE
|
||||
title.text = mContext.getString(com.ck.ckcollar.app.R.string.update_downloading, 0)
|
||||
}
|
||||
}
|
||||
|
||||
fun updateProgress(progress: Int) {
|
||||
binding?.apply {
|
||||
updateProgress.progress = progress
|
||||
progressText.text = "$progress%"
|
||||
title.text = mContext.getString(com.ck.ckcollar.app.R.string.update_downloading, progress)
|
||||
}
|
||||
}
|
||||
|
||||
fun showDownloadError() {
|
||||
binding?.apply {
|
||||
progressContainer.visibility = View.GONE
|
||||
btnConfirm.visibility = View.VISIBLE
|
||||
btnCenlel.visibility = if (isForce) View.GONE else View.VISIBLE
|
||||
textAlert.visibility = View.VISIBLE
|
||||
title.text = mContext.getString(com.ck.ckcollar.app.R.string.update_content)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
interface AlertClickListener {
|
||||
fun onBack(isConfirm : Boolean)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,9 @@ object Const {
|
||||
const val LOGIN_NAME = "login_name"
|
||||
const val LOGIN_PWD = "login_pwd"
|
||||
const val TOKEN = "token"
|
||||
const val MEMBER_PRICE = "member_price"
|
||||
const val MEMBER_PRICE_CACHE_TIME = "member_price_cache_time"
|
||||
//微信app-id
|
||||
const val WX_APP_ID = "wx7681e74df7d88ddc"
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
package com.ck.ckcollar.app.utils
|
||||
|
||||
import java.time.DateTimeException
|
||||
import java.time.LocalDate
|
||||
import java.time.format.DateTimeFormatter
|
||||
import java.time.format.ResolverStyle
|
||||
|
||||
/** 校验中国大陆地区的 15 位和 18 位居民身份证号码。 */
|
||||
object IDCardValidate {
|
||||
private val weights = intArrayOf(7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2)
|
||||
private val verifyCodes = charArrayOf('1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2')
|
||||
private val areaCodes = setOf(
|
||||
"11", "12", "13", "14", "15",
|
||||
"21", "22", "23",
|
||||
"31", "32", "33", "34", "35", "36", "37",
|
||||
"41", "42", "43", "44", "45", "46",
|
||||
"50", "51", "52", "53", "54",
|
||||
"61", "62", "63", "64", "65",
|
||||
"71", "81", "82", "91"
|
||||
)
|
||||
private val birthDateFormatter = DateTimeFormatter
|
||||
.ofPattern("uuuuMMdd")
|
||||
.withResolverStyle(ResolverStyle.STRICT)
|
||||
private val earliestBirthDate = LocalDate.of(1900, 1, 1)
|
||||
|
||||
@JvmStatic
|
||||
fun validate_effective(idcardNumber: String?): Boolean = validateEffective(idcardNumber)
|
||||
|
||||
/**
|
||||
* 为兼容 Water 项目而保留,第二个参数不会影响校验结果。
|
||||
*/
|
||||
@JvmStatic
|
||||
@Suppress("UNUSED_PARAMETER")
|
||||
fun validate_effective(idcardNumber: String?, isreturn_AutoCard: Boolean): Boolean =
|
||||
validateEffective(idcardNumber)
|
||||
|
||||
@JvmStatic
|
||||
fun validateEffective(idCardNumber: String?): Boolean {
|
||||
val source = idCardNumber?.trim()?.uppercase() ?: return false
|
||||
val cardNumber = when (source.length) {
|
||||
OLD_CARD_NUMBER_LENGTH -> convertToNewCardNumber(source) ?: return false
|
||||
NEW_CARD_NUMBER_LENGTH -> source
|
||||
else -> return false
|
||||
}
|
||||
|
||||
if (!cardNumber.take(17).all(Char::isDigit)) return false
|
||||
if (cardNumber.last() != 'X' && !cardNumber.last().isDigit()) return false
|
||||
if (cardNumber.substring(0, 2) !in areaCodes) return false
|
||||
if (!hasValidBirthDate(cardNumber.substring(6, 14))) return false
|
||||
return cardNumber.last() == calculateVerifyCode(cardNumber)
|
||||
}
|
||||
|
||||
private fun convertToNewCardNumber(oldCardNumber: String): String? {
|
||||
if (!oldCardNumber.all(Char::isDigit)) return null
|
||||
val firstSeventeen = buildString(17) {
|
||||
append(oldCardNumber, 0, 6)
|
||||
append("19")
|
||||
append(oldCardNumber, 6, oldCardNumber.length)
|
||||
}
|
||||
return firstSeventeen + calculateVerifyCode(firstSeventeen)
|
||||
}
|
||||
|
||||
private fun hasValidBirthDate(value: String): Boolean {
|
||||
val birthDate = try {
|
||||
LocalDate.parse(value, birthDateFormatter)
|
||||
} catch (_: DateTimeException) {
|
||||
return false
|
||||
}
|
||||
return birthDate.isAfter(earliestBirthDate) && birthDate.isBefore(LocalDate.now())
|
||||
}
|
||||
|
||||
private fun calculateVerifyCode(cardNumber: CharSequence): Char {
|
||||
val sum = weights.indices.sumOf { index ->
|
||||
(cardNumber[index] - '0') * weights[index]
|
||||
}
|
||||
return verifyCodes[sum % 11]
|
||||
}
|
||||
|
||||
private const val NEW_CARD_NUMBER_LENGTH = 18
|
||||
private const val OLD_CARD_NUMBER_LENGTH = 15
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package com.ck.ckcollar.app.utils
|
||||
|
||||
import android.content.Context
|
||||
import java.io.File
|
||||
import java.util.Locale
|
||||
import top.zibin.luban.Luban
|
||||
import top.zibin.luban.OnCompressListener
|
||||
|
||||
object LubanCompressUtil {
|
||||
|
||||
private const val DEFAULT_IGNORE_SIZE_KB = 100
|
||||
|
||||
interface CompressCallback {
|
||||
fun success(file: File)
|
||||
|
||||
fun fail(failMsg: String)
|
||||
}
|
||||
|
||||
fun getInstance(): LubanCompressUtil {
|
||||
return this
|
||||
}
|
||||
|
||||
fun getCompressFile(
|
||||
context: Context,
|
||||
oldFile: File,
|
||||
callback: CompressCallback?
|
||||
) {
|
||||
if (!oldFile.exists() || !oldFile.isFile) {
|
||||
callback?.fail("图片文件不存在")
|
||||
return
|
||||
}
|
||||
|
||||
Luban.with(context.applicationContext)
|
||||
.load(oldFile)
|
||||
.ignoreBy(DEFAULT_IGNORE_SIZE_KB)
|
||||
.filter { path ->
|
||||
path.isNotBlank() && !path.lowercase(Locale.ROOT).endsWith(".gif")
|
||||
}
|
||||
.setCompressListener(object : OnCompressListener {
|
||||
override fun onStart() {
|
||||
}
|
||||
|
||||
override fun onSuccess(file: File) {
|
||||
callback?.success(file)
|
||||
}
|
||||
|
||||
override fun onError(error: Throwable) {
|
||||
callback?.fail(error.message ?: "图片压缩失败")
|
||||
}
|
||||
})
|
||||
.launch()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package com.ck.ckcollar.app.utils
|
||||
|
||||
import android.content.Context
|
||||
import com.cyclone.shadowsocks.utils.PreferencesUtils
|
||||
|
||||
object MemberPriceCache {
|
||||
|
||||
private const val CACHE_VALID_DURATION = 24 * 60 * 60 * 1000L
|
||||
|
||||
fun getPrice(context: Context): Double? {
|
||||
return PreferencesUtils.getString(context, Const.MEMBER_PRICE, "")
|
||||
.toString()
|
||||
.toDoubleOrNull()
|
||||
}
|
||||
|
||||
fun isExpired(context: Context): Boolean {
|
||||
val cacheTime = PreferencesUtils.getString(context, Const.MEMBER_PRICE_CACHE_TIME, "0")
|
||||
.toString()
|
||||
.toLongOrNull() ?: 0L
|
||||
return System.currentTimeMillis() - cacheTime >= CACHE_VALID_DURATION
|
||||
}
|
||||
|
||||
fun save(context: Context, price: Double) {
|
||||
PreferencesUtils.putString(context, Const.MEMBER_PRICE, price.toString())
|
||||
PreferencesUtils.putString(
|
||||
context,
|
||||
Const.MEMBER_PRICE_CACHE_TIME,
|
||||
System.currentTimeMillis().toString()
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -2,4 +2,8 @@ package com.ck.ckcollar.app.utils.networkone
|
||||
interface ICallback {
|
||||
fun onSuccess(data: String)
|
||||
fun onFailed(code: String, msg: String)
|
||||
fun onFailed(code: String, msg: String, data: String) {
|
||||
onFailed(code, msg)
|
||||
}
|
||||
fun onComplete() {}
|
||||
}
|
||||
|
||||
@@ -78,7 +78,9 @@ object TTHttpClient {
|
||||
val string = response.body?.string()
|
||||
string?.let { TTLog.e("response", actionCode + "====" + it) }
|
||||
var model = JSONObject(string)
|
||||
if (isSusscee(model)) {
|
||||
// A withdrawal code of 201 means the transfer bill was created
|
||||
// and the client must continue with WeChat confirmation.
|
||||
if (isSusscee(model) || (actionCode == "提现" && getCode(model) == "201")) {
|
||||
activity.runOnUiThread {
|
||||
activity.hiddenProgeassDialog()
|
||||
iCallback.onSuccess(getData(model))
|
||||
@@ -137,7 +139,10 @@ object TTHttpClient {
|
||||
val string = response.body?.string()
|
||||
string?.let { TTLog.e("response", actionCode + "====" + it) }
|
||||
var model = JSONObject(string)
|
||||
if (isSusscee(model)) {
|
||||
// code 201 means the withdrawal bill was created and the
|
||||
// client must continue with WeChat confirmation. Keep the
|
||||
// response data available to the withdrawal screen.
|
||||
if (isSusscee(model) || (actionCode == "提现" && getCode(model) == "201")) {
|
||||
activity.runOnUiThread {
|
||||
activity.hiddenProgeassDialog()
|
||||
iCallback.onSuccess(getData(model))
|
||||
@@ -429,10 +434,12 @@ object TTHttpClient {
|
||||
}
|
||||
|
||||
withContext(Dispatchers.Main) {
|
||||
iCallback.onFailed("500", "网络连接失败,请检查网络")
|
||||
iCallback.onComplete()
|
||||
}
|
||||
}catch (e: Exception){
|
||||
|
||||
withContext(Dispatchers.Main) {
|
||||
iCallback.onFailed("500", e.message.orEmpty())
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -484,7 +491,7 @@ fun postJson(
|
||||
} else {
|
||||
activity.runOnUiThread {
|
||||
activity.hiddenProgeassDialog()
|
||||
iCallback.onFailed(getCode(model), getMessage(model))
|
||||
iCallback.onFailed(getCode(model), getMessage(model), model.toString())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -988,4 +995,4 @@ private fun getMessage(data: JSONObject): String {
|
||||
return ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.ck.ckcollar.app.utils.networkone.interceptor
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import com.ck.ckcollar.app.CKApp
|
||||
import com.ck.ckcollar.app.ui.act.login.LoginActivity
|
||||
import com.google.gson.Gson
|
||||
import com.tt.kit.networktwo.model.TTResposeData
|
||||
@@ -22,6 +23,7 @@ class ResponseInterceptor(val context : Context) : Interceptor{
|
||||
TTLog.i("ResponseInterceptor", "intercept model:" + body)
|
||||
// token失效,统一处理
|
||||
if (model.code == 401){
|
||||
CKApp.app.clearLoginState()
|
||||
var intent = Intent(context, LoginActivity::class.java)
|
||||
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
|
||||
context.startActivity(intent)
|
||||
@@ -49,4 +51,4 @@ class ResponseInterceptor(val context : Context) : Interceptor{
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,24 +3,63 @@ package com.ck.ckcollar.app.widget
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.view.MotionEvent
|
||||
import androidx.appcompat.widget.AppCompatImageView
|
||||
import androidx.viewpager.widget.ViewPager
|
||||
|
||||
class CKViewPager : ViewPager{
|
||||
|
||||
private var isMultiTouchGesture = false
|
||||
|
||||
constructor(context: Context) : super(context)
|
||||
|
||||
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
|
||||
|
||||
override fun dispatchTouchEvent(ev: MotionEvent): Boolean {
|
||||
when (ev.actionMasked) {
|
||||
MotionEvent.ACTION_DOWN -> isMultiTouchGesture = false
|
||||
MotionEvent.ACTION_POINTER_DOWN -> {
|
||||
if (ev.pointerCount > 1) {
|
||||
isMultiTouchGesture = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return try {
|
||||
super.dispatchTouchEvent(ev)
|
||||
} finally {
|
||||
// dispatchTouchEvent always sees the terminal event, even when
|
||||
// PhotoView has disabled parent interception during scaling.
|
||||
if (ev.actionMasked == MotionEvent.ACTION_UP ||
|
||||
ev.actionMasked == MotionEvent.ACTION_CANCEL
|
||||
) {
|
||||
isMultiTouchGesture = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onInterceptTouchEvent(ev: MotionEvent?): Boolean {
|
||||
if (ev == null) return false
|
||||
|
||||
// Keep the complete pinch sequence in PhotoView. If ViewPager intercepts
|
||||
// one MOVE event, the child receives CANCEL and scaling stops entirely.
|
||||
if (isMultiTouchGesture || ev.pointerCount > 1) {
|
||||
return false
|
||||
}
|
||||
|
||||
try {
|
||||
return super.onInterceptTouchEvent(ev)
|
||||
|
||||
}catch (e : Exception){
|
||||
} catch (e: IllegalArgumentException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
return false
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
override fun onTouchEvent(ev: MotionEvent?): Boolean {
|
||||
if (ev == null) return false
|
||||
return try {
|
||||
super.onTouchEvent(ev)
|
||||
} catch (e: IllegalArgumentException) {
|
||||
e.printStackTrace()
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import android.app.Activity
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import com.ck.ckcollar.app.CKApp
|
||||
import com.ck.ckcollar.app.ui.act.balance.WithDrawActivity
|
||||
import com.ck.ckcollar.app.ui.act.login.LoginActivity
|
||||
import com.ck.ckcollar.app.ui.act.user.UserInfoActivity
|
||||
import com.ck.ckcollar.app.utils.Const
|
||||
@@ -15,6 +16,7 @@ import com.tencent.mm.opensdk.openapi.IWXAPI
|
||||
import com.tencent.mm.opensdk.openapi.IWXAPIEventHandler
|
||||
import com.tencent.mm.opensdk.openapi.WXAPIFactory
|
||||
import com.tt.kit.utils.TTLog
|
||||
import com.tt.kit.utils.LiveDataBus
|
||||
|
||||
|
||||
class WXEntryActivity : Activity(), IWXAPIEventHandler {
|
||||
@@ -43,6 +45,13 @@ class WXEntryActivity : Activity(), IWXAPIEventHandler {
|
||||
}
|
||||
|
||||
override fun onResp(resp: BaseResp?) {
|
||||
if (resp?.type == ConstantsAPI.COMMAND_OPEN_BUSINESS_VIEW) {
|
||||
LiveDataBus.get()
|
||||
.with(WithDrawActivity.WX_WITHDRAW_RESULT)
|
||||
.value = resp.errCode
|
||||
finish()
|
||||
return
|
||||
}
|
||||
if (resp!!.getType() === ConstantsAPI.COMMAND_SENDAUTH) {
|
||||
val authResp = resp as SendAuth.Resp
|
||||
val code = authResp.code
|
||||
@@ -59,4 +68,4 @@ class WXEntryActivity : Activity(), IWXAPIEventHandler {
|
||||
}
|
||||
finish()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
package com.ck.ckcollar.app.wxapi
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.widget.Toast
|
||||
import com.ck.ckcollar.app.ui.act.balance.RechargeActivity
|
||||
import com.ck.ckcollar.app.utils.Const
|
||||
import com.tencent.mm.opensdk.modelbase.BaseReq
|
||||
import com.tencent.mm.opensdk.modelbase.BaseResp
|
||||
import com.tencent.mm.opensdk.constants.ConstantsAPI
|
||||
import com.ck.ckcollar.app.ui.act.balance.WithDrawActivity
|
||||
import com.tencent.mm.opensdk.openapi.IWXAPI
|
||||
import com.tencent.mm.opensdk.openapi.IWXAPIEventHandler
|
||||
import com.tencent.mm.opensdk.openapi.WXAPIFactory
|
||||
import com.tt.kit.utils.LiveDataBus
|
||||
|
||||
class WXPayEntryActivity : Activity(), IWXAPIEventHandler {
|
||||
private lateinit var api: IWXAPI
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
api = WXAPIFactory.createWXAPI(this, Const.WX_APP_ID, false)
|
||||
api.handleIntent(intent, this)
|
||||
}
|
||||
|
||||
override fun onNewIntent(intent: Intent?) {
|
||||
super.onNewIntent(intent)
|
||||
setIntent(intent)
|
||||
api.handleIntent(intent, this)
|
||||
}
|
||||
|
||||
override fun onReq(req: BaseReq?) = Unit
|
||||
|
||||
override fun onResp(resp: BaseResp?) {
|
||||
val resultCode = resp?.errCode ?: -1
|
||||
if (resp?.type == ConstantsAPI.COMMAND_OPEN_BUSINESS_VIEW) {
|
||||
LiveDataBus.get().with(WithDrawActivity.WX_WITHDRAW_RESULT).value = resultCode
|
||||
finish()
|
||||
return
|
||||
}
|
||||
val message = when (resultCode) {
|
||||
BaseResp.ErrCode.ERR_OK -> "微信支付成功"
|
||||
BaseResp.ErrCode.ERR_USER_CANCEL -> "已取消微信支付"
|
||||
else -> "微信支付失败"
|
||||
}
|
||||
Toast.makeText(this, message, Toast.LENGTH_SHORT).show()
|
||||
LiveDataBus.get().with(RechargeActivity.WX_PAY_RESULT).value = resultCode
|
||||
finish()
|
||||
}
|
||||
}
|
||||
@@ -88,6 +88,7 @@
|
||||
android:textColorHint="@color/textSecondColor"
|
||||
android:maxLength="11"
|
||||
android:maxLines="1"
|
||||
android:singleLine="true"
|
||||
android:inputType="number"
|
||||
android:textSize="14sp"></com.ck.ckcollar.app.widget.CKEditView>
|
||||
|
||||
@@ -165,7 +166,8 @@
|
||||
android:textColorHint="@color/textSecondColor"
|
||||
android:maxLength="50"
|
||||
android:maxLines="3"
|
||||
android:textSize="14sp"></com.ck.ckcollar.app.widget.CKEditView>
|
||||
android:textSize="14sp"
|
||||
android:singleLine="true"></com.ck.ckcollar.app.widget.CKEditView>
|
||||
|
||||
</com.ck.ckcollar.app.widget.CKLinearLayout>
|
||||
|
||||
|
||||
@@ -102,7 +102,7 @@
|
||||
android:text="@string/no_reason_text"
|
||||
android:background="@drawable/bg_cz_button"
|
||||
android:paddingHorizontal="5dp"
|
||||
></com.ck.ckcollar.app.widget.CKTextView>
|
||||
android:visibility="gone"/>
|
||||
</com.ck.ckcollar.app.widget.CKLinearLayout>
|
||||
|
||||
<com.ck.ckcollar.app.widget.CKLinearLayout
|
||||
|
||||
@@ -35,8 +35,8 @@
|
||||
<com.ck.ckcollar.app.widget.CKTextView
|
||||
android:id="@+id/textBalance"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="0.00"
|
||||
android:layout_height="50dp"
|
||||
android:gravity="center_vertical"
|
||||
android:textColor="@color/textColor"
|
||||
android:textSize="38sp"
|
||||
android:textStyle="bold"
|
||||
@@ -198,4 +198,4 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"></androidx.recyclerview.widget.RecyclerView>
|
||||
</com.ck.ckcollar.app.widget.CKLinearLayout>
|
||||
</com.ck.ckcollar.app.widget.CKLinearLayout>
|
||||
</com.ck.ckcollar.app.widget.CKLinearLayout>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<com.ck.ckcollar.app.widget.CKLinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
@@ -7,12 +8,12 @@
|
||||
android:background="@color/backgroundColor"
|
||||
>
|
||||
<include layout="@layout/action_bar"></include>
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/recyclerView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
></androidx.recyclerview.widget.RecyclerView>
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/recyclerView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
></androidx.recyclerview.widget.RecyclerView>
|
||||
|
||||
<com.ck.ckcollar.app.widget.CKLinearLayout
|
||||
android:layout_width="match_parent"
|
||||
@@ -20,7 +21,6 @@
|
||||
android:orientation="horizontal"
|
||||
android:background="@color/white"
|
||||
android:gravity="center_vertical"
|
||||
android:paddingHorizontal="20dp"
|
||||
>
|
||||
<com.ck.ckcollar.app.widget.CKImageView
|
||||
android:id="@+id/btnKeyboard"
|
||||
@@ -30,39 +30,89 @@
|
||||
android:visibility="gone"
|
||||
></com.ck.ckcollar.app.widget.CKImageView>
|
||||
|
||||
<com.ck.ckcollar.app.widget.CKEditView
|
||||
android:id="@+id/editMessage"
|
||||
android:layout_width="match_parent"
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:minHeight="34dp"
|
||||
android:layout_weight="1"
|
||||
android:textColor="@color/textColor"
|
||||
android:textSize="14sp"
|
||||
android:textColorHint="@color/textColor"
|
||||
android:hint="@string/please_input_message"
|
||||
android:paddingHorizontal="16dp"
|
||||
android:paddingVertical="5dp"
|
||||
android:layout_marginVertical="10dp"
|
||||
android:layout_marginHorizontal="12dp"
|
||||
android:background="@drawable/bg_input_message"
|
||||
android:imeOptions="actionSend"
|
||||
android:inputType="text"
|
||||
android:maxLength="100"
|
||||
></com.ck.ckcollar.app.widget.CKEditView>
|
||||
<com.ck.ckcollar.app.widget.CKImageView
|
||||
android:id="@+id/btnSmile"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:src="@mipmap/image_smile"
|
||||
></com.ck.ckcollar.app.widget.CKImageView>
|
||||
android:orientation="vertical">
|
||||
|
||||
<com.ck.ckcollar.app.widget.CKImageView
|
||||
android:id="@+id/btnMore"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:src="@mipmap/image_more"
|
||||
android:layout_marginLeft="12dp"
|
||||
></com.ck.ckcollar.app.widget.CKImageView>
|
||||
<FrameLayout
|
||||
android:id="@+id/contentImagePreview"
|
||||
android:layout_width="80dp"
|
||||
android:layout_height="80dp"
|
||||
android:layout_marginStart="12dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:visibility="gone">
|
||||
|
||||
<com.ck.ckcollar.app.widget.CKRoundImageView
|
||||
android:id="@+id/imagePreview"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:scaleType="centerCrop"
|
||||
app:roundRadius="6dp" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/btnDeleteImage"
|
||||
android:layout_width="18dp"
|
||||
android:layout_height="18dp"
|
||||
android:layout_gravity="end|top"
|
||||
android:layout_margin="4dp"
|
||||
android:contentDescription="@null"
|
||||
android:src="@mipmap/icon_img_del_red" />
|
||||
</FrameLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical">
|
||||
|
||||
<com.ck.ckcollar.app.widget.CKEditView
|
||||
android:id="@+id/editMessage"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:minHeight="34dp"
|
||||
android:textColor="@color/textColor"
|
||||
android:textSize="14sp"
|
||||
android:textColorHint="@color/textColor"
|
||||
android:hint="@string/please_input_message"
|
||||
android:paddingHorizontal="16dp"
|
||||
android:paddingVertical="8dp"
|
||||
android:layout_marginVertical="10dp"
|
||||
android:layout_marginHorizontal="12dp"
|
||||
android:background="@drawable/bg_input_message"
|
||||
android:imeOptions="actionSend"
|
||||
android:inputType="text"
|
||||
android:maxHeight="70dp"
|
||||
android:maxLines="4"
|
||||
android:scrollbars="vertical"
|
||||
android:maxLength="100" />
|
||||
<com.ck.ckcollar.app.widget.CKImageView
|
||||
android:id="@+id/btnSmile"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:src="@mipmap/image_smile"
|
||||
android:visibility="gone"/>
|
||||
|
||||
<com.ck.ckcollar.app.widget.CKImageView
|
||||
android:id="@+id/btnMore"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:src="@mipmap/image_more"
|
||||
android:layout_marginLeft="12dp"
|
||||
android:layout_marginRight="15dp"/>
|
||||
|
||||
<com.ck.ckcollar.app.widget.CKImageView
|
||||
android:id="@+id/btnSend"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:src="@mipmap/icon_send_yellow"
|
||||
android:layout_marginLeft="12dp"
|
||||
android:layout_marginRight="15dp"
|
||||
android:visibility="gone"/>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</com.ck.ckcollar.app.widget.CKLinearLayout>
|
||||
|
||||
<com.ck.ckcollar.app.widget.CKLinearLayout
|
||||
@@ -125,4 +175,4 @@
|
||||
</com.ck.ckcollar.app.widget.CKLinearLayout>
|
||||
|
||||
</com.ck.ckcollar.app.widget.CKLinearLayout>
|
||||
</com.ck.ckcollar.app.widget.CKLinearLayout>
|
||||
</com.ck.ckcollar.app.widget.CKLinearLayout>
|
||||
|
||||
@@ -165,6 +165,16 @@
|
||||
android:background="@drawable/bg_login_button"
|
||||
></com.ck.ckcollar.app.widget.CKButton>
|
||||
|
||||
<com.ck.ckcollar.app.widget.CKButton
|
||||
android:id="@+id/btnQuickLogin"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="40dp"
|
||||
android:layout_marginTop="10dp"
|
||||
android:background="@drawable/bg_login_button"
|
||||
android:text="临时快捷登录"
|
||||
android:textColor="@color/buttonTextColor"
|
||||
android:visibility="gone"/>
|
||||
|
||||
<com.ck.ckcollar.app.widget.CKLinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="30dp"
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
|
||||
<com.ck.ckcollar.app.widget.CKLinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="52dp"
|
||||
android:layout_height="60dp"
|
||||
android:background="?attr/mainBackground"
|
||||
android:orientation="horizontal"
|
||||
>
|
||||
|
||||
@@ -33,16 +33,21 @@
|
||||
android:orientation="vertical"
|
||||
>
|
||||
<com.ck.ckcollar.app.widget.CKLinearLayout
|
||||
android:id="@+id/priceContent"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
android:layout_height="58dp"
|
||||
android:baselineAligned="true"
|
||||
android:baselineAlignedChildIndex="1"
|
||||
android:gravity="bottom"
|
||||
android:orientation="horizontal"
|
||||
android:visibility="invisible">
|
||||
|
||||
<com.ck.ckcollar.app.widget.CKTextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="¥"
|
||||
android:textColor="@color/color_7B4B12"
|
||||
android:textSize="22sp"></com.ck.ckcollar.app.widget.CKTextView>
|
||||
android:textSize="22sp"/>
|
||||
|
||||
<com.ck.ckcollar.app.widget.CKTextView
|
||||
android:id="@+id/textMoney"
|
||||
@@ -51,14 +56,15 @@
|
||||
android:text=""
|
||||
android:textColor="@color/color_7B4B12"
|
||||
android:textSize="48sp"
|
||||
android:textStyle="bold"></com.ck.ckcollar.app.widget.CKTextView>
|
||||
android:textStyle="bold"/>
|
||||
|
||||
<com.ck.ckcollar.app.widget.CKTextView
|
||||
android:id="@+id/tv_month"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="/月"
|
||||
android:textColor="@color/color_7B4B12"
|
||||
android:textSize="22sp"></com.ck.ckcollar.app.widget.CKTextView>
|
||||
android:textSize="22sp"/>
|
||||
</com.ck.ckcollar.app.widget.CKLinearLayout>
|
||||
|
||||
|
||||
@@ -71,7 +77,7 @@
|
||||
android:gravity="center"
|
||||
android:text="@string/pet_member_open_now"
|
||||
android:textColor="@color/color_CACACA"
|
||||
android:textSize="16sp"></com.ck.ckcollar.app.widget.CKTextView>
|
||||
android:textSize="16sp"/>
|
||||
</com.ck.ckcollar.app.widget.CKLinearLayout>
|
||||
|
||||
<com.ck.ckcollar.app.widget.CKLinearLayout
|
||||
@@ -93,7 +99,7 @@
|
||||
android:textColor="@color/color_7B4B12"
|
||||
android:textSize="22sp"
|
||||
android:textStyle="bold"
|
||||
></com.ck.ckcollar.app.widget.CKTextView>
|
||||
/>
|
||||
|
||||
<com.ck.ckcollar.app.widget.CKTextView
|
||||
android:id="@+id/textMemberDate"
|
||||
@@ -101,7 +107,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/deadline_date"
|
||||
android:textColor="@color/color_7B4B12"
|
||||
android:textSize="16sp"></com.ck.ckcollar.app.widget.CKTextView>
|
||||
android:textSize="16sp"/>
|
||||
</com.ck.ckcollar.app.widget.CKLinearLayout>
|
||||
|
||||
|
||||
@@ -260,13 +266,13 @@
|
||||
android:id="@+id/textNode"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="16sp"
|
||||
android:textSize="14sp"
|
||||
android:textColor="@color/color_CACACA"
|
||||
android:text=""
|
||||
android:text="商城商品享受折扣,开通会员赠送积分"
|
||||
android:layout_marginTop="20dp"
|
||||
></com.ck.ckcollar.app.widget.CKTextView>
|
||||
|
||||
</com.ck.ckcollar.app.widget.CKLinearLayout>
|
||||
</com.ck.ckcollar.app.widget.CKLinearLayout>
|
||||
|
||||
</com.ck.ckcollar.app.widget.CKLinearLayout>
|
||||
</com.ck.ckcollar.app.widget.CKLinearLayout>
|
||||
|
||||
@@ -80,18 +80,34 @@
|
||||
android:layout_height="match_parent">
|
||||
<com.scwang.smartrefresh.layout.header.ClassicsHeader
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"></com.scwang.smartrefresh.layout.header.ClassicsHeader>
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/recyclerView"
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingHorizontal="20dp"
|
||||
android:layout_marginVertical="12dp"
|
||||
></androidx.recyclerview.widget.RecyclerView>
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/recyclerView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingHorizontal="20dp"
|
||||
android:layout_marginVertical="12dp" />
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/rel_noresult"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:visibility="gone">
|
||||
|
||||
<include
|
||||
android:id="@+id/include_noresult"
|
||||
layout="@layout/include_no_result_layout" />
|
||||
</RelativeLayout>
|
||||
</FrameLayout>
|
||||
|
||||
<com.scwang.smartrefresh.layout.footer.ClassicsFooter
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"></com.scwang.smartrefresh.layout.footer.ClassicsFooter>
|
||||
android:layout_height="wrap_content"/>
|
||||
</com.scwang.smartrefresh.layout.SmartRefreshLayout>
|
||||
|
||||
</com.ck.ckcollar.app.widget.CKLinearLayout>
|
||||
</com.ck.ckcollar.app.widget.CKLinearLayout>
|
||||
|
||||
@@ -49,38 +49,6 @@
|
||||
android:layout_marginBottom="10dp"
|
||||
></com.ck.ckcollar.app.widget.CKTextView>
|
||||
|
||||
<com.ck.ckcollar.app.widget.CKLinearLayout
|
||||
android:id="@+id/btnAli"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="50dp"
|
||||
android:orientation="horizontal"
|
||||
android:paddingHorizontal="20dp"
|
||||
android:background="@drawable/bg_view_gray_radius_12_stroke_1"
|
||||
android:gravity="center_vertical"
|
||||
>
|
||||
|
||||
<com.ck.ckcollar.app.widget.CKImageView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:src="@mipmap/image_ali"
|
||||
></com.ck.ckcollar.app.widget.CKImageView>
|
||||
|
||||
<com.ck.ckcollar.app.widget.CKTextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:textSize="14sp"
|
||||
android:textColor="@color/textColor"
|
||||
android:text="@string/alipay"
|
||||
android:paddingLeft="8dp"
|
||||
></com.ck.ckcollar.app.widget.CKTextView>
|
||||
<com.ck.ckcollar.app.widget.CKImageView
|
||||
android:id="@+id/image1"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:src="@mipmap/image_address_check_select"
|
||||
></com.ck.ckcollar.app.widget.CKImageView>
|
||||
</com.ck.ckcollar.app.widget.CKLinearLayout>
|
||||
|
||||
<com.ck.ckcollar.app.widget.CKLinearLayout
|
||||
android:id="@+id/btnWX"
|
||||
@@ -91,7 +59,7 @@
|
||||
android:background="@drawable/bg_view_gray_radius_12_stroke_1"
|
||||
android:gravity="center_vertical"
|
||||
android:layout_marginTop="10dp"
|
||||
android:visibility="gone"
|
||||
android:visibility="visible"
|
||||
>
|
||||
|
||||
<com.ck.ckcollar.app.widget.CKImageView
|
||||
@@ -113,10 +81,46 @@
|
||||
android:id="@+id/image2"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:src="@mipmap/image_address_check_select"
|
||||
></com.ck.ckcollar.app.widget.CKImageView>
|
||||
</com.ck.ckcollar.app.widget.CKLinearLayout>
|
||||
|
||||
|
||||
<com.ck.ckcollar.app.widget.CKLinearLayout
|
||||
android:id="@+id/btnAli"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="50dp"
|
||||
android:orientation="horizontal"
|
||||
android:paddingHorizontal="20dp"
|
||||
android:background="@drawable/bg_view_gray_radius_12_stroke_1"
|
||||
android:gravity="center_vertical"
|
||||
android:layout_marginTop="10dp">
|
||||
|
||||
<com.ck.ckcollar.app.widget.CKImageView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:src="@mipmap/image_ali"
|
||||
></com.ck.ckcollar.app.widget.CKImageView>
|
||||
|
||||
<com.ck.ckcollar.app.widget.CKTextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:textSize="14sp"
|
||||
android:textColor="@color/textColor"
|
||||
android:text="@string/alipay"
|
||||
android:paddingLeft="8dp"
|
||||
></com.ck.ckcollar.app.widget.CKTextView>
|
||||
<com.ck.ckcollar.app.widget.CKImageView
|
||||
android:id="@+id/image1"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:src="@mipmap/image_address_check_narmal"
|
||||
></com.ck.ckcollar.app.widget.CKImageView>
|
||||
</com.ck.ckcollar.app.widget.CKLinearLayout>
|
||||
|
||||
|
||||
|
||||
<com.ck.ckcollar.app.widget.CKLinearLayout
|
||||
android:id="@+id/btnBalance"
|
||||
android:layout_width="match_parent"
|
||||
|
||||
@@ -263,7 +263,7 @@
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
android:layout_marginTop="10dp"
|
||||
android:visibility="gone"
|
||||
android:visibility="visible"
|
||||
>
|
||||
|
||||
<com.ck.ckcollar.app.widget.CKImageView
|
||||
@@ -295,7 +295,6 @@
|
||||
android:layout_height="50dp"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
android:layout_marginTop="10dp"
|
||||
>
|
||||
|
||||
<com.ck.ckcollar.app.widget.CKImageView
|
||||
@@ -317,7 +316,7 @@
|
||||
android:id="@+id/image1"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:src="@mipmap/image_address_check_select"
|
||||
android:src="@mipmap/image_address_check_narmal"
|
||||
></com.ck.ckcollar.app.widget.CKImageView>
|
||||
</com.ck.ckcollar.app.widget.CKLinearLayout>
|
||||
|
||||
|
||||
@@ -232,7 +232,7 @@
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
android:layout_marginTop="10dp"
|
||||
android:visibility="gone"
|
||||
android:visibility="visible"
|
||||
>
|
||||
|
||||
<com.ck.ckcollar.app.widget.CKImageView
|
||||
@@ -264,7 +264,6 @@
|
||||
android:layout_height="50dp"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
android:layout_marginTop="10dp"
|
||||
>
|
||||
|
||||
<com.ck.ckcollar.app.widget.CKImageView
|
||||
@@ -286,7 +285,7 @@
|
||||
android:id="@+id/image1"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:src="@mipmap/image_address_check_select"
|
||||
android:src="@mipmap/image_address_check_narmal"
|
||||
></com.ck.ckcollar.app.widget.CKImageView>
|
||||
</com.ck.ckcollar.app.widget.CKLinearLayout>
|
||||
|
||||
|
||||
@@ -14,12 +14,27 @@
|
||||
android:padding="20dp"
|
||||
>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/recyclerView"
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
></androidx.recyclerview.widget.RecyclerView>
|
||||
android:layout_weight="1">
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/recyclerView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/rel_noresult"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:visibility="gone">
|
||||
|
||||
<include
|
||||
android:id="@+id/include_noresult"
|
||||
layout="@layout/include_no_result_layout" />
|
||||
</RelativeLayout>
|
||||
</FrameLayout>
|
||||
|
||||
|
||||
<com.ck.ckcollar.app.widget.CKButton
|
||||
@@ -35,4 +50,4 @@
|
||||
</com.ck.ckcollar.app.widget.CKLinearLayout>
|
||||
|
||||
|
||||
</com.ck.ckcollar.app.widget.CKLinearLayout>
|
||||
</com.ck.ckcollar.app.widget.CKLinearLayout>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user