添加项目

This commit is contained in:
zhanglei
2025-06-30 14:12:14 +08:00
commit 8a60755b60
2374 changed files with 198527 additions and 0 deletions
+26
View File
@@ -0,0 +1,26 @@
*.iml
.gradle
/local.properties
/.idea/caches
/.idea/libraries
/.idea/modules.xml
/.idea/workspace.xml
/.idea/navEditor.xml
/.idea/*
/.idea/assetWizardSettings.xml
.DS_Store
/build
/system/**/build/
/captures
.externalNativeBuild
.cxx
local.properties
/system/video/build/
/system/tuigroup/build/
/system/tuicore/build/
/system/tuiconversation/build/
/system/tuicontact/build/
/system/tuichat/build/
/system/tuicallkit/build/
*.apk
app/debug/
+10
View File
@@ -0,0 +1,10 @@
# 专家端专家端安卓原生
#### 介绍
专家端专家端
#### 软件架构
软件架构说明
使用MVVM架构
+18
View File
@@ -0,0 +1,18 @@
*.iml
.gradle
/local.properties
/.idea/caches
/.idea/libraries
/.idea/modules.xml
/.idea/workspace.xml
/.idea/navEditor.xml
/.idea/assetWizardSettings.xml
.DS_Store
/build
/captures
.externalNativeBuild
.cxx
local.properties
.idea/
.idea/gradle.xml
.idea/misc.xml
+133
View File
@@ -0,0 +1,133 @@
plugins {
id 'com.android.application'
id 'kotlin-android'
// id 'kotlin-android-extensions'
id 'kotlin-kapt'
id 'org.jetbrains.kotlin.android'
id 'kotlin-parcelize'
// id 'com.huawei.agconnect'
}
android {
compileSdk rootProject.ext.compileSdkVersion
defaultConfig {
applicationId "com.yxjk.healthexpertclient"
minSdk rootProject.ext.minSdkVersion
targetSdk rootProject.ext.targetSdkVersion
versionCode rootProject.ext.versionCode
versionName rootProject.ext.versionName
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
ndk {
// 选择实际需要的cpu架构
abiFilters 'armeabi-v7a', 'arm64-v8a'//, 'x86', 'x86_64'
}
// manifestPlaceholders = [
// JPUSH_PKGNAME : applicationId,
// JPUSH_APPKEY : "4480cf772398ae1b775c91aa", //JPush 上注册的包名对应的 Appkey.
// JPUSH_CHANNEL : "developer-default", //暂时填写默认值即可.
// MEIZU_APPKEY : "MZ-魅族的APPKEY",
// MEIZU_APPID : "MZ-魅族的APPID",
// XIAOMI_APPID : "MI-小米的APPID",
// XIAOMI_APPKEY : "MI-小米的APPKEY",
// OPPO_APPKEY : "OP-oppo的APPKEY",
// OPPO_APPID : "OP-oppo的APPID",
// OPPO_APPSECRET : "OP-oppo的APPSECRET",
// VIVO_APPKEY : "vivo的APPKEY",
// VIVO_APPID : "vivo的APPID",
// HONOR_APPID : "Honor的APP ID"
// ]
}
signingConfigs{
release {
storeFile file('/key/yxjkExpert.jks')
storePassword "yxjk1234"
keyAlias "yxjk"
keyPassword "yxjk1234"
//SHA1: 48:30:3D:D2:C1:6E:E7:D5:CC:1C:24:A4:64:F5:04:19:2E:9D:F3:98
}
}
buildTypes {
debug {
signingConfig signingConfigs.release
minifyEnabled false // 开启混淆
shrinkResources false // 启动资源压缩
zipAlignEnabled true // 开启zipalign优化
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
release {
signingConfig signingConfigs.release
minifyEnabled false
shrinkResources false // 启动资源压缩
zipAlignEnabled true // 开启zipalign优化
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_11
targetCompatibility JavaVersion.VERSION_11
}
kotlinOptions {
jvmTarget = '1.8'
}
packagingOptions {
exclude 'META-INF/gradle/incremental.annotation.processors'
exclude 'DebugProbesKt.bin'
}
dataBinding {
enabled = true
}
kapt {
generateStubs = true
}
sourceSets {
main {
jniLibs.srcDirs = ['libs']
res.srcDirs = [
'src/main/res-login',
'src/main/res-workbench',
'src/main/res-mine',
'src/main/res-other',
'src/main/res-im',
'src/main/res'
]
}
}
}
dependencies {
implementation project(path: ':lib_base')
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
implementation rootProject.ext.androidxLibs
// ViewModel and LiveData
implementation rootProject.ext.jetpackLibs
/* annotationProcessor */
kapt rootProject.ext.annotationProcessorLibs
/*网络请求相关*/
implementation rootProject.ext.networkLibs
/*Glide*/
implementation rootProject.ext.glideLibs
/*AgentWeb*/
implementation rootProject.ext.agentWebLibs
/*高德地图*/
implementation rootProject.ext.mapLibs
/*极光推送*/
// implementation rootProject.ext.jPushLibs
// 其他包
implementation rootProject.ext.commonLibs
// implementation project(path: ':systemLib')
implementation project(path: ':system:base_resource')
implementation project(path: ':system:video')
implementation project(path: ':ninegridview')
api project(':system:tuichat')
api project(':system:tuicontact')
api project(':system:tuiconversation')
api project(':system:tuigroup')
api project(':system:tuicallkit')
// api project(':system:tuicallkit-7.3.4358')
}
Binary file not shown.
+229
View File
@@ -0,0 +1,229 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
# 指定代码的压缩级别
-optimizationpasses 5
# 不忽略库中的非public的类成员
-dontskipnonpubliclibraryclassmembers
# google推荐算法
-optimizations !code/simplification/arithmetic,!code/simplification/cast,!field/*,!class/merging/*
# 避免混淆内部类、匿名类
-keepattributes InnerClasses,EnclosingMethod
# 抛出异常时保留代码行号
-keepattributes SourceFile,LineNumberTable
-verbose
-printmapping proguardMapping.txt
################support###############
-keep class android.support.** { *; }
-keep interface android.support.** { *; }
-dontwarn android.support.**
# Androidx的混淆
-keep class com.google.android.material.** {*;}
-keep class androidx.** {*;}
-keep public class * extends androidx.**
-keep interface androidx.** {*;}
-dontwarn com.google.android.material.**
-dontnote com.google.android.material.**
-dontwarn androidx.**
#kotlin
-keep class kotlin.** { *; }
-keep class kotlin.Metadata { *; }
-dontwarn kotlin.**
-keepclassmembers class **$WhenMappings {
<fields>;
}
-keepclassmembers class kotlin.Metadata {
public <methods>;
}
-assumenosideeffects class kotlin.jvm.internal.Intrinsics {
static void checkParameterIsNotNull(java.lang.Object, java.lang.String);
static void checkNotNullParameter(java.lang.Object, java.lang.String);
}
################glide###############
-keep public class * implements com.bumptech.glide.module.GlideModule
-keep class * extends com.bumptech.glide.module.AppGlideModule {
<init>(...);
}
-keep public enum com.bumptech.glide.load.ImageHeaderParser$** {
**[] $VALUES;
public *;
}
-keep class com.bumptech.glide.load.data.ParcelFileDescriptorRewinder$InternalRewinder {
*** rewind();
}
#okhttp
-dontwarn com.squareup.okhttp3.**
-keep class com.squareup.okhttp3.** { *;}
-dontwarn okio.**
################retrofit###############
-dontwarn retrofit2.**
-keep class retrofit2.** { *; }
-keep class io.reactivex.rxjava2.** { *; }
-keep class org.jetbrains.kotlin.** { *; }
-keepattributes Signature
-keepattributes Exceptions
################common###############
#实体类不参与混淆
-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}
-keepnames class * implements java.io.Serializable
-keepattributes Signature
-keep class **.R$* {*;}
-ignorewarnings
-dontwarn com.google.errorprone.annotations.Immutable
-keepclassmembers class **.R$* {
public static <fields>;
}
-keepclasseswithmembernames class * { # 保持native方法不被混淆
native <methods>;
}
-keepclassmembers enum * { # 使用enum类型时需要注意避免以下两个方法混淆,因为enum类的特殊性,以下两个方法会被反射调用,
public static **[] values();
public static ** valueOf(java.lang.String);
}
# 保留自定义控件(继承自View)不能被混淆
-keep public class * extends android.view.View {
public <init>(android.content.Context);
public <init>(android.content.Context, android.util.AttributeSet);
public <init>(android.content.Context, android.util.AttributeSet, int);
public <init>(android.content.Context, android.util.AttributeSet, int, int);
public void set*(***);
*** get* ();
}
-keep class * extends androidx.lifecycle.ViewModel
-keepclassmembers public class * extends androidx.lifecycle.ViewModel {
public <init>(...);
}
-keep class * implements androidx.viewbinding.ViewBinding {
*;
}
-keepattributes JavascriptInterface
-keepclassmembers class * {
@android.webkit.JavascriptInterface <methods>;
}
-keepclassmembers class android.webkit.WebView {
public *;
}
-keepclassmembers class * extends android.webkit.WebViewClient {
public void *(android.webkit.WebView, java.lang.String, android.graphics.Bitmap);
public boolean *(android.webkit.WebView, java.lang.String);
}
# 过滤注解
-keepattributes *Annotation*
-keep class * extends java.lang.annotation.Annotation { *; }
-keep interface * extends java.lang.annotation.Annotation { *; }
# 过滤泛型
-keepattributes Signature
#保持bean目录下文件不被混淆
-keep class com.yxjk.healthexpertclient.bean.** {*;}
-keep class com.btpj.lib_base.data.bean.** {*;}
# ImmersionBar
-keep class com.gyf.immersionbar.* {*;}
-dontwarn com.gyf.immersionbar.**
# PictureSelector
-keep class com.luck.picture.lib.** { *; }
-keep class com.luck.lib.camerax.** { *; }
-dontwarn com.yalantis.ucrop**
-keep class com.yalantis.ucrop** { *; }
-keep interface com.yalantis.ucrop** { *; }
# BaseRecyclerViewAdapterHelper混淆
-keep public class * extends com.chad.library.adapter.base.viewholder.BaseViewHolder
-keep public class * extends com.chad.library.adapter.base.viewholder.BaseDataBindingHolder
-keepclassmembers class com.chad.library.adapter.base.viewholder.BaseDataBindingHolder {
public void *(android.view.View);
}
-keepclassmembers class * extends com.chad.library.adapter.base.viewholder.BaseDataBindingHolder {
public void *(android.view.View);
}
# Gson
-keep class com.google.gson.** {*;}
-keep class com.google.**{*;}
-dontwarn com.kingja.loadsir.**
-keep class com.kingja.loadsir.** {*;}
# 对于带有回调函数的onXXEvent、**On*Listener的,不能被混淆
-keepclassmembers class * {
void *(**On*Event);
void *(**On*Listener);
}
# AgentWeb
-keep class com.just.agentweb.** {
*;
}
-dontwarn com.just.agentweb.**
#EventBus
-keepattributes *Annotation*
-keepclassmembers class * {
@org.greenrobot.eventbus.Subscribe <methods>;
}
-keep enum org.greenrobot.eventbus.ThreadMode { *; }
# Only required if you use AsyncExecutor
-keepclassmembers class * extends org.greenrobot.eventbus.util.ThrowableFailureEvent {
<init>(java.lang.Throwable);
}
# IM混淆配置
-keep class com.tencent.imsdk.** { *; }
# 高德地图SDK(都加上,省的以后万一加功能还得加)
-keep class com.amap.api.maps.**{*;}
-keep class com.autonavi.**{*;}
-keep class com.amap.api.trace.**{*;}
# 定位
-keep class com.amap.api.location.**{*;}
-keep class com.amap.api.fence.**{*;}
-keep class com.autonavi.aps.amapapi.model.**{*;}
# 搜索
-keep class com.amap.api.services.**{*;}
# 2D地图
-keep class com.amap.api.maps2d.**{*;}
-keep class com.amap.api.mapcore2d.**{*;}
# 导航
-keep class com.amap.api.navi.**{*;}
-keep class com.autonavi.**{*;}
# 蒲公英
#-libraryjars libs/pgyer_sdk_x.x.jar
-dontwarn com.pgyersdk.**
-keep class com.pgyersdk.** { *; }
# 极光推送
-dontoptimize
-dontpreverify
-dontwarn cn.jpush.**
-keep class cn.jpush.** { *; }
-keep class * extends cn.jpush.android.service.JPushMessageReceiver { *; }
-dontwarn cn.jiguang.**
-keep class cn.jiguang.** { *; }
+20
View File
@@ -0,0 +1,20 @@
{
"version": 3,
"artifactType": {
"type": "APK",
"kind": "Directory"
},
"applicationId": "com.yxjk.healthexpertclient",
"variantName": "release",
"elements": [
{
"type": "SINGLE",
"filters": [],
"attributes": [],
"versionCode": 13,
"versionName": "1.0.23",
"outputFile": "app-release.apk"
}
],
"elementType": "File"
}
+228
View File
@@ -0,0 +1,228 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.yxjk.healthexpertclient"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.VIBRATE" />
<!--用于进行网络定位-->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"></uses-permission>
<!--用于访问GPS定位-->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission>
<!--允许程序获取网络状态-->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!--允许程序读写手机状态和身份-->
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<!--用于访问wifi网络信息,wifi信息会用于进行网络定位-->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>
<!--用于获取wifi的获取权限,wifi信息会用来进行网络定位-->
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"></uses-permission>
<!--Android 13版本适配,细化存储权限-->
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
<!-- 蒲公英使用,用户手机设置中允许未知来源安装包安装状态为关;-->
<!-- Android8.0 以后,如果要安装 apk 需要额外添加权限:-->
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES"
tools:ignore="QueryAllPackagesPermission" />
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
<!--极光推送-->
<!-- <uses-permission android:name="com.yxjk.healthexpertclient.permission.JPUSH_MESSAGE" />-->
<queries package="${applicationId}">
<package android:name="com.yxjk.healthexpertclient"/>
<intent>
<action android:name="android.media.action.IMAGE_CAPTURE">
</action>
</intent>
<intent>
<action android:name="android.media.action.ACTION_VIDEO_CAPTURE">
</action>
</intent>
</queries>
<application
android:allowBackup="false"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:taskAffinity="com.yxjk.healthexpertclient"
tools:replace="android:allowBackup"
android:allowNativeHeapPointerTagging="false"
android:networkSecurityConfig="@xml/network_security_config"
android:usesCleartextTraffic="true"
android:name="com.yxjk.healthexpertclient.MyApplication"
android:theme="@style/Theme.HearthyClients">
<meta-data
android:name="com.amap.api.v2.apikey"
android:value="62fe51fa2942941774fc033ece96bbad" />
<!--高德定位服务-->
<service android:name="com.amap.api.location.APSService"></service>
<activity
android:name="com.yxjk.healthexpertclient.ui.main.MainActivity"
android:screenOrientation="portrait"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.yxjk.healthexpertclient.ui.login.LoginActivity"
android:label="@string/title_login"
android:screenOrientation="portrait">
</activity>
<activity
android:name="com.yxjk.healthexpertclient.ui.login.RetrievePassWordActivity"
android:label="@string/title_retrieve_password"
android:screenOrientation="portrait">
</activity>
<activity
android:name="com.yxjk.healthexpertclient.ui.workbench.ConsultRecordActivity"
android:label="@string/title_consult_record"
android:screenOrientation="portrait">
</activity>
<activity
android:name="com.yxjk.healthexpertclient.ui.workbench.ImageTextConsultDetailActivity"
android:label="@string/title_consult_detail"
android:screenOrientation="portrait">
</activity>
<activity
android:name="com.yxjk.healthexpertclient.ui.workbench.BaseHealthyInformationActivity"
android:label="@string/title_consult_detail"
android:screenOrientation="portrait">
</activity>
<activity
android:name="com.yxjk.healthexpertclient.ui.workbench.ArchivesDetailActivity"
android:label="@string/title_record_detail"
android:screenOrientation="portrait"/>
<activity
android:name="com.yxjk.healthexpertclient.ui.workbench.ConsultHistoryActivity"
android:label="@string/title_consult_history"
android:screenOrientation="portrait"/>
<activity
android:name="com.yxjk.healthexpertclient.ui.workbench.AudioVideoConsultActivity"
android:label="@string/title_consult_wait_confirm"
android:screenOrientation="portrait"/>
<activity
android:name="com.yxjk.healthexpertclient.ui.workbench.ConsultFinishActivity"
android:label="@string/title_consult_wait_confirm"
android:screenOrientation="portrait"/>
<activity
android:name="com.yxjk.healthexpertclient.ui.workbench.ConsultWaitStartActivity"
android:label="@string/title_consult_wait_confirm"
android:screenOrientation="portrait"/>
<activity
android:name="com.yxjk.healthexpertclient.ui.workbench.CheckUpDetailActivity"
android:label="@string/title_check_up_detail"
android:screenOrientation="portrait"/>
<activity
android:name="com.yxjk.healthexpertclient.ui.mine.SchedulingActivity"
android:label="@string/title_scheduling"
android:screenOrientation="portrait"/>
<activity
android:name="com.yxjk.healthexpertclient.ui.mine.CustomSchedulingActivity"
android:label="@string/title_custom_scheduling"
android:screenOrientation="portrait"/>
<activity
android:name="com.yxjk.healthexpertclient.ui.mine.SuspensionServiceActivity"
android:label="@string/title_suspension_service"
android:screenOrientation="portrait"/>
<activity
android:name="com.yxjk.healthexpertclient.ui.mine.AddSuspensionAnnouncementActivity"
android:label="@string/title_add_suspension_announcement"
android:screenOrientation="portrait"/>
<activity
android:name="com.yxjk.healthexpertclient.ui.mine.ConsultStatisticsActivity"
android:label="@string/title_consult_statistics"
android:screenOrientation="portrait"/>
<activity
android:name="com.yxjk.healthexpertclient.ui.mine.BillRecordActivity"
android:label="@string/title_bill_record"
android:screenOrientation="portrait"/>
<activity
android:name="com.yxjk.healthexpertclient.ui.mine.WithDrawActivity"
android:label="@string/title_with_draw"
android:screenOrientation="portrait"/>
<activity
android:name="com.yxjk.healthexpertclient.ui.mine.EditPasswordActivity"
android:label="@string/title_edit_password"
android:screenOrientation="portrait"/>
<activity
android:name="com.yxjk.healthexpertclient.ui.mine.PersonInfoActivity"
android:label="@string/title_person_info"
android:windowSoftInputMode="stateAlwaysHidden|adjustResize"
android:screenOrientation="portrait"/>
<activity
android:name="com.yxjk.healthexpertclient.ui.mine.SettingActivity"
android:label="@string/title_setting"
android:screenOrientation="portrait"/>
<activity
android:name="com.yxjk.healthexpertclient.ui.main.WebActivity"
android:label="@string/title_web_view"
android:screenOrientation="portrait"/>
<activity
android:name="com.yxjk.healthexpertclient.ui.mine.GoodAtDiseaseActivity"
android:label="@string/title_good_at_disease"
android:screenOrientation="portrait"/>
<activity
android:name="com.yxjk.healthexpertclient.ui.im.ViewLocationActivity"
android:label="@string/title_view_location"
android:screenOrientation="portrait"/>
<activity
android:name="com.yxjk.healthexpertclient.ui.workbench.MessageListActivity"
android:label="@string/title_message_list"
android:screenOrientation="portrait"/>
<activity
android:name="com.yxjk.healthexpertclient.ui.im.SelectLocationActivity"
android:label="@string/title_select_location"
android:screenOrientation="portrait"/>
<activity
android:name="com.yxjk.healthexpertclient.ui.workbench.BigImageActivity"
android:label="@string/title_image"
android:screenOrientation="portrait"/>
<activity
android:name=".ui.login.ChangePassWordActivity"
android:label="@string/title_image"
android:screenOrientation="portrait"/>
<activity
android:name=".ui.other.SimulateUserActivity"
android:label="模拟用户"
android:screenOrientation="portrait"/>
<!-- 可配置android:process参数将Service放在其他进程中;android:enabled属性不能是false -->
<!-- 这个是自定义Service,要继承极光JCommonService,可以在更多手机平台上使得推送通道保持的更稳定 -->
<!-- <service android:name="com.yxjk.healthexpertclient.jpush.MyJPushService"-->
<!-- android:enabled="true"-->
<!-- android:exported="false"-->
<!-- android:process=":pushcore">-->
<!-- <intent-filter>-->
<!-- <action android:name="cn.jiguang.user.service.action" />-->
<!-- </intent-filter>-->
<!-- </service>-->
<!-- 新的 tag/alias 接口结果返回需要开发者配置一个自定的广播 -->
<!-- 3.3.0开始所有事件将通过该类回调 -->
<!-- 该广播需要继承 JPush 提供的 JPushMessageReceiver 类, 并如下新增一个 Intent-Filter -->
<!-- <receiver-->
<!-- android:name="com.yxjk.healthexpertclient.jpush.MyJPushMessageReceiver"-->
<!-- android:enabled="true"-->
<!-- android:exported="false" >-->
<!-- <intent-filter>-->
<!-- <action android:name="cn.jpush.android.intent.RECEIVE_MESSAGE" />-->
<!-- <category android:name="com.yxjk.healthexpertclient" />-->
<!-- </intent-filter>-->
<!-- </receiver>-->
</application>
</manifest>
+23
View File
@@ -0,0 +1,23 @@
{
"textColorNormal": "#A4A3A3",
"textColorSelected": "#21BEBD",
"textSizeNormal": 12,
"textSizeSelected": 12,
"backgroundColor": "#e9e9e9",
"isNameResId": false,
"isTitleVisible": true,
"tabs": [
{
"tabName": "工作台",
"tabTag": "WorkbenchFragment",
"iconNormal": "icon_main_workbench_normal",
"iconSelected": "icon_main_workbench_selected"
},
{
"tabName": "我的",
"tabTag": "MineFragment",
"iconNormal": "icon_main_mine_normal",
"iconSelected": "icon_main_mine_selected"
}
]
}
@@ -0,0 +1,210 @@
package com.yxjk.healthexpertclient
import android.app.Activity
import android.content.Context
import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import com.btpj.lib_base.BaseApp
import com.btpj.lib_base.data.local.DataStoreManager
import com.btpj.lib_base.data.local.IpManager
import com.btpj.lib_base.ext.hideLoading
import com.btpj.lib_base.ext.jsonToBean
import com.btpj.lib_base.ext.showLoading
import com.lzy.ninegrid.NineGridView
import com.yxjk.healthexpertclient.bean.AppUpdateBean
import com.yxjk.healthexpertclient.ext.startLoginActivity
import com.yxjk.healthexpertclient.ext.userSigExpired
import com.yxjk.healthexpertclient.ui.main.viewmodel.AppViewModel
import com.yxjk.healthexpertclient.utils.BrandUtil
import com.yxjk.healthexpertclient.utils.CustomActivityManager
import com.yxjk.healthexpertclient.utils.DebuggerUtils
import com.yxjk.healthexpertclient.utils.NineGridViewImageLoader
import com.yxjk.healthexpertclient.utils.updateplugin.CheckUpdateAppVersion
import com.yxjk.healthexpertclient.view.CustomDownloadNotifier
import com.yxjk.healthexpertclient.view.CustomInstallNotifier
import com.yxjk.healthexpertclient.view.CustomUpdateNotifier
import com.tencent.imsdk.v2.V2TIMManager
import com.tencent.imsdk.v2.V2TIMValueCallback
import com.tencent.qcloud.tuicore.TUILogin
import com.tencent.qcloud.tuicore.interfaces.TUILoginListener
import com.tencent.qcloud.tuicore.util.ErrorMessageConverter
import com.tencent.qcloud.tuikit.tuichat.config.TUIChatConfigs
import com.tencent.qcloud.tuikit.tuichat.interfaces.IMInputViewActionListener
import org.json.JSONException
import org.json.JSONObject
import org.lzh.framework.updatepluginlib.UpdateConfig
import org.lzh.framework.updatepluginlib.base.UpdateParser
import org.lzh.framework.updatepluginlib.base.UpdateStrategy
import org.lzh.framework.updatepluginlib.model.CheckEntity
import org.lzh.framework.updatepluginlib.model.Update
class MyApplication : BaseApp() {
val TAG = MyApplication::class.java.simpleName
companion object {
lateinit var appViewModel: AppViewModel
}
override fun onCreate() {
super.onCreate()
appViewModel = getAppViewModelProvider()[AppViewModel::class.java]
appViewModel.init()
initBuildInformation()
initLoginStatusListener()
NineGridView.setImageLoader(NineGridViewImageLoader())
initUpdateApp()
initJPushSdk()
DataStoreManager.initialize(this)
DebuggerUtils.checkDebuggableInNotDebugModel(this)
TUIChatConfigs.getConfigs().imInputViewActionListener =
IMInputViewActionListener { workType, workId ->
var activity = CustomActivityManager.getInstance().currentActivity()
if(activity is AppCompatActivity){
activity?.showLoading()
}
appViewModel.finishIMChat(workType, workId, finallyCall = {
hideLoading()
})
}
registerActivityLifecycleCallbacks(AdjustLifecycleCallbacks())
}
override fun attachBaseContext(base: Context) {
super.attachBaseContext(base)
}
/**
* 初始化极光推送
*/
private fun initJPushSdk(){
// JPushInterface.setDebugMode(true)
// // 调整点一:初始化代码前增加setAuth调用
// var isPrivacyReady: Boolean = true // app根据是否已弹窗获取隐私授权来赋值
// if (!isPrivacyReady) {
// JCollectionAuth.setAuth(this, false) // 后续初始化过程将被拦截
// }
// JPushInterface.init(this)
// // 调整点二:隐私政策授权获取成功后调用
// JCollectionAuth.setAuth(this, true); //如初始化被拦截过,将重试初始化过程
}
private fun initUpdateApp(){
UpdateConfig.getConfig()
.setCheckWorker(CheckUpdateAppVersion::class.java)
//为了通过原检查更新库的检查随便传入的地址,实际请求参考CheckUpdateAppVersion.class
.setCheckEntity(CheckEntity().setUrl("https://www.baidu.com"))
.setCheckNotifier(CustomUpdateNotifier())
.setInstallNotifier(CustomInstallNotifier())
.setDownloadNotifier(CustomDownloadNotifier())
.setUpdateParser(object : UpdateParser() {
override fun parse(response: String?): Update {
val resultBean: AppUpdateBean? = response.jsonToBean(AppUpdateBean::class.java)
val update = Update()
if(resultBean == null){
return update
}
// 此apk包的下载地址
update.updateUrl = IpManager.getImageBaseUrl()+resultBean.appUrl
// 此apk包的版本号(因接口只有在有更新时才会返回数据,而且没有返回云端APP版本号,故将当前APP版本号+1,传给更新框架用作判断有新版本)
update.versionCode = resultBean.versionNo ?: 0
// 此apk包的版本名称
update.versionName = resultBean.versionName
// 此apk包的更新内容
update.updateContent = resultBean.updateContent
// 此apk包是否为强制更新
if (resultBean != null) {
update.isForced = 1 == resultBean.forced
}else{
update.isForced = false
}
// 是否显示忽略此次版本更新按钮
update.isIgnore = 1 == resultBean.ignoreFlag
return update
}
}).updateStrategy = object : UpdateStrategy() {
override fun isShowUpdateDialog(update: Update): Boolean {
// 是否在检查到有新版本更新时展示Dialog。
return true
}
override fun isAutoInstall(): Boolean {
// 是否自动更新.当为自动更新时。代表下载成功后不通知用户。直接调起安装。
return true
}
override fun isShowDownloadDialog(): Boolean {
// 在APK下载时。是否显示下载进度的Dialog
return true
}
}
}
private fun initBuildInformation() {
try {
val buildInfoJson = JSONObject()
buildInfoJson.put("buildBrand", BrandUtil.getBuildBrand())
buildInfoJson.put("buildManufacturer", BrandUtil.getBuildManufacturer())
buildInfoJson.put("buildModel", BrandUtil.getBuildModel())
buildInfoJson.put("buildVersionRelease", BrandUtil.getBuildVersionRelease())
buildInfoJson.put("buildVersionSDKInt", BrandUtil.getBuildVersionSDKInt())
// 工信部要求 app 在运行期间只能获取一次设备信息。因此 app 获取设备信息设置给 SDK 后,SDK 使用该值并且不再调用系统接口。
V2TIMManager.getInstance().callExperimentalAPI(
"setBuildInfo",
buildInfoJson.toString(),
object : V2TIMValueCallback<Any?> {
override fun onSuccess(o: Any?) {
Log.i(TAG, "setBuildInfo success")
}
override fun onError(code: Int, desc: String) {
Log.i(
TAG,
"setBuildInfo code:" + code + " desc:" + ErrorMessageConverter.convertIMError(
code,
desc
)
)
}
})
} catch (e: JSONException) {
e.printStackTrace()
}
}
private fun initLoginStatusListener() {
TUILogin.addLoginListener(loginStatusListener)
}
private val loginStatusListener: TUILoginListener = object : TUILoginListener() {
override fun onKickedOffline() {
startLoginActivity(CustomActivityManager.getInstance().currentActivity())
}
override fun onUserSigExpired() {
CustomActivityManager.getInstance().currentActivity().userSigExpired()
}
}
private class AdjustLifecycleCallbacks : ActivityLifecycleCallbacks {
override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {
println("路径" + activity.javaClass.name)
CustomActivityManager.getInstance().addActivity(activity)
}
override fun onActivityStarted(activity: Activity) {
}
override fun onActivityResumed(activity: Activity) {
}
override fun onActivityPaused(activity: Activity) {
}
override fun onActivityStopped(activity: Activity) {
}
override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {
}
override fun onActivityDestroyed(activity: Activity) {
CustomActivityManager.getInstance().removeActivity(activity)
}
}
}
@@ -0,0 +1,95 @@
package com.buddy.kredit.android.base
import android.content.Intent
import android.os.Bundle
import android.os.SystemClock
import androidx.databinding.ViewDataBinding
import com.btpj.lib_base.base.BaseVMBActivity
import com.btpj.lib_base.base.BaseViewModel
import com.btpj.lib_base.data.local.DataStoreManager
import com.yxjk.healthexpertclient.ext.startLoginActivity
import com.yxjk.healthexpertclient.utils.CustomActivityManager
import retrofit2.HttpException
/**
* 继承自BaseVMBActivity
* 在这里只做了统一处理跳转登录页面的逻辑
*
* @author nanfeifei 2021/11/23
*/
abstract class BaseActivity<VM : BaseViewModel, B : ViewDataBinding>(contentViewResId: Int) :
BaseVMBActivity<VM, B>(contentViewResId) {
override fun createObserve() {
super.createObserve()
mViewModel.errorResponse.observe(this) {
if (it?.code == 401) {
startLoginActivity(this)
}
}
mViewModel.exception.observe(this){
if(it is HttpException){
if(it.code() == 401){
startLoginActivity(this)
}
}
}
}
fun isLogin(): Boolean{
return if(!DataStoreManager.isLogin()){
startLoginActivity(this)
false
}else{
true
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// CustomActivityManager.getInstance().addActivity(this)
}
override fun onBackEvent() {
CustomActivityManager.getInstance().printActivity()
super.onBackEvent()
}
/**
* 每次启动activity都会调用此方法
*/
override fun startActivity(intent: Intent) {
if (checkDoubleClick(intent)){
super.startActivity(intent)
}
}
private var mActivityJumpTag //activity跳转tag
: String? = null
private var mClickTime //activity跳转时间
: Long = 0
/**
* 检查是否重复跳转,不需要则重写方法并返回true
*/
protected open fun checkDoubleClick(intent: Intent): Boolean {
// 默认检查通过
var result = true
// 标记对象
val tag: String? = if (intent.component != null) { // 显式跳转
intent.component!!.className
} else if (intent.action != null) { // 隐式跳转
intent.action
} else {
return true
}
if (tag == mActivityJumpTag && mClickTime >= SystemClock.uptimeMillis() - 500) {
// 检查不通过
result = false
}
// 记录启动标记和时间
mActivityJumpTag = tag
mClickTime = SystemClock.uptimeMillis()
return result
}
}
@@ -0,0 +1,81 @@
package com.buddy.kredit.android.base
import android.content.Intent
import android.os.Bundle
import android.os.SystemClock
import androidx.databinding.ViewDataBinding
import com.btpj.lib_base.base.BaseVMBFragment
import com.btpj.lib_base.base.BaseViewModel
import com.btpj.lib_base.data.local.DataStoreManager
import com.yxjk.healthexpertclient.ext.startLoginActivity
import retrofit2.HttpException
/**
* 继承自BaseVMBFragment
* 在这里只做了统一处理跳转登录页面的逻辑
*
* @author nanfeifei 2021/11/23
*/
abstract class BaseFragment<VM : BaseViewModel, B : ViewDataBinding>(contentViewResId: Int) :
BaseVMBFragment<VM, B>(contentViewResId) {
override fun createObserve() {
super.createObserve()
mViewModel.errorResponse.observe(viewLifecycleOwner) {
if (it?.code == 401) { // 需要登录
startLoginActivity(requireContext())
}
}
mViewModel.exception.observe(this){
if(it is HttpException){
if(it.code() == 401){
startLoginActivity(requireContext())
}
}
}
}
fun isLogin(): Boolean{
return if(!DataStoreManager.isLogin()){
startLoginActivity(requireContext())
false
}else{
true
}
}
/**
* 每次启动activity都会调用此方法
*/
override fun startActivity(intent: Intent, options: Bundle?) {
if (checkDoubleClick(intent)){
super.startActivity(intent)
}
}
private var mActivityJumpTag //activity跳转tag
: String? = null
private var mClickTime //activity跳转时间
: Long = 0
/**
* 检查是否重复跳转,不需要则重写方法并返回true
*/
protected open fun checkDoubleClick(intent: Intent): Boolean {
// 默认检查通过
var result = true
// 标记对象
val tag: String? = if (intent.component != null) { // 显式跳转
intent.component!!.className
} else if (intent.action != null) { // 隐式跳转
intent.action
} else {
return true
}
if (tag == mActivityJumpTag && mClickTime >= SystemClock.uptimeMillis() - 500) {
// 检查不通过
result = false
}
// 记录启动标记和时间
mActivityJumpTag = tag
mClickTime = SystemClock.uptimeMillis()
return result
}
}
@@ -0,0 +1,16 @@
package com.yxjk.healthexpertclient.bean
data class AppUpdateBean(
var appId: String = "",
var appName: String = "",
var appStatus: Int = 0,
var appUrl: String = "",
var deviceType: Int = 0,
var forced: Int = 0,
var id: String = "",
var ignoreFlag: Int = 0,
var updateContent: String = "",
var updateTime: Any? = null,
var versionName: String = "",
var versionNo: Int = 0
)
@@ -0,0 +1,14 @@
package com.yxjk.healthexpertclient.bean
import com.btpj.lib_base.base.adapter.BaseCheckRecycleViewAdapter
/**
* 配置菜单
*/
data class CommonSettingMenuBean(
val value: String = "",
val text: String = "",
override val itemType: Int = -1,
override var checked: Boolean = false
): BaseCheckRecycleViewAdapter.CheckItem
@@ -0,0 +1,6 @@
package com.yxjk.healthexpertclient.bean
/**
* 类似九宫格图集使用
*/
data class ImageBean(var imageUrl: String = "", var isFilePath: Boolean = false, var isAddButton: Boolean = false)
@@ -0,0 +1,5 @@
package com.yxjk.healthexpertclient.bean
data class UploadFileResultBean(
var url: String = ""
)
@@ -0,0 +1,43 @@
package com.yxjk.healthexpertclient.bean
/**
* 登录成功之后返回的用户信息
*/
data class UserInfoBean(
var activitiSync: Any? = null,
var avatar: String = "",
var birthday: String = "",
var bpmStatus: Any? = null,
var clientId: Any? = null,
var createBy: Any? = null,
var createTime: String = "",
var delFlag: Int = 0,
var depart: Any? = null,
var departIds: Any? = null,
var departTree: List<Any> = listOf(),
var email: Any? = null,
var homePath: Any? = null,
var id: String = "",
var idCard: String = "",
var loginTenantId: Int = 0,
var orgCode: Any? = null,
var orgCodeTxt: Any? = null,
var personType: Any? = null,
var phone: String = "",
var post: Any? = null,
var postText: Any? = null,
var realname: String = "",
var relTenantIds: String = "",
var secondDepart: Any? = null,
var sex: String = "",
var sex_dictText: String = "",
var status: String = "",
var status_dictText: String = "",
var telephone: Any? = null,
var updateBy: String = "",
var updateTime: String = "",
var userIdentity: Any? = null,
var username: String = "",
var workNo: String = "",
var userToken: String = ""
)
@@ -0,0 +1,11 @@
package com.yxjk.healthexpertclient.bean.im
class IMAssistantBean(
var helpId: String = "",
var id: String = "",
val groupId: String,
val userId: String,
val member: ArrayList<String>,
val tfNew: String
)
@@ -0,0 +1,7 @@
package com.yxjk.healthexpertclient.bean.im
data class IMInfoBean(
val userSig: String,
val userId: String,
val sdkAppId: String
)
@@ -0,0 +1,8 @@
package com.yxjk.healthexpertclient.bean.login
import com.yxjk.healthexpertclient.bean.UserInfoBean
data class LoginResultBean(
var token: String = "",
var userInfo: UserInfoBean = UserInfoBean()
)
@@ -0,0 +1,34 @@
package com.yxjk.healthexpertclient.bean.mine
data class BillRecordBean(
var accountMoney: String? = "",
var charDate: String? = "",
var createBy: String? = "",
var createTime: String? = "",
var delFlag: Int = 0,
var id: Int = 0,
var income: String = "",
var incomeTime: String? = "",
var memo: String? = "",
var operateId: String? = "",
var operateName: String? = "",
var operateType: String? = "",
var paymentAccount: String? = "",
var paymentMoney: String? = "",
var paymentName: String? = "",
var paymentTime: String? = "",
var realityMoney: String? = "",
var remarks: String? = "",
var sessionId: String? = "",
var status: Int = 0,
var sumIncome: String? = "",
var sumPaymentMoney: String? = "",
var updateBy: String? = "",
var updateTime: String? = "",
var userId: String? = "",
var userName: String? = "",
var withdraw: String? = "",
var withdrawalName: String? = "",
var waterType: String = "", //1是收益 2是支出
var operateTypeName: String = ""
)
@@ -0,0 +1,13 @@
package com.yxjk.healthexpertclient.bean.mine
import com.btpj.lib_base.base.adapter.BaseCheckRecycleViewAdapter
/**
* 暂停原因
*/
data class CommonSettingMenuBean(
val value: String,
val text: String,
override val itemType: Int = -1,
override var checked: Boolean = false
): BaseCheckRecycleViewAdapter.CheckItem
@@ -0,0 +1,7 @@
package com.yxjk.healthexpertclient.bean.mine
data class ConsultStatisticsBean(
var sumIncome: String = "",
var sumPaymentMoney: String = "",
var unsettled: String = ""
)
@@ -0,0 +1,8 @@
package com.yxjk.healthexpertclient.bean.mine
data class ConsultTypeBean(
var completed: Int = 0,
var content_type: String = "",
var inProgress: Int = 0,
var total: Int = 0
)
@@ -0,0 +1,15 @@
package com.yxjk.healthexpertclient.bean.mine
import android.os.Parcelable
import com.btpj.lib_base.base.adapter.BaseCheckRecycleViewAdapter
import kotlinx.android.parcel.Parcelize
@Parcelize
data class DiseaseBean(
var departmentId: String = "",
var descript: String = "",
var id: String = "",
var sicksName: String = "",
override val itemType: Int = -1,
override var checked: Boolean = false
): BaseCheckRecycleViewAdapter.CheckItem, Parcelable
@@ -0,0 +1,54 @@
package com.yxjk.healthexpertclient.bean.mine
/**
* 专家信息实体
*/
data class DoctorBean(
var address: String? = null,
var award: String? = null,
var contactAddress: String? = null,
var createBy: String? = null,
var createTime: String? = null,
var degreeHeat: String? = null,
var delFlag: Int = 0,
var departmentId: String = "",
var departmentName: String? = null,
var doctorJob: String = "",
var doctorLabel: String? = null,
var doctorName: String = "",
var doctorStatus: String = "",
var doctorTitle: String = "",
var eq: String? = null,
var experience: String = "",
var gdId: String = "",
var goodAt: String = "",
var goodAtSymptom: String = "",
var healthStatus: String? = null,
var id: String = "",
var introduction: String? = null,
var isAccept: String = "",
var joinWork: String? = null,
var memo: String? = null,
var messageNum: String? = null,
var nationality: String? = null,
var nativePlace: String? = null,
var onDutyTime: String? = null,
var outTime: String? = null,
var overallMerit: String? = null,
var photo: String? = null,
var replyNum: String? = null,
var resourceId: String = "",
var resourceName: String? = null,
var responseRate: String? = null,
var school: String? = null,
var sort: String = "",
var status: Int = 0,
var tfRecommend: String = "",
var type: String = "",
var updateBy: String? = null,
var updateTime: String? = null,
var userScore: String = "",
var userScoreNum: String = "",
var goodAtSickness: String? = "",
var goodAtSicknessName: MutableList<DiseaseBean>? = null
)
@@ -0,0 +1,9 @@
package com.yxjk.healthexpertclient.bean.mine
data class PageManagerBean<T>(
var current: Int = 0,
var pages: Int = 0,
var records: MutableList<T> = mutableListOf(),
var size: Int = 0,
var total: Int = 0
)
@@ -0,0 +1,17 @@
package com.yxjk.healthexpertclient.bean.mine
import com.btpj.lib_base.base.adapter.BaseCheckRecycleViewAdapter
data class SchedulingBean(
var amNum: String? = "0",
var id: String? = "",
var pmNum: String? = "0",
var tfJumpHoliday: String? = "",
var type: String? = "",
var week: String? = "",
var timePeriod: Int = 0,
var tfDefault: String? = "",
var consultSwitchOn: Boolean = true,
override val itemType: Int = -1,
override var checked: Boolean = false
): BaseCheckRecycleViewAdapter.CheckItem
@@ -0,0 +1,8 @@
package com.yxjk.healthexpertclient.bean.mine
data class SchedulingResultBean(
var list: MutableList<SchedulingBean>,
var tfJumpHoliday: String,
var tfDefault: String,
var audioStatus: String
)
@@ -0,0 +1,24 @@
package com.yxjk.healthexpertclient.bean.mine
import com.chad.library.adapter.base.entity.SectionEntity
data class SuspensionServiceBean(
var createBy: String? = "",
var createTime: String? = "",
var delFlag: Int? = 0,
var doctorId: String? = "",
var doctorName: String? = "",
var endDay: String? = "",
var id: String? = "",
var memo: String? = "",
var notice: String? = "",
var serviceStatus: Int? = 0,
var startDay: String? = "",
var status: Int? = null,
var stopReason: String? = "",
var updateBy: String? = "",
var updateTime: String? = "",
var startDayLong: Long = 0,
var endDayLong: Long = 0,
override val isHeader: Boolean = false
): SectionEntity
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,46 @@
package com.yxjk.healthexpertclient.bean.workbench
import android.os.Parcelable
import kotlinx.parcelize.Parcelize
@Parcelize
data class AppointmentBean(
val amPm: String = "",
val charDate: String = "",
val contentStatus: String = "",
val contentType: String = "",
val cost: String = "",
val createBy: String = "",
val createTime: String = "",
val delFlag: String = "",
val doctorEndTime: String = "",
val doctorStartTime: String = "",
val endTime: String = "",
val fromAccount: String = "",
val fromName: String = "",
val id: String = "",
val imId: String = "",
val jobStatus: String = "",
val medicalRecordsId: String = "",
val memberAge: String = "",
val memberId: String = "",
val memberName: String = "",
val memberSex: String = "",
val memo: String = "",
val reasonType: String = "",
val rejectReason: String = "",
val reservationTime: String = "",
val schedulingDateId: String = "",
val sessionDate: String = "",
val sessionStatus: String = "",
val sessionTime: String = "",
val sessionType: String = "",
val status: String = "",
val thirdAccount: String = "",
val thirdName: String = "",
val toAccount: String = "",
val toName: String = "",
val updateBy: String = "",
val updateTime: String = "",
val week: String = ""
): Parcelable
@@ -0,0 +1,24 @@
package com.yxjk.healthexpertclient.bean.workbench
import android.os.Parcelable
import kotlinx.parcelize.Parcelize
@Parcelize
data class ArchivesBean(
val id: String? = null,
var medicalDescribe: String = "",
var recordsName: String = "",
val createTime: String = "",
val createTimeLong: Long = 0,
var tfPermission: String? = null,
var haveTime: String? = null,
var haveTimeValue: String? = null,
var desire: String = "",
var tfLook: String? = null,
var lookOffice: String? = null,
var tfLookValue: String? = null,
var lookMedicalName: String? = null,
var image: String = "",
var updateTime : String? = null,
var memberId: String? = null
): Parcelable
@@ -0,0 +1,12 @@
package com.yxjk.healthexpertclient.bean.workbench
/**
* @author nanfeifei
* @time 2023/6/20 13:35
* @description
*/
class ArchivesDetailResultBean (
var answer: MutableList<HealthInfoBean>? = mutableListOf(),
var conMedicalRecordsDO: ArchivesBean? = null,
var conFamilyMembersDO: ConsultInfoBean? = null
)
@@ -0,0 +1,15 @@
package com.yxjk.healthexpertclient.bean.workbench
import com.google.gson.annotations.SerializedName
data class AudioVideoCallBean(
@SerializedName("groupId")
var groupId: String = "",
@SerializedName("member")
var member: List<String> = listOf(),
@SerializedName("userId")
var userId: String = "",
@SerializedName("videoSessionId")
var videoSessionId: String = ""
)
@@ -0,0 +1,15 @@
package com.yxjk.healthexpertclient.bean.workbench
import android.os.Parcelable
import kotlinx.parcelize.Parcelize
@Parcelize
data class CallTimeBean(
val createTime: String = "",
val endTime: String = "",
val createTimeLong: Long? = null,
val endTimeLong: Long?= null,
var startTime: String = "",
var startTimLong: Long? = null,
val type: String = ""
): Parcelable
@@ -0,0 +1,522 @@
package com.yxjk.healthexpertclient.bean.workbench;
import java.io.Serializable;
import java.util.List;
/**
* @author nanfeifei 有问题找梁文杰咨询,复制的
*/
public class CheckItemBySfzhTotalBean implements Serializable {
private SuggestionInfoDTO conclusionInfo;
private SuggestionInfoDTO suggestionInfo;
private Integer normalCount;
private List<ResultListDTO> resultList;
private Integer unusualCount;
public SuggestionInfoDTO getConclusionInfo() {
return conclusionInfo;
}
public void setConclusionInfo(SuggestionInfoDTO conclusionInfo) {
this.conclusionInfo = conclusionInfo;
}
public SuggestionInfoDTO getSuggestionInfo() {
return suggestionInfo;
}
public void setSuggestionInfo(SuggestionInfoDTO suggestionInfo) {
this.suggestionInfo = suggestionInfo;
}
public Integer getNormalCount() {
return normalCount;
}
public void setNormalCount(Integer normalCount) {
this.normalCount = normalCount;
}
public List<ResultListDTO> getResultList() {
return resultList;
}
public void setResultList(List<ResultListDTO> resultList) {
this.resultList = resultList;
}
public Integer getUnusualCount() {
return unusualCount;
}
public void setUnusualCount(Integer unusualCount) {
this.unusualCount = unusualCount;
}
public static class SuggestionInfoDTO implements Serializable {
private Object id;
private String cqbh;
private String cqbhBak;
private String cqmc;
private Object cqckz;
private String xmz;
private String jcms;
private String xmdw;
private Object officeIds;
private Boolean exceptionFlag;
private Boolean newX;
private Boolean show;
public Object getId() {
return id;
}
public void setId(Object id) {
this.id = id;
}
public String getCqbh() {
return cqbh;
}
public void setCqbh(String cqbh) {
this.cqbh = cqbh;
}
public String getCqbhBak() {
return cqbhBak;
}
public void setCqbhBak(String cqbhBak) {
this.cqbhBak = cqbhBak;
}
public String getCqmc() {
return cqmc;
}
public void setCqmc(String cqmc) {
this.cqmc = cqmc;
}
public Object getCqckz() {
return cqckz;
}
public void setCqckz(Object cqckz) {
this.cqckz = cqckz;
}
public String getXmz() {
return xmz;
}
public void setXmz(String xmz) {
this.xmz = xmz;
}
public String getJcms() {
return jcms;
}
public void setJcms(String jcms) {
this.jcms = jcms;
}
public String getXmdw() {
return xmdw;
}
public void setXmdw(String xmdw) {
this.xmdw = xmdw;
}
public Object getOfficeIds() {
return officeIds;
}
public void setOfficeIds(Object officeIds) {
this.officeIds = officeIds;
}
public Boolean getExceptionFlag() {
return exceptionFlag;
}
public void setExceptionFlag(Boolean exceptionFlag) {
this.exceptionFlag = exceptionFlag;
}
public Boolean getNewX() {
return newX;
}
public void setNewX(Boolean newX) {
this.newX = newX;
}
public Boolean getShow() {
return show;
}
public void setShow(Boolean show) {
this.show = show;
}
}
public static class ResultListDTO implements Serializable {
private Object id;
private String cqbh;
private String cqbhBak;
private String cqmc;
private Object cqckz;
private Object xmz;
private Object jcms;
private Object xmdw;
private Object officeIds;
private List<ChildlistDTO> childlist;
private Boolean exceptionFlag;
private Boolean newX;
private Boolean show;
public Object getId() {
return id;
}
public void setId(Object id) {
this.id = id;
}
public String getCqbh() {
return cqbh;
}
public void setCqbh(String cqbh) {
this.cqbh = cqbh;
}
public String getCqbhBak() {
return cqbhBak;
}
public void setCqbhBak(String cqbhBak) {
this.cqbhBak = cqbhBak;
}
public String getCqmc() {
return cqmc;
}
public void setCqmc(String cqmc) {
this.cqmc = cqmc;
}
public Object getCqckz() {
return cqckz;
}
public void setCqckz(Object cqckz) {
this.cqckz = cqckz;
}
public Object getXmz() {
return xmz;
}
public void setXmz(Object xmz) {
this.xmz = xmz;
}
public Object getJcms() {
return jcms;
}
public void setJcms(Object jcms) {
this.jcms = jcms;
}
public Object getXmdw() {
return xmdw;
}
public void setXmdw(Object xmdw) {
this.xmdw = xmdw;
}
public Object getOfficeIds() {
return officeIds;
}
public void setOfficeIds(Object officeIds) {
this.officeIds = officeIds;
}
public List<ChildlistDTO> getChildlist() {
return childlist;
}
public void setChildlist(List<ChildlistDTO> childlist) {
this.childlist = childlist;
}
public Boolean getExceptionFlag() {
return exceptionFlag;
}
public void setExceptionFlag(Boolean exceptionFlag) {
this.exceptionFlag = exceptionFlag;
}
public Boolean getNewX() {
return newX;
}
public void setNewX(Boolean newX) {
this.newX = newX;
}
public Boolean getShow() {
return show;
}
public void setShow(Boolean show) {
this.show = show;
}
public static class ChildlistDTO implements Serializable {
private Object id;
private String cqbh;
private String cqbhBak;
private String cqmc;
private String cqckz;
private String xmz;
private String jcms;
private String xmdw;
private Object officeIds;
private List<ChildlistDTO2> childlist;
private Boolean exceptionFlag;
private Boolean newX;
private Boolean show;
public Object getId() {
return id;
}
public void setId(Object id) {
this.id = id;
}
public String getCqbh() {
return cqbh;
}
public void setCqbh(String cqbh) {
this.cqbh = cqbh;
}
public String getCqbhBak() {
return cqbhBak;
}
public void setCqbhBak(String cqbhBak) {
this.cqbhBak = cqbhBak;
}
public String getCqmc() {
return cqmc;
}
public void setCqmc(String cqmc) {
this.cqmc = cqmc;
}
public String getCqckz() {
return cqckz;
}
public void setCqckz(String cqckz) {
this.cqckz = cqckz;
}
public String getXmz() {
return xmz;
}
public void setXmz(String xmz) {
this.xmz = xmz;
}
public String getJcms() {
return jcms;
}
public void setJcms(String jcms) {
this.jcms = jcms;
}
public String getXmdw() {
return xmdw;
}
public void setXmdw(String xmdw) {
this.xmdw = xmdw;
}
public Object getOfficeIds() {
return officeIds;
}
public void setOfficeIds(Object officeIds) {
this.officeIds = officeIds;
}
public List<ChildlistDTO2> getChildlist() {
return childlist;
}
public void setChildlist(List<ChildlistDTO2> childlist) {
this.childlist = childlist;
}
public Boolean getExceptionFlag() {
return exceptionFlag;
}
public void setExceptionFlag(Boolean exceptionFlag) {
this.exceptionFlag = exceptionFlag;
}
public Boolean getNewX() {
return newX;
}
public void setNewX(Boolean newX) {
this.newX = newX;
}
public Boolean getShow() {
return show;
}
public void setShow(Boolean show) {
this.show = show;
}
}
public static class ChildlistDTO2 implements Serializable {
private Object id;
private String cqbh;
private String cqbhBak;
private String cqmc;
private String cqckz;
private String xmz;
private String jcms;
private String xmdw;
private Object officeIds;
private Boolean exceptionFlag;
private Boolean newX;
private Boolean show;
public Object getId() {
return id;
}
public void setId(Object id) {
this.id = id;
}
public String getCqbh() {
return cqbh;
}
public void setCqbh(String cqbh) {
this.cqbh = cqbh;
}
public String getCqbhBak() {
return cqbhBak;
}
public void setCqbhBak(String cqbhBak) {
this.cqbhBak = cqbhBak;
}
public String getCqmc() {
return cqmc;
}
public void setCqmc(String cqmc) {
this.cqmc = cqmc;
}
public String getCqckz() {
return cqckz;
}
public void setCqckz(String cqckz) {
this.cqckz = cqckz;
}
public String getXmz() {
return xmz;
}
public void setXmz(String xmz) {
this.xmz = xmz;
}
public String getJcms() {
return jcms;
}
public void setJcms(String jcms) {
this.jcms = jcms;
}
public String getXmdw() {
return xmdw;
}
public void setXmdw(String xmdw) {
this.xmdw = xmdw;
}
public Object getOfficeIds() {
return officeIds;
}
public void setOfficeIds(Object officeIds) {
this.officeIds = officeIds;
}
public Boolean getExceptionFlag() {
return exceptionFlag;
}
public void setExceptionFlag(Boolean exceptionFlag) {
this.exceptionFlag = exceptionFlag;
}
public Boolean getNewX() {
return newX;
}
public void setNewX(Boolean newX) {
this.newX = newX;
}
public Boolean getShow() {
return show;
}
public void setShow(Boolean show) {
this.show = show;
}
}
}
}
@@ -0,0 +1,167 @@
package com.yxjk.healthexpertclient.bean.workbench;
import java.util.ArrayList;
/**
* 体检报告结果使用,copy自用户端
*/
public class CheckRecordUserInfoBean {
private String id;
private String userId;
private String userName;
private String sex;
private String sex_dictText;
private String age;
private String card;
private String mobilePhone;
private String email;
private String empNativeplace;
private String peQueueDate;
private String empBirthday;
private String conclusion;
private String suggest;
private String medicalYear;
private String hospitalName;
private ArrayList<ResultItemListBean> resultItemResList;
public String getHospitalName() {
return hospitalName == null ? "" : hospitalName;
}
public void setHospitalName(String hospitalName) {
this.hospitalName = hospitalName;
}
public ArrayList<ResultItemListBean> getResultItemResList() {
if (resultItemResList == null) {
return new ArrayList<>();
}
return resultItemResList;
}
public void setResultItemResList(ArrayList<ResultItemListBean> resultItemResList) {
this.resultItemResList = resultItemResList;
}
public String getId() {
return id == null ? "" : id;
}
public void setId(String id) {
this.id = id;
}
public String getUserId() {
return userId == null ? "" : userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getUserName() {
return userName == null ? "" : userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getSex() {
return sex == null ? "" : sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getSex_dictText() {
return sex_dictText == null ? "" : sex_dictText;
}
public void setSex_dictText(String sex_dictText) {
this.sex_dictText = sex_dictText;
}
public String getAge() {
return age == null ? "" : age;
}
public void setAge(String age) {
this.age = age;
}
public String getCard() {
return card == null ? "" : card;
}
public void setCard(String card) {
this.card = card;
}
public String getMobilePhone() {
return mobilePhone == null ? "" : mobilePhone;
}
public void setMobilePhone(String mobilePhone) {
this.mobilePhone = mobilePhone;
}
public String getEmail() {
return email == null ? "" : email;
}
public void setEmail(String email) {
this.email = email;
}
public String getEmpNativeplace() {
return empNativeplace == null ? "" : empNativeplace;
}
public void setEmpNativeplace(String empNativeplace) {
this.empNativeplace = empNativeplace;
}
public String getPeQueueDate() {
return peQueueDate == null ? "" : peQueueDate;
}
public void setPeQueueDate(String peQueueDate) {
this.peQueueDate = peQueueDate;
}
public String getEmpBirthday() {
return empBirthday == null ? "" : empBirthday;
}
public void setEmpBirthday(String empBirthday) {
this.empBirthday = empBirthday;
}
public String getConclusion() {
return conclusion == null ? "" : conclusion;
}
public void setConclusion(String conclusion) {
this.conclusion = conclusion;
}
public String getSuggest() {
return suggest == null ? "" : suggest;
}
public void setSuggest(String suggest) {
this.suggest = suggest;
}
public String getMedicalYear() {
return medicalYear == null ? "" : medicalYear;
}
public void setMedicalYear(String medicalYear) {
this.medicalYear = medicalYear;
}
}
@@ -0,0 +1,190 @@
package com.yxjk.healthexpertclient.bean.workbench;
import java.util.List;
public class CheckUpDetailListBean {
private String cqmc;
private String cqbh;
private String cqbhBak;
private String cqmcChild;
private String cqbhChild;
private String cqbhBakChild;
private List<CheckUpDetailListChildBean> list;
public String getCqmc() {
return cqmc;
}
public void setCqmc(String cqmc) {
this.cqmc = cqmc;
}
public String getCqbh() {
return cqbh;
}
public void setCqbh(String cqbh) {
this.cqbh = cqbh;
}
public String getCqbhBak() {
return cqbhBak;
}
public void setCqbhBak(String cqbhBak) {
this.cqbhBak = cqbhBak;
}
public String getCqmcChild() {
return cqmcChild;
}
public void setCqmcChild(String cqmcChild) {
this.cqmcChild = cqmcChild;
}
public String getCqbhChild() {
return cqbhChild;
}
public void setCqbhChild(String cqbhChild) {
this.cqbhChild = cqbhChild;
}
public String getCqbhBakChild() {
return cqbhBakChild;
}
public void setCqbhBakChild(String cqbhBakChild) {
this.cqbhBakChild = cqbhBakChild;
}
public List<CheckUpDetailListChildBean> getList() {
return list;
}
public void setList(List<CheckUpDetailListChildBean> list) {
this.list = list;
}
public static class CheckUpDetailListChildBean {
private Object id;
private String cqbh;
private String cqbhBak;
private String cqmc;
private String cqckz;
private String xmz;
private String jcms;
private String xmdw;
private Object officeIds;
private List<?> childlist;
private Boolean exceptionFlag=false;
private Boolean newX;
private Boolean show;
public Object getId() {
return id;
}
public void setId(Object id) {
this.id = id;
}
public String getCqbh() {
return cqbh;
}
public void setCqbh(String cqbh) {
this.cqbh = cqbh;
}
public String getCqbhBak() {
return cqbhBak;
}
public void setCqbhBak(String cqbhBak) {
this.cqbhBak = cqbhBak;
}
public String getCqmc() {
return cqmc;
}
public void setCqmc(String cqmc) {
this.cqmc = cqmc;
}
public String getCqckz() {
return cqckz;
}
public void setCqckz(String cqckz) {
this.cqckz = cqckz;
}
public String getXmz() {
return xmz;
}
public void setXmz(String xmz) {
this.xmz = xmz;
}
public String getJcms() {
return jcms;
}
public void setJcms(String jcms) {
this.jcms = jcms;
}
public String getXmdw() {
return xmdw;
}
public void setXmdw(String xmdw) {
this.xmdw = xmdw;
}
public Object getOfficeIds() {
return officeIds;
}
public void setOfficeIds(Object officeIds) {
this.officeIds = officeIds;
}
public List<?> getChildlist() {
return childlist;
}
public void setChildlist(List<?> childlist) {
this.childlist = childlist;
}
public Boolean getExceptionFlag() {
return exceptionFlag;
}
public void setExceptionFlag(Boolean exceptionFlag) {
this.exceptionFlag = exceptionFlag;
}
public Boolean getNewX() {
return newX;
}
public void setNewX(Boolean newX) {
this.newX = newX;
}
public Boolean getShow() {
return show;
}
public void setShow(Boolean show) {
this.show = show;
}
}
}
@@ -0,0 +1,15 @@
package com.yxjk.healthexpertclient.bean.workbench
import android.os.Parcelable
import kotlinx.parcelize.Parcelize
@Parcelize
data class ConsultDetailBean(
var answer: MutableList<HealthInfoBean>? = mutableListOf(),
var conFamilyMembersDO: ConsultInfoBean? = ConsultInfoBean(),
var conMedicalRecordsListDO: ArchivesBean? = ArchivesBean(),
var conSession: ConsultRecordBean? = ConsultRecordBean(),
var createTime: Long = 0,
var idNo: String? = null,
var imList: MutableList<CallTimeBean>? = mutableListOf()
): Parcelable
@@ -0,0 +1,19 @@
package com.yxjk.healthexpertclient.bean.workbench
import android.os.Parcelable
import kotlinx.parcelize.Parcelize
/**
* 咨询人相关信息
*/
@Parcelize
data class ConsultInfoBean(
val birthday: String = "",
val familyRelation: String = "",
val gender: String = "",
val height: String = "",
val id: String = "",
val name: String = "",
val weight: String = "",
val age: String = ""
): Parcelable
@@ -0,0 +1,31 @@
package com.yxjk.healthexpertclient.bean.workbench
import android.os.Parcelable
import kotlinx.parcelize.Parcelize
/**
* 咨询记录相关信息
*/
@Parcelize
data class ConsultRecordBean(
val doctorEndTime: String? = "",
val doctorStartTime: String? = "",
val doctorEndTimeLong: Long? = null,
val doctorStartTimeLong: Long? = null,
val sessionDateLong: Long? = null,
val week: String? = "",
val amPm: String? = "",
val id: String? = "",
val imId: String? = "",
val memberAge: String? = "",
val memberId: String? = "",
val memberName: String? = "",
val memberSex: String? = "",
val createTime: String? = "",
var unreadCount: Int = 0,
val contentStatus: String? = "", //预约状态 1待确认 2待开始 3已开始 4待评价 5完成 6拒绝 7取消
val contentType: String? = "", //咨询类型:1图文咨询 2音视频咨询
val reasonType: String? = "", //拒绝原因
val rejectReason: String? = "", //拒绝的备注
var fromAccount: String? = null
) : Parcelable
@@ -0,0 +1,10 @@
package com.yxjk.healthexpertclient.bean.workbench
import android.os.Parcelable
import kotlinx.parcelize.Parcelize
@Parcelize
data class HealthInfoBean(
val answerKey: String,
val answerValue: String
): Parcelable
@@ -0,0 +1,21 @@
package com.yxjk.healthexpertclient.bean.workbench
data class MessageBean(
var contentType: String? = null,
var createBy: String = "",
var createTime: String = "",
var delFlag: String = "",
var endTime: String = "",
var fromAccount: String = "",
var groupId: String = "",
var id: String = "",
var memo: String = "",
var msgContent: String = "",
var msgSeq: String = "",
var msgType: String = "",
var sendTime: String = "",
var status: String = "",
var toAccount: String = "",
var updateBy: String = "",
var updateTime: String = ""
)
@@ -0,0 +1,18 @@
package com.yxjk.healthexpertclient.bean.workbench
import com.google.gson.annotations.SerializedName
/**
* 体检报告(字段命名骂后台就行)
*/
data class PhysicalExaminationReportBean(
var id: String = "",
@SerializedName("peQueueDate")
var insertdate: String = "", //体检记录生成时间
@SerializedName("userName")
var name: String = "", //体检人姓名
@SerializedName("hospitalName")
var yymc: String = "", //体检地点
@SerializedName("medicalYear")
var tjrq: String = "" //体检日期
)
@@ -0,0 +1,6 @@
package com.yxjk.healthexpertclient.bean.workbench
data class RefuseReasonBean(
val value: String,
val text: String
)
@@ -0,0 +1,178 @@
package com.yxjk.healthexpertclient.bean.workbench;
import java.util.List;
/**
* 体检报告结果使用,copy自用户端
*/
public class ResultItemListBean {
private String analysisId;
private String analysisName;
private List<SenResultResDTO> senResultRes;
public String getAnalysisId() {
return analysisId;
}
public void setAnalysisId(String analysisId) {
this.analysisId = analysisId;
}
public String getAnalysisName() {
return analysisName == null ? "" : analysisName;
}
public void setAnalysisName(String analysisName) {
this.analysisName = analysisName;
}
public List<SenResultResDTO> getSenResultRes() {
return senResultRes;
}
public void setSenResultRes(List<SenResultResDTO> senResultRes) {
this.senResultRes = senResultRes;
}
public static class SenResultResDTO {
private String uniItemClassId;
private String uniItemClassName;
private List<ThirdResultResDTO> thirdResultRes;
public String getUniItemClassId() {
return uniItemClassId;
}
public void setUniItemClassId(String uniItemClassId) {
this.uniItemClassId = uniItemClassId;
}
public String getUniItemClassName() {
return uniItemClassName;
}
public void setUniItemClassName(String uniItemClassName) {
this.uniItemClassName = uniItemClassName;
}
public List<ThirdResultResDTO> getThirdResultRes() {
return thirdResultRes;
}
public void setThirdResultRes(List<ThirdResultResDTO> thirdResultRes) {
this.thirdResultRes = thirdResultRes;
}
public static class ThirdResultResDTO {
private Object userResultId;
private String id;
private String peItemName;
private Object uniItemId;
private String printContext;
private String peResult;
private String unit;
private String colour;
private Object uniItemClassId;
private Object uniItemClassName;
private Object analysisId;
private Object analysisName;
public String getColour() {
return colour == null ? "" : colour;
}
public void setColour(String colour) {
this.colour = colour;
}
public Object getUserResultId() {
return userResultId;
}
public void setUserResultId(Object userResultId) {
this.userResultId = userResultId;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getPeItemName() {
return peItemName;
}
public void setPeItemName(String peItemName) {
this.peItemName = peItemName;
}
public Object getUniItemId() {
return uniItemId;
}
public void setUniItemId(Object uniItemId) {
this.uniItemId = uniItemId;
}
public String getPrintContext() {
return printContext;
}
public void setPrintContext(String printContext) {
this.printContext = printContext;
}
public String getPeResult() {
return peResult;
}
public void setPeResult(String peResult) {
this.peResult = peResult;
}
public String getUnit() {
return unit;
}
public void setUnit(String unit) {
this.unit = unit;
}
public Object getUniItemClassId() {
return uniItemClassId;
}
public void setUniItemClassId(Object uniItemClassId) {
this.uniItemClassId = uniItemClassId;
}
public Object getUniItemClassName() {
return uniItemClassName;
}
public void setUniItemClassName(Object uniItemClassName) {
this.uniItemClassName = uniItemClassName;
}
public Object getAnalysisId() {
return analysisId;
}
public void setAnalysisId(Object analysisId) {
this.analysisId = analysisId;
}
public Object getAnalysisName() {
return analysisName;
}
public void setAnalysisName(Object analysisName) {
this.analysisName = analysisName;
}
}
}
}
@@ -0,0 +1,19 @@
package com.yxjk.healthexpertclient.bean.workbench
import com.google.gson.annotations.SerializedName
class WorkBenchConsultNumBean(
@SerializedName("pictureFinish")
var pictureFinish: String = "",
@SerializedName("pictureIng")
var pictureIng: String = "",
@SerializedName("pictureUnReply")
var pictureUnReply: String = "",
@SerializedName("videoFinish")
var videoFinish: String = "",
@SerializedName("videoIng")
var videoIng: String = "",
@SerializedName("videoUnReply")
var videoUnReply: String = ""
)
@@ -0,0 +1,14 @@
package com.yxjk.healthexpertclient.data.api
import com.btpj.lib_base.data.bean.ApiResponse
import com.yxjk.healthexpertclient.bean.im.IMInfoBean
import retrofit2.http.GET
interface IMApi {
/**
* 获取IM登录Sig
*/
@GET("/health-im/wnapp/userSigAndroid")
suspend fun getIMSig(): ApiResponse<IMInfoBean>
}
@@ -0,0 +1,37 @@
package com.yxjk.healthexpertclient.data.api
import com.btpj.lib_base.data.bean.ApiResponse
import com.yxjk.healthexpertclient.bean.CommonSettingMenuBean
import com.yxjk.healthexpertclient.bean.login.LoginResultBean
import okhttp3.RequestBody
import retrofit2.http.Body
import retrofit2.http.GET
import retrofit2.http.POST
import retrofit2.http.QueryMap
interface LoginApi {
/**
* 登录接口
*/
@POST("/health-consultation/conDoctor/loginDoctor")
// @POST("/sys/mLogin")
suspend fun login(@Body requestBody: RequestBody): ApiResponse<LoginResultBean>
/**
* 校验用户信息
*/
@POST("health-system/api/anon/sys/checkUser")
suspend fun checkUserInfo(@Body requestBody: RequestBody): ApiResponse<String>
/**
* 修改密码
*/
@POST("health-system/api/anon/sys/resetUserPwd")
suspend fun resetUserPwd(@Body requestBody: RequestBody): ApiResponse<String>
/**
* 获取后台配置的菜单(例如:咨询人中与本人的关系)
*/
@GET("/health-consultation/api/consult/conDoctor/selectDictList")
suspend fun getCommonSettingMenuList(@QueryMap params: MutableMap<String, Any?>): ApiResponse<MutableList<CommonSettingMenuBean>>
}
@@ -0,0 +1,126 @@
package com.yxjk.healthexpertclient.data.api
import com.btpj.lib_base.data.bean.ApiResponse
import com.yxjk.healthexpertclient.bean.UploadFileResultBean
import com.yxjk.healthexpertclient.bean.im.IMAssistantBean
import com.yxjk.healthexpertclient.bean.mine.BillRecordBean
import com.yxjk.healthexpertclient.bean.mine.CommonSettingMenuBean
import com.yxjk.healthexpertclient.bean.mine.ConsultStatisticsBean
import com.yxjk.healthexpertclient.bean.mine.ConsultTypeBean
import com.yxjk.healthexpertclient.bean.mine.DiseaseBean
import com.yxjk.healthexpertclient.bean.mine.DoctorBean
import com.yxjk.healthexpertclient.bean.mine.PageManagerBean
import com.yxjk.healthexpertclient.bean.mine.SchedulingResultBean
import com.yxjk.healthexpertclient.bean.mine.SuspensionServiceBean
import okhttp3.MultipartBody
import okhttp3.RequestBody
import retrofit2.http.Body
import retrofit2.http.GET
import retrofit2.http.Multipart
import retrofit2.http.POST
import retrofit2.http.PUT
import retrofit2.http.Part
import retrofit2.http.QueryMap
interface MineApi {
/**
* 获取专家信息
*/
@GET("/health-consultation/api/consult/conDoctor/queryDoctor")
suspend fun getDoctorInfo(): ApiResponse<DoctorBean>
/**
* 修改专家信息
*/
@POST("/health-consultation/api/consult/conDoctor/update")
suspend fun editDoctorInfo(@Body requestBody: RequestBody): ApiResponse<String?>
/**
* 查询医生排班
*/
@GET("/health-consultation/api/consult/conDoctorScheduling/selectDoctorScheduling")
suspend fun getDoctorScheduling(@QueryMap params: MutableMap<String, Any?>): ApiResponse<SchedulingResultBean>
/**
* 一次性插入排班
*/
@POST("/health-consultation/api/consult/conDoctorScheduling/insertDoctorScheduling")
suspend fun createDoctorScheduling(@Body requestBody: RequestBody): ApiResponse<String>
/**
* 单条插入排班
*/
@POST("/health-consultation/api/consult/conDoctorScheduling/insertDoctorSchedulingSingle")
suspend fun createDoctorCustomScheduling(@Body requestBody: RequestBody): ApiResponse<String>
/**
* 修改密码
*/
@PUT("/health-consultation/api/consult/conDoctor/updatePassword")
suspend fun editPassword(@Body requestBody: RequestBody): ApiResponse<String>
/**
* 账单明细
*/
@GET("/health-consultation/api/consult/conCostStatistics/findlistpage")
suspend fun getBillRecord(@QueryMap params: MutableMap<String, Any?>): ApiResponse<PageManagerBean<BillRecordBean>>
/**
* 账单详情
*/
@GET("/health-consultation/api/consult/conCostStatistics/queryById")
suspend fun getBillDetail(@QueryMap params: MutableMap<String, Any?>): ApiResponse<BillRecordBean>
/**
* 收益统计
*/
@GET("/health-consultation/api/consult/conCostStatistics/getStatistics")
suspend fun getConsultStatistics(): ApiResponse<ConsultStatisticsBean>
/**
* 咨询方式统计(按月)
*/
@GET("/health-consultation/api/consult/conCostStatistics/groupByTypehList")
suspend fun getConsultTypeData(@QueryMap params: MutableMap<String, Any?>): ApiResponse<MutableList<ConsultTypeBean>>
/**
* 暂停服务记录
*/
@GET("/health-consultation/api/consult/conService/list")
suspend fun getSuspensionServiceList(@QueryMap params: MutableMap<String, Any?>): ApiResponse<PageManagerBean<SuspensionServiceBean>>
/**
* 停止暂定服务
*/
@POST("/health-consultation/api/consult/conService/edit")
suspend fun stopSuspensionService(@Body requestBody: RequestBody): ApiResponse<String>
/**
* 添加暂定服务
*/
@POST("/health-consultation/api/consult/conService/add")
suspend fun addSuspensionService(@Body requestBody: RequestBody): ApiResponse<String>
/**
* 获取后台配置的功能列表(例如:医生暂停服务原因列表)
*/
@GET("/health-consultation/api/consult/conDoctor/selectDictList")
suspend fun getCommonSettingMenuList(@QueryMap params: MutableMap<String, Any?>): ApiResponse<MutableList<CommonSettingMenuBean>>
/**
* 获取指定时间范围内存在的咨询单
*/
@GET("/health-consultation/api/consult/conSession/selectSessionVideoExistDoctor")
suspend fun getDateRangeConsultNum(@QueryMap params: MutableMap<String, Any?>): ApiResponse<String>
/**
* 上传文件
*/
@Multipart
@POST("/sys/upload/uploadFile")
suspend fun uploadFile(@Part part: MultipartBody.Part, @Part("biz") path: RequestBody): ApiResponse<UploadFileResultBean>
/**
* 更像头像
*/
@POST("/sys/user/updateUserAvatar")
suspend fun uploadHeadImage(@QueryMap params: MutableMap<String, Any?>): ApiResponse<String>
/**
* 获取医生可选擅长疾病
*/
@GET("/health-consultation/api/consult/conSicks/selectSickListByDepartmentIdDoctorSearch")
suspend fun getDoctorGoodAtDisease(@QueryMap params: MutableMap<String, Any?>): ApiResponse<MutableList<DiseaseBean>>
/**
* 咨询小助手
*/
@GET("health-consultation/api/consult/conSession/insertProfessorAndHelperSession")
suspend fun submitAssistantConsultApply(): ApiResponse<IMAssistantBean>
}
@@ -0,0 +1,58 @@
package com.yxjk.healthexpertclient.data.api
import com.btpj.lib_base.data.bean.ApiResponse
import com.yxjk.healthexpertclient.bean.AppUpdateBean
import com.yxjk.healthexpertclient.bean.other.UserListBean
import com.yxjk.healthexpertclient.bean.workbench.ArchivesDetailResultBean
import com.yxjk.healthexpertclient.bean.workbench.AudioVideoCallBean
import com.yxjk.healthexpertclient.bean.workbench.CheckRecordUserInfoBean
import com.yxjk.healthexpertclient.bean.workbench.ConsultDetailBean
import com.yxjk.healthexpertclient.bean.workbench.ConsultRecordBean
import com.yxjk.healthexpertclient.bean.workbench.HealthInfoBean
import com.yxjk.healthexpertclient.bean.workbench.MessageBean
import com.yxjk.healthexpertclient.bean.workbench.PhysicalExaminationReportBean
import com.yxjk.healthexpertclient.bean.workbench.RefuseReasonBean
import com.yxjk.healthexpertclient.bean.workbench.WorkBenchConsultNumBean
import okhttp3.RequestBody
import retrofit2.http.Body
import retrofit2.http.FieldMap
import retrofit2.http.FormUrlEncoded
import retrofit2.http.GET
import retrofit2.http.POST
import retrofit2.http.QueryMap
/**
* @author nanfeifei
* @time 2023/5/24 15:08
* @description 工作台接口定义
*/
interface OtherApi {
/**
* 获取模拟用户列表
*/
@GET("/health-system/sys/user/listAll")
suspend fun listAll(@QueryMap params: MutableMap<String, Any?>): ApiResponse<UserListBean>
/**
* 模拟用户信息
*/
@FormUrlEncoded
@POST("/health-system/test/fake")
suspend fun fake(@FieldMap params: MutableMap<String, Any?>): ApiResponse<Boolean>
/**
* 获取模拟用户信息
*/
@POST("/health-system/test/fakeUser")
suspend fun fakeUser(@Body requestBody: RequestBody): ApiResponse<UserListBean.RecordsDTO>
/**
* 重置模拟
*/
@POST("/health-system/test/restore")
suspend fun restore(@Body requestBody: RequestBody): ApiResponse<Boolean>
/**
* 校验token是否过期
*/
@GET("/health-consultation/api/consult/msgRecord/selectTokenExpire")
suspend fun selectTokenExpire(@QueryMap params: MutableMap<String, Any?>): ApiResponse<Boolean>
}
@@ -0,0 +1,139 @@
package com.yxjk.healthexpertclient.data.api
import com.btpj.lib_base.data.bean.ApiResponse
import com.yxjk.healthexpertclient.bean.AppUpdateBean
import com.yxjk.healthexpertclient.bean.workbench.ArchivesDetailResultBean
import com.yxjk.healthexpertclient.bean.workbench.AudioVideoCallBean
import com.yxjk.healthexpertclient.bean.workbench.CheckRecordUserInfoBean
import com.yxjk.healthexpertclient.bean.workbench.ConsultDetailBean
import com.yxjk.healthexpertclient.bean.workbench.ConsultRecordBean
import com.yxjk.healthexpertclient.bean.workbench.HealthInfoBean
import com.yxjk.healthexpertclient.bean.workbench.MessageBean
import com.yxjk.healthexpertclient.bean.workbench.PhysicalExaminationReportBean
import com.yxjk.healthexpertclient.bean.workbench.RefuseReasonBean
import com.yxjk.healthexpertclient.bean.workbench.WorkBenchConsultNumBean
import okhttp3.RequestBody
import retrofit2.http.Body
import retrofit2.http.GET
import retrofit2.http.POST
import retrofit2.http.QueryMap
/**
* @author nanfeifei
* @time 2023/5/24 15:08
* @description 工作台接口定义
*/
interface WorkbenchApi {
/**
* 获取咨询记录(当前登录人专家的咨询列表)
*/
@GET("/health-consultation/api/consult/conSession/selectSessionListByDoctorIdNew")
suspend fun getConsultRecord(@QueryMap params: MutableMap<String, Any?>): ApiResponse<MutableList<ConsultRecordBean>>
/**
* 获取咨询记录(某个用户(员工)的咨询历史记录)
*/
@GET("/health-consultation/api/consult/conSession/sessionDetailDoctorSearch")
suspend fun getConsultHistory(@QueryMap params: MutableMap<String, Any?>): ApiResponse<MutableList<ConsultRecordBean>>
/**
* 图文咨询详情
*/
@GET("/health-consultation/api/consult/conSession/sessionDetailDoctor")
suspend fun getImageTextConsultDetail(@QueryMap params: MutableMap<String, Any?>): ApiResponse<ConsultDetailBean>
/**
* 音视频咨询详情
*/
@GET("/health-consultation/api/consult/conSession/sessionDetailDoctorAll")
suspend fun getAudioVideoConsultDetail(@QueryMap params: MutableMap<String, Any?>): ApiResponse<ConsultDetailBean>
/**
* 医生接受会话的原因
*/
@GET("/health-consultation/api/consult/conSession/selectRejectReason")
suspend fun getRefusalAudioVideoCallReason(): ApiResponse<MutableList<RefuseReasonBean>>
/**
* 医生拒绝会话
*/
@GET("/health-consultation/api/consult/conSession/sessionReject")
suspend fun refusalAudioVideoCall(@QueryMap params: MutableMap<String, Any?>): ApiResponse<String>
/**
* 医生接受会话
*/
@GET("/health-consultation/api/consult/conSession/sessionConfirm")
suspend fun acceptAudioVideoCall(@QueryMap params: MutableMap<String, Any?>): ApiResponse<String>
/**
* 医生发起会话
*/
@GET("/health-consultation/api/consult/conSessionVideoInfo/startVideoSession")
suspend fun initiateAudioVideoCall(@QueryMap params: MutableMap<String, Any?>): ApiResponse<AudioVideoCallBean>
/**
* 查询档案详情
*/
@GET("/health-consultation/api/consult/medicalRecords/selectConMedicalRecordsByIdDoctor")
suspend fun getArchivesDetail(@QueryMap params: MutableMap<String, Any?>): ApiResponse<ArchivesDetailResultBean>
/**
* 查询体检报告
*/
@GET("/health-archives/historyReport/selectNewHealthReport")
suspend fun getPhysicalExaminationReport(@QueryMap params: MutableMap<String, Any?>): ApiResponse<PhysicalExaminationReportBean>
/**
* 获取音视频咨询未处理消息数
*/
@GET("/health-consultation/api/consult/ ")
suspend fun getAudioVideoUnreadNum(@QueryMap params: MutableMap<String, Any?>): ApiResponse<String>
/**
* 通过IM会话列表匹配对应的图文咨询列表
*/
@POST("/health-consultation/api/consult/conSession/selectSessionByImIdNewNew")
suspend fun getImageTextConsultRecord(@Body requestBody: RequestBody): ApiResponse<MutableList<ConsultRecordBean>>
/**
* 获取用户基本健康信息
*/
@GET("/health-consultation/api/consult/healthInfo/selectHealthInfoDoctor")
suspend fun getBaseHealthInfo(@QueryMap params: MutableMap<String, Any?>): ApiResponse<MutableList<HealthInfoBean>>
/**
* 查询体检信息(这里复制的用户端的)
*/
// @GET("cqyt/middleController/getCheckItemBySfzhTotal")
// suspend fun getCheckItemBySfzhTotal(@Query("sfzh") sfzh:String, @Query("tjrq") tjrq:String, @Query("type") type:String=""): ApiResponse<CheckItemBySfzhTotalBean>
@GET("health-archives/historyReport/getHistoryReportById")
suspend fun getHistoryReportNoDetail(@QueryMap params: MutableMap<String, Any?>): ApiResponse<CheckRecordUserInfoBean>
/**
* 结束咨询
*/
@GET("/health-consultation/api/consult/conSession/finishSession")
suspend fun finishConsult(@QueryMap params: MutableMap<String, Any?>): ApiResponse<String>
/**
* 音视频通话之后再次预约时间
*/
@GET("/health-consultation/api/consult/sessionReservationDate/sessionReservationDate")
suspend fun againAppointmentDateTime(@QueryMap params: MutableMap<String, Any?>): ApiResponse<String>
/**
* 音视频通话开始
*/
@GET("/health-consultation/api/consult/sessionReservationDate/sessionReservationDate")
suspend fun audioVideoCallStart(@QueryMap params: MutableMap<String, Any?>): ApiResponse<String>
/**
* 音视频通话结束
*/
@GET("/health-consultation/api/consult/sessionReservationDate/endPhone")
suspend fun audioVideoCallEnd(@QueryMap params: MutableMap<String, Any?>): ApiResponse<String>
/**
* 首页咨询数量获取
*/
@GET("/health-consultation/api/consult/conSession/selectSessionProfessorIngNew")
suspend fun getWorkBenchConsultNum(): ApiResponse<WorkBenchConsultNumBean>
/**
* 获取当前咨询中的小助手信息
*/
@GET("/health-consultation/api/consult/conSession/insertProfessorAndHelperSessionShow")
suspend fun getConsultAssistantInfo(): ApiResponse<String>
/**
* 获取消息列表
*/
@POST("/health-consultation/api/consult/msgRecord/selectMsgRecordList")
suspend fun getMessageList(@Body requestBody: RequestBody): ApiResponse<MutableList<MessageBean>>
/**
* 检查更新
*/
@GET("/health-system/version/getSysVersionDetailByPackageName")
suspend fun getAppUpdateInfo(@QueryMap params: MutableMap<String, Any?>): ApiResponse<AppUpdateBean>
}
@@ -0,0 +1,17 @@
package com.yxjk.healthexpertclient.data.repository
import com.btpj.lib_base.data.bean.ApiResponse
import com.btpj.lib_base.http.BaseRepository
import com.btpj.lib_base.http.RetrofitManager
import com.yxjk.healthexpertclient.bean.im.IMInfoBean
import com.yxjk.healthexpertclient.data.api.IMApi
object IMRepository: BaseRepository() {
private val service by lazy { RetrofitManager.getService(IMApi::class.java) }
suspend fun getIMSig(): ApiResponse<IMInfoBean> {
return apiCall { service.getIMSig() }
}
}
@@ -0,0 +1,53 @@
package com.yxjk.healthexpertclient.data.repository
import com.btpj.lib_base.data.bean.ApiResponse
import com.btpj.lib_base.ext.toJson
import com.btpj.lib_base.http.BaseRepository
import com.btpj.lib_base.http.RetrofitManager
import com.btpj.lib_base.http.RetrofitManager.toRequestBody
import com.yxjk.healthexpertclient.bean.CommonSettingMenuBean
import com.yxjk.healthexpertclient.bean.login.LoginResultBean
import com.yxjk.healthexpertclient.data.api.LoginApi
import com.yxjk.healthexpertclient.utils.DevicesInfoUtils
object LoginRepository: BaseRepository() {
private val service by lazy { RetrofitManager.getService(LoginApi::class.java) }
suspend fun login(account: String, password: String): ApiResponse<LoginResultBean> {
val params = mutableMapOf<String, Any?>()
params["deviceType"] = "${DevicesInfoUtils.getDeviceBrand()}"
params["deviceSystem"] = "${DevicesInfoUtils.getDeviceModel()}(Android${DevicesInfoUtils.getDeviceAndroidVersion()})"
params["username"] = account
params["password"] = password
return apiCall { service.login(params.toJson().toRequestBody()) }
}
/**
* 校验用户信息
*/
suspend fun checkUserInfo(realname:String,idCard:String,phone:String): ApiResponse<String> {
return apiCall {
val map = mutableMapOf<String, Any?>()
map.put("realname",realname)
map.put("idCard",idCard)
map.put("phone",phone)
service.checkUserInfo(map.toJson().toRequestBody())
}
}
/**
* 修改密码
*/
suspend fun resetUserPwd(newPassword:String,newPasswordConfirm:String,resetCode:String): ApiResponse<String> {
return apiCall {
val map = mutableMapOf<String, Any?>()
map.put("newPassword",newPassword)
map.put("newPasswordConfirm",newPasswordConfirm)
map.put("resetCode",resetCode)
service.resetUserPwd(map.toJson().toRequestBody())
}
}
suspend fun getCommonSettingMenuList(menuKey: String): ApiResponse<MutableList<CommonSettingMenuBean>> {
val params = mutableMapOf<String, Any?>()
params["dictKey"] = menuKey
return apiCall { service.getCommonSettingMenuList(params)}
}
}
@@ -0,0 +1,150 @@
package com.yxjk.healthexpertclient.data.repository
import com.btpj.lib_base.data.bean.ApiResponse
import com.btpj.lib_base.ext.toJson
import com.btpj.lib_base.http.BaseRepository
import com.btpj.lib_base.http.RetrofitManager
import com.btpj.lib_base.http.RetrofitManager.toRequestBody
import com.yxjk.healthexpertclient.bean.UploadFileResultBean
import com.yxjk.healthexpertclient.bean.im.IMAssistantBean
import com.yxjk.healthexpertclient.bean.mine.BillRecordBean
import com.yxjk.healthexpertclient.bean.mine.CommonSettingMenuBean
import com.yxjk.healthexpertclient.bean.mine.ConsultStatisticsBean
import com.yxjk.healthexpertclient.bean.mine.ConsultTypeBean
import com.yxjk.healthexpertclient.bean.mine.DiseaseBean
import com.yxjk.healthexpertclient.bean.mine.DoctorBean
import com.yxjk.healthexpertclient.bean.mine.PageManagerBean
import com.yxjk.healthexpertclient.bean.mine.SchedulingBean
import com.yxjk.healthexpertclient.bean.mine.SchedulingResultBean
import com.yxjk.healthexpertclient.bean.mine.SuspensionServiceBean
import com.yxjk.healthexpertclient.data.api.MineApi
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.MultipartBody
import okhttp3.RequestBody.Companion.asRequestBody
import okhttp3.RequestBody.Companion.toRequestBody
import java.io.File
object MineRepository : BaseRepository() {
private val service by lazy { RetrofitManager.getService(MineApi::class.java) }
suspend fun getDoctorInfo(): ApiResponse<DoctorBean> {
return apiCall { service.getDoctorInfo() }
}
suspend fun editDoctorInfo(doctorBean: DoctorBean): ApiResponse<String?> {
return apiCall { service.editDoctorInfo(doctorBean.toJson().toRequestBody()) }
}
suspend fun getDoctorScheduling(): ApiResponse<SchedulingResultBean> {
val params = mutableMapOf<String, Any?>()
return apiCall { service.getDoctorScheduling(params) }
}
suspend fun createDoctorScheduling(
schedulingList: MutableList<SchedulingBean>,
isJumpHoliday: Boolean,
openAudioVideo: Boolean,
isCustomScheduling: Boolean
): ApiResponse<String> {
val params = mutableMapOf<String, Any?>()
params["list"] = schedulingList
params["tfJumpHoliday"] = if (isJumpHoliday) "1" else "0"
params["tfDefault"] = if (isCustomScheduling) "1" else "0"
params["audioStatus"] = if (openAudioVideo) "1" else "0"
return apiCall { service.createDoctorScheduling(params.toJson().toRequestBody()) }
}
suspend fun createDoctorCustomScheduling(schedulingBean: SchedulingBean): ApiResponse<String> {
return apiCall { service.createDoctorScheduling(schedulingBean.toJson().toRequestBody()) }
}
suspend fun editPassword(
username: String,
oldPassword: String,
password: String,
confirmPassword: String
): ApiResponse<String> {
val params = mutableMapOf<String, Any?>()
params["username"] = username
params["oldpassword"] = oldPassword
params["confirmpassword"] = confirmPassword
params["password"] = password
// params["oldPassword"] = oldPassword
// params["confirmPassword"] = confirmPassword
return apiCall { service.editPassword(params.toJson().toRequestBody()) }
}
suspend fun getBillRecord(date: String, type: String, pageNo: Int, pageSize: Int = 20): ApiResponse<PageManagerBean<BillRecordBean>>{
val params = mutableMapOf<String, Any?>()
params["date"] = date
params["type"] = type
params["pageNo"] = pageNo
params["pageSize"] = pageSize
return apiCall { service.getBillRecord(params) }
}
suspend fun getBillDetail(id: String): ApiResponse<BillRecordBean>{
val params = mutableMapOf<String, Any?>()
params["id"] = id
return apiCall { service.getBillDetail(params) }
}
/**
* 收益统计
*/
suspend fun getConsultStatistics(): ApiResponse<ConsultStatisticsBean>{
return apiCall { service.getConsultStatistics() }
}
/**
* 咨询方式统计(按月)
* @param date 月份,示例2023-05
*/
suspend fun getConsultTypeData(date: String): ApiResponse<MutableList<ConsultTypeBean>>{
val params = mutableMapOf<String, Any?>()
params["date"] = date
return apiCall { service.getConsultTypeData(params) }
}
suspend fun getSuspensionServiceList(pageNo: Int, pageSize: Int = 20): ApiResponse<PageManagerBean<SuspensionServiceBean>>{
val params = mutableMapOf<String, Any?>()
params["pageNo"] = pageNo
params["pageSize"] = pageSize
return apiCall { service.getSuspensionServiceList(params) }
}
suspend fun stopSuspensionService(recordId: String): ApiResponse<String>{
val params = mutableMapOf<String, Any?>()
params["id"] = recordId
params["serviceStatus"] = 1
return apiCall { service.stopSuspensionService(params.toJson().toRequestBody()) }
}
suspend fun getSuspensionReasonList(): ApiResponse<MutableList<CommonSettingMenuBean>>{
val params = mutableMapOf<String, Any?>()
params["dictKey"] = "doctor_stop_reason_type"
return apiCall { service.getCommonSettingMenuList(params) }
}
suspend fun addSuspensionService(suspensionServiceBean: SuspensionServiceBean): ApiResponse<String>{
return apiCall { service.addSuspensionService(suspensionServiceBean.toJson().toRequestBody()) }
}
suspend fun getDateRangeConsultNum(startDate: Long, endDate: Long): ApiResponse<String>{
val params = mutableMapOf<String, Any?>()
params["startTime"] = startDate
params["endTime"] = endDate
return apiCall { service.getDateRangeConsultNum(params) }
}
suspend fun uploadFile(file: File): ApiResponse<UploadFileResultBean>{
val photoPart = MultipartBody.Part.createFormData("file", file.name, file.asRequestBody("image/jpg".toMediaTypeOrNull()))
return apiCall { service.uploadFile(photoPart, "".toRequestBody("".toMediaTypeOrNull())) }
}
suspend fun uploadHeadImage(imageUrl: String): ApiResponse<String>{
val params = mutableMapOf<String, Any?>()
params["avatar"] = imageUrl
return apiCall { service.uploadHeadImage(params) }
}
suspend fun getDoctorGoodAtDisease(departmentId: String): ApiResponse<MutableList<DiseaseBean>>{
val params = mutableMapOf<String, Any?>()
params["departmentId"] = departmentId
return apiCall { service.getDoctorGoodAtDisease(params) }
}
suspend fun submitAssistantConsultApply(): ApiResponse<IMAssistantBean>{
return apiCall { service.submitAssistantConsultApply() }
}
}
@@ -0,0 +1,74 @@
package com.yxjk.healthexpertclient.data.repository
import com.btpj.lib_base.data.bean.ApiResponse
import com.btpj.lib_base.data.local.DataStoreManager
import com.btpj.lib_base.ext.toJson
import com.btpj.lib_base.http.BaseRepository
import com.btpj.lib_base.http.RetrofitManager
import com.btpj.lib_base.http.RetrofitManager.toRequestBody
import com.yxjk.healthexpertclient.BuildConfig
import com.yxjk.healthexpertclient.bean.AppUpdateBean
import com.yxjk.healthexpertclient.bean.other.UserListBean
import com.yxjk.healthexpertclient.bean.workbench.ArchivesDetailResultBean
import com.yxjk.healthexpertclient.bean.workbench.AudioVideoCallBean
import com.yxjk.healthexpertclient.bean.workbench.CheckRecordUserInfoBean
import com.yxjk.healthexpertclient.bean.workbench.ConsultDetailBean
import com.yxjk.healthexpertclient.bean.workbench.ConsultRecordBean
import com.yxjk.healthexpertclient.bean.workbench.HealthInfoBean
import com.yxjk.healthexpertclient.bean.workbench.MessageBean
import com.yxjk.healthexpertclient.bean.workbench.PhysicalExaminationReportBean
import com.yxjk.healthexpertclient.bean.workbench.RefuseReasonBean
import com.yxjk.healthexpertclient.bean.workbench.WorkBenchConsultNumBean
import com.yxjk.healthexpertclient.data.api.OtherApi
import com.yxjk.healthexpertclient.data.api.WorkbenchApi
import com.yxjk.healthexpertclient.utils.DevicesInfoUtils
object OtherRepository : BaseRepository() {
private val service by lazy { RetrofitManager.getService(OtherApi::class.java) }
suspend fun getList(
username: String
): ApiResponse<UserListBean> {
val params = mutableMapOf<String, Any?>()
params["personType"] = 3
params["username"] = username
params["pageNo"] = 1
params["pageSize"] = 100
return apiCall {
service.listAll(params)
}
}
suspend fun simulateUser(
userId: String
): ApiResponse<Boolean> {
val params = mutableMapOf<String, Any?>()
params["userId"] = userId
return apiCall { service.fake(params) }
}
suspend fun fakeUser(
): ApiResponse<UserListBean.RecordsDTO> {
val params = mutableMapOf<String, Any?>()
// params["X-Access-Token"] = DataStoreManager.getToken()
return apiCall { service.fakeUser(params.toJson().toRequestBody()) }
}
suspend fun restore(
): ApiResponse<Boolean> {
val params = mutableMapOf<String, Any?>()
// params["userId"] = userId
return apiCall { service.restore(params.toJson().toRequestBody()) }
}
/**
* 校验token有效性
*/
suspend fun selectTokenExpire(token:String): ApiResponse<Boolean> {
return apiCall {
val map = mutableMapOf<String, Any?>()
map.put("token",token)
service.selectTokenExpire(map)
}
}
}
@@ -0,0 +1,193 @@
package com.yxjk.healthexpertclient.data.repository
import com.btpj.lib_base.data.bean.ApiResponse
import com.btpj.lib_base.ext.toJson
import com.btpj.lib_base.http.BaseRepository
import com.btpj.lib_base.http.RetrofitManager
import com.btpj.lib_base.http.RetrofitManager.toRequestBody
import com.yxjk.healthexpertclient.BuildConfig
import com.yxjk.healthexpertclient.bean.AppUpdateBean
import com.yxjk.healthexpertclient.bean.workbench.ArchivesDetailResultBean
import com.yxjk.healthexpertclient.bean.workbench.AudioVideoCallBean
import com.yxjk.healthexpertclient.bean.workbench.CheckRecordUserInfoBean
import com.yxjk.healthexpertclient.bean.workbench.ConsultDetailBean
import com.yxjk.healthexpertclient.bean.workbench.ConsultRecordBean
import com.yxjk.healthexpertclient.bean.workbench.HealthInfoBean
import com.yxjk.healthexpertclient.bean.workbench.MessageBean
import com.yxjk.healthexpertclient.bean.workbench.PhysicalExaminationReportBean
import com.yxjk.healthexpertclient.bean.workbench.RefuseReasonBean
import com.yxjk.healthexpertclient.bean.workbench.WorkBenchConsultNumBean
import com.yxjk.healthexpertclient.data.api.WorkbenchApi
object WorkbenchRepository : BaseRepository() {
private val service by lazy { RetrofitManager.getService(WorkbenchApi::class.java) }
suspend fun getConsultRecord(
type: String,
status: String,
pageNo: Int,
pageSize: Int
): ApiResponse<MutableList<ConsultRecordBean>> {
val params = mutableMapOf<String, Any?>()
params["type"] = type
params["status"] = status
params["pageNo"] = pageNo
params["pageSize"] = pageSize
return apiCall {
var result = service.getConsultRecord(params)
result
}
}
suspend fun getConsultHistory(
memberId: String,
searchKey: String,
pageNo: Int,
pageSize: Int
): ApiResponse<MutableList<ConsultRecordBean>> {
val params = mutableMapOf<String, Any?>()
params["memberId"] = memberId
params["searchKey"] = searchKey
params["pageNo"] = pageNo
params["pageSize"] = pageSize
return apiCall { service.getConsultRecord(params) }
}
suspend fun getImageTextConsultDetail(recordId: String): ApiResponse<ConsultDetailBean> {
val params = mutableMapOf<String, Any?>()
params["id"] = recordId
return apiCall { service.getImageTextConsultDetail(params) }
}
suspend fun getAudioVideoConsultDetail(recordId: String): ApiResponse<ConsultDetailBean> {
val params = mutableMapOf<String, Any?>()
params["id"] = recordId
return apiCall { service.getAudioVideoConsultDetail(params) }
}
suspend fun getRefusalAudioVideoCallReason(): ApiResponse<MutableList<RefuseReasonBean>> {
return apiCall { service.getRefusalAudioVideoCallReason() }
}
suspend fun refusalAudioVideoCall(
recordId: String,
reasonType: String,
rejectReason: String
): ApiResponse<String> {
val params = mutableMapOf<String, Any?>()
params["id"] = recordId
params["reasonType"] = reasonType
params["rejectReason"] = rejectReason
return apiCall { service.refusalAudioVideoCall(params) }
}
suspend fun acceptAudioVideoCall(
recordId: String,
startTime: Long,
endTime: Long
): ApiResponse<String> {
val params = mutableMapOf<String, Any?>()
params["id"] = recordId
params["startTime"] = startTime
params["endTime"] = endTime
return apiCall { service.acceptAudioVideoCall(params) }
}
suspend fun initiateAudioVideoCall(sessionId: String): ApiResponse<AudioVideoCallBean> {
val params = mutableMapOf<String, Any?>()
params["sessionId"] = sessionId
return apiCall { service.initiateAudioVideoCall(params) }
}
suspend fun getArchivesDetail(archivesId: String): ApiResponse<ArchivesDetailResultBean> {
val params = mutableMapOf<String, Any?>()
params["id"] = archivesId
return apiCall { service.getArchivesDetail(params) }
}
suspend fun getPhysicalExaminationReport(userId: String): ApiResponse<PhysicalExaminationReportBean> {
val params = mutableMapOf<String, Any?>()
params["userId"] = userId
return apiCall { service.getPhysicalExaminationReport(params) }
}
suspend fun getAudioVideoUnreadNum(): ApiResponse<String> {
val params = mutableMapOf<String, Any?>()
return apiCall { service.getAudioVideoUnreadNum(params) }
}
suspend fun getImageTextConsultRecord(tfReply:Int,imIdList: MutableList<String>): ApiResponse<MutableList<ConsultRecordBean>> {
val params = mutableMapOf<String, Any?>()
params["tfReply"] = tfReply
params["imIds"] = imIdList
return apiCall { service.getImageTextConsultRecord(params.toJson().toRequestBody()) }
}
suspend fun getBaseHealthInfo(memberId: String): ApiResponse<MutableList<HealthInfoBean>> {
val params = mutableMapOf<String, Any?>()
params["memberId"] = memberId
return apiCall { service.getBaseHealthInfo(params) }
}
// suspend fun getPhysicalExaminationReportDetail(
// idCard: String,
// year: String,
// type: String = ""
// ): ApiResponse<CheckItemBySfzhTotalBean> {
// return apiCall { service.getCheckItemBySfzhTotal(idCard, year, type) }
// }
suspend fun getHistoryReportNoDetail(id: String): ApiResponse<CheckRecordUserInfoBean>{
val params = mutableMapOf<String, Any?>()
params["id"] = id
return apiCall {service.getHistoryReportNoDetail(params)}
}
suspend fun finishConsult(id: String): ApiResponse<String> {
val map = mutableMapOf<String, Any?>()
map["id"] = id
return apiCall { service.finishConsult(map) }
}
suspend fun againAppointmentDateTime(
id: String,
startTime: Long,
endTime: Long
): ApiResponse<String> {
val params = mutableMapOf<String, Any?>()
params["id"] = id
params["startTime"] = startTime
params["endTime"] = endTime
params["type"] = "1"
return apiCall { service.againAppointmentDateTime(params) }
}
suspend fun audioVideoCallStart(id: String): ApiResponse<String>{
val params = mutableMapOf<String, Any?>()
params["id"] = id
params["type"] = "2" //郑文斌写的接口,非要这么搞,骂人骂他
params["startTime"] = ""
params["endTime"] = ""
return apiCall { service.audioVideoCallStart(params) }
}
suspend fun audioVideoCallEnd(id: String): ApiResponse<String>{
val params = mutableMapOf<String, Any?>()
params["id"] = id
return apiCall { service.audioVideoCallEnd(params) }
}
suspend fun getWorkBenchConsultNum(): ApiResponse<WorkBenchConsultNumBean>{
return apiCall { service.getWorkBenchConsultNum() }
}
suspend fun getConsultAssistantInfo(): ApiResponse<String>{
return apiCall { service.getConsultAssistantInfo() }
}
suspend fun getMessageList(pageNo: Int,
pageSize: Int): ApiResponse<MutableList<MessageBean>>{
val params = mutableMapOf<String, Any?>()
params["pageNo"] = pageNo
params["pageSize"] = pageSize
return apiCall { service.getMessageList(params.toJson().toRequestBody()) }
}
suspend fun getAppUpdateInfo(appId: String): ApiResponse<AppUpdateBean>{
val params = mutableMapOf<String, Any?>()
params["androidOrIos"] = 1
params["packageName"] = BuildConfig.APPLICATION_ID
return apiCall { service.getAppUpdateInfo(params) }
}
}
@@ -0,0 +1,11 @@
package com.yxjk.healthexpertclient.event
import com.yxjk.healthexpertclient.bean.mine.DiseaseBean
/**
* @author nanfeifei
* @time 2023/6/25 18:34
* @description
*/
class AddGoodAtDiseaseEvent(val list: MutableList<DiseaseBean>) {
}
@@ -0,0 +1,9 @@
package com.yxjk.healthexpertclient.event
/**
* @author nanfeifei
* @time 2023/5/29 16:50
* @description 咨询记录在详情页操作导致状态变化后刷新列表使用
*/
class ConsultRecordEvent {
}
@@ -0,0 +1,9 @@
package com.yxjk.healthexpertclient.event
/**
* @author nanfeifei
* @time 2023/6/5 16:22
* @description 医生信息发生变化后刷新首页医生信息
*/
class DoctorEvent {
}
@@ -0,0 +1,14 @@
package com.yxjk.healthexpertclient.event;
public class GlobalEvent {
public final int message;//0 重新登录
public Object object;
public GlobalEvent(int message) {
this.message = message;
}
public GlobalEvent(int message, Object object) {
this.message = message;
this.object=object;
}
}
@@ -0,0 +1,9 @@
package com.yxjk.healthexpertclient.event
/**
* @author nanfeifei
* @time 2023/6/5 14:07
* @description 发布暂停服务后刷新暂停服务记录
*/
class SuspensionServiceEvent {
}
@@ -0,0 +1,9 @@
package com.yxjk.healthexpertclient.event
/**
* @author nanfeifei
* @time 2023/7/18 10:30
* @description
*/
class WorkbenchEvent {
}
@@ -0,0 +1,25 @@
package com.yxjk.healthexpertclient.ext
import com.github.gzuliyujiang.wheelpicker.entity.DateEntity
import com.github.gzuliyujiang.wheelpicker.entity.DatimeEntity
import java.util.Calendar
/**
* @author nanfeifei
* @time 2023/7/11 14:01
* @description 几天之后的时间
* @param day 日期差值
*/
fun DatimeEntity.dayOnAfter(day: Int): DatimeEntity{
val entity = DatimeEntity()
var calendar = Calendar.getInstance()
calendar.timeInMillis = this.toTimeInMillis()
calendar.add(Calendar.DAY_OF_MONTH, day)
entity.date = DateEntity.target(calendar)
return entity
}
fun DateEntity.target(millis: Long): DateEntity{
var calendar = Calendar.getInstance()
calendar.timeInMillis = millis
return DateEntity.target(calendar)
}
@@ -0,0 +1,161 @@
package com.yxjk.healthexpertclient.ext
import android.content.Context
import android.util.Log
import com.yxjk.healthexpertclient.MyApplication.Companion.appViewModel
import com.yxjk.healthexpertclient.utils.TUIUtils
import com.tencent.imsdk.BaseConstants
import com.tencent.imsdk.v2.V2TIMConversation
import com.tencent.imsdk.v2.V2TIMManager
import com.tencent.imsdk.v2.V2TIMSDKConfig
import com.tencent.imsdk.v2.V2TIMSDKListener
import com.tencent.imsdk.v2.V2TIMUserFullInfo
import com.tencent.imsdk.v2.V2TIMUserStatus
import com.tencent.qcloud.tuicore.TUILogin
import com.tencent.qcloud.tuicore.interfaces.TUICallback
import com.tencent.qcloud.tuikit.TUICommonDefine
import com.tencent.qcloud.tuikit.tuicallengine.TUICallDefine
import com.tencent.qcloud.tuikit.tuicallkit.TUICallKit
import com.tencent.qcloud.tuikit.tuicallkit.base.Constants
import com.tencent.qcloud.tuikit.tuicallkit.config.OfflinePushInfoConfig
import com.tencent.qcloud.tuikit.tuichat.bean.WorkBean
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
fun Context.initIMSDK(imSdkAppId: Int) {
val config = V2TIMSDKConfig()
config.logLevel = V2TIMSDKConfig.V2TIM_LOG_INFO
V2TIMManager.getInstance().initSDK(this, imSdkAppId, config)
}
/**
* 腾讯im登录方法
*/
fun Context.loginIm(successCall: () -> Unit = {}) {
var userId = appViewModel.imUserId.value
var userSig: String = appViewModel.imSig.value
var appId = appViewModel.imAppId.value
if (userSig.isNullOrEmpty()) {
CoroutineScope(Dispatchers.Main).launch {
appViewModel.getIMSig(successCall = {
loginIm(it.sdkAppId, it.userId, it.userSig, successCall)
})
}
} else {
loginIm(appId, userId, userSig, successCall)
}
}
fun Context.loginIm(appId: String, userId: String, userSig: String, successCall: () -> Unit = {}) {
if (TUILogin.isUserLogined() && userId == TUILogin.getUserId()) {
successCall.invoke()
return
}
TUILogin.login(
this,
appId.toInt(),
userId,
userSig,
TUIUtils.getLoginConfig(),
object : TUICallback() {
override fun onError(code: Int, desc: String) {
when (code) {
BaseConstants.ERR_SVR_ACCOUNT_USERSIG_EXPIRED,
BaseConstants.ERR_USER_SIG_EXPIRED -> {//UserSig过期
userSigExpired()
}
}
Log.i(
"loginIm",
"imLogin errorCode = $code, errorInfo = $desc"
)
}
override fun onSuccess() {
appViewModel.setUserIMInfo()
successCall.invoke()
}
})
}
fun Context.userSigExpired(loginSuccessCall: () -> Unit = {}){
logout(successCall = {
loginIm(loginSuccessCall)
})
}
fun logout(successCall: () -> Unit = {}){
if (!TUILogin.isUserLogined()){
return
}
CoroutineScope(Dispatchers.Main).launch{
appViewModel.imSig.emit("") //清空本地缓存的UserSig
appViewModel.imUserId.emit("")
}
TUILogin.logout(object : TUICallback(){
override fun onSuccess() {
successCall.invoke()
}
override fun onError(errorCode: Int, errorMessage: String?) {
Log.i("logout","IM logout errorCode = $errorCode, errorInfo = $errorMessage")
}
})
}
fun Context.startC2CChat(chatId: String, groupName: String, workBean: WorkBean? = null) {
if (TUILogin.isUserLogined()) {
// TUIUtils.createGroup("VHMQIUMM", "android测试组", V2TIMConversation.V2TIM_GROUP)
TUIUtils.startChat(chatId, groupName, V2TIMConversation.V2TIM_C2C, workBean)
} else {
loginIm(successCall = {
TUIUtils.startChat(chatId, groupName, V2TIMConversation.V2TIM_C2C, workBean)
})
}
}
fun Context.startGroupChat(groupId: String, groupName: String = "", workBean: WorkBean? = null) {
if (TUILogin.isUserLogined()) {
// TUIUtils.createGroup("VHMQIUMM", "android测试组", V2TIMConversation.V2TIM_GROUP)
TUIUtils.startChat(groupId, groupName, V2TIMConversation.V2TIM_GROUP, workBean)
} else {
loginIm(successCall = {
TUIUtils.startChat(groupId, groupName, V2TIMConversation.V2TIM_GROUP, workBean)
})
}
}
fun Context.call(
userId: String,
callMediaType: TUICallDefine.MediaType = TUICallDefine.MediaType.Video
) {
if (TUILogin.isUserLogined()) {
TUICallKit.createInstance(this).call(userId, callMediaType)
} else {
loginIm(successCall = {
TUICallKit.createInstance(this).call(userId, callMediaType)
})
}
}
fun Context.groupCall(
groupId: String,
userIdList: List<String>,
callMediaType: TUICallDefine.MediaType = TUICallDefine.MediaType.Video,
params: TUICallDefine.CallParams? = null,
callback: TUICommonDefine.Callback? = null
) {
var callParams = TUICallDefine.CallParams()
if (params == null) {
callParams.offlinePushInfo = OfflinePushInfoConfig.createOfflinePushInfo(this)
callParams.timeout = Constants.SIGNALING_MAX_TIME
} else {
callParams = params
}
if (TUILogin.isUserLogined()) {
TUICallKit.createInstance(this)
.groupCall(groupId, userIdList, callMediaType, callParams, callback)
} else {
loginIm(successCall = {
TUICallKit.createInstance(this)
.groupCall(groupId, userIdList, callMediaType, callParams, callback)
})
}
}
@@ -0,0 +1,262 @@
package com.yxjk.healthexpertclient.ext
import android.content.Context
import android.content.Intent
import android.os.Bundle
import androidx.core.view.ContentInfoCompat
import com.yxjk.healthexpertclient.bean.mine.DiseaseBean
import com.yxjk.healthexpertclient.ui.login.ChangePassWordActivity
import com.yxjk.healthexpertclient.ui.login.LoginActivity
import com.yxjk.healthexpertclient.ui.login.RetrievePassWordActivity
import com.yxjk.healthexpertclient.ui.main.MainActivity
import com.yxjk.healthexpertclient.ui.main.WebActivity
import com.yxjk.healthexpertclient.ui.mine.AddSuspensionAnnouncementActivity
import com.yxjk.healthexpertclient.ui.mine.BillRecordActivity
import com.yxjk.healthexpertclient.ui.mine.ConsultStatisticsActivity
import com.yxjk.healthexpertclient.ui.mine.CustomSchedulingActivity
import com.yxjk.healthexpertclient.ui.mine.EditPasswordActivity
import com.yxjk.healthexpertclient.ui.mine.GoodAtDiseaseActivity
import com.yxjk.healthexpertclient.ui.mine.PersonInfoActivity
import com.yxjk.healthexpertclient.ui.mine.SchedulingActivity
import com.yxjk.healthexpertclient.ui.mine.SettingActivity
import com.yxjk.healthexpertclient.ui.mine.SuspensionServiceActivity
import com.yxjk.healthexpertclient.ui.mine.WithDrawActivity
import com.yxjk.healthexpertclient.ui.other.SimulateUserActivity
import com.yxjk.healthexpertclient.ui.workbench.ArchivesDetailActivity
import com.yxjk.healthexpertclient.ui.workbench.AudioVideoConsultActivity
import com.yxjk.healthexpertclient.ui.workbench.BaseHealthyInformationActivity
import com.yxjk.healthexpertclient.ui.workbench.BigImageActivity
import com.yxjk.healthexpertclient.ui.workbench.CheckUpDetailActivity
import com.yxjk.healthexpertclient.ui.workbench.ConsultFinishActivity
import com.yxjk.healthexpertclient.ui.workbench.ConsultHistoryActivity
import com.yxjk.healthexpertclient.ui.workbench.ConsultRecordActivity
import com.yxjk.healthexpertclient.ui.workbench.ConsultWaitStartActivity
import com.yxjk.healthexpertclient.ui.workbench.ImageTextConsultDetailActivity
import com.yxjk.healthexpertclient.ui.workbench.MessageListActivity
fun startActivity(context: Context, @ContentInfoCompat.Flags flags: MutableList<Int>? = null,
bundle: Bundle? = null, targetClass: Class<*>){
var intent = Intent(context, targetClass)
if(!flags.isNullOrEmpty()){
flags.forEachIndexed { index, flag ->
if (0 == index){
intent.flags = flag
}else{
intent.addFlags(flag)
}
}
}
if (bundle != null){
intent.putExtras(bundle)
}
context.startActivity(intent)
}
/**
* 登录
*/
fun startLoginActivity(context: Context){
var flagArray = mutableListOf<Int>()
// flagArray.add(Intent.FLAG_ACTIVITY_NO_HISTORY)
flagArray.add(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK)
startActivity(context, flags = flagArray, targetClass = LoginActivity::class.java)
}
/**
* 找回密码
*/
fun startRetrievePassWordActivity(context: Context){
val bundle = Bundle()
startActivity(context, bundle = bundle, targetClass = RetrievePassWordActivity::class.java)
}
/**
* 首页
*/
fun startMainActivity(context: Context){
val bundle = Bundle()
startActivity(context, bundle = bundle, targetClass = MainActivity::class.java)
}
/**
* 咨询记录
*/
fun startConsultRecordActivity(context: Context, consultModel: Int, consultIndex: Int = 0){
val bundle = Bundle()
bundle.putInt("consultModel", consultModel)
bundle.putInt("consultIndex", consultIndex)
startActivity(context, bundle = bundle, targetClass = ConsultRecordActivity::class.java)
}
/**
* 咨询详情
*/
fun startConsultDetailActivity(context: Context, recordId: String){
val bundle = Bundle()
bundle.putString("recordId", recordId)
startActivity(context, bundle = bundle, targetClass = ImageTextConsultDetailActivity::class.java)
}
/**
* 基础健康信息
*/
fun startBaseHealthyInformationActivity(context: Context, recordId: Int){
val bundle = Bundle()
bundle.putInt("memberId", recordId)
startActivity(context, bundle = bundle, targetClass = BaseHealthyInformationActivity::class.java)
}
/**
* 档案详情
*/
fun startArchivesDetailActivity(context: Context, archivesId: String){
val bundle = Bundle()
bundle.putString("archivesId", archivesId)
startActivity(context, bundle = bundle, targetClass = ArchivesDetailActivity::class.java)
}
/**
* 咨询历史
*/
fun startConsultHistoryActivity(context: Context, recordId: Int){
val bundle = Bundle()
bundle.putInt("recordId", recordId)
startActivity(context, bundle = bundle, targetClass = ConsultHistoryActivity::class.java)
}
/**
* 音视频咨询-待确认
*/
fun startConsultWaitConfirmActivity(context: Context, recordId: String){
val bundle = Bundle()
bundle.putString("recordId", recordId)
startActivity(context, bundle = bundle, targetClass = AudioVideoConsultActivity::class.java)
}
/**
* 音视频咨询-已完成
*/
fun startConsultFinishActivity(context: Context, recordId: String){
val bundle = Bundle()
bundle.putString("recordId", recordId)
startActivity(context, bundle = bundle, targetClass = ConsultFinishActivity::class.java)
}
/**
* 音视频咨询-待开始
*/
fun startConsultWaitStartActivity(context: Context, recordId: String){
val bundle = Bundle()
bundle.putString("recordId", recordId)
startActivity(context, bundle = bundle, targetClass = ConsultWaitStartActivity::class.java)
}
/**
* 排班设置
*/
fun startSchedulingActivity(context: Context){
startActivity(context, targetClass = SchedulingActivity::class.java)
}
/**
* 自定义排班
*/
fun startCustomSchedulingActivity(context: Context){
startActivity(context, targetClass = CustomSchedulingActivity::class.java)
}
/**
* 暂停服务
*/
fun startSuspensionServiceActivity(context: Context){
startActivity(context, targetClass = SuspensionServiceActivity::class.java)
}
/**
* 暂停服务公告
*/
fun startAddSuspensionAnnouncementActivity(context: Context){
startActivity(context, targetClass = AddSuspensionAnnouncementActivity::class.java)
}
/**
* 咨询统计
*/
fun startConsultStatisticsActivity(context: Context){
startActivity(context, targetClass = ConsultStatisticsActivity::class.java)
}
/**
* 账单明细
*/
fun startBillRecordActivity(context: Context){
startActivity(context, targetClass = BillRecordActivity::class.java)
}
/**
* 提现详情
*/
fun startWithDrawActivity(context: Context, recordId: Int){
val bundle = Bundle()
bundle.putInt("recordId", recordId)
startActivity(context, bundle = bundle, targetClass = WithDrawActivity::class.java)
}
/**
* 修改密码
*/
fun startEditPasswordActivity(context: Context){
startActivity(context, targetClass = EditPasswordActivity::class.java)
}
/**
* 修改密码
*/
fun Context.startChangePassWordActivity(code:String) {
val bundle = Bundle()
bundle.putString("code", code)
startActivity(this, bundle = bundle,targetClass = ChangePassWordActivity::class.java)
}
/**
* 个人信息
*/
fun startPersonInfoActivity(context: Context){
startActivity(context, targetClass = PersonInfoActivity::class.java)
}
/**
* 设置
*/
fun startSettingActivity(context: Context){
startActivity(context, targetClass = SettingActivity::class.java)
}
/**
* 擅长病种
*/
fun startGoodAtDiseaseActivity(context: Context, departmentId: String, currentDiseaseList: MutableList<DiseaseBean>){
val bundle = Bundle()
bundle.putString("departmentId", departmentId)
bundle.putParcelableArrayList("currentDiseaseList", ArrayList(currentDiseaseList))
startActivity(context, bundle = bundle, targetClass = GoodAtDiseaseActivity::class.java)
}
/**
* 体检详情
*/
fun startCheckUpDetailActivity(context: Context, id: String?){
val bundle = Bundle()
bundle.putString("id", id.orEmpty())
startActivity(context, bundle = bundle, targetClass = CheckUpDetailActivity::class.java)
}
/**
* 跳转Web
*/
fun startWebActivity(context: Context, url: String){
val bundle = Bundle()
bundle.putString("url", url)
bundle.putBoolean("javaScriptEnabled", true)
startActivity(context, bundle = bundle, targetClass = WebActivity::class.java)
}
/**
* 消息
*/
fun startMessageListActivity(context: Context){
startActivity(context, targetClass = MessageListActivity::class.java)
}
/**
* 查看大图
*/
fun Context.startBigImageActivity(url: String, isFilePath: Boolean = false){
val bundle = Bundle()
bundle.putString("imageUrl", url)
bundle.putBoolean("isFilePath", isFilePath)
startActivity(this, bundle = bundle, targetClass = BigImageActivity::class.java)
}
/**
* 模拟用户
*/
fun startSimulateUserActivity(context: Context){
startActivity(context, targetClass = SimulateUserActivity::class.java)
}
@@ -0,0 +1,581 @@
package com.yxjk.healthexpertclient.ui.im;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Build;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import androidx.viewpager2.widget.ViewPager2;
import com.yxjk.healthexpertclient.R;
import com.yxjk.healthexpertclient.ui.im.adapter.FragmentAdapter;
import com.yxjk.healthexpertclient.ui.im.view.Menu;
import com.yxjk.healthexpertclient.utils.TUIUtils;
import com.tencent.imsdk.BaseConstants;
import com.tencent.imsdk.v2.V2TIMCallback;
import com.tencent.imsdk.v2.V2TIMConversation;
import com.tencent.imsdk.v2.V2TIMConversationListFilter;
import com.tencent.imsdk.v2.V2TIMConversationOperationResult;
import com.tencent.imsdk.v2.V2TIMConversationResult;
import com.tencent.imsdk.v2.V2TIMFriendApplication;
import com.tencent.imsdk.v2.V2TIMFriendApplicationResult;
import com.tencent.imsdk.v2.V2TIMFriendshipListener;
import com.tencent.imsdk.v2.V2TIMManager;
import com.tencent.imsdk.v2.V2TIMValueCallback;
import com.tencent.qcloud.tuicore.TUIConstants;
import com.tencent.qcloud.tuicore.component.TitleBarLayout;
import com.tencent.qcloud.tuicore.component.action.PopActionClickListener;
import com.tencent.qcloud.tuicore.component.action.PopMenuAction;
import com.tencent.qcloud.tuicore.component.activities.BaseLightActivity;
import com.tencent.qcloud.tuicore.component.interfaces.ITitleBarLayout;
import com.tencent.qcloud.tuicore.util.ErrorMessageConverter;
import com.tencent.qcloud.tuicore.util.ToastUtil;
import com.tencent.qcloud.tuikit.tuicontact.TUIContactConstants;
import com.tencent.qcloud.tuikit.tuicontact.classicui.pages.TUIContactFragment;
import com.tencent.qcloud.tuikit.tuiconversation.TUIConversationConstants;
import com.tencent.qcloud.tuikit.tuiconversation.classicui.page.TUIConversationFragment;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
public class IMMainActivity extends BaseLightActivity {
private static final String TAG = IMMainActivity.class.getSimpleName();
private TextView mCommunityBtnText;
private TextView mConversationBtnText;
private TextView mContactBtnText;
private TextView mProfileSelfBtnText;
private View mConversationBtn;
private ImageView mCommunityBtnIcon;
private ImageView mConversationBtnIcon;
private ImageView mContactBtnIcon;
private ImageView mProfileSelfBtnIcon;
private TextView mMsgUnread;
private TextView mNewFriendUnread;
private View mainNavigationBar;
private TitleBarLayout mainTitleBar;
private Menu menu;
private ViewPager2 mainViewPager;
private List<Fragment> fragments;
private int count = 0;
private long lastClickTime = 0;
private HashMap<String, V2TIMConversation> markUnreadMap = new HashMap<>();
private static WeakReference<IMMainActivity> instance;
private BroadcastReceiver unreadCountReceiver;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
Log.i(TAG, "onCreate");
super.onCreate(savedInstanceState);
instance = new WeakReference<>(this);
initView();
initUnreadCountReceiver();
}
private void initUnreadCountReceiver() {
unreadCountReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
long unreadCount = intent.getLongExtra(TUIConstants.UNREAD_COUNT_EXTRA, 0);
if (unreadCount > 0) {
mMsgUnread.setVisibility(View.VISIBLE);
} else {
mMsgUnread.setVisibility(View.GONE);
}
String unreadStr = "" + unreadCount;
if (unreadCount > 100) {
unreadStr = "99+";
}
mMsgUnread.setText(unreadStr);
// update Huawei offline push Badge
// OfflineMessageDispatcher.updateBadge(MainActivity.this, (int) unreadCount);
}
};
IntentFilter unreadCountFilter = new IntentFilter();
unreadCountFilter.addAction(TUIConstants.CONVERSATION_UNREAD_COUNT_ACTION);
LocalBroadcastManager.getInstance(this).registerReceiver(unreadCountReceiver, unreadCountFilter);
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
Log.i(TAG, "onNewIntent");
setIntent(intent);
}
private void initView() {
setContentView(R.layout.im_activity);
mainTitleBar = findViewById(R.id.main_title_bar);
initMenuAction();
mCommunityBtnText = findViewById(R.id.tab_community_tv);
mConversationBtnText = findViewById(R.id.conversation);
mContactBtnText = findViewById(R.id.contact);
mProfileSelfBtnText = findViewById(R.id.mine);
mCommunityBtnIcon = findViewById(R.id.tab_community_icon);
mConversationBtnIcon = findViewById(R.id.tab_conversation_icon);
mContactBtnIcon = findViewById(R.id.tab_contact_icon);
mProfileSelfBtnIcon = findViewById(R.id.tab_profile_icon);
mConversationBtn = findViewById(R.id.conversation_btn_group);
mMsgUnread = findViewById(R.id.msg_total_unread);
mNewFriendUnread = findViewById(R.id.new_friend_total_unread);
mainNavigationBar = findViewById(R.id.main_navigation_bar);
fragments = new ArrayList<>();
fragments.add(new TUIConversationFragment());
// fragments.add(new TUICommunityFragment());
fragments.add(new TUIContactFragment());
// fragments.add(new ProfileFragment());
mainViewPager = findViewById(R.id.view_pager);
FragmentAdapter fragmentAdapter = new FragmentAdapter(this);
fragmentAdapter.setFragmentList(fragments);
mainViewPager.setUserInputEnabled(false);
mainViewPager.setOffscreenPageLimit(4);
mainViewPager.setAdapter(fragmentAdapter);
mainViewPager.setCurrentItem(0, false);
setConversationTitleBar();
prepareToClearAllUnreadMessage();
}
private void initMenuAction() {
int titleBarIconSize = 23;
mainTitleBar.getLeftIcon().setMaxHeight(titleBarIconSize);
mainTitleBar.getLeftIcon().setMaxWidth(titleBarIconSize);
mainTitleBar.getRightIcon().setMaxHeight(titleBarIconSize);
mainTitleBar.getRightIcon().setMaxWidth(titleBarIconSize);
mainTitleBar.setOnRightClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (menu == null) {
return;
}
if (menu.isShowing()) {
menu.hide();
} else {
menu.show();
}
}
});
}
private void prepareToClearAllUnreadMessage() {
mMsgUnread.setOnTouchListener(new View.OnTouchListener() {
private float downX;
private float downY;
private boolean isTriggered = false;
@Override
public boolean onTouch(View view, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
downX = mMsgUnread.getX();
downY = mMsgUnread.getY();
break;
case MotionEvent.ACTION_MOVE:
if (isTriggered) {
return true;
}
float viewX = view.getX();
float viewY = view.getY();
float eventX = event.getX();
float eventY = event.getY();
float translationX = eventX + viewX - downX;
float translationY = eventY + viewY - downY;
view.setTranslationX(translationX);
view.setTranslationY(translationY);
// If the moved x and y axis coordinates exceed a certain pixel, it will trigger one-click to clear all unread sessions
if (Math.abs(translationX) > 200|| Math.abs(translationY) > 200) {
isTriggered = true;
mMsgUnread.setVisibility(View.GONE);
triggerClearAllUnreadMessage();
}
break;
case MotionEvent.ACTION_UP:
view.setTranslationX(0);
view.setTranslationY(0);
isTriggered = false;
break;
case MotionEvent.ACTION_CANCEL:
isTriggered = false;
break;
}
return true;
}
});
}
private void triggerClearAllUnreadMessage() {
V2TIMManager.getMessageManager().markAllMessageAsRead(new V2TIMCallback() {
@Override
public void onSuccess() {
Log.i(TAG, "markAllMessageAsRead success");
ToastUtil.toastShortMessage(IMMainActivity.this.getString(R.string.mark_all_message_as_read_succ));
}
@Override
public void onError(int code, String desc) {
Log.i(TAG, "markAllMessageAsRead error:" + code + ", desc:" + ErrorMessageConverter.convertIMError(code, desc));
ToastUtil.toastShortMessage(IMMainActivity.this.getString(R.string.mark_all_message_as_read_err_format, code, ErrorMessageConverter.convertIMError(code, desc)));
mMsgUnread.setVisibility(View.VISIBLE);
}
});
V2TIMConversationListFilter filter = new V2TIMConversationListFilter();
filter.setMarkType(V2TIMConversation.V2TIM_CONVERSATION_MARK_TYPE_UNREAD);
getMarkUnreadConversationList(filter, 0, 100, true, new V2TIMValueCallback<HashMap<String, V2TIMConversation>>() {
@Override
public void onSuccess(HashMap<String, V2TIMConversation> stringV2TIMConversationHashMap) {
if (stringV2TIMConversationHashMap.size() == 0) {
return;
}
List<String> unreadConversationIDList = new ArrayList<>();
Iterator<Map.Entry<String, V2TIMConversation>> iterator = markUnreadMap.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, V2TIMConversation> entry = iterator.next();
unreadConversationIDList.add(entry.getKey());
}
V2TIMManager.getConversationManager().markConversation(unreadConversationIDList,
V2TIMConversation.V2TIM_CONVERSATION_MARK_TYPE_UNREAD,
false,
new V2TIMValueCallback<List<V2TIMConversationOperationResult>>() {
@Override
public void onSuccess(List<V2TIMConversationOperationResult> v2TIMConversationOperationResults) {
for (V2TIMConversationOperationResult result : v2TIMConversationOperationResults) {
if (result.getResultCode() == BaseConstants.ERR_SUCC) {
V2TIMConversation v2TIMConversation = markUnreadMap.get(result.getConversationID());
if (!v2TIMConversation.getMarkList().contains(V2TIMConversation.V2TIM_CONVERSATION_MARK_TYPE_HIDE)) {
markUnreadMap.remove(result.getConversationID());
}
}
}
}
@Override
public void onError(int code, String desc) {
Log.e(TAG, "triggerClearAllUnreadMessage->markConversation error:" + code + ", desc:" + ErrorMessageConverter.convertIMError(code, desc));
}
});
}
@Override
public void onError(int code, String desc) {
Log.e(TAG, "triggerClearAllUnreadMessage->getMarkUnreadConversationList error:" + code + ", desc:" + ErrorMessageConverter.convertIMError(code, desc));
}
});
}
private void getMarkUnreadConversationList(V2TIMConversationListFilter filter, long nextSeq, int count, boolean fromStart, V2TIMValueCallback<HashMap<String, V2TIMConversation>> callback) {
if (fromStart) {
markUnreadMap.clear();
}
V2TIMManager.getConversationManager().getConversationListByFilter(filter, nextSeq, count, new V2TIMValueCallback<V2TIMConversationResult>() {
@Override
public void onSuccess(V2TIMConversationResult v2TIMConversationResult) {
List<V2TIMConversation> conversationList = v2TIMConversationResult.getConversationList();
for (V2TIMConversation conversation : conversationList) {
markUnreadMap.put(conversation.getConversationID(), conversation);
}
if (!v2TIMConversationResult.isFinished()) {
getMarkUnreadConversationList(filter, v2TIMConversationResult.getNextSeq(), count, false, callback);
} else {
if (callback != null) {
callback.onSuccess(markUnreadMap);
}
}
}
@Override
public void onError(int code, String desc) {
Log.e(TAG, "getMarkUnreadConversationList error:" + code + ", desc:" + ErrorMessageConverter.convertIMError(code, desc));
}
});
}
public void tabClick(View view) {
resetMenuState();
switch (view.getId()) {
case R.id.conversation_btn_group:
mainTitleBar.setVisibility(View.VISIBLE);
mainViewPager.setCurrentItem(0, false);
setConversationTitleBar();
break;
case R.id.community_btn_group:
mainTitleBar.setVisibility(View.GONE);
mainViewPager.setCurrentItem(1, false);
setCommunityBackground();
break;
case R.id.contact_btn_group:
mainTitleBar.setVisibility(View.VISIBLE);
mainViewPager.setCurrentItem(2, false);
setContactTitleBar();
break;
case R.id.myself_btn_group:
mainTitleBar.setVisibility(View.VISIBLE);
mainViewPager.setCurrentItem(3, false);
setProfileTitleBar();
break;
default:
break;
}
}
private void setCommunityBackground() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
getWindow().setStatusBarColor(getResources().getColor(R.color.demo_community_page_status_bar_color));
}
mainNavigationBar.setBackgroundColor(getResources().getColor(R.color.demo_community_page_navigate_bar_color));
}
private void setConversationTitleBar() {
mainTitleBar.setTitle(getResources().getString(R.string.conversation_title), ITitleBarLayout.Position.MIDDLE);
mainTitleBar.getLeftGroup().setVisibility(View.GONE);
mainTitleBar.getRightGroup().setVisibility(View.VISIBLE);
int titleBarIconSize = 23;
ViewGroup.LayoutParams params = mainTitleBar.getRightIcon().getLayoutParams();
params.width = titleBarIconSize;
params.height = titleBarIconSize;
mainTitleBar.getRightIcon().setLayoutParams(params);
setConversationMenu();
}
private void setConversationMenu() {
menu = new Menu(this, mainTitleBar.getRightIcon());
PopActionClickListener popActionClickListener = new PopActionClickListener() {
@Override
public void onActionClick(int position, Object data) {
PopMenuAction action = (PopMenuAction) data;
if (TextUtils.equals(action.getActionName(), getResources().getString(R.string.start_conversation))) {
TUIUtils.startActivity("StartC2CChatActivity", null);
}
if (TextUtils.equals(action.getActionName(), getResources().getString(R.string.create_private_group))) {
Bundle bundle = new Bundle();
bundle.putInt(TUIConversationConstants.GroupType.TYPE, TUIConversationConstants.GroupType.PRIVATE);
TUIUtils.startActivity("StartGroupChatActivity", bundle);
}
if (TextUtils.equals(action.getActionName(), getResources().getString(R.string.create_group_chat))) {
Bundle bundle = new Bundle();
bundle.putInt(TUIConversationConstants.GroupType.TYPE, TUIConversationConstants.GroupType.PUBLIC);
TUIUtils.startActivity("StartGroupChatActivity", bundle);
}
if (TextUtils.equals(action.getActionName(), getResources().getString(R.string.create_chat_room))) {
Bundle bundle = new Bundle();
bundle.putInt(TUIConversationConstants.GroupType.TYPE, TUIConversationConstants.GroupType.CHAT_ROOM);
TUIUtils.startActivity("StartGroupChatActivity", bundle);
}
if (TextUtils.equals(action.getActionName(), getResources().getString(R.string.create_community))) {
Bundle bundle = new Bundle();
bundle.putInt(TUIConversationConstants.GroupType.TYPE, TUIConversationConstants.GroupType.COMMUNITY);
TUIUtils.startActivity("StartGroupChatActivity", bundle);
}
menu.hide();
}
};
List<PopMenuAction> menuActions = new ArrayList<>();
PopMenuAction action = new PopMenuAction();
action.setActionName(getResources().getString(R.string.start_conversation));
action.setActionClickListener(popActionClickListener);
action.setIconResId(R.drawable.create_c2c);
menuActions.add(action);
action = new PopMenuAction();
action.setActionName(getResources().getString(R.string.create_group_chat));
action.setIconResId(R.drawable.group_icon);
action.setActionClickListener(popActionClickListener);
menuActions.add(action);
menu.setMenuAction(menuActions);
}
private void setContactTitleBar() {
mainTitleBar.setTitle(getResources().getString(R.string.contact_title), ITitleBarLayout.Position.MIDDLE);
mainTitleBar.getLeftGroup().setVisibility(View.GONE);
mainTitleBar.getRightGroup().setVisibility(View.VISIBLE);
setContactMenu();
}
public void setContactMenu() {
menu = new Menu(this, mainTitleBar.getRightIcon());
List<PopMenuAction> menuActionList = new ArrayList<>(2);
PopActionClickListener popActionClickListener = new PopActionClickListener() {
@Override
public void onActionClick(int index, Object data) {
PopMenuAction action = (PopMenuAction) data;
if (TextUtils.equals(action.getActionName(), getResources().getString(R.string.add_friend))) {
Bundle bundle = new Bundle();
bundle.putBoolean(TUIContactConstants.GroupType.GROUP, false);
TUIUtils.startActivity("AddMoreActivity", bundle);
}
if (TextUtils.equals(action.getActionName(), getResources().getString(R.string.add_group))) {
Bundle bundle = new Bundle();
bundle.putBoolean(TUIContactConstants.GroupType.GROUP, true);
TUIUtils.startActivity("AddMoreActivity", bundle);
}
menu.hide();
}
};
PopMenuAction action = new PopMenuAction();
action.setActionName(getResources().getString(R.string.add_friend));
action.setIconResId(com.tencent.qcloud.tuikit.tuicontact.R.drawable.contact_add_friend);
action.setActionClickListener(popActionClickListener);
menuActionList.add(action);
action = new PopMenuAction();
action.setActionName(getResources().getString(R.string.add_group));
action.setIconResId(com.tencent.qcloud.tuikit.tuicontact.R.drawable.contact_add_group);
action.setActionClickListener(popActionClickListener);
menuActionList.add(action);
menu.setMenuAction(menuActionList);
}
private void setProfileTitleBar() {
mainTitleBar.getLeftGroup().setVisibility(View.GONE);
mainTitleBar.getRightGroup().setVisibility(View.GONE);
mainTitleBar.setTitle(getResources().getString(R.string.profile), ITitleBarLayout.Position.MIDDLE);
}
private void resetMenuState() {
}
private final V2TIMFriendshipListener friendshipListener = new V2TIMFriendshipListener() {
@Override
public void onFriendApplicationListAdded(List<V2TIMFriendApplication> applicationList) {
refreshFriendApplicationUnreadCount();
}
@Override
public void onFriendApplicationListDeleted(List<String> userIDList) {
refreshFriendApplicationUnreadCount();
}
@Override
public void onFriendApplicationListRead() {
refreshFriendApplicationUnreadCount();
}
};
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
finish();
}
return super.onKeyDown(keyCode, event);
}
@Override
public void finish() {
super.finish();
}
@Override
protected void onStart() {
Log.i(TAG, "onStart");
super.onStart();
}
@Override
protected void onResume() {
Log.i(TAG, "onResume");
super.onResume();
registerUnreadListener();
// handleOfflinePush();
}
private void registerUnreadListener() {
V2TIMManager.getFriendshipManager().addFriendListener(friendshipListener);
refreshFriendApplicationUnreadCount();
}
private void refreshFriendApplicationUnreadCount() {
V2TIMManager.getFriendshipManager().getFriendApplicationList(new V2TIMValueCallback<V2TIMFriendApplicationResult>() {
@Override
public void onSuccess(V2TIMFriendApplicationResult v2TIMFriendApplicationResult) {
runOnUiThread(new Runnable() {
@Override
public void run() {
int unreadCount = v2TIMFriendApplicationResult.getUnreadCount();
if (unreadCount > 0) {
mNewFriendUnread.setVisibility(View.VISIBLE);
} else {
mNewFriendUnread.setVisibility(View.GONE);
}
String unreadStr = "" + unreadCount;
if (unreadCount > 100) {
unreadStr = "99+";
}
mNewFriendUnread.setText(unreadStr);
}
});
}
@Override
public void onError(int code, String desc) {
}
});
}
@Override
protected void onPause() {
Log.i(TAG, "onPause");
super.onPause();
V2TIMManager.getFriendshipManager().removeFriendListener(friendshipListener);
}
@Override
protected void onStop() {
Log.i(TAG, "onStop");
super.onStop();
}
@Override
protected void onDestroy() {
Log.i(TAG, "onDestroy");
super.onDestroy();
if (unreadCountReceiver != null) {
LocalBroadcastManager.getInstance(this).unregisterReceiver(unreadCountReceiver);
unreadCountReceiver = null;
}
}
public static void finishMainActivity() {
if (instance != null && instance.get() != null) {
instance.get().finish();
}
}
}
@@ -0,0 +1,446 @@
package com.yxjk.healthexpertclient.ui.im;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import androidx.viewpager2.widget.ViewPager2;
import com.yxjk.healthexpertclient.R;
import com.yxjk.healthexpertclient.ui.im.adapter.FragmentAdapter;
import com.tencent.imsdk.BaseConstants;
import com.tencent.imsdk.v2.V2TIMCallback;
import com.tencent.imsdk.v2.V2TIMConversation;
import com.tencent.imsdk.v2.V2TIMConversationListFilter;
import com.tencent.imsdk.v2.V2TIMConversationOperationResult;
import com.tencent.imsdk.v2.V2TIMConversationResult;
import com.tencent.imsdk.v2.V2TIMFriendApplication;
import com.tencent.imsdk.v2.V2TIMFriendApplicationResult;
import com.tencent.imsdk.v2.V2TIMFriendshipListener;
import com.tencent.imsdk.v2.V2TIMManager;
import com.tencent.imsdk.v2.V2TIMValueCallback;
import com.tencent.qcloud.tuicore.TUIConstants;
import com.tencent.qcloud.tuicore.component.activities.BaseMinimalistLightActivity;
import com.tencent.qcloud.tuicore.util.ErrorMessageConverter;
import com.tencent.qcloud.tuicore.util.ToastUtil;
import com.tencent.qcloud.tuikit.tuicontact.minimalistui.pages.TUIContactMinimalistFragment;
import com.tencent.qcloud.tuikit.tuiconversation.minimalistui.page.ConversationMinimalistFragment;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
public class MainMinimalistActivity extends BaseMinimalistLightActivity {
private static final String TAG = MainMinimalistActivity.class.getSimpleName();
private TextView mConversationBtnText;
private TextView mContactBtnText;
private TextView mProfileSelfBtnText;
private ImageView mConversationBtnIcon;
private ImageView mContactBtnIcon;
private ImageView mProfileSelfBtnIcon;
private TextView mMsgUnread;
private TextView mNewFriendUnread;
private ViewPager2 mainViewPager;
private List<Fragment> fragments;
private HashMap<String, V2TIMConversation> markUnreadMap = new HashMap<>();
private static WeakReference<MainMinimalistActivity> instance;
private BroadcastReceiver unreadCountReceiver;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
Log.i(TAG, "onCreate");
super.onCreate(savedInstanceState);
instance = new WeakReference<>(this);
initView();
initUnreadCountReceiver();
}
private void initUnreadCountReceiver() {
unreadCountReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
long unreadCount = intent.getLongExtra(TUIConstants.UNREAD_COUNT_EXTRA, 0);
if (unreadCount > 0) {
mMsgUnread.setVisibility(View.VISIBLE);
} else {
mMsgUnread.setVisibility(View.GONE);
}
String unreadStr = "" + unreadCount;
if (unreadCount > 100) {
unreadStr = "99+";
}
mMsgUnread.setText(unreadStr);
// update Huawei offline push Badge
// OfflineMessageDispatcher.updateBadge(MainMinimalistActivity.this, (int) unreadCount);
}
};
IntentFilter unreadCountFilter = new IntentFilter();
unreadCountFilter.addAction(TUIConstants.CONVERSATION_UNREAD_COUNT_ACTION);
LocalBroadcastManager.getInstance(this).registerReceiver(unreadCountReceiver, unreadCountFilter);
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
Log.i(TAG, "onNewIntent");
setIntent(intent);
}
private void initView() {
setContentView(R.layout.overseas_main_activity);
mConversationBtnText = findViewById(R.id.conversation);
mContactBtnText = findViewById(R.id.contact);
mProfileSelfBtnText = findViewById(R.id.mine);
mConversationBtnIcon = findViewById(R.id.tab_conversation_icon);
mContactBtnIcon = findViewById(R.id.tab_contact_icon);
mProfileSelfBtnIcon = findViewById(R.id.tab_profile_icon);
mMsgUnread = findViewById(R.id.msg_total_unread);
mNewFriendUnread = findViewById(R.id.new_friend_total_unread);
fragments = new ArrayList<>();
fragments.add(new ConversationMinimalistFragment());
fragments.add(new TUIContactMinimalistFragment());
// fragments.add(new ProfileMinimalistFragment());
mainViewPager = findViewById(R.id.view_pager);
FragmentAdapter fragmentAdapter = new FragmentAdapter(this);
fragmentAdapter.setFragmentList(fragments);
mainViewPager.setUserInputEnabled(false);
mainViewPager.setOffscreenPageLimit(4);
mainViewPager.setAdapter(fragmentAdapter);
mainViewPager.setCurrentItem(0, false);
prepareToClearAllUnreadMessage();
}
private void prepareToClearAllUnreadMessage() {
mMsgUnread.setOnTouchListener(new View.OnTouchListener() {
private float downX;
private float downY;
private boolean isTriggered = false;
@Override
public boolean onTouch(View view, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
downX = mMsgUnread.getX();
downY = mMsgUnread.getY();
break;
case MotionEvent.ACTION_MOVE:
if (isTriggered) {
return true;
}
float viewX = view.getX();
float viewY = view.getY();
float eventX = event.getX();
float eventY = event.getY();
float translationX = eventX + viewX - downX;
float translationY = eventY + viewY - downY;
view.setTranslationX(translationX);
view.setTranslationY(translationY);
// If the moved x and y axis coordinates exceed a certain pixel, it will trigger one-click to clear all unread sessions
if (Math.abs(translationX) > 200|| Math.abs(translationY) > 200) {
isTriggered = true;
mMsgUnread.setVisibility(View.GONE);
triggerClearAllUnreadMessage();
}
break;
case MotionEvent.ACTION_UP:
view.setTranslationX(0);
view.setTranslationY(0);
isTriggered = false;
break;
case MotionEvent.ACTION_CANCEL:
isTriggered = false;
break;
}
return true;
}
});
}
private void triggerClearAllUnreadMessage() {
V2TIMManager.getMessageManager().markAllMessageAsRead(new V2TIMCallback() {
@Override
public void onSuccess() {
Log.i(TAG, "markAllMessageAsRead success");
ToastUtil.toastShortMessage(MainMinimalistActivity.this.getString(R.string.mark_all_message_as_read_succ));
}
@Override
public void onError(int code, String desc) {
Log.i(TAG, "markAllMessageAsRead error:" + code + ", desc:" + ErrorMessageConverter.convertIMError(code, desc));
ToastUtil.toastShortMessage(MainMinimalistActivity.this.getString(R.string.mark_all_message_as_read_err_format, code, ErrorMessageConverter.convertIMError(code, desc)));
mMsgUnread.setVisibility(View.VISIBLE);
}
});
V2TIMConversationListFilter filter = new V2TIMConversationListFilter();
filter.setMarkType(V2TIMConversation.V2TIM_CONVERSATION_MARK_TYPE_UNREAD);
getMarkUnreadConversationList(filter, 0, 100, true, new V2TIMValueCallback<HashMap<String, V2TIMConversation>>() {
@Override
public void onSuccess(HashMap<String, V2TIMConversation> stringV2TIMConversationHashMap) {
if (stringV2TIMConversationHashMap.size() == 0) {
return;
}
List<String> unreadConversationIDList = new ArrayList<>();
Iterator<Map.Entry<String, V2TIMConversation>> iterator = markUnreadMap.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, V2TIMConversation> entry = iterator.next();
unreadConversationIDList.add(entry.getKey());
}
V2TIMManager.getConversationManager().markConversation(unreadConversationIDList,
V2TIMConversation.V2TIM_CONVERSATION_MARK_TYPE_UNREAD,
false,
new V2TIMValueCallback<List<V2TIMConversationOperationResult>>() {
@Override
public void onSuccess(List<V2TIMConversationOperationResult> v2TIMConversationOperationResults) {
for (V2TIMConversationOperationResult result : v2TIMConversationOperationResults) {
if (result.getResultCode() == BaseConstants.ERR_SUCC) {
V2TIMConversation v2TIMConversation = markUnreadMap.get(result.getConversationID());
if (!v2TIMConversation.getMarkList().contains(V2TIMConversation.V2TIM_CONVERSATION_MARK_TYPE_HIDE)) {
markUnreadMap.remove(result.getConversationID());
}
}
}
}
@Override
public void onError(int code, String desc) {
Log.e(TAG, "triggerClearAllUnreadMessage->markConversation error:" + code + ", desc:" + ErrorMessageConverter.convertIMError(code, desc));
}
});
}
@Override
public void onError(int code, String desc) {
Log.e(TAG, "triggerClearAllUnreadMessage->getMarkUnreadConversationList error:" + code + ", desc:" + ErrorMessageConverter.convertIMError(code, desc));
}
});
}
private void getMarkUnreadConversationList(V2TIMConversationListFilter filter, long nextSeq, int count, boolean fromStart, V2TIMValueCallback<HashMap<String, V2TIMConversation>> callback) {
if (fromStart) {
markUnreadMap.clear();
}
V2TIMManager.getConversationManager().getConversationListByFilter(filter, nextSeq, count, new V2TIMValueCallback<V2TIMConversationResult>() {
@Override
public void onSuccess(V2TIMConversationResult v2TIMConversationResult) {
List<V2TIMConversation> conversationList = v2TIMConversationResult.getConversationList();
for (V2TIMConversation conversation : conversationList) {
markUnreadMap.put(conversation.getConversationID(), conversation);
}
if (!v2TIMConversationResult.isFinished()) {
getMarkUnreadConversationList(filter, v2TIMConversationResult.getNextSeq(), count, false, callback);
} else {
if (callback != null) {
callback.onSuccess(markUnreadMap);
}
}
}
@Override
public void onError(int code, String desc) {
Log.e(TAG, "getMarkUnreadConversationList error:" + code + ", desc:" + ErrorMessageConverter.convertIMError(code, desc));
}
});
}
public void tabClick(View view) {
resetMenuState();
switch (view.getId()) {
case R.id.conversation_btn_group:
mainViewPager.setCurrentItem(0, false);
mConversationBtnText.setTextColor(getResources().getColor(R.color.demo_main_tab_text_selected_color_light));
mConversationBtnIcon.setBackground(getResources().getDrawable(R.drawable.demo_overseas_main_tab_conversation_selected));
break;
case R.id.contact_btn_group:
mainViewPager.setCurrentItem(1, false);
mContactBtnText.setTextColor(getResources().getColor(R.color.demo_main_tab_text_selected_color_light));
mContactBtnIcon.setBackground(getResources().getDrawable(R.drawable.demo_overseas_main_tab_contact_selected_bg));
break;
case R.id.myself_btn_group:
mainViewPager.setCurrentItem(2, false);
mProfileSelfBtnText.setTextColor(getResources().getColor(R.color.demo_main_tab_text_selected_color_light));
mProfileSelfBtnIcon.setBackground(getResources().getDrawable(R.drawable.demo_overseas_main_tab_settings_selected_bg));
break;
default:
break;
}
}
private void resetMenuState() {
mConversationBtnText.setTextColor(getResources().getColor(com.tencent.qcloud.tuicore.R.color.core_light_bg_secondary_text_color_light));
mConversationBtnIcon.setBackground(getResources().getDrawable(R.drawable.demo_overseas_main_tab_conversation_normal));
mContactBtnText.setTextColor(getResources().getColor(com.tencent.qcloud.tuicore.R.color.core_light_bg_secondary_text_color_light));
mContactBtnIcon.setBackground(getResources().getDrawable(R.drawable.demo_overseas_main_tab_contact_normal_bg));
mProfileSelfBtnText.setTextColor(getResources().getColor(com.tencent.qcloud.tuicore.R.color.core_light_bg_secondary_text_color_light));
mProfileSelfBtnIcon.setBackground(getResources().getDrawable(R.drawable.demo_overseas_main_tab_settings_normal_bg));
}
private final V2TIMFriendshipListener friendshipListener = new V2TIMFriendshipListener() {
@Override
public void onFriendApplicationListAdded(List<V2TIMFriendApplication> applicationList) {
refreshFriendApplicationUnreadCount();
}
@Override
public void onFriendApplicationListDeleted(List<String> userIDList) {
refreshFriendApplicationUnreadCount();
}
@Override
public void onFriendApplicationListRead() {
refreshFriendApplicationUnreadCount();
}
};
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
finish();
}
return super.onKeyDown(keyCode, event);
}
@Override
public void finish() {
super.finish();
}
@Override
protected void onStart() {
Log.i(TAG, "onStart");
super.onStart();
}
@Override
protected void onResume() {
Log.i(TAG, "onResume");
super.onResume();
registerUnreadListener();
handleOfflinePush();
}
private void handleOfflinePush() {
Intent intent = getIntent();
if (intent == null) {
Log.d(TAG, "handleOfflinePush intent is null");
return;
}
// if (OfflinePushConfigs.getOfflinePushConfigs().getClickNotificationCallbackMode() == OfflinePushConfigs.CLICK_NOTIFICATION_CALLBACK_INTENT) {
// TUIUtils.handleOfflinePush(intent, new HandleOfflinePushCallBack() {
// @Override
// public void onHandleOfflinePush(boolean hasLogged) {
// if (hasLogged) {
// setIntent(null);
// } else {
// finish();
// }
// }
// });
// } else {
// String ext = intent.getStringExtra(TUIConstants.TUIOfflinePush.NOTIFICATION_EXT_KEY);
// TUIUtils.handleOfflinePush(ext, new HandleOfflinePushCallBack() {
// @Override
// public void onHandleOfflinePush(boolean hasLogged) {
// if (hasLogged) {
// setIntent(null);
// } else {
// finish();
// }
// }
// });
// }
}
private void registerUnreadListener() {
V2TIMManager.getFriendshipManager().addFriendListener(friendshipListener);
refreshFriendApplicationUnreadCount();
}
private void refreshFriendApplicationUnreadCount() {
V2TIMManager.getFriendshipManager().getFriendApplicationList(new V2TIMValueCallback<V2TIMFriendApplicationResult>() {
@Override
public void onSuccess(V2TIMFriendApplicationResult v2TIMFriendApplicationResult) {
runOnUiThread(new Runnable() {
@Override
public void run() {
int unreadCount = v2TIMFriendApplicationResult.getUnreadCount();
if (unreadCount > 0) {
mNewFriendUnread.setVisibility(View.VISIBLE);
} else {
mNewFriendUnread.setVisibility(View.GONE);
}
String unreadStr = "" + unreadCount;
if (unreadCount > 100) {
unreadStr = "99+";
}
mNewFriendUnread.setText(unreadStr);
}
});
}
@Override
public void onError(int code, String desc) {
}
});
}
@Override
protected void onPause() {
Log.i(TAG, "onPause");
super.onPause();
V2TIMManager.getFriendshipManager().removeFriendListener(friendshipListener);
}
@Override
protected void onStop() {
Log.i(TAG, "onStop");
super.onStop();
}
@Override
protected void onDestroy() {
Log.i(TAG, "onDestroy");
super.onDestroy();
if (unreadCountReceiver != null) {
LocalBroadcastManager.getInstance(this).unregisterReceiver(unreadCountReceiver);
unreadCountReceiver = null;
}
}
public static void finishMainActivity() {
if (instance != null && instance.get() != null) {
instance.get().finish();
}
}
}
@@ -0,0 +1,152 @@
package com.yxjk.healthexpertclient.ui.im
import android.Manifest
import android.content.Intent
import android.graphics.BitmapFactory
import android.os.Bundle
import android.view.View
import com.amap.api.location.AMapLocationClient
import com.amap.api.maps.AMap
import com.amap.api.maps.CameraUpdateFactory
import com.amap.api.maps.model.BitmapDescriptorFactory
import com.amap.api.maps.model.CameraPosition
import com.amap.api.maps.model.LatLng
import com.amap.api.maps.model.MarkerOptions
import com.amap.api.maps.model.MyLocationStyle
import com.btpj.lib_base.ext.toJson
import com.buddy.kredit.android.base.BaseActivity
import com.permissionx.guolindev.PermissionX
import com.yxjk.healthexpertclient.R
import com.yxjk.healthexpertclient.databinding.ActivitySelectLocationBinding
import com.yxjk.healthexpertclient.ui.im.viewmodel.SelectLocationViewModel
import com.tencent.qcloud.tuikit.tuichat.bean.message.LocationMessageBean
import com.tencent.qcloud.tuikit.tuichat.classicui.setting.ChatLayoutSetting
/**
* @author nanfeifei
* @time 2023/7/4 10:38
* @description 选择位置(IM发送位置使用)
*/
class SelectLocationActivity : BaseActivity<SelectLocationViewModel, ActivitySelectLocationBinding>(
R.layout.activity_select_location) {
//初始化地图控制器对象
var aMap: AMap? = null
var mCurrentLat: Double = 0.0
var mCurrentLon: Double = 0.0
var mPermissionList= arrayListOf(
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION)
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
mBinding.mapView.onSaveInstanceState(outState)
}
override fun onCreate(savedInstanceState: Bundle?) {
AMapLocationClient.updatePrivacyShow(this@SelectLocationActivity, true, true)
AMapLocationClient.updatePrivacyAgree(this@SelectLocationActivity, true)
super.onCreate(savedInstanceState)
}
override fun initView(savedInstanceState: Bundle?) {
setToolBarRightText(getString(R.string.select_location_send))
mBinding.apply {
mapView.onCreate(savedInstanceState)
if (aMap == null) {
aMap = mapView.map
}
PermissionX.init(this@SelectLocationActivity)
.permissions(mPermissionList)
.request { allGranted, grantedList, deniedList ->
if (allGranted){
setUpMap()
}
}
}
}
override fun initData() {
}
private fun setUpMap() {
// 自定义系统定位小蓝点
val myLocationStyle = MyLocationStyle()
// 设置小蓝点的图
myLocationStyle.myLocationIcon(
BitmapDescriptorFactory
.fromResource(R.drawable.ic_my_location)
)
myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_SHOW)
mBinding.apply {
aMap?.myLocationStyle = myLocationStyle
aMap?.moveCamera(CameraUpdateFactory.zoomTo(13F))
aMap?.uiSettings?.isMyLocationButtonEnabled = true // 设置默认定位按钮是否显示
aMap?.uiSettings?.isRotateGesturesEnabled = false
aMap?.uiSettings?.isTiltGesturesEnabled = false
aMap?.isMyLocationEnabled = true // 设置为true表示显示定位层并可触发定位,false表示隐藏定位层并不可触发定位,默认是false
aMap?.setOnMyLocationChangeListener {
mCurrentLat = it.latitude
mCurrentLon = it.longitude
val markerOption = MarkerOptions()
markerOption.position(LatLng(mCurrentLat, mCurrentLon))
aMap?.moveCamera(CameraUpdateFactory.newLatLng(LatLng(mCurrentLat, mCurrentLon)))
markerOption.icon(
BitmapDescriptorFactory.fromBitmap(
BitmapFactory
.decodeResource(resources, R.drawable.ic_select_location)
)
)
markerOption.isFlat = true
var marker = aMap?.addMarker(markerOption)
aMap?.setOnCameraChangeListener(object : AMap.OnCameraChangeListener {
override fun onCameraChange(cameraPosition: CameraPosition?) {
if (cameraPosition != null) {
marker?.position = cameraPosition.target
mCurrentLat = cameraPosition.target.latitude
mCurrentLon = cameraPosition.target.longitude
}
}
override fun onCameraChangeFinish(p0: CameraPosition?) {
}
})
}
}
}
override fun onResume() {
super.onResume()
mBinding.mapView.onResume()
}
override fun onPause() {
super.onPause()
mBinding.mapView.onPause()
}
override fun onDestroy() {
super.onDestroy()
mBinding.mapView.onDestroy()
}
override fun bindEvent() {
addClickViews(mBinding.toolbarLay.tvRight)
}
override fun onClick(paramView: View?) {
super.onClick(paramView)
when (paramView?.id) {
R.id.tv_right -> {
var intent = Intent()
var locationMessageBean = LocationMessageBean()
locationMessageBean.longitude = mCurrentLon
locationMessageBean.latitude = mCurrentLat
intent.putExtra(ChatLayoutSetting.KEY_CUSTOM_MESSAGE, locationMessageBean.toJson())
setResult(ChatLayoutSetting.RESULT_CODE_LOCATION, intent)
finish()
}
}
}
}
@@ -0,0 +1,118 @@
package com.yxjk.healthexpertclient.ui.im
import android.Manifest
import android.graphics.BitmapFactory
import android.os.Bundle
import com.amap.api.location.AMapLocationClient
import com.amap.api.maps.AMap
import com.amap.api.maps.CameraUpdateFactory
import com.amap.api.maps.model.BitmapDescriptorFactory
import com.amap.api.maps.model.LatLng
import com.amap.api.maps.model.MarkerOptions
import com.amap.api.maps.model.MyLocationStyle
import com.buddy.kredit.android.base.BaseActivity
import com.permissionx.guolindev.PermissionX
import com.yxjk.healthexpertclient.R
import com.yxjk.healthexpertclient.databinding.ActivityViewLocationBinding
import com.yxjk.healthexpertclient.ui.im.viewmodel.ViewLocationViewModel
/**
* @author nanfeifei
* @time 2023/7/4 10:38
* @description 查看位置(IM查看位置使用)
*/
class ViewLocationActivity : BaseActivity<ViewLocationViewModel, ActivityViewLocationBinding>(
R.layout.activity_view_location) {
//初始化地图控制器对象
var aMap: AMap? = null
var mCurrentLat: Double = 0.0
var mCurrentLon: Double = 0.0
var mPermissionList= arrayListOf(
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.QUERY_ALL_PACKAGES)
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
mBinding.mapView.onSaveInstanceState(outState)
}
override fun onCreate(savedInstanceState: Bundle?) {
AMapLocationClient.updatePrivacyShow(this@ViewLocationActivity, true, true)
AMapLocationClient.updatePrivacyAgree(this@ViewLocationActivity, true)
super.onCreate(savedInstanceState)
}
override fun initView(savedInstanceState: Bundle?) {
intent.extras?.let {
mCurrentLat = it.getDouble("latitude")
mCurrentLon = it.getDouble("longitude")
}
mBinding.apply {
mapView.onCreate(savedInstanceState)
if (aMap == null) {
aMap = mapView.map
}
PermissionX.init(this@ViewLocationActivity)
.permissions(mPermissionList)
.request { allGranted, grantedList, deniedList ->
setUpMap(allGranted)
}
}
}
override fun initData() {
}
private fun setUpMap(allGranted: Boolean) {
mBinding.apply {
if (allGranted){
// 自定义系统定位小蓝点
val myLocationStyle = MyLocationStyle()
// 设置小蓝点的图
myLocationStyle.myLocationIcon(
BitmapDescriptorFactory
.fromResource(R.drawable.ic_my_location)
)
myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_SHOW)
aMap?.myLocationStyle = myLocationStyle
aMap?.uiSettings?.isMyLocationButtonEnabled = true // 设置默认定位按钮是否显示
aMap?.uiSettings?.isRotateGesturesEnabled = false
aMap?.uiSettings?.isTiltGesturesEnabled = false
aMap?.isMyLocationEnabled = true // 设置为true表示显示定位层并可触发定位,false表示隐藏定位层并不可触发定位,默认是false
}
aMap?.moveCamera(CameraUpdateFactory.zoomTo(13F))
val markerOption = MarkerOptions()
markerOption.position(LatLng(mCurrentLat, mCurrentLon))
aMap?.moveCamera(CameraUpdateFactory.newLatLng(LatLng(mCurrentLat, mCurrentLon)))
markerOption.icon(
BitmapDescriptorFactory.fromBitmap(
BitmapFactory
.decodeResource(resources, R.drawable.ic_select_location)
)
)
markerOption.isFlat = true
aMap?.addMarker(markerOption)
}
}
override fun onResume() {
super.onResume()
mBinding.mapView.onResume()
}
override fun onPause() {
super.onPause()
mBinding.mapView.onPause()
}
override fun onDestroy() {
super.onDestroy()
mBinding.mapView.onDestroy()
}
override fun bindEvent() {
}
}
@@ -0,0 +1,46 @@
package com.yxjk.healthexpertclient.ui.im.adapter;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;
import androidx.lifecycle.Lifecycle;
import androidx.viewpager2.adapter.FragmentStateAdapter;
import java.util.List;
public class FragmentAdapter extends FragmentStateAdapter {
private static final String TAG = FragmentAdapter.class.getSimpleName();
private List<Fragment> fragmentList;
public FragmentAdapter(@NonNull FragmentActivity fragmentActivity) {
super(fragmentActivity);
}
public FragmentAdapter(@NonNull Fragment fragment) {
super(fragment);
}
public FragmentAdapter(@NonNull FragmentManager fragmentManager, @NonNull Lifecycle lifecycle) {
super(fragmentManager, lifecycle);
}
public void setFragmentList(List<Fragment> fragmentList) {
this.fragmentList = fragmentList;
}
@NonNull
@Override
public Fragment createFragment(int position) {
if (fragmentList == null || fragmentList.size() <= position) {
return new Fragment();
}
return fragmentList.get(position);
}
@Override
public int getItemCount() {
return fragmentList == null ? 0 : fragmentList.size();
}
}
@@ -0,0 +1,29 @@
package com.yxjk.healthexpertclient.ui.im.utils
import com.tencent.qcloud.tuikit.tuichat.classicui.setting.InputActionSetting
object IMInputActionSettingUtils {
/**
* 图文咨询IM功能配置
*/
fun createImageTextConsultSetting(isSelf: Boolean = false, disableSendMessage: Boolean = false){
var inputActionSetting = InputActionSetting.createInstance()
inputActionSetting.isDisableAudioCall = true
inputActionSetting.isDisableVideoCall = true
inputActionSetting.isDisableArchives = false
inputActionSetting.isDisableMedicalExaminationReport = !isSelf
inputActionSetting.isDisableSendMessage = disableSendMessage
}
/**
* 小助手IM功能配置
*/
fun createAssistantSetting(){
var inputActionSetting = InputActionSetting.createInstance()
inputActionSetting.isDisableAudioCall = true
inputActionSetting.isDisableVideoCall = true
inputActionSetting.isDisableArchives = true
inputActionSetting.isDisableMedicalExaminationReport = true
inputActionSetting.isDisableSendMessage = false
}
}
@@ -0,0 +1,172 @@
package com.yxjk.healthexpertclient.ui.im.view;
import android.app.Activity;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PixelFormat;
import android.graphics.RectF;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.PopupWindow;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.tencent.qcloud.tuicore.R;
import com.tencent.qcloud.tuicore.component.action.PopMenuAction;
import com.tencent.qcloud.tuicore.component.action.PopMenuAdapter;
import com.tencent.qcloud.tuicore.util.ScreenUtil;
import java.util.ArrayList;
import java.util.List;
public class Menu {
private static final int SHADOW_WIDTH = 10;
private static final int Y_OFFSET = 4;
private ListView mMenuList;
private PopMenuAdapter mMenuAdapter;
private PopupWindow mMenuWindow;
private List<PopMenuAction> mActions = new ArrayList<>();
private Activity mActivity;
private View mAttachView;
public Menu(Activity activity, View attach) {
mActivity = activity;
mAttachView = attach;
}
public void setMenuAction(List<PopMenuAction> menuActions) {
mActions.clear();
mActions.addAll(menuActions);
}
public boolean isShowing() {
if (mMenuWindow == null) {
return false;
}
return mMenuWindow.isShowing();
}
public void hide() {
mMenuWindow.dismiss();
}
public void show() {
if (mActions == null || mActions.size() == 0) {
return;
}
mMenuWindow = new PopupWindow(mActivity);
mMenuWindow.setWidth(ViewGroup.LayoutParams.WRAP_CONTENT);
mMenuWindow.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
mMenuWindow.setBackgroundDrawable(new ColorDrawable());
mMenuAdapter = new PopMenuAdapter();
mMenuAdapter.setDataSource(mActions);
View menuView = LayoutInflater.from(mActivity).inflate(R.layout.core_pop_menu, null);
menuView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
mMenuWindow.setContentView(menuView);
mMenuList = menuView.findViewById(R.id.menu_pop_list);
mMenuList.setAdapter(mMenuAdapter);
mMenuList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
PopMenuAction action = (PopMenuAction) mMenuAdapter.getItem(position);
if (action != null && action.getActionClickListener() != null) {
action.getActionClickListener().onActionClick(position, mActions.get(position));
}
}
});
int paddingLeftRight = ScreenUtil.dip2px(15.0f);
int paddingTopBottom = ScreenUtil.dip2px(12.0f);
int itemWidth = mActivity.getResources().getDimensionPixelSize(R.dimen.core_pop_menu_item_width);
int itemHeight = mActivity.getResources().getDimensionPixelSize(R.dimen.core_pop_menu_item_height);
float anchorWidth = mAttachView.getWidth();
float anchorHeight = mAttachView.getHeight();
mMenuWindow.getContentView().measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
int[] location = new int[2];
mAttachView.getLocationOnScreen(location);
int rowCount = mActions.size();
int indicatorHeight = mActivity.getResources().getDimensionPixelOffset(R.dimen.core_pop_menu_indicator_height);
int popWidth = itemWidth + paddingLeftRight * 2 - SHADOW_WIDTH;
int popHeight = itemHeight * rowCount + paddingTopBottom * 2 - SHADOW_WIDTH;
float indicatorX = anchorWidth / 2;
int screenWidth = ScreenUtil.getScreenWidth(mActivity);
int x = location[0];
int y;
float xOffset = anchorWidth / 2;
// If it is on the right, the x-coordinate of the small arrow and the x-position of the pop-up window will change
if (location[0] * 2 + anchorWidth > screenWidth) {
indicatorX = popWidth - anchorWidth / 2 - xOffset;
x = (int) (location[0] + anchorWidth - popWidth + xOffset);
}
y = (int) (location[1] + anchorHeight) + Y_OFFSET;
popHeight = popHeight - indicatorHeight;
Drawable backgroundDrawable = getBackgroundDrawable(popWidth, popHeight, indicatorX, indicatorHeight, 16);
menuView.setBackground(backgroundDrawable);
mMenuWindow.setFocusable(true);
mMenuWindow.setTouchable(true);
mMenuWindow.setOutsideTouchable(true);
mMenuWindow.showAtLocation(mAttachView, Gravity.NO_GRAVITY, x, y);
}
/**
* Draw a popup background with small triangles
*/
public Drawable getBackgroundDrawable(final float widthPixel, final float heightPixel, float indicatorX, float indicatorHeight, float radius) {
int borderWidth = SHADOW_WIDTH;
Path path = new Path();
Drawable drawable = new Drawable() {
@Override
public void draw(@NonNull Canvas canvas) {
Paint paint = new Paint();
paint.setColor(Color.WHITE);
paint.setStyle(Paint.Style.FILL);
paint.setShadowLayer(borderWidth, 0,0,0xFFAAAAAA);
path.addRoundRect(new RectF(borderWidth, indicatorHeight + borderWidth, widthPixel - borderWidth, heightPixel + indicatorHeight - borderWidth), radius, radius, Path.Direction.CW);
path.moveTo(indicatorX - indicatorHeight, indicatorHeight + borderWidth);
path.lineTo(indicatorX, borderWidth);
path.lineTo(indicatorX + indicatorHeight, indicatorHeight + borderWidth);
path.close();
canvas.drawPath(path, paint);
}
@Override
public void setAlpha(int alpha) {
}
@Override
public void setColorFilter(@Nullable ColorFilter colorFilter) {
}
@Override
public int getOpacity() {
return PixelFormat.TRANSLUCENT;
}
};
return drawable;
}
}
@@ -0,0 +1,14 @@
package com.yxjk.healthexpertclient.ui.im.viewmodel
import com.btpj.lib_base.base.BaseViewModel
/**
* @author nanfeifei
* @time 2023/7/4 10:38
* @description
*/
class SelectLocationViewModel: BaseViewModel() {
override fun init() {
}
}
@@ -0,0 +1,14 @@
package com.yxjk.healthexpertclient.ui.im.viewmodel
import com.btpj.lib_base.base.BaseViewModel
/**
* @author nanfeifei
* @time 2023/7/4 10:38
* @description
*/
class ViewLocationViewModel: BaseViewModel() {
override fun init() {
}
}
@@ -0,0 +1,117 @@
package com.yxjk.healthexpertclient.ui.login
import android.content.res.ColorStateList
import android.graphics.Color
import android.graphics.drawable.GradientDrawable
import android.os.Bundle
import android.os.Handler
import android.os.Message
import android.text.method.HideReturnsTransformationMethod
import android.text.method.PasswordTransformationMethod
import android.view.View
import android.widget.RadioButton
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import com.btpj.lib_base.base.BaseVMBActivity
import com.yxjk.healthexpertclient.R
import com.yxjk.healthexpertclient.databinding.ActivityChangePasswordBinding
import com.yxjk.healthexpertclient.ui.login.viewmodel.LoginViewModel
import com.yxjk.healthexpertclient.utils.CommonUtils
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
/**
* 找回密码
*/
class ChangePassWordActivity: BaseVMBActivity<LoginViewModel, ActivityChangePasswordBinding>(R.layout.activity_change_password), View.OnClickListener {
var mCode=""
override fun initView(savedInstanceState: Bundle?) {
}
override fun initData() {
mCode= intent.getStringExtra("code").toString()
}
override fun bindEvent() {
mBinding?.let{
addClickViews(it.retrieveConfirm)
it.loginIvEye.setOnClickListener {
mBinding?.let {
var selection=it.tvNewPassword.selectionEnd
if (it.tvNewPassword.transformationMethod== PasswordTransformationMethod.getInstance()){
it.tvNewPassword.setTransformationMethod(
HideReturnsTransformationMethod.getInstance())
it.loginIvEye.setImageResource(R.mipmap.ic_password_show)
}else{
it.tvNewPassword.setTransformationMethod(
PasswordTransformationMethod.getInstance())
it.loginIvEye.setImageResource(R.mipmap.ic_password_hind)
}
it.tvNewPassword.setSelection(selection)
}
}
it.loginIvEye2.setOnClickListener {
mBinding?.let {
var selection=it.tvConfirmPassword.selectionEnd
if (it.tvConfirmPassword.transformationMethod== PasswordTransformationMethod.getInstance()){
it.tvConfirmPassword.setTransformationMethod(
HideReturnsTransformationMethod.getInstance())
it.loginIvEye2.setImageResource(R.mipmap.ic_password_show)
}else{
it.tvConfirmPassword.setTransformationMethod(
PasswordTransformationMethod.getInstance())
it.loginIvEye2.setImageResource(R.mipmap.ic_password_hind)
}
it.tvConfirmPassword.setSelection(selection)
}
}
}
}
override fun createObserve() {
super.createObserve()
mBinding.apply {
lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.CREATED) {
mViewModel.mChangeState.collectLatest { result ->
if (result){
showToast("修改密码成功")
finish()
}
}
}
}
}
}
override fun onClick(v: View?) {
processClick(v)
}
fun processClick(paramView: View?) {
when(paramView?.id){
R.id.retrieve_confirm -> {
//密码需要为12-32位(包含数字、大写、小写字母、特殊字符)
// TODO: 2024/5/11 密码改为12-32位
var newPassword=mBinding?.tvNewPassword?.text.toString().trim()
if (newPassword.isNullOrEmpty()) {
showToast("请输入新密码")
return
}
var confirmPassword=mBinding?.tvConfirmPassword?.text.toString().trim()
if (confirmPassword.isNullOrEmpty()) {
showToast("请输入验证码")
return
}
if (newPassword!=confirmPassword) {
showToast("两次密码输入不一致,请重新输入")
return
}
if (newPassword.length < 12 || newPassword.length > 32 || !CommonUtils.isPasswordMatches(newPassword)){
showToast(getString(R.string.password_hint))
return
}
mViewModel.resetUserPwd(newPassword,confirmPassword,mCode)
}
}
}
}
@@ -0,0 +1,276 @@
package com.yxjk.healthexpertclient.ui.login
import android.os.Bundle
import android.text.SpannableString
import android.text.Spanned
import android.text.TextPaint
import android.text.TextUtils
import android.text.method.LinkMovementMethod
import android.text.style.ClickableSpan
import android.text.style.ForegroundColorSpan
import android.text.style.UnderlineSpan
import android.view.Gravity
import android.view.View
import androidx.core.content.ContextCompat
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import com.btpj.lib_base.data.local.DataStoreManager
import com.btpj.lib_base.data.local.IpManager
import com.buddy.kredit.android.base.BaseActivity
import com.yxjk.healthexpertclient.MyApplication.Companion.appViewModel
import com.yxjk.healthexpertclient.R
import com.yxjk.healthexpertclient.databinding.ActivityLoginBinding
import com.yxjk.healthexpertclient.ext.startMainActivity
import com.yxjk.healthexpertclient.ext.startRetrievePassWordActivity
import com.yxjk.healthexpertclient.ext.startWebActivity
import com.yxjk.healthexpertclient.ui.login.viewmodel.LoginViewModel
import com.yxjk.healthexpertclient.utils.CommonUtils
import com.yxjk.healthexpertclient.utils.ConstantUtils
import com.yxjk.healthexpertclient.view.PrivacyDialog
import com.yxjk.healthexpertclient.view.TextViewDialog
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
/**
* @author nanfeifei
* @time 2023/5/29 16:33
* @description 登录
*/
class LoginActivity :
BaseActivity<LoginViewModel, ActivityLoginBinding>(R.layout.activity_login) {
var mTextViewDialog: TextViewDialog? = null
override fun transparentStatusBar(): Boolean {
return true
}
override fun initView(savedInstanceState: Bundle?) {
initAgreement()
mTextViewDialog = TextViewDialog(this)
mBinding.apply {
}
}
override fun createObserve() {
super.createObserve()
lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.CREATED) {
appViewModel.loginState.collect { isLogin ->
if (isLogin) {
startMainActivity(this@LoginActivity)
finish()
} else {
CommonUtils.clearUserInfo()
}
}
}
}
lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.CREATED) {
mViewModel.list.collectLatest { list ->
if (list != null) {
list?.let {
for (index in 0 until it.size) {
when (it[index].value) {
"1" -> {
//用户协议
if (it[index].text.isNotEmpty()) {
DataStoreManager.saveUserAgreementUrl(
IpManager.getH5BaseUrl(
IpManager.baseUrlType
) + it[index].text
)
}
}
"2" -> {
//隐私政策
if (it[index].text.isNotEmpty()) {
DataStoreManager.savePrivacyAgreementUrl(
IpManager.getH5BaseUrl(
IpManager.baseUrlType
) + it[index].text
)
}
}
"3" -> {
//相关法律说明
if (it[index].text.isNotEmpty()) {
DataStoreManager.saveLawUrl(
IpManager.getH5BaseUrl(
IpManager.baseUrlType
) + it[index].text
)
}
}
}
}
}
}
}
}
}
}
override fun initData() {
lifecycleScope.launch {
appViewModel.loginState.emit(false)
}
mViewModel.getAgreementData()
if (!DataStoreManager.isPrivacyState()) {
privacyShow()
}
}
fun privacyShow() {
val textViewDialog = PrivacyDialog(LoginActivity@ this)
textViewDialog?.setDialogTitle("隐私协议授权", 18f)
textViewDialog?.setContent(ConstantUtils.mPrivacy, 14f)
textViewDialog?.setContentStyle(Gravity.LEFT)
textViewDialog?.setBtnText("同意", 18f)
textViewDialog?.setDialogCancelable(false)
textViewDialog?.setCancelBtnText("退出", 18f)
textViewDialog?.setOnAffirmClickListener(object : PrivacyDialog.OnAffirmClickListener {
override fun onAffirmClick(viewDialog: PrivacyDialog) {
DataStoreManager.savePrivacyState(true)
}
override fun onCancelClick(viewDialog: PrivacyDialog) {
System.exit(0)
}
})
textViewDialog?.show()
}
override fun bindEvent() {
mBinding.apply {
addClickViews(loginSubmit, loginRetrievePassword)
}
mTextViewDialog?.let {
it.setDialogTitle("温馨提示", 18f)
it.setContent("您的密码不安全,请先修改密码", 14f)
it.setContentStyle(Gravity.LEFT)
it.setBtnText("确认", 18f)
it.setDialogCancelable(false)
it.setCancelBtnText("取消", 18f)
it.setOnAffirmClickListener(object : TextViewDialog.OnAffirmClickListener {
override fun onAffirmClick(viewDialog: TextViewDialog) {
startRetrievePassWordActivity(this@LoginActivity)
}
override fun onCancelClick(viewDialog: TextViewDialog) {
}
})
}
}
override fun onClick(v: View?) {
super.onClick(v)
when (v?.id) {
R.id.login_submit -> {
mBinding.apply {
val account = loginEtUserName.text.toString()
val password = loginEtUserPassword.getInputContext()
if (TextUtils.isEmpty(account)) {
showToast(resources?.getString(R.string.login_account_hint))
return
}
if (TextUtils.isEmpty(password)) {
showToast(resources?.getString(R.string.login_password_hint))
return
}
if (password.length < 12 || password.length > 32) {
//弹窗提示去修改密码
mTextViewDialog?.show()
} else {
mViewModel.login(account, password)
}
}
}
R.id.login_retrieve_password -> { //找回密码
startRetrievePassWordActivity(this)
}
}
}
private fun initAgreement() {
var span = SpannableString(getString(R.string.login_privacy_agreement))
span.setSpan(object : ClickableSpan() {
override fun onClick(widget: View) {
DataStoreManager.getUserAgreementUrl()?.let {
if (it.isNotEmpty()) {
startWebActivity(this@LoginActivity, it)
}
}
}
// 表示点击整个text的长度都有效触发这个事件
}, 6, 12, Spanned.SPAN_INCLUSIVE_EXCLUSIVE)
span.setSpan(NoUnderlineSpan(), 6, 12, Spanned.SPAN_MARK_MARK)
span.setSpan(
ForegroundColorSpan(
ContextCompat.getColor(
this@LoginActivity,
R.color.link_blue_color
)
), 6, 12, Spanned.SPAN_INCLUSIVE_EXCLUSIVE
)
span.setSpan(object : ClickableSpan() {
override fun onClick(widget: View) {
DataStoreManager.getPrivacyAgreementUrl()?.let {
if (it.isNotEmpty()) {
startWebActivity(this@LoginActivity, it)
}
}
}
// 表示点击整个text的长度都有效触发这个事件
}, 13, 19, Spanned.SPAN_INCLUSIVE_EXCLUSIVE)
span.setSpan(NoUnderlineSpan(), 13, 19, Spanned.SPAN_MARK_MARK)
span.setSpan(
ForegroundColorSpan(
ContextCompat.getColor(
this@LoginActivity,
R.color.link_blue_color
)
), 13, 19, Spanned.SPAN_INCLUSIVE_EXCLUSIVE
)
// span.setSpan(object : ClickableSpan() {
//
// override fun onClick(widget: View) {
// DataStoreManager.getLawUrl()?.let {
// if (it.isNotEmpty()) {
// startWebActivity(this@LoginActivity,it)
// }
// }
// }
// // 表示点击整个text的长度都有效触发这个事件
// }, 20, 28, Spanned.SPAN_INCLUSIVE_EXCLUSIVE)
// span.setSpan(NoUnderlineSpan(), 20, 28, Spanned.SPAN_MARK_MARK)
// span.setSpan(
// ForegroundColorSpan(
// ContextCompat.getColor(
// this@LoginActivity,
// R.color.link_blue_color
// )
// ), 20, 28, Spanned.SPAN_INCLUSIVE_EXCLUSIVE
// )
mBinding.loginTvAgreement.text = span
mBinding.loginTvAgreement.movementMethod = LinkMovementMethod.getInstance()
}
internal class NoUnderlineSpan : UnderlineSpan() {
override fun updateDrawState(ds: TextPaint) {
ds.color = ds.linkColor
ds.isUnderlineText = false
}
}
}
@@ -0,0 +1,165 @@
package com.yxjk.healthexpertclient.ui.login
import android.content.res.ColorStateList
import android.graphics.Color
import android.os.Bundle
import android.os.CountDownTimer
import android.os.Handler
import android.os.Message
import android.view.View
import android.widget.RadioButton
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import com.btpj.lib_base.base.BaseVMBActivity
import com.yxjk.healthexpertclient.R
import com.yxjk.healthexpertclient.databinding.ActivityRetrievePasswordBinding
import com.yxjk.healthexpertclient.ext.startChangePassWordActivity
import com.yxjk.healthexpertclient.ui.login.viewmodel.LoginViewModel
import com.yxjk.healthexpertclient.ui.login.viewmodel.RetrievePassWordViewModel
import com.yxjk.healthexpertclient.utils.AuthCodeCountDownTimer
import com.yxjk.healthexpertclient.utils.phoneCheck
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
/**
* @author nanfeifei
* @time 2023/5/29 19:30
* @description 找回密码
*/
class RetrievePassWordActivity: BaseVMBActivity<LoginViewModel,ActivityRetrievePasswordBinding>(R.layout.activity_retrieve_password) , View.OnClickListener{
var mNumber=60
var mIsSendCode=true
var type=0 //0 信息找回 1 验证码找回
var mhandler=object : Handler(){
override fun handleMessage(msg: Message) {
super.handleMessage(msg)
when (msg.what) {
0 -> {
if (type==1) {
if (mNumber==1) {
mIsSendCode=true
mNumber=60
mBinding?.retrieveGetCheckCode?.text="重新发送"
mBinding?.retrieveGetCheckCode?.backgroundTintList = ColorStateList.valueOf(
Color.parseColor("#21BEBD"))
}else{
mIsSendCode=false
mNumber=mNumber-1
mBinding?.retrieveGetCheckCode?.text="重新发送(${mNumber}s)"
sendEmptyMessageDelayed(0,1000)
}
}else{
mNumber=60
mBinding?.retrieveGetCheckCode?.text="获取验证码"
mBinding?.retrieveGetCheckCode?.backgroundTintList = ColorStateList.valueOf(
Color.parseColor("#21BEBD"))
}
}
else -> {}
}
}
}
override fun initView(savedInstanceState: Bundle?) {
switchFindMode()
}
override fun initData() {
}
override fun bindEvent() {
mBinding?.let{
addClickViews(it.retrieveGetCheckCode,it.retrieveConfirm)
}
mBinding?.radioGroup?.setOnCheckedChangeListener { group, checkedId ->
var radio=findViewById<RadioButton>(checkedId)
var value=radio.text.toString()
if (value=="用户信息找回") {
type=0
switchFindMode()
}else{
type=1
switchFindMode()
}
}
}
fun switchFindMode(){
if (type==0){
mBinding?.llInfoFind?.visibility=View.VISIBLE
mBinding?.llCodeFind?.visibility=View.GONE
}else{
mBinding?.llInfoFind?.visibility=View.GONE
mBinding?.llCodeFind?.visibility=View.VISIBLE
}
}
override fun createObserve() {
super.createObserve()
mBinding.apply {
lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.CREATED) {
mViewModel.mCode.collectLatest { code ->
if (!code.isNullOrEmpty()) {
startChangePassWordActivity(code)
finish()
}
}
}
}
}
}
override fun onClick(v: View?) {
processClick(v)
}
fun processClick(paramView: View?) {
when(paramView?.id){
R.id.retrieve_get_check_code -> {
if (mIsSendCode) {
mBinding?.retrieveGetCheckCode?.backgroundTintList = ColorStateList.valueOf(
Color.parseColor("#BBBBBB"))
mBinding?.retrieveGetCheckCode?.text="重新发送(${mNumber}s)"
mhandler.sendEmptyMessageDelayed(0,1000)
}
}
R.id.retrieve_confirm -> {
if (type==0) {
var name=mBinding?.tvUserName?.text.toString().trim()
var idcard=mBinding?.tvUserIdCard?.text.toString().trim()
var phone=mBinding?.tvUserPhone?.text.toString().trim()
if (name.isNullOrEmpty()) {
showToast("请输入用户姓名")
return
}
if (idcard.isNullOrEmpty()) {
showToast("请输入身份证号")
return
}
if (phone.isNullOrEmpty()) {
showToast("请输入手机号")
return
}
mViewModel.checkUserInfo(name,idcard,phone)
}else if (type==1) {
var phone=mBinding?.retrievePhone?.text.toString().trim()
if (phone.isNullOrEmpty()) {
showToast("请输入手机号码")
return
}
if(!phone.phoneCheck()){
showToast("手机号码格式不正确")
return
}
var code=mBinding?.retrieveCheckCode?.text.toString().trim()
if (code.isNullOrEmpty()) {
showToast("请输入验证码")
return
}
}
}
}
}
}
@@ -0,0 +1,75 @@
package com.yxjk.healthexpertclient.ui.login.viewmodel
import com.baileren.rsalibrary.RSACipherStrategy
import com.btpj.lib_base.BaseApp.Companion.appContext
import com.btpj.lib_base.base.BaseViewModel
import com.btpj.lib_base.ext.encrypt
import com.btpj.lib_base.ext.handleRequest
import com.btpj.lib_base.ext.launch
import com.yxjk.healthexpertclient.MyApplication.Companion.appViewModel
import com.yxjk.healthexpertclient.R
import com.yxjk.healthexpertclient.bean.CommonSettingMenuBean
import com.yxjk.healthexpertclient.data.repository.LoginRepository
import com.yxjk.healthexpertclient.utils.CommonUtils
import com.yxjk.healthexpertclient.utils.ConstantUtils
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
/**
* @author nanfeifei
* @time 2023/5/29 18:32
* @description
*/
class LoginViewModel : BaseViewModel() {
val agreement = MutableStateFlow(false)
var mCode = MutableStateFlow("")
var mChangeState = MutableSharedFlow<Boolean>()
var list = MutableStateFlow<MutableList<CommonSettingMenuBean>?>(null)
override fun init() {
}
fun checkUserInfo(realname:String,idCard:String,phone:String){
launch({
handleRequest(LoginRepository.checkUserInfo(realname,idCard,phone), successBlock = {
it.result?.let { it1 -> mCode.emit(it1) }
})
})
}
fun login(account: String,password: String) {
launch(
{
if (!agreement.value) {
exception.value =
Exception(appContext.getString(R.string.login_privacy_agreement))
return@launch
}
handleRequest(LoginRepository.login(account, password.encrypt(ConstantUtils.RSA_PUBLIC_KEY)), successBlock = {
it.result?.let { result ->
result.userInfo.userToken = result.token
CommonUtils.saveUserInfo(result.userInfo)
}
appViewModel.loginState.emit(true)
})
})
}
fun getAgreementData(){
launch({
handleRequest(LoginRepository.getCommonSettingMenuList("z_jump_url"), successBlock = {
it.result?.let { it1 -> list.emit(it1) }
})
})
}
fun resetUserPwd(password:String,confirmPassword:String,resetCode:String){
var newPassword= RSACipherStrategy().encrypt(ConstantUtils.RSA_PUBLIC_KEY,password)
var newPasswordConfirm= RSACipherStrategy().encrypt(ConstantUtils.RSA_PUBLIC_KEY,confirmPassword)
launch({
handleRequest(LoginRepository.resetUserPwd(newPassword,newPasswordConfirm,resetCode), successBlock = {
it.result?.let { it1 -> mChangeState.emit(true) }
})
})
}
}
@@ -0,0 +1,54 @@
package com.yxjk.healthexpertclient.ui.login.viewmodel
import com.btpj.lib_base.BaseApp.Companion.appContext
import com.btpj.lib_base.base.BaseViewModel
import com.btpj.lib_base.ext.isMobile
import com.btpj.lib_base.ext.launch
import com.yxjk.healthexpertclient.R
import kotlinx.coroutines.flow.MutableStateFlow
/**
* @author nanfeifei
* @time 2023/5/29 19:30
* @description
*/
class RetrievePassWordViewModel: BaseViewModel() {
var mobile = MutableStateFlow("")
var authCode = MutableStateFlow("")
var sendAuthCode = MutableStateFlow(false)
override fun init() {
}
fun sendAuthCode(){
launch({
if(mobile.value.isNullOrEmpty()){
exception.value = Exception(appContext.getString(R.string.retrieve_password_mobile_hint))
return@launch
}
if(!mobile.value.isMobile()){
exception.value = Exception(appContext.getString(R.string.retrieve_password_mobile_hint))
return@launch
}
sendAuthCode.emit(true)
})
}
fun submitAuthCode(){
launch({
if(mobile.value.isNullOrEmpty()){
exception.value = Exception(appContext.getString(R.string.retrieve_password_mobile_hint))
return@launch
}
if(!mobile.value.isMobile()){
exception.value = Exception(appContext.getString(R.string.retrieve_password_mobile_hint))
return@launch
}
if(!authCode.value.isMobile()){
exception.value = Exception(appContext.getString(R.string.retrieve_password_mobile_hint))
return@launch
}
})
}
}
@@ -0,0 +1,154 @@
package com.yxjk.healthexpertclient.ui.main
import android.os.Bundle
import androidx.fragment.app.Fragment
import com.btpj.lib_base.ext.clearLongClickToast
import com.buddy.kredit.android.base.BaseActivity
import com.yxjk.healthexpertclient.MyApplication.Companion.appViewModel
import com.yxjk.healthexpertclient.R
import com.yxjk.healthexpertclient.databinding.ActivityMainBinding
import com.yxjk.healthexpertclient.event.DoctorEvent
import com.yxjk.healthexpertclient.ext.loginIm
import com.yxjk.healthexpertclient.ui.main.viewmodel.MainViewModel
import com.yxjk.healthexpertclient.ui.mine.fragment.MineFragment
import com.yxjk.healthexpertclient.ui.workbench.fragment.WorkbenchFragment
import com.tencent.qcloud.tuicore.TUIThemeManager
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import org.lzh.framework.updatepluginlib.UpdateBuilder
class MainActivity : BaseActivity<MainViewModel, ActivityMainBinding>(R.layout.activity_main) {
companion object {
/** 记录修改配置(如页面旋转)前navBar的位置的常量 */
private const val CURRENT_NAV_POSITION = "currentNavPosition"
}
private val workbenchFragment by lazy { WorkbenchFragment.newInstance() }
private val mineFragment by lazy { MineFragment.newInstance() }
/** 设置默认值为账号页,目的是第一次设置Fragment的时候防止跟实际会设置的Fragment一样,导致不添加() */
private var mCurrentFragment: Fragment? = null
private var mCurrentNavPosition = 0
override fun initView(savedInstanceState: Bundle?) {
// 修改配置时(例如页面旋转、深浅模式切换等)的页面恢复
if (savedInstanceState != null) {
getIndexFragment(savedInstanceState.getInt(CURRENT_NAV_POSITION))
}
initTUIThemeManager()
UpdateBuilder.create()
.check()// 启动更新任务
mBinding.apply {
bottomNavigationView.apply {
// 处理bottomNavigationView的item长按出现Toast的问题
clearLongClickToast(
mutableListOf(
R.id.menu_workbench,
R.id.menu_mine
)
)
setOnItemSelectedListener {
return@setOnItemSelectedListener onNavBarItemSelected(it.itemId)
}
}
}
getIndexFragment(0)
}
override fun initData() {
if(isLogin()){
appViewModel.getIMSig(successCall = {
loginIm()
})
}else{
finish()
}
}
private fun initTUIThemeManager(){
TUIThemeManager.getInstance().changeTheme(this, TUIThemeManager.THEME_SERIOUS)
TUIThemeManager.setWebViewLanguage(this)
}
/**
* 设置指定下标的Fragment
*/
private fun getIndexFragment(index: Int) {
when (index) {
0 -> R.id.menu_workbench
1 -> R.id.menu_mine
else -> R.id.menu_workbench
}.let {
mBinding.bottomNavigationView.selectedItemId = it
onNavBarItemSelected(it)
}
}
/**
* bottomNavigationView切换时调用的方法
*
* @param itemId 切换Item的id
*/
private fun onNavBarItemSelected(itemId: Int): Boolean {
when (itemId) {
R.id.menu_workbench -> {
mCurrentNavPosition = 0
switchFragment(workbenchFragment)
return true
}
R.id.menu_mine -> {
mCurrentNavPosition = 1
switchFragment(mineFragment)
return true
}
else -> {
mCurrentNavPosition = 0
switchFragment(workbenchFragment)
return true
}
}
}
/**
* 切换Fragment
*
* @param fragment 要切换的Fragment
*/
private fun switchFragment(fragment: Fragment) {
if (fragment !== mCurrentFragment) {
val fragmentTransaction = supportFragmentManager.beginTransaction()
// 先隐藏当前显示的Fragment
mCurrentFragment?.let { fragmentTransaction.hide(it) }
if (!fragment.isAdded) {
var oldFragment = supportFragmentManager.findFragmentByTag(fragment.javaClass.simpleName)
if(oldFragment == null){
// 存入Tag,以便获取,解决界面重叠问题 参考http://blog.csdn.net/showdy/article/details/50825800
fragmentTransaction.add(R.id.main_content_layout, fragment, fragment.javaClass.simpleName)
.show(fragment)
}else{
fragmentTransaction.show(oldFragment)
}
} else {
fragmentTransaction.show(fragment)
}
// 执行提交
fragmentTransaction.commitAllowingStateLoss()
// 将当前Fragment赋值为切换后的Fragment
mCurrentFragment = fragment
}
}
override fun onSaveInstanceState(outState: Bundle) {
// 解决Fragment界面重叠问题,直接传递一个空的Bundle 参考http://blog.csdn.net/showdy/article/details/50825800
super.onSaveInstanceState(Bundle())
// 记录屏幕旋转/更换深浅模式等之前切换的Fragment的位置
outState.putInt(CURRENT_NAV_POSITION, mCurrentNavPosition)
}
override fun onBackPressed() {
super.onBackPressed()
finish()
}
override fun bindEvent() {
}
@Subscribe(threadMode = ThreadMode.MAIN)
fun onEvent(event: DoctorEvent) {
mViewModel.getDoctorInfo()
}
}
@@ -0,0 +1,69 @@
package com.yxjk.healthexpertclient.ui.main
import android.os.Bundle
import android.webkit.WebView
import android.widget.FrameLayout
import com.buddy.kredit.android.base.BaseActivity
import com.just.agentweb.AgentWeb
import com.just.agentweb.WebChromeClient
import com.yxjk.healthexpertclient.R
import com.yxjk.healthexpertclient.databinding.ActivityWebBinding
import com.yxjk.healthexpertclient.ui.main.viewmodel.WebViewModel
/**
* @author nanfeifei
* @time 2023/5/23 16:20
* @description WebView页面
*/
class WebActivity: BaseActivity<WebViewModel, ActivityWebBinding>(R.layout.activity_web) {
private lateinit var mAgentWeb: AgentWeb
private lateinit var mUrl: String
private lateinit var mTitle: String
override fun initView(savedInstanceState: Bundle?) {
mAgentWeb = AgentWeb.with(this)
.setAgentWebParent(mBinding.flWeb, FrameLayout.LayoutParams(-1, -1))
.useDefaultIndicator()
.setWebChromeClient(object : WebChromeClient() {
override fun onReceivedTitle(view: WebView?, title: String?) {
super.onReceivedTitle(view, title)
mTitle = title ?: ""
if(mTitle.startsWith("http")){
mTitle = getString(R.string.app_name)
}
mBinding.toolbarLay.tvTitle.text = mTitle
}
})
.createAgentWeb()
.ready()
.go(getUrl())
var javaScriptEnabled = intent.extras?.getBoolean("javaScriptEnabled")
if (javaScriptEnabled != null) {
mAgentWeb.agentWebSettings.webSettings.javaScriptEnabled = javaScriptEnabled
}
}
override fun bindEvent() {
}
private fun getUrl(): String {
mUrl = intent.extras?.getString("url").toString()
return mUrl
}
override fun onResume() {
mAgentWeb.webLifeCycle.onResume()
super.onResume()
}
override fun onPause() {
mAgentWeb.webLifeCycle.onPause()
super.onPause()
}
override fun onDestroy() {
mAgentWeb.webLifeCycle.onDestroy()
super.onDestroy()
}
}
@@ -0,0 +1,128 @@
package com.yxjk.healthexpertclient.ui.main.adapter
import android.view.View
import com.btpj.lib_base.base.adapter.BaseDataBindingAdapter
import com.btpj.lib_base.ext.loadRoundedImage
import com.chad.library.adapter.base.module.LoadMoreModule
import com.chad.library.adapter.base.viewholder.BaseDataBindingHolder
import com.yxjk.healthexpertclient.R
import com.yxjk.healthexpertclient.bean.ImageBean
import com.yxjk.healthexpertclient.databinding.ItemRecycleImageBinding
import java.io.File
/**
* @author nanfeifei
* @time 2023/5/25 18:01
* @description
*/
class ImageAdapter(var maxNum: Int): BaseDataBindingAdapter<ImageBean, ItemRecycleImageBinding>(
R.layout.item_recycle_image
), LoadMoreModule {
private var isEditModel = false
private var editImageShow = false
override fun bindViewClickListener(
viewHolder: BaseDataBindingHolder<ItemRecycleImageBinding>,
viewType: Int
) {
addChildClickViewIds(R.id.btn_delete)
super.bindViewClickListener(viewHolder, viewType)
}
override fun convert(
holder: BaseDataBindingHolder<ItemRecycleImageBinding>,
item: ImageBean
) {
val mBinding = holder.dataBinding
mBinding?.let {
if(item.isAddButton){
mBinding.ivImage.setImageResource(R.drawable.icon_image_add)
mBinding.btnDelete.visibility = View.GONE
}else{
if(item.isFilePath){
mBinding.ivImage.loadRoundedImage(File(item.imageUrl), 5f)
}else{
mBinding.ivImage.loadRoundedImage(item.imageUrl, 5f, R.drawable.ic_default_archives_image)
}
if(isEditModel){
mBinding.btnDelete.visibility = View.VISIBLE
}else{
mBinding.btnDelete.visibility = View.GONE
}
}
}
}
fun isEditModel(isEdit: Boolean){
isEditModel = isEdit
notifyDataSetChanged()
if(isEditModel && !editImageShow){
showAddButton(true)
}
}
override fun setList(list: Collection<ImageBean>?) {
super.setList(list)
if(isEditModel){
showAddButton(true)
}
}
override fun setNewInstance(list: MutableList<ImageBean>?) {
super.setNewInstance(list)
if(isEditModel){
showAddButton(true)
}
}
override fun addData(newData: Collection<ImageBean>) {
if(isEditModel){
if(editImageShow){
var lastPosition = data.size - 1
if(lastPosition < 0){
lastPosition = 0
}
addData(lastPosition, newData)
}else{
showAddButton(true)
}
if(data.size > maxNum){
showAddButton(false)
}
}else{
super.addData(newData)
}
}
override fun removeAt(position: Int) {
super.removeAt(position)
if(isEditModel && !editImageShow){
showAddButton(true)
}
}
fun getImageList(): MutableList<ImageBean>{
var list = mutableListOf<ImageBean>()
data.forEach { imageBean ->
if(!imageBean.isAddButton){
list.add(imageBean)
}
}
return list
}
fun getImageSize(): Int {
if(isEditModel && editImageShow){
return getDefItemCount() - 1
}
return getDefItemCount()
}
/**
* 显示添加图片按钮
* @param isShow true为显示 false为隐藏
*/
private fun showAddButton(isShow: Boolean){
editImageShow = if(isShow){
addData(ImageBean(isAddButton = true))
true
}else{
removeAt(data.size-1)
false
}
}
}
@@ -0,0 +1,84 @@
package com.yxjk.healthexpertclient.ui.main.viewmodel
import com.btpj.lib_base.BaseApp.Companion.appContext
import com.btpj.lib_base.base.BaseViewModel
import com.btpj.lib_base.ext.addImageBaseUrl
import com.btpj.lib_base.ext.handleRequest
import com.btpj.lib_base.ext.launch
import com.yxjk.healthexpertclient.bean.UserInfoBean
import com.yxjk.healthexpertclient.bean.im.IMInfoBean
import com.yxjk.healthexpertclient.data.repository.IMRepository
import com.yxjk.healthexpertclient.data.repository.WorkbenchRepository
import com.yxjk.healthexpertclient.event.ConsultRecordEvent
import com.yxjk.healthexpertclient.event.WorkbenchEvent
import com.yxjk.healthexpertclient.ext.initIMSDK
import com.yxjk.healthexpertclient.utils.CommonUtils
import com.yxjk.healthexpertclient.utils.TUIUtils
import com.tencent.imsdk.v2.V2TIMCallback
import com.tencent.imsdk.v2.V2TIMManager
import com.tencent.imsdk.v2.V2TIMUserFullInfo
import kotlinx.coroutines.flow.MutableStateFlow
import org.greenrobot.eventbus.EventBus
/**
* @author nanfeifei
* @time 2023/5/11 14:11
* @description
*/
class AppViewModel: BaseViewModel() {
var loginState = MutableStateFlow(false)
var imSig = MutableStateFlow("")
var imAppId = MutableStateFlow("")
var imUserId = MutableStateFlow("")
override fun init() {
}
fun getIMSig(successCall: (IMInfoBean) -> Unit = {}){
launch({
handleRequest(IMRepository.getIMSig(), successBlock = {
it.result?.let { imBean ->
imSig.emit(imBean.userSig)
imUserId.emit(imBean.userId)
imAppId.emit(imBean.sdkAppId)
appContext.initIMSDK(imBean.sdkAppId.toInt())
successCall.invoke(imBean)
}
})
})
}
fun setUserIMInfo(){
var info = V2TIMUserFullInfo()
var userInfo: UserInfoBean? = CommonUtils.getUserInfo() ?: return
info.setNickname(userInfo?.realname)
info.faceUrl = addImageBaseUrl(userInfo?.avatar)
V2TIMManager.getInstance().setSelfInfo(info, object : V2TIMCallback {
override fun onSuccess() {
// 设置个人资料成功
}
override fun onError(code: Int, desc: String) {
// 设置个人资料失败
}
})
}
fun finishIMChat(workType: Int, workId: String, finallyCall: () -> Unit = {}){
launch({
when(workType){
TUIUtils.WORK_TYPE_IMAGE_TEXT_CONSULT -> {
handleRequest(WorkbenchRepository.finishConsult(workId), successBlock = {
EventBus.getDefault().post(ConsultRecordEvent())
EventBus.getDefault().post(WorkbenchEvent())
})
}
TUIUtils.WORK_TYPE_ASSISTANT -> {
handleRequest(WorkbenchRepository.finishConsult(workId), successBlock = {
EventBus.getDefault().post(WorkbenchEvent())
})
}
}
}, finallyBlock = {
finallyCall.invoke()
})
}
}
@@ -0,0 +1,30 @@
package com.yxjk.healthexpertclient.ui.main.viewmodel
import com.btpj.lib_base.base.BaseViewModel
import com.btpj.lib_base.ext.handleRequest
import com.btpj.lib_base.ext.launch
import com.yxjk.healthexpertclient.bean.im.IMAssistantBean
import com.yxjk.healthexpertclient.bean.mine.DoctorBean
import com.yxjk.healthexpertclient.data.repository.MineRepository
import kotlinx.coroutines.flow.MutableStateFlow
class MainViewModel: BaseViewModel() {
var doctorBean = MutableStateFlow(DoctorBean())
override fun init() {
getDoctorInfo()
}
fun getDoctorInfo(){
launch({
handleRequest(MineRepository.getDoctorInfo(), successBlock = {
it.result?.let { result -> doctorBean.emit(result) }
})
})
}
fun submitAssistantConsultApply(successCall: (IMAssistantBean) -> Unit = {}){
launch({
handleRequest(MineRepository.submitAssistantConsultApply(), successBlock = {
it.result?.let { it1 -> successCall.invoke(it1) }
})
})
}
}
@@ -0,0 +1,8 @@
package com.yxjk.healthexpertclient.ui.main.viewmodel
import com.btpj.lib_base.base.BaseViewModel
class WebViewModel: BaseViewModel() {
override fun init() {
}
}
@@ -0,0 +1,173 @@
package com.yxjk.healthexpertclient.ui.mine
import android.os.Bundle
import android.view.View
import androidx.core.view.ViewCompat
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import com.btpj.lib_base.base.adapter.BaseCheckRecycleViewAdapter
import com.buddy.kredit.android.base.BaseActivity
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.listener.OnItemClickListener
import com.github.gzuliyujiang.wheelpicker.DatePicker
import com.github.gzuliyujiang.wheelpicker.annotation.DateMode
import com.github.gzuliyujiang.wheelpicker.entity.DateEntity
import com.google.android.flexbox.FlexboxLayoutManager
import com.yxjk.healthexpertclient.R
import com.yxjk.healthexpertclient.databinding.ActivityAddSuspensionAnnouncementBinding
import com.yxjk.healthexpertclient.ui.mine.adapter.SuspensionCauseAdapter
import com.yxjk.healthexpertclient.ui.mine.viewmodel.AddSuspensionAnnouncementViewModel
import com.yxjk.healthexpertclient.view.SuspensionAnnouncementAffirmDialog
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
/**
* @author nanfeifei
* @time 2023/5/17 18:30
* @description 暂停服务公告
*/
class AddSuspensionAnnouncementActivity :
BaseActivity<AddSuspensionAnnouncementViewModel, ActivityAddSuspensionAnnouncementBinding>(R.layout.activity_add_suspension_announcement),
OnItemClickListener {
private val affirmDialog by lazy { SuspensionAnnouncementAffirmDialog(this) }
private val mAdapter: SuspensionCauseAdapter = SuspensionCauseAdapter()
val dataPicker: DatePicker by lazy { DatePicker(this) }
private var startDate: DateEntity = DateEntity.today()
private var endDate: DateEntity = DateEntity.today()
companion object{
const val DATE_TYPE_START = 1
const val DATE_TYPE_END = 2
}
override fun initView(savedInstanceState: Bundle?) {
mBinding.apply {
val flexboxLayoutManager = FlexboxLayoutManager(this@AddSuspensionAnnouncementActivity)
rvCauseList.layoutManager = flexboxLayoutManager
ViewCompat.setNestedScrollingEnabled(rvCauseList, false)
}
}
override fun initData() {
super.initData()
setDate(startDate.year, startDate.month, startDate.day, DATE_TYPE_START)
setDate(endDate.year, endDate.month, endDate.day, DATE_TYPE_END)
}
override fun createObserve() {
super.createObserve()
mBinding.apply {
lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.CREATED) {
mViewModel.causeList.collectLatest { list ->
if(list.isNullOrEmpty()){
return@collectLatest
}
mAdapter.setNewInstance(list)
if (rvCauseList.adapter == null) {
mAdapter.enabledCheckMode = true
mAdapter.singleMode = true
mAdapter.singleModeIsCanCancel = true
mAdapter.setOnItemClickListener(this@AddSuspensionAnnouncementActivity)
rvCauseList.adapter = mAdapter
}
}
}
}
lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.CREATED) {
mViewModel.underwayConsult.collectLatest { it ->
affirmDialog.setAudioVideoNum(it)
if(!affirmDialog.isShowing){
affirmDialog.show()
}
}
}
}
lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.CREATED) {
mViewModel.finishActivity.collectLatest {
if(it){
finish()
}
}
}
}
}
}
override fun bindEvent() {
addClickViews(mBinding.btnSubmit, mBinding.tvStartTime, mBinding.tvEndTime)
affirmDialog.setOnSubmitClickListener(object : SuspensionAnnouncementAffirmDialog.OnSubmitClickListener{
override fun onSubmitClick(viewDialog: SuspensionAnnouncementAffirmDialog) {
mViewModel.addSuspensionAnnouncement()
}
override fun onCloseClick(viewDialog: SuspensionAnnouncementAffirmDialog) {
}
})
}
override fun onClick(v: View?) {
super.onClick(v)
when(v?.id){
R.id.btn_submit -> {
mViewModel.checkSuspensionAnnouncementContent(mAdapter.checkedItems)
}
R.id.tv_start_time -> {
showDatePicker(R.string.add_suspension_announcement_start_time, startDate, DATE_TYPE_START)
}
R.id.tv_end_time -> {
showDatePicker(R.string.add_suspension_announcement_end_time, endDate, DATE_TYPE_END)
}
}
}
private fun showDatePicker(titleId: Int, defaultData: DateEntity, dateType: Int) {
dataPicker.setBackgroundResource(R.drawable.rectangle_top_round_corner20_white)
dataPicker.setTitle(titleId)
var wheelLayout = dataPicker.wheelLayout
wheelLayout.setDateMode(DateMode.YEAR_MONTH_DAY)
wheelLayout.setRange(DateEntity.today(), DateEntity.yearOnFuture(1), defaultData)
wheelLayout.setResetWhenLinkage(false)
dataPicker.setOnDatePickedListener { year, month, day ->
setDate(year, month, day, dateType)
}
if(!dataPicker.isShowing){
dataPicker.show()
}
}
private fun setDate(year: Int, month: Int, day: Int, dateType: Int) {
when(dateType){
DATE_TYPE_START -> {
startDate = DateEntity.target(year, month, day)
mViewModel.suspensionServiceBean.value.startDayLong = startDate.toTimeInMillis()
mViewModel.suspensionServiceBean.value.startDay = startDate.toString()
mBinding.tvStartTime.text =
getString(R.string.add_suspension_announcement_birthday_format, year, month, day)
if(startDateBeforeEndDate(startDate, endDate)){
setDate(year, month, day, DATE_TYPE_END)
}
}
DATE_TYPE_END -> {
endDate = DateEntity.target(year, month, day)
mViewModel.suspensionServiceBean.value.endDayLong = endDate.toTimeInMillis()
mViewModel.suspensionServiceBean.value.endDay = endDate.toString()
mBinding.tvEndTime.text =
getString(R.string.add_suspension_announcement_birthday_format, year, month, day)
}
}
}
/**
* 开始时间是否在结束时间之前
* @param startDate
* @param endDate
*/
private fun startDateBeforeEndDate(startDate: DateEntity, endDate: DateEntity): Boolean{
if(startDate == null || endDate == null){
false
}
return startDate.toTimeInMillis() > endDate.toTimeInMillis()
}
override fun onItemClick(adapter: BaseQuickAdapter<*, *>, view: View, position: Int) {
(adapter as BaseCheckRecycleViewAdapter).clickItem(position, false)
}
}
@@ -0,0 +1,109 @@
package com.yxjk.healthexpertclient.ui.mine
import android.content.res.ColorStateList
import android.os.Bundle
import android.view.Gravity
import android.view.View
import android.widget.TextView
import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
import androidx.lifecycle.lifecycleScope
import androidx.viewpager2.widget.ViewPager2
import com.btpj.lib_base.utils.DateUtil.getDateYearMonthStr
import com.buddy.kredit.android.base.BaseActivity
import com.github.gzuliyujiang.wheelpicker.DatePicker
import com.github.gzuliyujiang.wheelpicker.annotation.DateMode
import com.github.gzuliyujiang.wheelpicker.entity.DateEntity
import com.google.android.material.tabs.TabLayoutMediator
import com.yxjk.healthexpertclient.R
import com.yxjk.healthexpertclient.databinding.ActivityBillRecordBinding
import com.yxjk.healthexpertclient.ui.mine.fragment.BillRecordFragment
import com.yxjk.healthexpertclient.ui.mine.fragment.BillRecordFragment.Companion.BILL_TYPE_ALL
import com.yxjk.healthexpertclient.ui.mine.fragment.BillRecordFragment.Companion.BILL_TYPE_INCOME
import com.yxjk.healthexpertclient.ui.mine.fragment.BillRecordFragment.Companion.BILL_TYPE_PAYMENT
import com.yxjk.healthexpertclient.ui.mine.viewmodel.BillRecordViewModel
import com.yxjk.healthexpertclient.view.viewpager.ViewPagerAdapter
import kotlinx.coroutines.launch
/**
* 账单明细
*/
class BillRecordActivity: BaseActivity<BillRecordViewModel, ActivityBillRecordBinding>(R.layout.activity_bill_record),
ViewPagerAdapter.OnCreateFragmentListener {
val dataPicker: DatePicker by lazy { DatePicker(this) }
var defaultData: DateEntity = DateEntity.today()
override fun initView(savedInstanceState: Bundle?) {
setToolBarRightText(getString(R.string.bill_record_date_select))
val tabs = arrayOf("全部", "收益记录", "提现记录")
//禁用预加载
mBinding.viewPager.offscreenPageLimit = ViewPager2.OFFSCREEN_PAGE_LIMIT_DEFAULT
mBinding.viewPager.adapter = ViewPagerAdapter(this, tabs, this)
var mediator = TabLayoutMediator(
mBinding.tabLayout, mBinding.viewPager, false, true
) { tab, position -> //这里可以自定义TabView
val tabView = TextView(this@BillRecordActivity)
tabView.gravity = Gravity.CENTER
tabView.text = tabs[position]
val states = arrayOfNulls<IntArray>(2)
states[0] = intArrayOf(android.R.attr.state_selected)
states[1] = intArrayOf()
val colors = intArrayOf(
ContextCompat.getColor(this@BillRecordActivity, R.color.text_black_33),
ContextCompat.getColor(this@BillRecordActivity, R.color.text_black_66))
val colorStateList = ColorStateList (states, colors)
tabView.setTextColor(colorStateList)
tab.customView = tabView
}
//要执行这一句才是真正将两者绑定起来
mediator.attach()
}
override fun bindEvent() {
}
override fun createFragment(position: Int): Fragment {
when(position){
0 -> {
return BillRecordFragment.newInstance(BILL_TYPE_ALL)
}
1 -> {
return BillRecordFragment.newInstance(BILL_TYPE_INCOME)
}
2 -> {
return BillRecordFragment.newInstance(BILL_TYPE_PAYMENT)
}
}
return BillRecordFragment.newInstance(BILL_TYPE_ALL)
}
override fun onClick(v: View?) {
super.onClick(v)
when(v?.id){
R.id.tv_right -> {
showDatePicker()
}
}
}
private fun showDatePicker() {
dataPicker.setBackgroundResource(R.drawable.rectangle_top_round_corner20_white)
dataPicker.setTitle(R.string.bill_record_date_select)
var wheelLayout = dataPicker.wheelLayout
wheelLayout.setDateMode(DateMode.YEAR_MONTH)
wheelLayout.setRange(DateEntity.target(2020, 1, 1), DateEntity.today(), defaultData)
wheelLayout.setResetWhenLinkage(false)
dataPicker.setOnDatePickedListener { year, month, day ->
defaultData = DateEntity.target(year, month, day)
var dateStr = getDateYearMonthStr(defaultData.toTimeInMillis())
mBinding.toolbarLay.tvRight.text = dateStr
lifecycleScope.launch {
mViewModel.billDate.emit(dateStr)
}
}
if(!dataPicker.isShowing){
dataPicker.show()
}
}
}
@@ -0,0 +1,191 @@
package com.yxjk.healthexpertclient.ui.mine
import android.graphics.Color
import android.os.Bundle
import android.view.View
import android.widget.AdapterView
import android.widget.AdapterView.OnItemSelectedListener
import android.widget.ArrayAdapter
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import com.btpj.lib_base.utils.DateUtil
import com.buddy.kredit.android.base.BaseActivity
import com.github.mikephil.charting.charts.PieChart
import com.github.mikephil.charting.components.Description
import com.github.mikephil.charting.components.Legend
import com.github.mikephil.charting.data.PieData
import com.github.mikephil.charting.data.PieDataSet
import com.github.mikephil.charting.data.PieEntry
import com.yxjk.healthexpertclient.R
import com.yxjk.healthexpertclient.bean.mine.ConsultTypeBean
import com.yxjk.healthexpertclient.databinding.ActivityConsultStatisticsBinding
import com.yxjk.healthexpertclient.ext.startBillRecordActivity
import com.yxjk.healthexpertclient.ui.mine.utils.ConsultStatisticsFormatter
import com.yxjk.healthexpertclient.ui.mine.viewmodel.ConsultStatisticsViewModel
import com.yxjk.healthexpertclient.utils.CommonUtils
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
/**
* @author nanfeifei
* @time 2023/5/18 17:26
* @description 咨询统计
*/
class ConsultStatisticsActivity :
BaseActivity<ConsultStatisticsViewModel, ActivityConsultStatisticsBinding>(
R.layout.activity_consult_statistics
) {
override fun initView(savedInstanceState: Bundle?) {
}
override fun createObserve() {
super.createObserve()
lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.CREATED) {
mViewModel.consultTypeMonthList.collectLatest {
var visibility = View.VISIBLE
if (it.isNullOrEmpty()){
visibility = View.VISIBLE
}else{
it.forEach { consultTypeBean ->
if (consultTypeBean.total > 0){
visibility = View.GONE
}
}
}
mBinding.tvNoDate.visibility = visibility
if (it != null) {
showPieChart(mBinding.pieChartView, it)
}
}
}
}
lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.CREATED) {
mViewModel.firstMonthList.collectLatest {
setSpinnerData(it.toTypedArray())
}
}
}
}
override fun bindEvent() {
addClickViews(mBinding.clMoneyLay)
}
override fun onClick(v: View?) {
super.onClick(v)
when(v?.id){
R.id.cl_money_lay -> {
startBillRecordActivity(this@ConsultStatisticsActivity)
}
}
}
private fun setSpinnerData(array: Array<String>){
val adapter = ArrayAdapter(this@ConsultStatisticsActivity, R.layout.item_spinner_dropdown, array)
mBinding.spinnerMonth.adapter = adapter
mBinding.spinnerMonth.onItemSelectedListener = object : OnItemSelectedListener{
override fun onItemSelected(
parent: AdapterView<*>?,
view: View?,
position: Int,
id: Long
) {
lifecycleScope.launch {
if(mViewModel.firstMonthList.value != null && position < mViewModel.firstMonthList.value.size){
mViewModel.date.emit(DateUtil.chineseDateToStrShortMonth(mViewModel.firstMonthList.value[position]))
mViewModel.getConsultTypeMonthData()
}
}
}
override fun onNothingSelected(parent: AdapterView<*>?) {
}
}
}
private fun getPieChartData(list: MutableList<ConsultTypeBean>): List<PieEntry> {
var mPie: MutableList<PieEntry> = mutableListOf()
var pieEntry: PieEntry
for (data in list) {
pieEntry = PieEntry(data.total.toFloat(), data.content_type)
mPie.add(pieEntry)
}
return mPie
}
private fun showPieChart(pieChart: PieChart, pieList: MutableList<ConsultTypeBean>) {
val dataSet = PieDataSet(getPieChartData(pieList), "")
// 设置颜色list
dataSet.colors = getPieColor(pieList)
val pieData = PieData(dataSet)
// 设置描述
val description = Description()
description.isEnabled = false
pieChart.description = description
//设置半透明圆环的半径, 0为透明
pieChart.transparentCircleRadius = 0f
//设置初始旋转角度
pieChart.rotationAngle = -12f
//数据连接线距图形片内部边界的距离,为百分数
// dataSet.valueLinePart1OffsetPercentage = 90f
dataSet.valueLinePart1Length = 0.5f
//设置连接线的颜色
// dataSet.valueLineColor = Color.LTGRAY
dataSet.isUsingSliceColorAsValueLineColor = true
// 连接线在饼状图外面
dataSet.yValuePosition = PieDataSet.ValuePosition.OUTSIDE_SLICE
// 设置饼块之间的间隔
// dataSet.sliceSpace = 1f
dataSet.isHighlightEnabled = true
// 显示图例
val legend = pieChart.legend
legend.isEnabled = true
legend.horizontalAlignment = Legend.LegendHorizontalAlignment.CENTER
legend.textSize = 10f //设置图例标签文本的大小
legend.textColor = R.color.text_black_33//设置图例标签文本的颜色
// 和四周相隔一段距离,显示数据
pieChart.setExtraOffsets(35f, 5f, 35f, 5f)
// 设置pieChart图表是否可以手动旋转
pieChart.isRotationEnabled = false
// 设置piecahrt图表点击Item高亮是否可用
pieChart.isHighlightPerTapEnabled = false
// 设置pieChart图表展示动画效果,动画运行1.4秒结束
pieChart.animateY(700)
//设置pieChart是否只显示饼图上百分比不显示文字
pieChart.setDrawEntryLabels(false)
//是否绘制PieChart内部中心文本
pieChart.setDrawCenterText(true)
pieChart.centerText = "咨询方式"
// pieChart.setCenterTextColor(R.color.text_black_33)
// pieChart.setCenterTextSize(14f)
// 绘制内容value,设置字体颜色大小
pieData.setDrawValues(true)
pieData.setValueFormatter(ConsultStatisticsFormatter())
pieData.setValueTextSize(10f)
pieData.setValueTextColor(Color.DKGRAY)
pieChart.data = pieData
// 更新 piechart 视图
pieChart.postInvalidate()
}
private fun getPieColor(list: MutableList<ConsultTypeBean>): ArrayList<Int>{
val colors = ArrayList<Int>()
for (index in list.indices) {
when(index){
0 -> {
colors.add(Color.parseColor("#407FFF"))
}
1 -> {
colors.add(Color.parseColor("#A682E6"))
}
else -> {
colors.add(CommonUtils.getRandomColor())
}
}
}
return colors
}
}
@@ -0,0 +1,119 @@
package com.yxjk.healthexpertclient.ui.mine
import android.os.Bundle
import android.view.View
import androidx.core.view.ViewCompat
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import androidx.recyclerview.widget.GridLayoutManager
import com.btpj.lib_base.base.adapter.BaseCheckRecycleViewAdapter
import com.buddy.kredit.android.base.BaseActivity
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.listener.OnItemClickListener
import com.yxjk.healthexpertclient.R
import com.yxjk.healthexpertclient.bean.mine.SchedulingBean
import com.yxjk.healthexpertclient.databinding.ActivityCustomSchedulingBinding
import com.yxjk.healthexpertclient.ext.startSchedulingActivity
import com.yxjk.healthexpertclient.ui.mine.adapter.CustomSchedulingAdapter
import com.yxjk.healthexpertclient.ui.mine.viewmodel.CustomSchedulingViewModel
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
/**
* @author nanfeifei
* @time 2023/5/17 13:10
* @description 自定义排班
*/
class CustomSchedulingActivity: BaseActivity<CustomSchedulingViewModel, ActivityCustomSchedulingBinding>(
R.layout.activity_custom_scheduling), OnItemClickListener {
private val mAdapter: CustomSchedulingAdapter = CustomSchedulingAdapter()
override fun initView(savedInstanceState: Bundle?) {
mBinding.apply {
val gridLayoutManager = GridLayoutManager(this@CustomSchedulingActivity, 7)
// linearLayoutManager.orientation = HORIZONTAL
rvList.layoutManager = gridLayoutManager
ViewCompat.setNestedScrollingEnabled(rvList, false)
}
mAdapter.enabledCheckMode = true
mAdapter.singleMode = true
mAdapter.singleModeIsCanCancel = false
mAdapter.setOnItemClickListener(this@CustomSchedulingActivity)
}
override fun createObserve() {
super.createObserve()
mBinding.apply {
lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.CREATED) {
mViewModel.schedulingList.collectLatest { list ->
if(list.isNullOrEmpty()){
return@collectLatest
}
mAdapter.setNewInstance(list)
if (rvList.adapter == null) {
rvList.adapter = mAdapter
}
changeWeek(mAdapter, 0)
}
}
}
lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.CREATED) {
mViewModel.showAudioVideoConsult.collectLatest { isShow ->
if(mAdapter.currentCheckedPosition < 0||mAdapter.data.isNullOrEmpty()||mAdapter.currentCheckedPosition >= mAdapter.data.size){
return@collectLatest
}
mAdapter.getItem(mAdapter.currentCheckedPosition).consultSwitchOn = isShow
}
}
}
}
}
override fun bindEvent() {
addClickViews(mBinding.btnUnifyScheduling, mBinding.btnSubmit)
}
override fun onClick(v: View?) {
super.onClick(v)
when(v?.id){
R.id.btn_submit -> {
setLastAppointmentNum()
mViewModel.createDoctorScheduling()
}
R.id.btn_unify_scheduling -> {
startSchedulingActivity(this)
finish()
}
}
}
override fun onItemClick(adapter: BaseQuickAdapter<*, *>, view: View, position: Int) {
changeWeek(adapter, position)
}
private fun changeWeek(adapter: BaseQuickAdapter<*, *>,position: Int){
setLastAppointmentNum()
(adapter as BaseCheckRecycleViewAdapter).clickItem(position, false)
var schedulingBean: SchedulingBean = adapter.getItem(position) as SchedulingBean
lifecycleScope.launch {
mViewModel.showAudioVideoConsult.emit(schedulingBean.consultSwitchOn)
}
mBinding.apply {
schedulingBean.amNum?.let {
layConsultNumSetting.etMorningAppointmentsNumber.setText(it)
}
schedulingBean.pmNum?.let {
layConsultNumSetting.etAfternoonAppointmentsNumber.setText(it)
}
}
}
private fun setLastAppointmentNum(){
//mAdapter.currentCheckedPosition在clickItem之后才会被更改,所以此时相当于还是上一次选中的值
if(mAdapter.currentCheckedPosition < 0||mAdapter.data.isNullOrEmpty()||mAdapter.currentCheckedPosition >= mAdapter.data.size){
return
}
var schedulingBean: SchedulingBean = mAdapter.getItem(mAdapter.currentCheckedPosition)
schedulingBean.amNum = mBinding.layConsultNumSetting.etMorningAppointmentsNumber.text.toString().trim()
schedulingBean.pmNum = mBinding.layConsultNumSetting.etAfternoonAppointmentsNumber.text.toString().trim()
}
}
@@ -0,0 +1,78 @@
package com.yxjk.healthexpertclient.ui.mine
import android.os.Bundle
import android.text.method.HideReturnsTransformationMethod
import android.text.method.PasswordTransformationMethod
import android.view.View
import com.buddy.kredit.android.base.BaseActivity
import com.yxjk.healthexpertclient.R
import com.yxjk.healthexpertclient.databinding.ActivityEditPasswordBinding
import com.yxjk.healthexpertclient.ui.mine.viewmodel.EditPasswordViewModel
/**
* @author nanfeifei
* @time 2023/5/22 17:06
* @description 修改密码
*/
class EditPasswordActivity: BaseActivity<EditPasswordViewModel, ActivityEditPasswordBinding>(R.layout.activity_edit_password) {
override fun initView(savedInstanceState: Bundle?) {
}
override fun bindEvent() {
mBinding.layOldPassword.loginIvEye.setOnClickListener {
mBinding?.let {
var selection=it.layOldPassword.evPasswordContent.selectionEnd
if (it.layOldPassword.evPasswordContent.transformationMethod== PasswordTransformationMethod.getInstance()){
it.layOldPassword.evPasswordContent.setTransformationMethod(
HideReturnsTransformationMethod.getInstance())
it.layOldPassword.loginIvEye.setImageResource(R.mipmap.ic_password_show)
}else{
it.layOldPassword.evPasswordContent.setTransformationMethod(PasswordTransformationMethod.getInstance())
it.layOldPassword.loginIvEye.setImageResource(R.mipmap.ic_password_hind)
}
it.layOldPassword.evPasswordContent.setSelection(selection)
}
}
mBinding.layNewPassword.loginIvEye.setOnClickListener {
mBinding?.let {
var selection=it.layNewPassword.evPasswordContent.selectionEnd
if (it.layNewPassword.evPasswordContent.transformationMethod== PasswordTransformationMethod.getInstance()){
it.layNewPassword.evPasswordContent.setTransformationMethod(
HideReturnsTransformationMethod.getInstance())
it.layNewPassword.loginIvEye.setImageResource(R.mipmap.ic_password_show)
}else{
it.layNewPassword.evPasswordContent.setTransformationMethod(PasswordTransformationMethod.getInstance())
it.layNewPassword.loginIvEye.setImageResource(R.mipmap.ic_password_hind)
}
it.layNewPassword.evPasswordContent.setSelection(selection)
}
}
mBinding.layConfirmPassword.loginIvEye.setOnClickListener {
mBinding?.let {
var selection=it.layConfirmPassword.evPasswordContent.selectionEnd
if (it.layConfirmPassword.evPasswordContent.transformationMethod== PasswordTransformationMethod.getInstance()){
it.layConfirmPassword.evPasswordContent.setTransformationMethod(
HideReturnsTransformationMethod.getInstance())
it.layConfirmPassword.loginIvEye.setImageResource(R.mipmap.ic_password_show)
}else{
it.layConfirmPassword.evPasswordContent.setTransformationMethod(PasswordTransformationMethod.getInstance())
it.layConfirmPassword.loginIvEye.setImageResource(R.mipmap.ic_password_hind)
}
it.layConfirmPassword.evPasswordContent.setSelection(selection)
}
}
addClickViews(mBinding.btnSubmit)
}
override fun onClick(v: View?) {
super.onClick(v)
when(v?.id){
R.id.btn_submit -> {
mViewModel.submitEditPassword(successCall = {
finish()
})
}
}
}
}
@@ -0,0 +1,82 @@
package com.yxjk.healthexpertclient.ui.mine
import android.os.Bundle
import android.view.View
import androidx.core.view.ViewCompat
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import androidx.recyclerview.widget.GridLayoutManager
import com.btpj.lib_base.base.adapter.BaseCheckRecycleViewAdapter
import com.buddy.kredit.android.base.BaseActivity
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.listener.OnItemClickListener
import com.yxjk.healthexpertclient.R
import com.yxjk.healthexpertclient.bean.mine.DiseaseBean
import com.yxjk.healthexpertclient.databinding.ActivityGoodAtDiseaseBinding
import com.yxjk.healthexpertclient.event.AddGoodAtDiseaseEvent
import com.yxjk.healthexpertclient.ui.mine.adapter.DiseaseAdapter
import com.yxjk.healthexpertclient.ui.mine.viewmodel.GoodAtDiseaseViewModel
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
import org.greenrobot.eventbus.EventBus
/**
* @author nanfeifei
* @time 2023/6/25 18:04
* @description 添加擅长疾病
*/
class GoodAtDiseaseActivity: BaseActivity<GoodAtDiseaseViewModel, ActivityGoodAtDiseaseBinding>(R.layout.activity_good_at_disease),
OnItemClickListener {
private val mAdapter: DiseaseAdapter = DiseaseAdapter()
lateinit var departmentId: String
lateinit var currentDiseaseList: ArrayList<DiseaseBean>
override fun initView(savedInstanceState: Bundle?) {
departmentId = intent.extras?.getString("departmentId") ?: ""
currentDiseaseList = intent.extras?.getParcelableArrayList("currentDiseaseList") ?: arrayListOf()
setToolBarRightText(getString(R.string.dialog_add_disease_affirm))
mBinding.apply {
val gridLayoutManager = GridLayoutManager(this@GoodAtDiseaseActivity, 2)
rvList.layoutManager = gridLayoutManager
ViewCompat.setNestedScrollingEnabled(rvList, false)
}
mAdapter.enabledCheckMode = true
mAdapter.setOnItemClickListener(this@GoodAtDiseaseActivity)
}
override fun createObserve() {
super.createObserve()
lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.CREATED) {
mViewModel.allDiseaseList.collectLatest { list ->
mAdapter.setList(list)
if (mBinding.rvList.adapter == null){
mBinding.rvList.adapter = mAdapter
}
}
}
}
}
override fun initData() {
super.initData()
mViewModel.getDoctorGoodAtDisease(departmentId, currentDiseaseList)
}
override fun bindEvent() {
}
override fun onClick(v: View?) {
super.onClick(v)
when(v?.id){
R.id.tv_right -> {
EventBus.getDefault().post(AddGoodAtDiseaseEvent(mAdapter.checkedItems.toMutableList()))
finish()
}
}
}
override fun onItemClick(adapter: BaseQuickAdapter<*, *>, view: View, position: Int) {
(adapter as BaseCheckRecycleViewAdapter).clickItem(position, false)
}
}
@@ -0,0 +1,172 @@
package com.yxjk.healthexpertclient.ui.mine
import android.os.Bundle
import android.view.View
import androidx.core.view.ViewCompat
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import com.btpj.lib_base.ext.loadCircle
import com.buddy.kredit.android.base.BaseActivity
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.listener.OnItemChildClickListener
import com.google.android.flexbox.FlexboxLayoutManager
import com.luck.picture.lib.basic.PictureSelectionModel
import com.luck.picture.lib.basic.PictureSelector
import com.luck.picture.lib.config.SelectMimeType
import com.luck.picture.lib.config.SelectModeConfig
import com.luck.picture.lib.entity.LocalMedia
import com.luck.picture.lib.interfaces.OnResultCallbackListener
import com.luck.picture.lib.utils.SandboxTransformUtils
import com.yxjk.healthexpertclient.R
import com.yxjk.healthexpertclient.bean.mine.DoctorBean
import com.yxjk.healthexpertclient.databinding.ActivityPersonInfoBinding
import com.yxjk.healthexpertclient.event.AddGoodAtDiseaseEvent
import com.yxjk.healthexpertclient.ext.startGoodAtDiseaseActivity
import com.yxjk.healthexpertclient.ui.mine.adapter.AddDiseaseAdapter
import com.yxjk.healthexpertclient.ui.mine.viewmodel.PersonInfoViewModel
import com.yxjk.healthexpertclient.utils.AndroidBug5497Workaround
import com.yxjk.healthexpertclient.utils.pictureSelector.GlideEngine
import com.yxjk.healthexpertclient.utils.pictureSelector.ImageFileCompressEngine
import com.yxjk.healthexpertclient.utils.pictureSelector.ImageFileCropEngine
import com.yxjk.healthexpertclient.view.AddDiseaseDialog
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import java.io.File
/**
* @author nanfeifei
* @time 2023/5/22 19:34
* @description 个人信息
*/
class PersonInfoActivity: BaseActivity<PersonInfoViewModel, ActivityPersonInfoBinding>(R.layout.activity_person_info),
OnItemChildClickListener {
val mAdapter by lazy { AddDiseaseAdapter() }
val addDiseaseDialog by lazy { AddDiseaseDialog(this@PersonInfoActivity) }
override fun initView(savedInstanceState: Bundle?) {
AndroidBug5497Workaround.assistActivity(this)
mBinding.apply {
val flexboxLayoutManager = FlexboxLayoutManager(this@PersonInfoActivity)
rvDisease.layoutManager = flexboxLayoutManager
ViewCompat.setNestedScrollingEnabled(rvDisease, false)
}
}
override fun createObserve() {
super.createObserve()
mBinding.apply {
lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.CREATED){
mViewModel.doctorBean.collectLatest {
setDoctorInfo(it)
}
}
}
lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.CREATED) {
mViewModel.diseaseList.collectLatest { list ->
mAdapter.setNewInstance(list)
if (rvDisease.adapter == null) {
mAdapter.setOnItemChildClickListener(this@PersonInfoActivity)
rvDisease.adapter = mAdapter
}
}
}
}
}
}
private fun setDoctorInfo(doctorBean: DoctorBean){
mBinding.apply {
}
}
override fun bindEvent() {
addClickViews(mBinding.rlHeadImage, mBinding.btnAdd, mBinding.btnSave)
addDiseaseDialog.setOnSubmitClickListener(object : AddDiseaseDialog.OnSubmitClickListener{
override fun onSubmitClick(viewDialog: AddDiseaseDialog, inputText: String) {
// mAdapter.addData(inputText)
}
override fun onCloseClick(viewDialog: AddDiseaseDialog) {
}
})
}
override fun onClick(v: View?) {
super.onClick(v)
when(v?.id){
R.id.rl_head_image -> {
initPictureSelectorModel()
.forResult(object : OnResultCallbackListener<LocalMedia?> {
override fun onResult(result: ArrayList<LocalMedia?>?) {
result?.get(0)
?.let {
// showLoading()
var path = getImagePath(it)
mBinding.ivHeadImg.loadCircle(
File(path))
mViewModel.uploadFile(path)
}
}
override fun onCancel() {}
})
}
R.id.btn_add -> {
startGoodAtDiseaseActivity(this, mViewModel.doctorBean.value.departmentId, mViewModel.diseaseList.value)
// addDiseaseDialog.show()
}
R.id.btn_save -> {
mViewModel.savePersonInfo()
}
}
}
override fun onItemChildClick(adapter: BaseQuickAdapter<*, *>, view: View, position: Int) {
when(view.id){
R.id.btn_delete -> {
mAdapter.removeAt(position)
}
}
}
fun getImagePath(localMedia: LocalMedia): String {
if(!localMedia.cutPath.isNullOrEmpty()){
return localMedia.cutPath
}
if (!localMedia.compressPath.isNullOrEmpty()) {
return localMedia.compressPath
}
if (!localMedia.sandboxPath.isNullOrEmpty()) {
return localMedia.sandboxPath
}
return localMedia.path
}
private fun initPictureSelectorModel(): PictureSelectionModel {
return PictureSelector.create(this)
.openGallery(SelectMimeType.TYPE_IMAGE)
.setSelectionMode(SelectModeConfig.SINGLE)
.setCropEngine(ImageFileCropEngine())
.setCompressEngine(ImageFileCompressEngine())
.setImageEngine(GlideEngine.createGlideEngine())
.setSandboxFileEngine { context, srcPath, mineType, call ->
if (call != null) {
var sandboxPath =
SandboxTransformUtils.copyPathToSandbox(context, srcPath, mineType)
call.onCallback(srcPath, sandboxPath)
}
}
}
@Subscribe(threadMode = ThreadMode.MAIN)
fun onEvent(event: AddGoodAtDiseaseEvent) {
if(event == null){
return
}
lifecycleScope.launch {
mViewModel.diseaseList.emit(event.list)
}
}
}
@@ -0,0 +1,72 @@
package com.yxjk.healthexpertclient.ui.mine
import android.os.Bundle
import android.view.View
import androidx.core.view.ViewCompat
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import androidx.recyclerview.widget.LinearLayoutManager
import com.buddy.kredit.android.base.BaseActivity
import com.buddy.kredit.android.view.SpaceItemDecoration
import com.yxjk.healthexpertclient.R
import com.yxjk.healthexpertclient.databinding.ActivitySchedulingBinding
import com.yxjk.healthexpertclient.ext.startCustomSchedulingActivity
import com.yxjk.healthexpertclient.ui.mine.adapter.NewSchedulingAdapter
import com.yxjk.healthexpertclient.ui.mine.viewmodel.SchedulingViewModel
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
/**
* @author nanfeifei
* @time 2023/5/16 14:23
* @description 排班设置
*/
class SchedulingActivity: BaseActivity<SchedulingViewModel, ActivitySchedulingBinding>(R.layout.activity_scheduling) {
private val mAdapter: NewSchedulingAdapter = NewSchedulingAdapter()
override fun initView(savedInstanceState: Bundle?) {
mBinding.apply {
val linearLayoutManager = LinearLayoutManager(this@SchedulingActivity)
rvList.layoutManager = linearLayoutManager
rvList.addItemDecoration(SpaceItemDecoration(this@SchedulingActivity, 0, 8f))
ViewCompat.setNestedScrollingEnabled(rvList, false)
}
}
override fun createObserve() {
super.createObserve()
mBinding.apply {
lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.CREATED) {
mViewModel.schedulingList.collectLatest { list ->
mAdapter.setList(list)
if (rvList.adapter == null) {
rvList.adapter = mAdapter
}
}
}
}
}
}
override fun initData() {
super.initData()
}
override fun bindEvent() {
mBinding.apply {
addClickViews(btnSubmit, btnCustomScheduling)
}
}
override fun onClick(v: View?) {
super.onClick(v)
when(v?.id){
R.id.btn_submit -> {
mViewModel.createDoctorScheduling()
}
R.id.btn_custom_scheduling -> {
startCustomSchedulingActivity(this)
finish()
}
}
}
}
@@ -0,0 +1,125 @@
package com.yxjk.healthexpertclient.ui.mine
import android.app.ProgressDialog
import android.os.Bundle
import android.view.View
import android.view.Window
import com.btpj.lib_base.data.local.DataStoreManager
import com.btpj.lib_base.data.local.IpManager
import com.btpj.lib_base.ext.jsonToBean
import com.btpj.lib_base.utils.AppUtil
import com.buddy.kredit.android.base.BaseActivity
import com.yxjk.healthexpertclient.BuildConfig
import com.yxjk.healthexpertclient.R
import com.yxjk.healthexpertclient.bean.AppUpdateBean
import com.yxjk.healthexpertclient.databinding.ActivitySettingBinding
import com.yxjk.healthexpertclient.ext.startWebActivity
import com.yxjk.healthexpertclient.ui.mine.viewmodel.SettingViewModel
import com.yxjk.healthexpertclient.view.LoadingProgressDialog
import org.lzh.framework.updatepluginlib.UpdateBuilder
import org.lzh.framework.updatepluginlib.base.UpdateParser
import org.lzh.framework.updatepluginlib.model.Update
/**
* @author nanfeifei
* @time 2023/5/23 16:06
* @description 设置
*/
class SettingActivity: BaseActivity<SettingViewModel, ActivitySettingBinding>(R.layout.activity_setting) {
var dialog: LoadingProgressDialog? = null
override fun initView(savedInstanceState: Bundle?) {
}
override fun initData() {
super.initData()
createDialog()
var str=AppUtil.getAppVersionName(this)+"(${AppUtil.getAppVersionCode(this)})"
mBinding.tvVersion.text = getString(R.string.app_version, str)
// mBinding.tvAbout.text = getString(R.string.setting_about, getString(R.string.app_name))
initUpdateApp(false)
}
override fun bindEvent() {
addClickViews(mBinding.tvUserProtocol, mBinding.tvPrivacyPolicy, mBinding.tvAbout,mBinding.rlVersionUpdate)
}
override fun onClick(v: View?) {
super.onClick(v)
when(v?.id){
R.id.tv_user_protocol -> {
DataStoreManager.getUserAgreementUrl()?.let {
if (it.isNotEmpty()) {
startWebActivity(this@SettingActivity,it)
}
}
}
R.id.tv_privacy_policy -> {
DataStoreManager.getPrivacyAgreementUrl()?.let {
if (it.isNotEmpty()) {
startWebActivity(this@SettingActivity,it)
}
}
}
R.id.tv_about -> {
}
R.id.rl_version_update -> {
initUpdateApp(true)
}
}
}
private fun initUpdateApp(isClick:Boolean){
dialog?.show()
UpdateBuilder.create().setUpdateParser(object : UpdateParser() {
override fun parse(response: String?): Update {
val resultBean: AppUpdateBean? = response.jsonToBean(AppUpdateBean::class.java)
val update = Update()
if(resultBean == null){
return update
}
runOnUiThread {
dialog?.dismiss()
if (resultBean.versionNo> BuildConfig.VERSION_CODE){
mBinding?.tvVersionUpdate?.text="有新版本待更新"
}else{
mBinding?.tvVersionUpdate?.text="已是最新版本"
}
}
if (!isClick) {
return update
}
// 此apk包的下载地址
update.updateUrl = IpManager.getImageBaseUrl()+resultBean.appUrl
// 此apk包的版本号(因接口只有在有更新时才会返回数据,而且没有返回云端APP版本号,故将当前APP版本号+1,传给更新框架用作判断有新版本)
update.versionCode = resultBean.versionNo ?: 0
// 此apk包的版本名称
update.versionName = resultBean.versionName
// 此apk包的更新内容
update.updateContent = resultBean.updateContent
// 此apk包是否为强制更新
if (resultBean != null) {
update.isForced = 1 == resultBean.forced
}else{
update.isForced = false
}
// 是否显示忽略此次版本更新按钮
update.isIgnore = 1 == resultBean.ignoreFlag
return update
}
}).check()
}
private fun createDialog() {
dialog = LoadingProgressDialog(
this@SettingActivity,
ProgressDialog.STYLE_SPINNER, "数据加载中"
)
dialog!!.requestWindowFeature(Window.FEATURE_NO_TITLE)
dialog!!.setCanceledOnTouchOutside(false)
dialog!!.setCancelable(false)
dialog!!.setMessage("请稍后...")
}
}
@@ -0,0 +1,141 @@
package com.yxjk.healthexpertclient.ui.mine
import android.os.Bundle
import android.view.View
import androidx.databinding.DataBindingUtil
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import com.btpj.lib_base.ext.getEmptyView
import com.btpj.lib_base.ext.initColors
import com.buddy.kredit.android.base.BaseActivity
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.listener.OnItemChildClickListener
import com.yxjk.healthexpertclient.R
import com.yxjk.healthexpertclient.bean.mine.SuspensionServiceBean
import com.yxjk.healthexpertclient.databinding.ActivitySuspensionServiceBinding
import com.yxjk.healthexpertclient.databinding.ViewFooterSuspensionServiceBinding
import com.yxjk.healthexpertclient.event.SuspensionServiceEvent
import com.yxjk.healthexpertclient.ext.startAddSuspensionAnnouncementActivity
import com.yxjk.healthexpertclient.ui.mine.adapter.SuspensionServiceAdapter
import com.yxjk.healthexpertclient.ui.mine.viewmodel.SuspensionServiceViewModel
import com.timehop.stickyheadersrecyclerview.StickyRecyclerHeadersDecoration
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
/**
* @author nanfeifei
* @time 2023/5/17 14:26
* @description 暂停服务
*/
class SuspensionServiceActivity :
BaseActivity<SuspensionServiceViewModel, ActivitySuspensionServiceBinding>(R.layout.activity_suspension_service),
OnItemChildClickListener, SwipeRefreshLayout.OnRefreshListener {
private val mAdapter: SuspensionServiceAdapter = SuspensionServiceAdapter()
override fun initView(savedInstanceState: Bundle?) {
mBinding.apply {
swipeRefresh.initColors()
swipeRefresh.setOnRefreshListener(this@SuspensionServiceActivity)
val linearLayoutManager = LinearLayoutManager(this@SuspensionServiceActivity
)
rvList.layoutManager = linearLayoutManager
val headersDecor = StickyRecyclerHeadersDecoration(mAdapter)
rvList.addItemDecoration(headersDecor)
}
}
override fun createObserve() {
super.createObserve()
mBinding.apply {
lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.CREATED) {
mViewModel.suspensionServiceList.collectLatest { list ->
if(list == null){
return@collectLatest
}
if (mViewModel.isRefreshing.value) {
mAdapter.setNewInstance(list)
} else {
mAdapter.addData(list)
}
mAdapter.loadMoreModule.loadMoreComplete()
if (rvList.adapter == null) {
mAdapter.setEmptyView(rvList.getEmptyView())
mAdapter.setOnItemChildClickListener(this@SuspensionServiceActivity)
// mAdapter.addFooterView(getFooterView())
initLoadMore()
rvList.adapter = mAdapter
}
}
}
}
lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.CREATED) {
mViewModel.isRefreshing.collectLatest {
swipeRefresh.isRefreshing = it
}
}
}
lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.CREATED) {
mViewModel.isLoadMoreEnd.collectLatest {
mAdapter.loadMoreModule.loadMoreEnd(it)
}
}
}
}
}
override fun bindEvent() {
addClickViews(mBinding.layOperate.btnAdd)
}
override fun onRefresh() {
mViewModel.getSuspensionServiceList(true)
}
private fun initLoadMore() {
mAdapter.loadMoreModule.setOnLoadMoreListener { mViewModel.getSuspensionServiceList(false) }
mAdapter.loadMoreModule.isAutoLoadMore = true
//当自动加载开启,同时数据不满一屏时,是否继续执行自动加载更多(默认为true)
mAdapter.loadMoreModule.isEnableLoadMoreIfNotFullPage = false
}
private fun getFooterView(): View{
val footerView: ViewFooterSuspensionServiceBinding =
DataBindingUtil.inflate(
layoutInflater,
R.layout.view_footer_suspension_service,
mBinding.rvList,
false
)
addClickViews(footerView.btnAdd)
return footerView.root
}
override fun onClick(v: View?) {
super.onClick(v)
when(v?.id){
R.id.btn_add -> {
startAddSuspensionAnnouncementActivity(this@SuspensionServiceActivity)
}
}
}
override fun onItemChildClick(adapter: BaseQuickAdapter<*, *>, view: View, position: Int) {
when(view?.id){
R.id.btn_status -> {
var suspensionServiceBean = adapter.getItem(position) as SuspensionServiceBean
if(suspensionServiceBean.serviceStatus == 0)
suspensionServiceBean.id?.let { mViewModel.editSuspensionAnnouncement(it) }
}
}
}
@Subscribe(threadMode = ThreadMode.MAIN)
fun onEvent(event: SuspensionServiceEvent) {
onRefresh()
}
}
@@ -0,0 +1,31 @@
package com.yxjk.healthexpertclient.ui.mine
import android.os.Bundle
import androidx.lifecycle.lifecycleScope
import com.buddy.kredit.android.base.BaseActivity
import com.yxjk.healthexpertclient.R
import com.yxjk.healthexpertclient.databinding.ActivityWithDrawBinding
import com.yxjk.healthexpertclient.ui.mine.viewmodel.WithDrawViewModel
import kotlinx.coroutines.launch
/**
* @author nanfeifei
* @time 2023/5/22 16:17
* @description 提现详情
*/
class WithDrawActivity: BaseActivity<WithDrawViewModel, ActivityWithDrawBinding>(R.layout.activity_with_draw) {
override fun initView(savedInstanceState: Bundle?) {
val recordId = intent.extras?.getInt("recordId") ?: 0
lifecycleScope.launch {
mViewModel.recordId.emit(recordId)
}
}
override fun initData() {
super.initData()
mViewModel.getWithDrawDetail()
}
override fun bindEvent() {
}
}
@@ -0,0 +1,34 @@
package com.yxjk.healthexpertclient.ui.mine.adapter
import com.btpj.lib_base.base.adapter.BaseDataBindingAdapter
import com.chad.library.adapter.base.viewholder.BaseDataBindingHolder
import com.yxjk.healthexpertclient.R
import com.yxjk.healthexpertclient.bean.mine.DiseaseBean
import com.yxjk.healthexpertclient.databinding.ItemRecycleAddDiseaseBinding
/**
* @author nanfeifei
* @time 2023/5/23 10:37
* @description
*/
class AddDiseaseAdapter: BaseDataBindingAdapter<DiseaseBean, ItemRecycleAddDiseaseBinding>(R.layout.item_recycle_add_disease) {
override fun bindViewClickListener(
viewHolder: BaseDataBindingHolder<ItemRecycleAddDiseaseBinding>,
viewType: Int
) {
addChildClickViewIds(R.id.btn_delete)
super.bindViewClickListener(viewHolder, viewType)
}
override fun convert(
holder: BaseDataBindingHolder<ItemRecycleAddDiseaseBinding>,
item: DiseaseBean
) {
val mBinding = holder.dataBinding
mBinding?.apply {
tvDisease.text = item.sicksName
}
}
}
@@ -0,0 +1,21 @@
package com.yxjk.healthexpertclient.ui.mine.adapter
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.module.LoadMoreModule
import com.chad.library.adapter.base.viewholder.BaseViewHolder
import com.yxjk.healthexpertclient.R
import com.yxjk.healthexpertclient.bean.mine.BillRecordBean
import com.yxjk.healthexpertclient.utils.CommonUtils
class BillRecordAdapter() :
BaseQuickAdapter<BillRecordBean, BaseViewHolder>(
R.layout.item_recycle_bill_record
), LoadMoreModule {
override fun convert(holder: BaseViewHolder, item: BillRecordBean) {
holder.setText(R.id.tv_title, item.operateTypeName)
holder.setText(R.id.tv_change_money, CommonUtils.getIncomeText(item.waterType, item.income))
holder.setTextColorRes(R.id.tv_change_money, CommonUtils.getIncomeTextColor(item.waterType))
holder.setText(R.id.tv_time, item.createTime)
holder.setText(R.id.tv_balance, context.getString(R.string.bill_record_balance, item.accountMoney))
}
}

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