Commit 6317251b by 万齐军

Merge branch 'feat/qj/arch3' into 'feat/lp/lp_nim2'

# Conflicts:
#   app/src/main/java/com/ydl/component/service/web/WVClickAbstractListener.java
#   settings.gradle
parents 21b13392 b10cd886
/build
\ No newline at end of file
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
apply from: "../../publish.gradle"
android {
compileSdkVersion rootProject.ext.android["compileSdkVersion"]
buildToolsVersion rootProject.ext.android["buildToolsVersion"]
defaultConfig {
minSdkVersion rootProject.ext.android["minSdkVersion"]
targetSdkVersion rootProject.ext.android["targetSdkVersion"]
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
}
dependencies {
implementation "com.alibaba:arouter-api:$arouter_api"
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
}
\ No newline at end of file
# 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
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.ydl.audioim.api">
</manifest>
\ No newline at end of file
package com.ydl.audioim.api
import android.app.Activity
import android.content.Context
import com.alibaba.android.arouter.facade.template.IProvider
/**
* Created by Ykai on 2022/7/26.
*/
interface IAudioImService : IProvider{
/**
* YDLavManager初始化方法
*/
fun yDLAvManagerInit(context: Context, appId: String)
/**
* 获取rtm是否在线
*/
fun getIsOnlineRtm(): Boolean
/**
* rtm登录返回并登录状态
*/
fun loginRtm(userId:String?,event: (isSuccess: Boolean, msg: String?) -> Unit)
/**
* rtm登录
*/
fun loginRtm(userId:String?)
/**
* 拨打语音电话转axb弹窗
*/
fun openAxbDialog(activity: Activity?, type:Int, phoneNumber: String?)
/**
* 事件上报
*/
fun callEventSave(status: String, res: String, session: String?, line: String)
}
\ No newline at end of file
......@@ -18,7 +18,7 @@ public class ExpertInfoBean {
public String listenerIsOpen;
public String listenOrderStatus;
public String channelId;
public ExpertInfoBean.ListenRemainingTime remainingTime;
public ListenRemainingTime remainingTime;
public String totalDuration;
public String commentUrl;
......
......@@ -2,19 +2,14 @@ package com.ydl.component
import android.Manifest
import android.annotation.SuppressLint
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.ServiceConnection
import android.graphics.PixelFormat
import android.media.MediaPlayer
import android.net.Uri
import android.os.Build
import android.os.IBinder
import android.provider.Settings
import android.text.TextUtils
import android.util.DisplayMetrics
import android.util.Log
import android.view.*
import android.widget.ImageView
import android.widget.TextView
......@@ -33,7 +28,6 @@ import com.ydl.component.mvp.DemoPresenter
import com.ydl.component.route.PlatformTempCommonRouteImpl
import com.ydl.component.rtc.MDTLoginActivity
import com.ydl.confide.home.ConfideHomeActivity
import com.ydl.media.audio.PlayService
import com.ydl.ydlcommon.data.http.ThrowableConsumer
import com.ydl.ydlcommon.modular.ModularServiceManager
import com.ydl.ydlcommon.mvp.lce.BaseLceActivity
......@@ -55,8 +49,6 @@ import com.yidianling.tests.home.NewTestHomeActivity
import com.yidianling.user.api.service.IUserService
import com.yidianling.user.ui.collect.CollectSexAndBirthActivity
import com.yidianling.user.ui.login.OneKeyLoginHelp
import com.yidianling.user.widget.SecretDialog
import com.yidianling.user.widget.SecretDialog.OnSecretDialogListener
import de.greenrobot.event.EventBus
import io.feeeei.circleseekbar.CircleSeekBar
import io.reactivex.Observable
......@@ -77,11 +69,6 @@ import kotlin.math.roundToInt
@Route(path = "/main/main")
class MainActivity : BaseLceActivity<DemoContract.View, DemoContract.Presenter>(),
DemoContract.View {
// private var secretDescriptionDialog: SecretDescriptionDialog? = null
private var serviceConnection: ServiceConnection? = null
private var secretDialog: SecretDialog? = null
protected var playService: PlayService? = null
private var mFloatDisposable:Disposable?=null
......@@ -295,9 +282,6 @@ class MainActivity : BaseLceActivity<DemoContract.View, DemoContract.Presenter>(
private fun bindService() {
val intent = Intent()
intent.setClass(this, PlayService::class.java!!)
serviceConnection = PlayServiceConnection()
bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE)
}
private fun initMeditationObserver(){
......@@ -317,11 +301,6 @@ class MainActivity : BaseLceActivity<DemoContract.View, DemoContract.Presenter>(
override fun onResume() {
super.onResume()
MobclickAgent.onResume(this)
// ModularServiceManager.provide(IConsultantService::class.java)
// .
// (this)
val trtcCalling = TRTCCalling.sharedInstance(this)
if (!TextUtils.isEmpty(trtcCalling.mRoomId) && !TextUtils.isEmpty(trtcCalling.mUserId)) {
val intent = Intent(mContext, YDLInvitionActivity::class.java)
......@@ -333,11 +312,7 @@ class MainActivity : BaseLceActivity<DemoContract.View, DemoContract.Presenter>(
}
}
override fun onPause() {
super.onPause()
// ModularServiceManager.provide(IConsultantService::class.java).hideConsultAssistantDialog()
}
fun onEvent(event: MeditationFloatEvent) {
......@@ -345,10 +320,6 @@ class MainActivity : BaseLceActivity<DemoContract.View, DemoContract.Presenter>(
@SuppressLint("MissingSuperCall")
override fun onDestroy() {
if (serviceConnection != null) {
unbindService(serviceConnection)
}
MediaPlayerManager.getInstance(this)?.stop()
hideFloatWindow()
......@@ -362,33 +333,6 @@ class MainActivity : BaseLceActivity<DemoContract.View, DemoContract.Presenter>(
super.onDestroy()
}
private inner class PlayServiceConnection : ServiceConnection {
override fun onServiceConnected(name: ComponentName, service: IBinder) {
playService = (service as PlayService.PlayBinder).service
}
override fun onServiceDisconnected(name: ComponentName) {
Log.e(javaClass.simpleName, "service disconnected")
}
}
private fun showEnsureDialog() {
secretDialog = SecretDialog(this, object : OnSecretDialogListener {
override fun onCancel() {
secretDialog!!.dismiss()
// finishAll()
// Process.killProcess(Process.myPid())
// System.exit(0)
}
override fun onSure() {
secretDialog!!.dismiss()
}
})
secretDialog!!.setCanceledOnTouchOutside(false)
secretDialog!!.show()
}
private lateinit var mWindowManager: WindowManager
private var floatRootView: View? = null
......@@ -454,7 +398,7 @@ class MainActivity : BaseLceActivity<DemoContract.View, DemoContract.Presenter>(
}
fun onEventMainThread(event: Any) {
if (event is com.ydl.ydlcommon.event.MeditationFloatEvent){
if (event is com.ydl.ydlcommon.event.MeditationFloatStopEvent){
mToShowWindow = event.show
if (event.show!=null && !event.show) {
if (event.stop == true){
......
......@@ -20,7 +20,6 @@ import com.umeng.socialize.UMShareAPI
import com.ydl.component.BuildConfig
import com.ydl.component.MainActivity
import com.ydl.component.R
import com.ydl.media.audio.PlayService
import com.ydl.ydlcommon.actions.crash.Cockroach
import com.ydl.ydlcommon.actions.crash.ExceptionHandler
import com.ydl.ydlcommon.base.config.HttpConfig
......@@ -78,15 +77,6 @@ class DemoAppLifecycles : IAppLifecycles {
// YDLCommonPlugin plugin = new YDLCommonPlugin();
// flutterEngine.getLocalizationChannel().channel.setMethodCallHandler(plugin);
val intent = Intent(application, PlayService::class.java)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
application.startForegroundService(intent)
}else{
application.startService(intent)
}
// application.registerActivityLifecycleCallbacks(new CoursePlayLifecycle());
}
}
......
......@@ -20,8 +20,8 @@ import java.util.List;
*/
public final class DemoGlobalConfig implements IConfigModule {
String APP_DOMAIN = "https://api.github.com/";
// public static String appEnv = YDLConstants.ENV_TEST;
public static String appEnv = YDLConstants.ENV_PROD;
public static String appEnv = YDLConstants.ENV_TEST;
// public static String appEnv = YDLConstants.ENV_PROD;
// public static String appEnv = YDLConstants.ENV_NEW_TEST;//配置未上传到maven库
@Override
......
package com.ydl.component.service.web;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.graphics.Rect;
......@@ -567,6 +568,15 @@ public class WVClickAbstractListener implements WebViewClientClickListener {
}
}
/**
* 打开时间选择器
*/
@SuppressLint("CheckResult")
@Override
public void openTimePicker(String jsCallBackName, String day, String doctorId, String orderId) {
}
@Override
public void showCommentArticleDialog(H5JsBean.H5JsCmd.Params params) {
......
......@@ -14,6 +14,7 @@ import com.ydl.ydlcommon.base.BaseActivityMgr
import com.ydl.ydlcommon.base.config.HttpConfig
import com.ydl.ydlcommon.modular.ModularServiceManager
import com.ydl.ydlcommon.modular.findRouteService
import com.ydl.ydlcommon.utils.Utils
import com.ydl.ydlcommon.utils.log.LogHelper
import com.yidianling.common.tools.LogUtil
import com.yidianling.user.UserHelper
......@@ -459,6 +460,13 @@ class WebJavascriptHandler(private val webView: WebView?, private val wvEnventPr
"switch_push_status" -> {
wvEnventPro?.switchPushStatus(jsData.cmd?.params)
}
// 打开时间选择器
"requestSelectTime"->{
if (Utils.isFastClick()){
return
}
wvEnventPro?.openTimePicker(jsData.cmd?.params?.callBack,jsData.cmd?.params?.day,jsData.cmd?.params?.doctorId.toString(),jsData.cmd?.params?.orderId)
}
"open_article_comment_dialog" -> {
wvEnventPro?.showCommentArticleDialog(jsData.cmd?.params)
......
......@@ -211,4 +211,8 @@ public interface WebViewClientClickListener {
void resourceToPreview(H5JsBean.H5JsCmd.Params params);
void showDocBooking(H5JsBean.H5JsCmd.Params params);
// 打开时间选择器
void openTimePicker(String jsCallBackName,String day,String doctorId,String orderId);
}
......@@ -14,7 +14,7 @@ buildscript {
ydlrouter_version = '1.2.3'
constrait_support_version = '1.0.2'
componentVersion = "0.3.0.5-SNAPSHOT"
componentVersion = "0.3.0.11"
}
repositories {
mavenCentral()
......
......@@ -98,12 +98,6 @@ ext {
"xxpermission" : "com.hjq:xxpermissions:10.2",
"rxerrorhandler2" : "me.jessyan:rxerrorhandler:2.1.1",
//tools
// "dagger2" : "com.google.dagger:dagger:${version["dagger2SdkVersion"]}",
// "dagger2-android" : "com.google.dagger:dagger-android:${version["dagger2SdkVersion"]}",
// "dagger2-android-support" : "com.google.dagger:dagger-android-support:${version["dagger2SdkVersion"]}",
// "dagger2-compiler" : "com.google.dagger:dagger-compiler:${version["dagger2SdkVersion"]}",
// "dagger2-android-processor" : "com.google.dagger:dagger-android-processor:${version["dagger2SdkVersion"]}",
"androideventbus" : "org.simple:androideventbus:1.0.5.1",
"otto" : "com.squareup:otto:1.3.8",
"gson" : "com.google.code.gson:gson:2.8.5",
......
......@@ -75,4 +75,5 @@ dependencies {
api project(':ydl-webview')
implementation project(":api:user")
implementation project(":api:im")
implementation project(":api:audioim")
}
......@@ -32,6 +32,7 @@ import com.ydl.audioim.http.command.ConnectCommand
import com.ydl.audioim.http.command.ConnectExceptionCommand
import com.ydl.audioim.http.command.NoticePushCommand
import com.ydl.audioim.http.command.PayLoad
import com.ydl.audioim.listener.IntentConstants
import com.ydl.audioim.player.AudioPlayer
import com.ydl.audioim.presenter.AudioHomePresenterImpl
import com.ydl.audioim.router.AudioImIn
......@@ -48,6 +49,7 @@ import com.ydl.ydl_av.voice.listener.IYDLVoiceEventHandler
import com.ydl.ydl_av.voice.manager.YDLVoiceManager
import com.ydl.ydl_image.config.SimpleImageOpConfiger
import com.ydl.ydl_image.manager.YDLImageCacheManager
import com.ydl.ydlcommon.app.Apm
import com.ydl.ydlcommon.base.BaseMvpActivity
import com.ydl.ydlcommon.modular.ModularServiceManager
import com.ydl.ydlcommon.modular.findRouteService
......@@ -318,6 +320,7 @@ class AudioHomeActivity :
if (err == 0 || err == 18) {
return
}
Apm.reportEvent("agora_android", "occur_error", "$err")
channelId?.let { YDLavManager.instances.callEndStatusUpdate(it, 4, "频道的错误回调信息$err") }
}
......@@ -369,8 +372,8 @@ class AudioHomeActivity :
override fun onRtcStats(stats: IRtcEngineEventHandler.RtcStats?) {
super.onRtcStats(stats)
writeAgoraLog("声网onRtcStats:users:${stats?.users}")
AliYunRichLogsHelper.getInstance()
.sendRichLog(AliYunLogConfig.AGORA, "声网onRtcStats:users:${stats?.users} channelId:${channelId}")
// AliYunRichLogsHelper.getInstance()
// .sendRichLog(AliYunLogConfig.AGORA, "声网onRtcStats:users:${stats?.users} channelId:${channelId}")
// 不需要移动端做离开房间逻辑,服务端会判断进行踢人逻辑
//因为用户端直接加入了频道,防止该回调执行时,专家还未加入频道,因此在连接成功之后,才进行频道人数判断
// if (isConnectSuccess && null != stats?.users && stats.users == 1) {
......@@ -388,6 +391,7 @@ class AudioHomeActivity :
override fun onConnectionStateChanged(state: Int, reason: Int) {
super.onConnectionStateChanged(state, reason)
// 3 网络连接被服务器中止 该情况现在是因为后端踢人逻辑
Apm.reportEvent("agora_android", "rtc_connection_failure", "$state,$reason")
if (reason == 3) {
callEventSave("50", "通话结束:网络连接被服务器中止 该情况现在是因为后端踢人逻辑,原因(${reason}")
writeAgoraLog("通话结束:网络连接被服务器中止 该情况现在是因为后端踢人逻辑,原因(${reason})")
......@@ -1063,6 +1067,7 @@ class AudioHomeActivity :
*/
voiceManage = YDLVoiceManager(this, BuildConfig.AGORA_APPID, mRtcEventHandler)
voiceManage?.init()
voiceManage?.getVoiceApi()?.setAudioProfile(Constants.AUDIO_PROFILE_DEFAULT,Constants.AUDIO_SCENARIO_CHATROOM_GAMING)
}
/**
......
......@@ -166,7 +166,7 @@ class YDLavManager {
LogUtil.e("[agora]呼叫${response?.calleeId}用户失败:${response?.response}")
AliYunRichLogsHelper.getInstance().sendRichLog(
AliYunLogConfig.AGORA,
"呼叫${response?.calleeId}用户失败:${response?.response}"
"呼叫${response?.calleeId}用户失败:${response?.response},${errorCode}"
)
val dimension = hashMapOf(
"call" to "call_fail",
......@@ -398,7 +398,7 @@ class YDLavManager {
@SuppressLint("CheckResult")
fun login(userId: String?, event: (isSuccess: Boolean, msg: String?) -> Unit) {
if (TextUtils.isEmpty(userId) || userId ?: "0" <= "0") {
if (TextUtils.isEmpty(userId) || (userId ?: "0") <= "0") {
//如果uid为空或小于等于0 ,则不进行登录,因为uid为0也会登录成功,会导致后面uid正确时无法登录
LogUtil.e("[agora]login-uid:$userId")
AliYunRichLogsHelper.getInstance()
......@@ -432,7 +432,7 @@ class YDLavManager {
override fun onFailure(msg: String?) {
if (msg != "LOGIN_ERR_ALREADY_LOGGED_IN") {
Apm.reportCustom("agora_login_error", msg ?: "", Exception(msg))
Apm.reportEvent("rtm_android", "connectionstate_error", msg ?: "")
}
LogUtil.e("[agora]实时消息登录失败:$msg")
writeAgoraLog(
......@@ -449,6 +449,7 @@ class YDLavManager {
}
})
} else {
Apm.reportEvent("rtm_android", "login_failure", "${it.code},${it.msg}")
LogUtil.e("声网token获取失败uid:" + userId + " error:" + it.msg)
LogHelper.getInstance()
.writeLogSync("声网token获取失败uid:" + userId + " error:" + it.msg)
......
package com.ydl.audioim.modular
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.net.Uri
import com.alibaba.android.arouter.facade.annotation.Route
import com.ydl.audioim.YDLavManager
import com.ydl.audioim.api.IAudioImService
import com.ydl.audioim.widget.AxbConfirmDialog
/**
* Created by Ykai on 2022/7/26.
*/
@Route(path = "/audioim/AudioImService")
class AudioImServiceImp : IAudioImService {
override fun yDLAvManagerInit(context: Context, appId: String) {
YDLavManager.instances.init(context, appId)
}
override fun getIsOnlineRtm(): Boolean {
return YDLavManager.isOnlineRtm
}
override fun loginRtm(userId: String?, event: (isSuccess: Boolean, msg: String?) -> Unit) {
YDLavManager.instances.login(userId, event)
}
override fun loginRtm(userId: String?) {
YDLavManager.instances.login(userId)
}
override fun openAxbDialog(activity: Activity?, type: Int, phoneNumber: String?) {
val dialog = AxbConfirmDialog(activity, type, object : AxbConfirmDialog.OnClickEnsureListener {
override fun onClickEnsure() {
phoneNumber?.let {
val phoneIntent = Intent(Intent.ACTION_DIAL, Uri.parse("tel:$phoneNumber"))
activity?.startActivity(phoneIntent)
}
}
override fun onClose() {
}
})
dialog.show()
}
override fun callEventSave(status: String, res: String, session: String?, line: String) {
YDLavManager.instances.callEventSave(status, res, session, line)
}
override fun init(context: Context?) {
}
}
\ No newline at end of file
# 声网module
\ No newline at end of file
......@@ -692,7 +692,9 @@ class ConsultantAudioHomeActivity :
* param mRtcEventHandler 事件回调(SDK 通过指定的事件通知应用程序 SDK 的运行事件,如: 加入或离开频道,新用户加入频道等)
*/
voiceManage = YDLVoiceManager(this, BuildConfig.AGORA_APPID, mRtcEventHandler)
voiceManage!!.init()
voiceManage?.init()
voiceManage?.getVoiceApi()?.setAudioProfile(Constants.AUDIO_PROFILE_DEFAULT,Constants.AUDIO_SCENARIO_CHATROOM_GAMING)
}
/**
......
......@@ -71,10 +71,10 @@ dependencies {
api rootProject.ext.dependencies["ydl-user-router"]
api project(':ydl-media')
api project(':ydl-platform')
api project(':m-audioim')
api project(":ydl-pay")
api project(':ydl-webview')
api project(':ydl-utils')
implementation project(":api:audioim")
implementation project(":api:im")
implementation project(":api:user")
implementation project(":api:consultant")
......
......@@ -24,7 +24,7 @@ import com.facebook.drawee.backends.pipeline.Fresco
import com.facebook.drawee.interfaces.DraweeController
import com.jcodecraeer.xrecyclerview.ProgressStyle
import com.jcodecraeer.xrecyclerview.XRecyclerView
import com.ydl.audioim.YDLavManager
import com.ydl.audioim.api.IAudioImService
import com.ydl.confide.R
import com.ydl.confide.api.ConfideRoute
import com.ydl.confide.home.adapter.ConfideHomeAdapter
......@@ -248,10 +248,8 @@ class ConfideHomeActivity :
}
if (!confidedId.isNullOrBlank() && !doctorId.isNullOrBlank()) {
if (!YDLavManager.isOnlineRtm) {
YDLavManager.instances.login(
PhoneCallIn.getUserService().getUserInfo()?.uid
) { _: Boolean, _ ->
if (!findRouteService(IAudioImService::class.java).getIsOnlineRtm()) {
findRouteService(IAudioImService::class.java).loginRtm(PhoneCallIn.getUserService().getUserInfo()?.uid) { _: Boolean, _ ->
showPayOrDetail(confidedId, doctorId)
}
} else {
......
......@@ -4,14 +4,12 @@ import android.app.Activity
import android.app.Application
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.text.TextUtils
import androidx.fragment.app.DialogFragment
import androidx.fragment.app.FragmentActivity
import com.alibaba.android.arouter.facade.annotation.Route
import com.google.gson.Gson
import com.ydl.audioim.YDLavManager
import com.ydl.audioim.widget.AxbConfirmDialog
import com.ydl.audioim.api.IAudioImService
import com.ydl.confide.api.IConfideService
import com.ydl.confide.home.ConfideBottomSheetDialogFragment
import com.ydl.confide.home.ConfideHomeActivity
......@@ -20,6 +18,7 @@ import com.ydl.confide.home.bean.ConfideConnectResponse
import com.ydl.webview.TellData
import com.ydl.ydlcommon.base.BaseApp
import com.ydl.ydlcommon.base.config.YDLConstants
import com.ydl.ydlcommon.modular.findRouteService
import com.ydl.ydlcommon.utils.YDLCacheUtils
/**
......@@ -73,7 +72,7 @@ class ConfdieServiceImpl : IConfideService {
override fun ydlAvManagerLogin(uid: String?) {
YDLavManager.instances.login(uid)
findRouteService(IAudioImService::class.java).loginRtm(uid)
}
override fun startCondifeHomePage(context: Context, isSplash: Boolean) {
......@@ -109,27 +108,15 @@ class ConfdieServiceImpl : IConfideService {
avManagerKey = "3387e9b251f3491e9221a9877e8f7830"
}
YDLavManager.instances.init(app, avManagerKey)
findRouteService(IAudioImService::class.java).yDLAvManagerInit(app, avManagerKey)
}
override fun isOnlineRtm(): Boolean {
return YDLavManager.isOnlineRtm
return findRouteService(IAudioImService::class.java).getIsOnlineRtm()
}
override fun showAxbConfirmDialog(activity: Activity?, type: Int, phoneNumber: String?) {
val dialog = AxbConfirmDialog(activity, type, object : AxbConfirmDialog.OnClickEnsureListener {
override fun onClickEnsure() {
phoneNumber?.let {
val phoneIntent = Intent(Intent.ACTION_DIAL, Uri.parse("tel:" + phoneNumber!!))
activity?.startActivity(phoneIntent)
}
}
override fun onClose() {
}
})
dialog.show()
findRouteService(IAudioImService::class.java).openAxbDialog(activity, type, phoneNumber)
}
override fun closePlayer() {
......
......@@ -3,15 +3,12 @@ package com.ydl.confide.home.modular.service
import android.annotation.SuppressLint
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.text.TextUtils
import androidx.fragment.app.FragmentActivity
import com.alibaba.android.arouter.launcher.ARouter
import com.ydl.audioim.IntentConstants
import com.ydl.audioim.YDLavManager
import com.ydl.audioim.api.IAudioImService
import com.ydl.audioim.bean.ExpertInfoBean
import com.ydl.audioim.widget.AxbConfirmDialog
import com.ydl.audioim.listener.IntentConstants
import com.ydl.confide.home.ConfidePermissionDialog
import com.ydl.confide.home.bean.ConfideConnectResponse
import com.ydl.confide.home.bean.ConnectParamJava
......@@ -109,7 +106,7 @@ class ConfideWebServiceImpl {
data: ConfideConnectResponse?
) {
val expertInfo = data?.dialDetail?.agoraExpertInfo ?: return
if (!YDLavManager.isOnlineRtm) { // 判断如果账号在其它设备登录rtm是否在线
if (!findRouteService(IAudioImService::class.java).getIsOnlineRtm()) { // 判断如果账号在其它设备登录rtm是否在线
ToastUtil.toastShort("网络通话错误代码001")
return
}
......@@ -128,21 +125,9 @@ class ConfideWebServiceImpl {
* axb 通话
* */
fun axb(activity: Activity, phone: String?) {
if (phone.isNullOrEmpty()) return
val dialog = AxbConfirmDialog(
activity,
1,
object : AxbConfirmDialog.OnClickEnsureListener {
override fun onClickEnsure() {
val phoneIntent = Intent(Intent.ACTION_DIAL, Uri.parse("tel:${phone}"))
activity.startActivity(phoneIntent)
}
override fun onClose() {
}
})
dialog.show()
if (phone.isNullOrEmpty())
return
findRouteService(IAudioImService::class.java).openAxbDialog(activity,1,phone)
}
//java版axb和声网接口
......@@ -154,8 +139,8 @@ class ConfideWebServiceImpl {
tellData: TellData?,
callType: String?
) {
if (!YDLavManager.isOnlineRtm) {
YDLavManager.instances.login(PhoneCallIn.getUserService().getUserInfo()?.uid) { isSuccess: Boolean, _ ->
if (!findRouteService(IAudioImService::class.java).getIsOnlineRtm()) {
findRouteService(IAudioImService::class.java).loginRtm(PhoneCallIn.getUserService().getUserInfo()?.uid) { isSuccess: Boolean, _ ->
if (isSuccess) {
toDial(id, type, callType, activity, tellData)
} else {
......@@ -340,7 +325,7 @@ class ConfideWebServiceImpl {
expertInfo.remainingTime =
ExpertInfoBean.ListenRemainingTime(expertInfo.totalDuration);
}
YDLavManager.instances.callEventSave("10", "用户点击拨打", expertInfo.channelId, "7")
findRouteService(IAudioImService::class.java).callEventSave("10", "用户点击拨打", expertInfo.channelId, "7")
Loading.close()
ARouter.getInstance().build("/av/AudioHomeActivity")
.withString(IntentConstants.INTENT_EXPERT_HEAD_URL, expertInfo.expertHeadUrl)
......
......@@ -16,7 +16,7 @@ import com.alibaba.android.arouter.launcher.ARouter
import com.dou361.ijkplayer.widget.IjkVideoView
import com.facebook.drawee.backends.pipeline.Fresco
import com.facebook.drawee.interfaces.DraweeController
import com.ydl.audioim.YDLavManager
import com.ydl.audioim.api.IAudioImService
import com.ydl.confide.R
import com.ydl.confide.api.ConfideRoute
import com.ydl.confide.databinding.ItemExpertIntroBinding
......@@ -36,7 +36,6 @@ import io.reactivex.Observable
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers
import kotlinx.android.synthetic.main.confide_home_activity.*
import tv.danmaku.ijk.media.player.IjkMediaPlayer
import java.io.UnsupportedEncodingException
import java.net.URLDecoder
......@@ -123,8 +122,8 @@ internal class ItemIntroHolder(binding: ItemExpertIntroBinding) :
}
else -> {
if (!item.confideId.isNullOrBlank()) {
if (!YDLavManager.isOnlineRtm) {
YDLavManager.instances.login(
if (!findRouteService(IAudioImService::class.java).getIsOnlineRtm()) {
findRouteService(IAudioImService::class.java).loginRtm(
PhoneCallIn.getUserService().getUserInfo()?.uid
) { _: Boolean, _ ->
showPayOrDetail(item, it)
......
......@@ -43,6 +43,7 @@ dependencies {
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0'
implementation 'in.xiandan:count-down-timer:1.0.3'
kapt 'com.alibaba:arouter-compiler:1.2.2'
implementation rootProject.ext.dependencies["BaseRecyclerViewAdapterHelper"]
api rootProject.ext.dependencies["ydl-user-router"]
......
......@@ -82,6 +82,9 @@ class ExpertSearchActivity : BaseMvpActivity<IExpertSearchView, ExpertSearchPres
YDLImageCacheManager.showImage(this, url, imgView, ops)
}
override fun showPromptPayment(promptPaymentBean: PromptPaymentBean) {
}
override fun showImage(
url: String?,
imgView: ImageView,
......
......@@ -31,9 +31,11 @@ import com.ydl.ydlcommon.base.BaseMvpFragment
import com.ydl.ydlcommon.base.config.ChannelConfig
import com.ydl.ydlcommon.base.config.HttpConfig
import com.ydl.ydlcommon.data.PlatformDataManager
import com.ydl.ydlcommon.modular.findRouteService
import com.ydl.ydlcommon.ui.LogoLoadingView
import com.ydl.ydlcommon.utils.BuryPointUtils
import com.ydl.ydlcommon.utils.DisplayUtils
import com.ydl.ydlcommon.utils.SharedPreferencesEditor
import com.ydl.ydlcommon.utils.StatusBarUtils
import com.ydl.ydlcommon.utils.actionutil.ActionCountUtils
import com.ydl.ydlcommon.utils.remind.ToastHelper
......@@ -42,8 +44,8 @@ import com.yidianling.common.tools.LogUtil
import com.yidianling.common.tools.RxImageTool
import com.yidianling.common.tools.ToastUtil
import com.yidianling.consultant.adapter.ExpertSearchAdapter
import com.yidianling.consultant.bean.FunctionWordConsultBean
import com.yidianling.consultant.constants.ConsultBIConstants
import com.yidianling.consultant.dialog.ConsultSubPayDialog
import com.yidianling.consultant.listener.OnCategoriesSelectedListener
import com.yidianling.consultant.listener.OnExpertClickListener
import com.yidianling.consultant.listener.OnFilterConfirmListener
......@@ -57,6 +59,7 @@ import com.yidianling.consultant.ui.view.FilterPopupWindow
import com.yidianling.consultant.ui.view.SortPopupWindow
import com.yidianling.consultant.ui.view.topView.RecommendListView
import com.yidianling.home.api.event.HomeModuleTabEvent
import com.yidianling.user.api.service.IUserService
import de.greenrobot.event.EventBus
import io.reactivex.Observable
import io.reactivex.android.schedulers.AndroidSchedulers
......@@ -69,6 +72,7 @@ import kotlinx.android.synthetic.main.consultant_layout_search_toolbar.*
import org.json.JSONObject
import java.util.concurrent.Executors
import java.util.concurrent.TimeUnit
import kotlin.collections.ArrayList
@Route(path = "/consultant/consultant")
class ExpertSearchFragment : BaseMvpFragment<IExpertSearchView, ExpertSearchPresenter>(),
......@@ -81,6 +85,7 @@ class ExpertSearchFragment : BaseMvpFragment<IExpertSearchView, ExpertSearchPres
var endTime = 0L
private var mIdssign1: String = "" // 列表埋点咨询师列表id拼接参数
var bottomWordDisposable: Disposable? = null
var isShow: Boolean = false
private lateinit var bottomWordlist: List<FunctionWordBean>
override fun layoutResId(): Int {
return R.layout.consultant_activity_expert_search_list
......@@ -125,6 +130,19 @@ class ExpertSearchFragment : BaseMvpFragment<IExpertSearchView, ExpertSearchPres
}
}
var consultSubPayDialog: ConsultSubPayDialog? = null
override fun showPromptPayment(promptPaymentBean: PromptPaymentBean) {
if (promptPaymentBean.toPayTime != 0L) {
//有订单
consultSubPayDialog = activity?.let { ConsultSubPayDialog(it, promptPaymentBean) }
consultSubPayDialog?.show()
consultSubPayDialog?.setOnDismissListener {
consultSubPayDialog = null
}
}
}
override fun showImage(
url: String?,
imgView: ImageView,
......@@ -306,6 +324,7 @@ class ExpertSearchFragment : BaseMvpFragment<IExpertSearchView, ExpertSearchPres
override fun setUserVisibleHint(isVisibleToUser: Boolean) {
super.setUserVisibleHint(isVisibleToUser)
isShow = isVisibleToUser
if (isVisibleToUser && isResumed) {
startTime = System.currentTimeMillis()
} else {
......@@ -1465,6 +1484,22 @@ class ExpertSearchFragment : BaseMvpFragment<IExpertSearchView, ExpertSearchPres
//
needRefresh = true
}
// val orderToPayTime = SharedPreferencesEditor.getString("orderToPayTime")
//
// var timeLimit = if (TextUtils.isEmpty(orderToPayTime)) {
// 0L
// } else {
// orderToPayTime.toLong()
// }
//
//
// if (isShow && !(consultSubPayDialog != null && consultSubPayDialog?.isShowing == true)) {
// if (findRouteService(IUserService::class.java).isLogin() && System.currentTimeMillis() > timeLimit) {
// getPresenter().fetchPromptPayment()
// }
// }
ActionCountUtils.count(ConsultBIConstants.ConsultEvent.APP_CONSULT_LIST_PAGE_VISIT)
ActionCountUtils.count("daoyi_advertisement_page|daoyi_advertisement_visit", "6")
}
......
......@@ -278,4 +278,18 @@ class ExpertSearchPresenter : SimplePresenter<IExpertSearchView>() {
}
})
}
@SuppressLint("CheckResult")
fun fetchPromptPayment() {
SearchApi.getSearchApi()
.promptPayment()
.compose(RxLifecycleUtils.bindToLifecycle(mView))//使用 Rxlifecycle,使 Disposable 和 Activity 一起销毁
.compose(RxUtils.resultJavaData())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe { resp ->
mView.showPromptPayment(resp)
}
}
}
\ No newline at end of file
......@@ -4,10 +4,7 @@ import android.widget.ImageView
import com.ydl.ydl_image.config.SimpleImageOpConfiger
import com.ydl.ydlcommon.mvp.base.IView
import com.yidianling.consultant.bean.FunctionWordConsultBean
import com.yidianling.consultant.model.bean.ExpertServiceItem
import com.yidianling.consultant.model.bean.Extras
import com.yidianling.consultant.model.bean.FunctionWordBean
import com.yidianling.consultant.model.bean.HeadData
import com.yidianling.consultant.model.bean.*
/**
* Created by zqk on 17-9-19.
......@@ -38,4 +35,6 @@ interface IExpertSearchView : IView {
*/
fun showImage(url : String?, imgView : ImageView, ops : SimpleImageOpConfiger)
fun showPromptPayment(promptPaymentBean: PromptPaymentBean)
}
\ No newline at end of file
package com.yidianling.consultant.dialog
import `in`.xiandan.countdowntimer.CountDownTimerSupport
import `in`.xiandan.countdowntimer.OnCountDownTimerListener
import android.app.Dialog
import android.content.Context
import android.os.Bundle
import android.text.TextUtils
import android.view.Gravity
import android.view.View
import android.view.WindowManager
import android.widget.ImageView
import android.widget.TextView
import com.bumptech.glide.Glide
import com.ydl.webview.H5Params
import com.ydl.webview.NewH5Activity
import com.ydl.ydlcommon.utils.SharedPreferencesEditor
import com.yidianling.common.tools.ToastUtil
import com.yidianling.consultant.R
import com.yidianling.consultant.model.bean.PromptPaymentBean
import java.text.DecimalFormat
import java.text.SimpleDateFormat
import java.util.*
/**
* 咨询助理浮层
* Created by xj on 2019/10/30.
*/
class ConsultSubPayDialog(
private val mContext: Context,
private val promptPaymentBean: PromptPaymentBean
) : Dialog(mContext, R.style.dialog_default_style) {
var mTimer: CountDownTimerSupport? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.consultant_expert_consult_sub_pay_dialog)
val params = window.attributes
params.width = WindowManager.LayoutParams.WRAP_CONTENT
params.height = WindowManager.LayoutParams.WRAP_CONTENT
params.gravity = Gravity.CENTER
window.attributes = params
setCanceledOnTouchOutside(false)
initView();
}
private fun initView() {
var titleTv = findViewById<TextView>(R.id.tv_title)
var timeTv = findViewById<TextView>(R.id.tv_time)
titleTv.paint.isFakeBoldText = true
Glide.with(mContext)
.load(promptPaymentBean.smallImage).into(findViewById<ImageView>(R.id.avaterIv))
findViewById<TextView>(R.id.nameTv).text = promptPaymentBean.name
findViewById<TextView>(R.id.desTv).text = promptPaymentBean.productName
val decimalFormat = DecimalFormat("###.##")
val price = decimalFormat.format(promptPaymentBean.price)
findViewById<TextView>(R.id.priceTv).text = "¥$price"
var format = SimpleDateFormat("HH:mm:ss");
format.timeZone = TimeZone.getTimeZone("GMT+0");
var millisInFuture = promptPaymentBean.currentTime?:0 - (promptPaymentBean.toPayTime?:0L)
mTimer = CountDownTimerSupport(millisInFuture, 1000)
mTimer?.setOnCountDownTimerListener(object : OnCountDownTimerListener {
override fun onTick(millisUntilFinished: Long) {
val time = format.format(millisUntilFinished)
timeTv.text = time
}
override fun onFinish() {
var nextShowTime = System.currentTimeMillis() + 24 * 60 * 60 * 1000
SharedPreferencesEditor.putString("orderToPayTime", nextShowTime.toString())
dismiss()
}
override fun onCancel() {
// 倒计时手动停止
}
})
mTimer?.start()
findViewById<TextView>(R.id.tv_close).setOnClickListener {
var nextShowTime = System.currentTimeMillis() + 24 * 60 * 60 * 1000
SharedPreferencesEditor.putString("orderToPayTime", nextShowTime.toString())
mTimer?.stop()
dismiss()
}
findViewById<View>(R.id.pay).setOnClickListener {
if (!TextUtils.isEmpty(promptPaymentBean.orderDetailUrl)) {
val h5Params = H5Params(promptPaymentBean.orderDetailUrl!!, null)
NewH5Activity.start(context, h5Params)
dismiss()
} else {
ToastUtil.toastShort("跳转失败")
dismiss()
}
var nextShowTime = System.currentTimeMillis() + 24 * 60 * 60 * 1000
SharedPreferencesEditor.putString("orderToPayTime", nextShowTime.toString())
}
}
override fun onDetachedFromWindow() {
super.onDetachedFromWindow()
if (mTimer != null) {
mTimer?.stop()
mTimer = null
}
}
}
\ No newline at end of file
......@@ -10,6 +10,7 @@ import com.yidianling.consultant.bean.*
import com.yidianling.consultant.model.bean.ExpertBean
import com.yidianling.consultant.model.bean.FunctionWordBean
import com.yidianling.consultant.model.bean.HeadData
import com.yidianling.consultant.model.bean.PromptPaymentBean
import io.reactivex.Observable
import retrofit2.http.*
......@@ -112,4 +113,10 @@ interface SearchApi {
): Observable<BaseAPIResponse<Long>>
//搜索条件
@GET("consult/user/order/promptPayment")
@Headers(YDL_DOMAIN + YDL_DOMAIN_JAVA)
fun promptPayment(): Observable<BaseAPIResponse<PromptPaymentBean>>
}
\ No newline at end of file
package com.yidianling.consultant.model.bean
data class PromptPaymentBean(
var uid: String? = "",
var orderId: String? = "",
var toPayTime: Long? = 0,
var smallImage: String? = "",
var name: String? = "",
var price: Float? = 0.00f,
var productName: String? = "",
var doctorId: String? = "",
var productId: String? = "",
var createTime: String? = "",
var orderToPayTime: Long? = 0,
var orderDetailUrl: String? = "",
var currentTime: Long? = 0
)
......@@ -74,6 +74,9 @@ class ConsultAssistantDialogUtils private constructor() {
shouldShowDialog(activity, origin)
}
}
"other_index" ->{
shouldShowDialog(activity, origin)
}
}
}
......@@ -87,9 +90,11 @@ class ConsultAssistantDialogUtils private constructor() {
origin: String,
fromActivity: Boolean = false
) {
if (!fromActivity){ // 不是咨询师二级列页的时候再所有的dialog dismiss
consultAssistantDialogFromHomePage?.dismiss()
consultAssistantFragmentDialog?.dismiss()
consultAssistantDialogFromMine?.dismiss()
}
when (origin) {
"home_index" -> {
showFromYdlHome(activity)
......
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="@dimen/platform_dp_20" />
<solid android:color="#FF6B5D" />
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="4dp"/>
<solid android:color="#F6F6F7" />
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="12dp"/>
<solid android:color="#ffffff" />
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="307dp"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="@color/white"
app:cardCornerRadius="12dp"
android:layout_centerInParent="true">
<RelativeLayout
android:layout_width="307dp"
android:layout_height="wrap_content"
android:background="@color/white"
android:layout_centerInParent="true">
<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="@dimen/platform_dp_16"
android:text="你还有订单等待付款"
android:textColor="#1C1F28"
android:textSize="18sp" />
<LinearLayout
android:id="@+id/ll_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dp_4"
android:layout_below="@+id/tv_title"
android:layout_centerHorizontal="true">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="还剩"
android:textColor="#1C1F28"
android:textSize="@dimen/platform_sp_14" />
<TextView
android:id="@+id/tv_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="00:12:21"
android:layout_marginLeft="@dimen/platform_dp_2"
android:layout_marginRight="@dimen/platform_dp_2"
android:textColor="#FF9534"
android:textSize="@dimen/platform_sp_14" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="订单将关闭"
android:textColor="#1C1F28"
android:textSize="@dimen/platform_sp_14" />
</LinearLayout>
<LinearLayout
android:id="@+id/ll_content"
android:layout_below="@+id/ll_time"
android:layout_width="match_parent"
android:layout_height="66dp"
android:background="@drawable/consultant_bg_sub_pay"
android:layout_marginTop="@dimen/platform_dp_16"
android:layout_marginLeft="@dimen/platform_dp_16"
android:layout_marginRight="@dimen/platform_dp_16"
android:orientation="horizontal">
<androidx.cardview.widget.CardView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="@dimen/platform_dp_12"
android:layout_marginRight="@dimen/platform_dp_8"
app:cardCornerRadius="4dp">
<ImageView
android:id="@+id/avaterIv"
android:layout_width="40dp"
android:layout_height="40dp"
android:scaleType="centerCrop" />
</androidx.cardview.widget.CardView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/nameTv"
android:layout_marginTop="@dimen/platform_dp_11"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="@dimen/platform_sp_14"
android:textColor="#1C1F28"
android:maxLines="1"
android:ellipsize="end"
android:layout_marginRight="@dimen/platform_dp_12"
/>
<TextView
android:id="@+id/desTv"
android:layout_marginTop="@dimen/platform_dp_6"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="@dimen/platform_sp_14"
android:textColor="#62636F"
android:maxLines="1"
android:ellipsize="end"
android:layout_marginBottom="@dimen/platform_dp_11"
android:layout_marginRight="@dimen/platform_dp_12"
/>
</LinearLayout>
</LinearLayout>
<LinearLayout
android:id="@+id/pay"
android:layout_below="@+id/ll_content"
android:layout_width="match_parent"
android:layout_height="@dimen/platform_dp_40"
android:padding="@dimen/platform_dp_9"
android:layout_marginLeft="@dimen/platform_dp_16"
android:layout_marginRight="@dimen/platform_dp_16"
android:gravity="center"
android:background="@drawable/consultant_bg_radius_red_20"
android:layout_marginTop="@dimen/platform_dp_28">
<TextView
android:layout_centerInParent="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/white"
android:textSize="@dimen/sp_16"
android:text="去付款"
/>
<TextView
android:id="@+id/priceTv"
android:layout_centerInParent="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/white"
android:textSize="@dimen/sp_16"
android:layout_marginLeft="@dimen/platform_dp_5"
android:text="¥200"
/>
</LinearLayout>
<TextView
android:id="@+id/tv_close"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="稍后再说"
android:layout_below="@+id/pay"
android:layout_centerHorizontal="true"
android:textSize="@dimen/platform_sp_14"
android:paddingLeft="@dimen/platform_dp_5"
android:paddingRight="@dimen/platform_dp_5"
android:paddingBottom="@dimen/platform_dp_3"
android:paddingTop="@dimen/platform_dp_3"
android:textColor="#62636F"
android:layout_marginTop="@dimen/platform_dp_16"
android:layout_marginBottom="@dimen/platform_dp_16"/>
</RelativeLayout>
</androidx.cardview.widget.CardView>
......@@ -45,4 +45,12 @@
</style>
<style name="dialog_default_style" parent="@android:style/Theme.Dialog">
<item name="android:windowBackground">@drawable/consultant_bg_sub_pay_dialog</item>
<item name="android:windowFrame">@null</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowIsFloating">true</item>
<item name="android:windowIsTranslucent">true</item>
<item name="android:backgroundDimEnabled">true</item>
</style>
</resources>
......@@ -44,6 +44,7 @@ import com.yidianling.im.session.extension.CustomAttachConsult;
import com.yidianling.im.session.extension.CustomAttachConsultCallStatus;
import com.yidianling.im.session.extension.CustomAttachConsultPerfectData;
import com.yidianling.im.session.extension.CustomAttachConsultSubScript;
import com.yidianling.im.session.extension.CustomAttachConsultSubScriptPayment;
import com.yidianling.im.session.extension.CustomAttachLingXiJumpConfideList;
import com.yidianling.im.session.extension.CustomAttachLingxiAnswerQuestion;
import com.yidianling.im.session.extension.CustomAttachLingxiFirstQuestion;
......@@ -85,6 +86,7 @@ import com.yidianling.im.session.viewholder.MsgViewHolderConfirmOrder;
import com.yidianling.im.session.viewholder.MsgViewHolderConsult;
import com.yidianling.im.session.viewholder.MsgViewHolderConsultCallStatus;
import com.yidianling.im.session.viewholder.MsgViewHolderConsultSubScribe;
import com.yidianling.im.session.viewholder.MsgViewHolderConsultSubScribePayment;
import com.yidianling.im.session.viewholder.MsgViewHolderCustomTip;
import com.yidianling.im.session.viewholder.MsgViewHolderCustomerServiceCard;
import com.yidianling.im.session.viewholder.MsgViewHolderDefCustom;
......@@ -479,6 +481,7 @@ public class SessionHelper {
NimUIKit.registerMsgItemViewHolder(CustomAttachLingxiAnswerQuestion.class, MsgViewHolderLingxiAnswerQuestion.class);//灵犀2.0-回答问题
NimUIKit.registerMsgItemViewHolder(CustomAttachLingxiFirstQuestion.class, MsgViewHolderLingxiFirstQuestion.class);//灵犀2.0-首问语
NimUIKit.registerMsgItemViewHolder(CustomAttachLingXiJumpConfideList.class, MsgViewHolderLingXiJumpConfideList.class);//灵犀2.0-倾诉列表
// NimUIKit.registerMsgItemViewHolder(CustomAttachConsultSubScriptPayment.class, MsgViewHolderConsultSubScribePayment.class);//咨询预约支付
}
......
package com.yidianling.im.session.extension;
import com.alibaba.fastjson.JSONObject;
/**
* 确认预约时间
* Created by harvie on 2017/1/10.
*/
public class CustomAttachConsultSubScriptPayment extends CustomAttachment {
private String TITLE = "title";
private String PRODUCT_NAME = "productName";
private String CONSULT_DATE = "bookingTime";
private String CONSULT_TIME = "consultDuration";
private String CONSULT_TYPE = "serviceType";
private String FLAG = "flag";
private String URL = "url";
private String IS_PACKAGE = "isPackage";
private static final String NEWSORDERID = "newOrderId";//用于跳转新版订单详情
private static final String STATUS = "status";//状态,1代表已确认,0代表待确认
private String FROM_CONTENT = "from_content";
private String TO_CONTENT = "to_content";
public String title; //自定义消息标题
public String productName;//商品名称
public String consultDate;//咨询时间
public String consultTime;//咨询时长
public String consultType;//咨询方式
public String url;//跳转url
public int flag;//0 未确认 1已确认
public byte isPackage = 0; //是否套餐 1单次 2套餐
/***新订单*/
public String newOrderId;
public String from_content;
public String to_content;
public CustomAttachConsultSubScriptPayment() {
super(CustomAttachmentType.TYPE_CONSULT_SUBSCRIBE_PAY);
}
@Override
protected void parseData(JSONObject data) {
title = data.getString(TITLE);
productName = data.getString(PRODUCT_NAME);
consultDate = data.getString(CONSULT_DATE);
consultTime = data.getString(CONSULT_TIME);
consultType = data.getString(CONSULT_TYPE);
url = data.getString(URL);
flag = data.getInteger(FLAG);
isPackage = data.getByte(IS_PACKAGE);
this.newOrderId = data.getString(NEWSORDERID);
from_content = data.getString(FROM_CONTENT);
to_content = data.getString(TO_CONTENT);
}
@Override
protected JSONObject packData() {
JSONObject data = new JSONObject();
data.put(TITLE,title);
data.put(PRODUCT_NAME,productName);
data.put(CONSULT_DATE,consultDate);
data.put(CONSULT_TIME,consultTime);
data.put(CONSULT_TYPE,consultType);
data.put(URL,url);
data.put(FLAG,flag);
data.put(IS_PACKAGE,isPackage);
data.put(NEWSORDERID, newOrderId);
data.put(FROM_CONTENT, from_content);
data.put(TO_CONTENT, to_content);
return data;
}
}
......@@ -158,6 +158,9 @@ public class CustomAttachParser implements MsgAttachmentParser {
case CustomAttachmentType.TYPE_LINGXI_FIRST_QUESTION: //首问语
attachment = new CustomAttachLingxiFirstQuestion();
break;
// case CustomAttachmentType.TYPE_CONSULT_SUBSCRIBE_PAY:
// attachment = new CustomAttachConsultSubScriptPayment();
// break;
default:
attachment = new DefaultCustomAttachment();
break;
......
......@@ -55,6 +55,9 @@ public interface CustomAttachmentType {
int TYPE_LINGXI_ANSWER_QUESTION=56;//回答消息
int TYPE_LINGXI_TEST_QUESTION=60;//测评结果
int TYPE_LINGXI_JUMP_CONFIDE_LIST = 73; // 跳转倾诉列表
int TYPE_CONSULT_SUBSCRIBE_PAY = 74; // 预约支付
}
......@@ -103,10 +103,8 @@ public class MsgViewHolderConsultSubScribe extends MsgViewHolderBase {
if (flag==1){
img_icon.setVisibility(View.VISIBLE);
tv_title.setTextColor(ContextCompat.getColor(context,R.color.im_color_00CC88));
}else {
img_icon.setVisibility(View.GONE);
tv_title.setTextColor(ContextCompat.getColor(context,R.color.platform_color_242424));
}
hideItemBg();
......
package com.yidianling.im.session.viewholder;
import android.text.TextUtils;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.core.content.ContextCompat;
import com.netease.nimlib.sdk.msg.attachment.MsgAttachment;
import com.ydl.webview.H5Params;
import com.ydl.webview.NewH5Activity;
import com.yidianling.im.R;
import com.yidianling.im.config.constants.ImConstants;
import com.yidianling.im.session.extension.CustomAttachConsultSubScriptPayment;
import com.yidianling.nimbase.common.ui.recyclerview.adapter.BaseMultiItemFetchLoadAdapter;
import com.yidianling.uikit.business.session.viewholder.MsgViewHolderBase;
/**
* author : harvie
* 确认咨询预约消息
*/
public class MsgViewHolderConsultSubScribePayment extends MsgViewHolderBase {
private TextView tv_title,tv_content,tv_date,tv_time_long,tv_type,tv_package;
private ImageView img_icon;
private View lin_root;
public String title; //自定义消息标题
public String productName;//商品名称
public String consultDate;//咨询时间
public String consultTime;//咨询时长
public String consultType;//咨询方式
public String url;//跳转url
public int flag;//0 未确认 1已确认
public byte isPackage;
/***新订单id*/
public String newOrderId;
public String from_content;
public String to_content;
public MsgViewHolderConsultSubScribePayment(BaseMultiItemFetchLoadAdapter adapter) {
super(adapter);
}
@Override
protected int getContentResId() {
return R.layout.im_ui_message_custom_consult_subscribe;
}
@Override
protected void inflateContentView() {
lin_root = view.findViewById(R.id.lin_root);
tv_title = view.findViewById(R.id.tv_title);
tv_content = view.findViewById(R.id.tv_content);
tv_date = view.findViewById(R.id.tv_date);
tv_time_long = view.findViewById(R.id.tv_time_long);
tv_type = view.findViewById(R.id.tv_type);
img_icon = view.findViewById(R.id.img_icon);
tv_package = view.findViewById(R.id.tv_package);
if (isReceivedMessage()){
setAvatarRightInVisibity();
lin_root.setBackgroundResource(R.drawable.im_bg_radius_no_topleft_white_8);
}else {
setAvatarLeftInVisibity();
lin_root.setBackgroundResource(R.drawable.im_bg_radius_no_topright_white_8);
}
}
@Override
protected void bindContentView() {
if (isReceivedMessage()){
setAvatarRightInVisibity();
}else {
setAvatarLeftInVisibity();
}
MsgAttachment attachment = message.getAttachment();
if (attachment instanceof CustomAttachConsultSubScriptPayment) {
title = ((CustomAttachConsultSubScriptPayment) attachment).title;
productName = ((CustomAttachConsultSubScriptPayment) attachment).productName;
consultDate = ((CustomAttachConsultSubScriptPayment) attachment).consultDate;
consultTime = ((CustomAttachConsultSubScriptPayment) attachment).consultTime;
consultType = ((CustomAttachConsultSubScriptPayment) attachment).consultType;
url = ((CustomAttachConsultSubScriptPayment) attachment).url;
flag = ((CustomAttachConsultSubScriptPayment) attachment).flag;
isPackage = ((CustomAttachConsultSubScriptPayment) attachment).isPackage;
newOrderId = ((CustomAttachConsultSubScriptPayment) attachment).newOrderId;
from_content = ((CustomAttachConsultSubScriptPayment) attachment).from_content;
to_content = ((CustomAttachConsultSubScriptPayment) attachment).to_content;
}
tv_title.setText(to_content);
tv_date.setText(consultDate);
tv_time_long.setText(consultTime);
tv_type.setText(consultType);
if (isPackage == 2){
tv_package.setVisibility(View.VISIBLE);
tv_content.setText("\u3000\u3000"+productName);
}else {
tv_package.setVisibility(View.GONE);
tv_content.setText(productName);
}
if (flag==1){
img_icon.setVisibility(View.VISIBLE);
}else {
img_icon.setVisibility(View.GONE);
}
hideItemBg();
}
@Override
protected void onItemClick() {
if (TextUtils.isEmpty(url)&& newOrderId == null){
return;
}
if (newOrderId == null || newOrderId.isEmpty()) {
NewH5Activity.start(context, new H5Params(url, null));
} else {
//跳转新订单详情页
H5Params orderParams = new H5Params(
ImConstants.Companion.getORDER_DETAIL() + (newOrderId.isEmpty() ? "" : newOrderId), null);
NewH5Activity.start(context, orderParams);
}
}
}
......@@ -345,12 +345,12 @@ public class WatchMessagePictureActivity extends UI {
@Override
public void onFailed(int i) {
Apm.INSTANCE.reportCustom("yx_attchment_error", "", new Exception(String.valueOf(i)));
Apm.INSTANCE.reportEvent("yxim_android", "attchment_error", "云信IM收取消息" + i);
}
@Override
public void onException(Throwable throwable) {
Apm.INSTANCE.reportCustom("yx_attchment_error", "", throwable);
Apm.INSTANCE.reportEvent("yxim_android", "attchment_error", "云信IM收取消息" + throwable.getMessage());
}
});
}
......
......@@ -509,12 +509,12 @@ public class WatchVideoActivity extends UI implements Callback {
@Override
public void onFailed(int i) {
Apm.INSTANCE.reportCustom("yx_attchment_error", "", new Exception(String.valueOf(i)));
Apm.INSTANCE.reportEvent("yxim_android", "attchment_error", "云信IM收取消息" + i);
}
@Override
public void onException(Throwable throwable) {
Apm.INSTANCE.reportCustom("yx_attchment_error", "", throwable);
Apm.INSTANCE.reportEvent("yxim_android", "attchment_error", "云信IM收取消息" + throwable.getMessage());
}
});
downloading = true;
......
......@@ -1367,7 +1367,7 @@ public class YDLMessageFragment extends TFragment implements ModuleProxy {
public void onFailed(int code) {
if (msg != null) {
sendFailWithBlackList(code, msg);
Apm.INSTANCE.reportCustom("yx_sendmessage_error", "sessionId:" + msg.getSessionId(), new Exception(String.valueOf(code)));
Apm.INSTANCE.reportEvent("yxim_android", "sendmessage_error", " 云信IM发送消息失败" + code + msg);
}
}
......
......@@ -849,12 +849,12 @@ public class MessageListPanelEx {
@Override
public void onFailed(int i) {
Apm.INSTANCE.reportCustom("yx_attchment_error", "", new Exception(String.valueOf(i)));
Apm.INSTANCE.reportEvent("yxim_android", "attchment_error", "云信IM收取消息" + i);
}
@Override
public void onException(Throwable throwable) {
Apm.INSTANCE.reportCustom("yx_attchment_error", "", throwable);
Apm.INSTANCE.reportEvent("yxim_android", "attchment_error", "云信IM收取消息" + throwable.getMessage());;
}
});
}
......@@ -1163,8 +1163,7 @@ public class MessageListPanelEx {
@Override
public void onFailed(int code) {
String sessionId = item.getSessionId();
Apm.INSTANCE.reportCustom("yx_revoke_error", "sessionId:" + sessionId, new Exception(String.valueOf(code)));
Apm.INSTANCE.reportEvent("yxim_android", "revoke_error", "云信IM回撤消息失败" + code);
if (code == ResponseCode.RES_OVERDUE) {
ToastHelper.showToast(container.activity, R.string.im_revoke_failed);
} else {
......
......@@ -82,12 +82,12 @@ public class MsgViewHolderAudio extends MsgViewHolderBase {
@Override
public void onFailed(int i) {
Apm.INSTANCE.reportCustom("yx_attchment_error", "", new Exception(String.valueOf(i)));
Apm.INSTANCE.reportEvent("yxim_android", "attchment_error", "云信IM收取消息" + i);
}
@Override
public void onException(Throwable throwable) {
Apm.INSTANCE.reportCustom("yx_attchment_error", "", throwable);
Apm.INSTANCE.reportEvent("yxim_android", "attchment_error", "云信IM收取消息" + throwable.getMessage());
}
});
......
......@@ -151,12 +151,12 @@ public abstract class MsgViewHolderBase extends RecyclerViewHolder<BaseMultiItem
@Override
public void onFailed(int i) {
Apm.INSTANCE.reportCustom("yx_attchment_error", "", new Exception(String.valueOf(i)));
Apm.INSTANCE.reportEvent("yxim_android", "attchment_error", "云信IM收取消息" + i);
}
@Override
public void onException(Throwable throwable) {
Apm.INSTANCE.reportCustom("yx_attchment_error", "", throwable);
Apm.INSTANCE.reportEvent("yxim_android", "attchment_error", "云信IM收取消息" + throwable.getMessage());
}
});
}
......
......@@ -18,7 +18,7 @@
android:layout_marginRight="4dp"
android:layout_alignTop="@+id/tv_title"
android:layout_alignBottom="@+id/tv_title"
android:src="@mipmap/im_consult_data_sure"
android:src="@mipmap/im_cunsult_data_sure_gary"
android:visibility="gone"
tools:visibility="gone"/>
......@@ -27,6 +27,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="14dp"
android:textStyle="bold"
android:textColor="@color/im_color_242424"
android:layout_toRightOf="@+id/img_icon"
tools:text="请确认我的预约消息"/>
......@@ -47,7 +48,6 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="14dp"
android:textStyle="bold"
android:textColor="@color/im_color_242424"
tools:text="\u3000\u3000幸福宝典fghrt ertyherthhtrht"/>
......@@ -68,7 +68,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/platform_color_666666"
android:textSize="10dp"
android:textSize="12dp"
android:layout_marginTop="5.8dp"
android:layout_below="@+id/tv_content"
tools:text="咨询时间:2019-12-55 12:00:00"/>
......@@ -78,7 +78,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/platform_color_999999"
android:textSize="10dp"
android:textSize="12dp"
android:layout_marginTop="2dp"
android:layout_below="@+id/tv_date"
tools:text="咨询时长:30分钟"/>
......@@ -88,7 +88,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/platform_color_999999"
android:textSize="10dp"
android:textSize="12dp"
android:layout_marginTop="2dp"
android:layout_below="@+id/tv_time_long"
tools:text="咨询方式:电话"/>
......
......@@ -20,5 +20,6 @@ object UserConstants {
//黑名单
val My_BLACK = HttpConfig.H5_URL + "mine/black-list/"
//百科
val MY_BAIKE = HttpConfig.MH5_URL + "newConsult/baike"
}
\ No newline at end of file
......@@ -2,5 +2,6 @@ package com.yidianling.user.bean
data class EvaluateOrderBean(
val consultOrder: Boolean? = null,
val listenOrder: Boolean? = null
val listenOrder: Boolean? = null,
val consultOrderNum: Int? = null
)
......@@ -29,12 +29,12 @@ import com.ydl.ydlcommon.utils.YdlBuryPointUtil
import com.ydl.ydlcommon.utils.actionutil.ActionCountUtils.Companion.count
import com.ydl.ydlcommon.view.dialog.YDLShareDialog
import com.ydl.ydlcommon.view.dialog.YDLShareDialog.Companion.style4
import com.yidianling.consultant.api.IConsultantService
import com.yidianling.dynamic.api.IDynamicService
import com.yidianling.im.api.service.IImService
import com.yidianling.im.message.param.MsgListParam
import com.yidianling.user.BuildConfig
import com.yidianling.user.R
import com.yidianling.user.UserConstants.MY_BAIKE
import com.yidianling.user.UserHelper.getUserInfo
import com.yidianling.user.UserHelper.getUsetSetting
import com.yidianling.user.UserHelper.isLogin
......@@ -54,7 +54,6 @@ import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.functions.Consumer
import io.reactivex.schedulers.Schedulers
import kotlinx.android.synthetic.main.user_mine_fragment_mine.*
import java.util.*
/**
* 我的Tab
......@@ -118,6 +117,8 @@ class MineFragment : BaseFragment(), SwipeRefreshLayout.OnRefreshListener, View.
rootView.findViewById<View>(R.id.ll_service).setOnClickListener(this)
//冥想
rootView.findViewById<View>(R.id.ll_meditation).setOnClickListener(this)
//心理百科
rootView.findViewById<View>(R.id.ll_wiki).setOnClickListener(this)
init()
GlideApp.with(this).load("https://static.yidianling.com/banner/bottombanner@2x.png")
......@@ -193,6 +194,7 @@ class MineFragment : BaseFragment(), SwipeRefreshLayout.OnRefreshListener, View.
refreshCouponData()
}
@SuppressLint("CheckResult")
private fun getConfideOrder(uid: String) {
MineHttpImpl.getInstance().getHasConfideOrder(uid)
.subscribeOn(Schedulers.io())
......@@ -207,9 +209,14 @@ class MineFragment : BaseFragment(), SwipeRefreshLayout.OnRefreshListener, View.
iv_confide_tip.visibility = View.GONE
getLocal().setConfide(false)
}
if (response.data.consultOrder == true) {
val orderNum = response.data?.consultOrderNum ?: 0
if (orderNum > 0) {
iv_order_tip.visibility = View.VISIBLE
if (orderNum > 99) {
iv_order_tip.text = "99+"
} else {
iv_order_tip.text = "$orderNum"
}
getLocal().setConsult(true)
} else {
iv_order_tip.visibility = View.GONE
......@@ -546,6 +553,13 @@ class MineFragment : BaseFragment(), SwipeRefreshLayout.OnRefreshListener, View.
NewH5Activity.start(it, h5Params3)
}
} else if (id == R.id.ll_wiki) { //心理百科
count(UserMyPageEvent.YDL_USER_MY_MIDDLE_TYPE_CLICK, "百科")
mActivity?.let {
val h5Params3 = H5Params(MY_BAIKE, null)
NewH5Activity.start(it, h5Params3)
}
}
}
......
......@@ -73,7 +73,7 @@ class LoginObservable(val activity: Activity, private val media: SHARE_MEDIA): O
}
override fun onError(p0: SHARE_MEDIA?, p1: Int, p2: Throwable?) {
Apm.reportCustom("login", "third_auth_error", p2 ?: Exception("${p0},$p1"))
Apm.reportEvent("login_android", "third_auth_error", "三方授权失败${p2?.message ?: p1}")
observer?.onError(p2?:Throwable("未知异常"))
}
......
......@@ -507,7 +507,7 @@ object OneKeyLoginHelp {
"一键登录失败 msg:${it.msg}"
)
ToastUtil.toastShort(it.msg)
Apm.reportCustom("login", "oneKey_error", Exception("${it.code},${it.msg}"))
Apm.reportEvent("login_android", "oneKey_error", "一键登录失败报错${it.code},${it.msg}")
mPhoneNumberAuthHelper?.hideLoginLoading()
}
}, {
......@@ -515,7 +515,7 @@ object OneKeyLoginHelp {
AliYunLogConfig.LOGIN,
"一键登录Error msg:${it.message}"
)
Apm.reportCustom("login", "oneKey_error", it)
Apm.reportEvent("login_android", "oneKey_error", "一键登录失败报错${it.message}")
ToastUtil.toastShort(it.message)
mPhoneNumberAuthHelper?.hideLoginLoading()
})
......@@ -527,7 +527,7 @@ object OneKeyLoginHelp {
}
override fun onTokenFailed(s: String) {
Apm.reportCustom("login", "oneKey_error", Exception("TokenFailed:${s}"))
Apm.reportEvent("login_android", "oneKey_error", "一键登录失败TokenFailed:${s}")
LogUtil.e("onTokenFailed"+s)
mIsGetTokenSuccess = false
val tokenRet = TokenRet.fromJson(s)
......
......@@ -115,12 +115,12 @@ class InputPassWordPresenterImpl :
AliYunRichLogsHelper.getInstance()
.sendRichLog(AliYunLogConfig.LOGIN, "手机号密码 登录失败 msg: ${it.msg}")
ToastUtil.toastShort(it.msg)
Apm.reportCustom("login", "password_error", Exception("密码登录失败,$phoneCountryCode-$phone"))
Apm.reportEvent("login_android", "password_error", "密码登录失败,$phoneCountryCode-$phone")
mView.startAnim()
} else {
if (it.data.userInfo?.user_type == 2) {
mView.showNormalDialog()
Apm.reportCustom("login", "isexpert", Exception("登录—专家帐号,$phoneCountryCode-$phone"))
Apm.reportEvent("login_android", "isexpert", "登录—专家帐号,$phoneCountryCode-$phone")
} else {
saveUserData(it.data)
if (it.data.firstLogin == 1) {//第一次登录:是注册
......@@ -140,7 +140,7 @@ class InputPassWordPresenterImpl :
}
}, {
YdlCommonOut.showToast(it.message!!)
Apm.reportCustom("login", "password_error", it)
Apm.reportEvent("login_android", "password_error", "密码登录失败${it.message}")
AliYunRichLogsHelper.getInstance()
.sendRichLog(AliYunLogConfig.LOGIN, "手机号密码 Error msg: ${it.message}")
......
......@@ -168,7 +168,7 @@ class LoginPresenterImpl(view: ILoginContract.View) :
if (it.data.isRegistered == 1) {
mView.showLoading(false)
mView.showHasBindedDialog()
Apm.reportCustom("login", "mobile_isbind", Exception("登录-手机被绑定,$countryCode-$phone"))
Apm.reportEvent("login_android", "mobile_isbind", "登录-手机被绑定,$countryCode-$phone")
} else {
mView.checkPhoneStatusSuccess(it.data, phone)
}
......@@ -176,7 +176,7 @@ class LoginPresenterImpl(view: ILoginContract.View) :
if (it.data.isDoctor == 1) {//是专家账号
mView.showLoading(false)
mView.showNormalDialog()
Apm.reportCustom("login", "isexpert", Exception("登录—专家帐号,$countryCode-$phone"))
Apm.reportEvent("login_android", "isexpert", "登录—专家帐号,$countryCode-$phone")
} else {
mView.checkPhoneStatusSuccess(it.data, phone)
}
......@@ -214,7 +214,7 @@ class LoginPresenterImpl(view: ILoginContract.View) :
.subscribe({
mView.dismissProgressView()
if (it?.data == null) {
Apm.reportCustom("login", "third_login_error", Exception("${it.code},${it.msg}"))
Apm.reportEvent("login_android", "third_login_error", "三方登录失败${it.code},${it.msg}")
ToastUtil.toastShort(it.msg)
return@subscribe
}
......@@ -268,7 +268,7 @@ class LoginPresenterImpl(view: ILoginContract.View) :
}, {
mView.dismissProgressView()
Apm.reportCustom("login", "third_login_error", it)
Apm.reportEvent("login", "third_login_error", it.message ?: "")
YdlCommonOut.showToast(it.message!!)
AliYunRichLogsHelper.getInstance()
.sendRichLog(AliYunLogConfig.LOGIN, media.getName() + "登录失败")
......
......@@ -47,12 +47,12 @@ class VerificationCodePresenterImpl(view: IVerificationCodeContract.View) : Base
mView.startCountdown(60)
} else {
mView.startAnim()
Apm.reportCustom("login", "getcode_error", Exception("${phone},${it.code},${it.msg}"))
Apm.reportEvent("login_android", "getcode_error", "获取验证码失败${phone},${it.code},${it.msg}")
ToastUtil.toastShort(it.msg)
}
}, {
mView.startAnim()
Apm.reportCustom("login", "getcode_error", it)
Apm.reportEvent("login", "getcode_error", "获取验证码失败${it.message}")
ToastUtil.toastShort(it.message)
})
}
......@@ -115,13 +115,13 @@ class VerificationCodePresenterImpl(view: IVerificationCodeContract.View) : Base
} else {
ToastUtil.toastShort(it.msg)//服务端返回{验证码错误&异常}信息
// mView.startAnim()
Apm.reportCustom("login", "bind_mobile_error", Exception("${param.countryCode}-${param.phoneNumber},${it.code},${it.msg}"))
Apm.reportEvent("login_android", "bind_mobile_error", " 手机号绑定失败${param.countryCode}-${param.phoneNumber},${it.code},${it.msg}")
mView.verificationErrorCode()
}
}, {
// mView.startAnim()
mView.verificationErrorCode()
Apm.reportCustom("login", "bind_mobile_error", it)
Apm.reportEvent("login_android", "bind_mobile_error", " 手机号绑定失败${param.countryCode}-${param.phoneNumber},${it.message}")
ToastUtil.toastShort(it.message)
})
......@@ -193,12 +193,12 @@ class VerificationCodePresenterImpl(view: IVerificationCodeContract.View) : Base
} else {
ToastUtil.toastShort(it.msg)//服务端返回{验证码错误&异常}信息
// mView.startAnim()
Apm.reportCustom("login", "code_error", Exception("${phoneCountryCode}-${phone},${it.code},${it.msg}"))
Apm.reportEvent("login_android", "code_error", "验证码登录失败${phoneCountryCode}-${phone},${it.code},${it.msg}")
mView.verificationErrorCode()
}
}, {
mView.startAnim()
Apm.reportCustom("login", "code_error", it)
Apm.reportEvent("login", "code_error", it.message ?: "")
ToastUtil.toastShort(it.message)
})
}
......
......@@ -416,15 +416,19 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
<TextView
tools:text="11"
android:id="@+id/iv_order_tip"
android:layout_width="8dp"
android:layout_height="8dp"
android:src="@drawable/user_mine_background_red_point_new_coupon"
android:layout_width="12dp"
android:layout_height="12dp"
android:gravity="center"
android:textSize="8dp"
android:textColor="@color/white"
android:background="@drawable/user_mine_background_red_point_new_coupon"
android:visibility="gone"
app:layout_constraintCircle="@id/iv_trade_order"
app:layout_constraintCircleAngle="45"
app:layout_constraintCircleRadius="13dp"
app:layout_constraintCircleRadius="10dp"
tools:visibility="visible" />
<TextView
......@@ -495,7 +499,6 @@
</LinearLayout>
<!--meditation start-->
<LinearLayout
android:id="@+id/ll_meditation"
android:layout_width="0dp"
......@@ -519,13 +522,30 @@
android:textSize="12sp" />
</LinearLayout>
<!--meditation end-->
<View
<LinearLayout
android:id="@+id/ll_wiki"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
android:layout_weight="1"
android:background="?android:attr/selectableItemBackground"
android:gravity="center_horizontal"
android:orientation="vertical">
<ImageView
android:layout_width="25dp"
android:layout_height="25dp"
android:src="@drawable/user_mine_ic_my_wiki" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="心理百科"
android:textColor="@color/platform_color_999999"
android:textSize="12sp" />
</LinearLayout>
</LinearLayout>
......
......@@ -4,8 +4,6 @@
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<application>
<service android:name=".audio.PlayService" />
<receiver android:name=".audio.receiver.RemoteControlReceiver">
<intent-filter>
<action android:name="android.intent.action.MEDIA_BUTTON" />
......
......@@ -13,7 +13,7 @@ import com.ydl.media.audio.manager.NotifyManager
import com.ydl.media.audio.model.Music
import com.ydl.media.audio.receiver.NoisyAudioStreamReceiver
import com.ydl.media.audio.utils.PlayProgressUtil
import com.ydl.ydlcommon.event.MeditationFloatEvent
import com.ydl.ydlcommon.event.MeditationFloatStopEvent
import com.ydl.ydlcommon.utils.LogUtil
import com.yidianling.common.tools.ToastUtil
import de.greenrobot.event.EventBus
......@@ -344,7 +344,7 @@ class AudioPlayer private constructor() {
}
}
val event = MeditationFloatEvent(show = false, stop = true, time = null)
val event = MeditationFloatStopEvent(show = false, stop = true, time = null)
EventBus.getDefault().post(event)
}
......
package com.ydl.media.audio
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.Service
import android.content.Context
import android.content.Intent
import android.os.Binder
import android.os.Build
import android.os.IBinder
import android.util.Log
import androidx.core.app.NotificationCompat
import com.ydl.media.audio.constants.Extras
import com.ydl.media.audio.manager.MediaSessionManager
import com.ydl.media.audio.manager.NotifyManager
/**
* Created by haorui on 2019-10-27 .
* Des: 音乐播放后台服务
*/
class PlayService : Service() {
inner class PlayBinder : Binder() {
val service: PlayService
get() = this@PlayService
}
override fun onCreate() {
super.onCreate()
if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.O){
var nm = getSystemService(NOTIFICATION_SERVICE) as NotificationManager;
//数字是随便写的“40”,
nm.createNotificationChannel( NotificationChannel("40", "App Service", NotificationManager.IMPORTANCE_DEFAULT));
var builder = NotificationCompat.Builder(this, "40");
//其中的2,是也随便写的,正式项目也是随便写
startForeground(2 ,builder.build());
}
Log.i(TAG, "onCreate: " + javaClass.simpleName)
AudioPlayer.get().init(this)
MediaSessionManager.get().init(this)
NotifyManager.get().init(this)
}
override fun onBind(intent: Intent): IBinder? {
return PlayBinder()
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
if (intent != null && intent.action != null) {
when (intent.action) {
Extras.ACTION_STOP -> stop()
}
}
return Service.START_NOT_STICKY
}
private fun stop() {
AudioPlayer.get().stopPlayer()
NotifyManager.get().cancelAll()
}
companion object {
private val TAG = "Service"
fun startCommand(context: Context, action: String) {
val intent = Intent(context, PlayService::class.java)
intent.action = action
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
context.startForegroundService(intent)
}else{
context.startService(intent)
}
} catch (e: Exception) {
e.printStackTrace()
}
}
}
}
package com.ydl.media.audio.manager
import android.content.Context
import android.graphics.Bitmap
import android.os.Build
import android.support.v4.media.MediaMetadataCompat
import android.support.v4.media.session.MediaSessionCompat
import android.support.v4.media.session.PlaybackStateCompat
import com.ydl.media.audio.AudioPlayer
import com.ydl.media.audio.PlayService
import com.ydl.media.audio.model.Music
import com.ydl.media.audio.utils.CoverImageUtils
......@@ -17,7 +17,7 @@ import com.ydl.media.audio.utils.CoverImageUtils
*/
class MediaSessionManager private constructor() {
private var playService: PlayService? = null
private var mContext: Context? = null
private var mediaSession: MediaSessionCompat? = null
private val callback = object : MediaSessionCompat.Callback() {
......@@ -50,22 +50,22 @@ class MediaSessionManager private constructor() {
val instance = MediaSessionManager()
}
fun init(playService: PlayService) {
this.playService = playService
fun init(context: Context) {
this.mContext = context
setupMediaSession()
}
private fun setupMediaSession() {
mediaSession = MediaSessionCompat(playService!!, TAG)
mediaSession!!.setFlags(MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS or MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS)
mediaSession!!.setCallback(callback)
mediaSession!!.isActive = true
mediaSession = MediaSessionCompat(mContext, TAG)
mediaSession?.setFlags(MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS or MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS)
mediaSession?.setCallback(callback)
mediaSession?.isActive = true
}
fun updatePlaybackState() {
val state =
if (AudioPlayer.get().isPlaying || AudioPlayer.get().isPreparing) PlaybackStateCompat.STATE_PLAYING else PlaybackStateCompat.STATE_PAUSED
mediaSession!!.setPlaybackState(
mediaSession?.setPlaybackState(
PlaybackStateCompat.Builder()
.setActions(MEDIA_SESSION_ACTIONS)
.setState(state, AudioPlayer.get().audioPosition, 1f)
......@@ -75,7 +75,7 @@ class MediaSessionManager private constructor() {
fun updateMetaData(music: Music?) {
if (music == null) {
mediaSession!!.setMetadata(null)
mediaSession?.setMetadata(null)
return
}
......@@ -95,7 +95,7 @@ class MediaSessionManager private constructor() {
// TODO: 2019-10-26 by:HaoRui
// metaData.putLong(MediaMetadataCompat.METADATA_KEY_NUM_TRACKS, AppCache.get().getLocalMusicList().size());
}
mediaSession!!.setMetadata(metaData.build())
mediaSession?.setMetadata(metaData.build())
}
})
}
......
......@@ -18,7 +18,6 @@ import android.widget.TextView
import com.bumptech.glide.Glide
import com.bumptech.glide.request.target.NotificationTarget
import com.ydl.media.R
import com.ydl.media.audio.PlayService
import com.ydl.media.audio.constants.Extras
import com.ydl.media.audio.model.Music
import com.ydl.media.audio.receiver.StatusBarReceiver
......@@ -30,32 +29,31 @@ import java.util.*
* Des: 通知管理器
*/
class NotifyManager private constructor() {
private var playService: PlayService? = null
private var mContext: Context? = null
private var notificationManager: NotificationManager? = null
private object SingletonHolder {
val instance = NotifyManager()
}
fun init(playService: PlayService) {
this.playService = playService
fun init(context: Context) {
this.mContext = context
notificationManager =
playService.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
mContext?.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
}
fun showPlay(music: Music?) {
if (music == null) {
return
}
playService?.startForeground(NOTIFICATION_ID, buildNotification(playService!!, music, true))
}
fun showPause(music: Music?) {
if (music == null) {
return
}
playService?.stopForeground(false)
notificationManager?.notify(NOTIFICATION_ID, buildNotification(playService!!, music, false))
notificationManager?.notify(NOTIFICATION_ID,
mContext?.let { buildNotification(it, music, false) })
}
fun cancelAll() {
......@@ -119,7 +117,7 @@ class NotifyManager private constructor() {
remoteViews.setTextViewText(R.id.tv_title, title)
remoteViews.setTextViewText(R.id.tv_subtitle, subtitle)
val isLightNotificationTheme = isLightNotificationTheme(playService)
val isLightNotificationTheme = isLightNotificationTheme(mContext)
val playIntent = Intent(StatusBarReceiver.ACTION_STATUS_BAR)
playIntent.setPackage("com.cxzapp.xinlizixun")
......
......@@ -28,7 +28,7 @@ import okio.BufferedSource;
* Des: 解析框架中的网络请求和响应结果并打印
*/
public class RequestLogInterceptor implements Interceptor {
private DefaultFormatPrinter mPrinter = new DefaultFormatPrinter();
// private DefaultFormatPrinter mPrinter = new DefaultFormatPrinter();
private boolean mIsDebug;
private RequestHandler mRequestHandler;
......@@ -40,18 +40,18 @@ public class RequestLogInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
//打印请求信息
if (request.body() != null && isParseable(request.body().contentType())) {
mPrinter.printJsonRequest(request, parseParams(request));
} else {
mPrinter.printFileRequest(request);
}
if (mRequestHandler != null) {
request = mRequestHandler.onHttpRequestBefore(chain, request);
}
long t1 = System.nanoTime();
//
// //打印请求信息
// if (request.body() != null && isParseable(request.body().contentType())) {
// mPrinter.printJsonRequest(request, parseParams(request));
// } else {
// mPrinter.printFileRequest(request);
// }
//
// if (mRequestHandler != null) {
// request = mRequestHandler.onHttpRequestBefore(chain, request);
// }
// long t1 = System.nanoTime();
Response originalResponse;
try {
originalResponse = chain.proceed(request);
......@@ -59,35 +59,35 @@ public class RequestLogInterceptor implements Interceptor {
NetLogUtils.debugInfo("Http Error: " + e);
throw e;
}
long t2 = System.nanoTime();
// long t2 = System.nanoTime();
ResponseBody responseBody = originalResponse.body();
// ResponseBody responseBody = originalResponse.body();
//打印响应结果
String bodyString = null;
if (responseBody != null && isParseable(responseBody.contentType())) {
bodyString = printResult(request, originalResponse);
if (mRequestHandler != null) {
mRequestHandler.onHttpResultResponse(bodyString, chain, originalResponse);
}
}
if (mIsDebug) {
final List<String> segmentList = request.url().encodedPathSegments();
final String header = originalResponse.headers().toString();
final int code = originalResponse.code();
final boolean isSuccessful = originalResponse.isSuccessful();
final String message = originalResponse.message();
final String url = originalResponse.request().url().toString();
if (responseBody != null && isParseable(responseBody.contentType())) {
mPrinter.printJsonResponse(TimeUnit.NANOSECONDS.toMillis(t2 - t1), isSuccessful,
code, header, responseBody.contentType(), bodyString, segmentList, message, url);
} else {
mPrinter.printFileResponse(TimeUnit.NANOSECONDS.toMillis(t2 - t1),
isSuccessful, code, header, segmentList, message, url);
}
}
// String bodyString = null;
// if (responseBody != null && isParseable(responseBody.contentType())) {
// bodyString = printResult(request, originalResponse);
// if (mRequestHandler != null) {
// mRequestHandler.onHttpResultResponse(bodyString, chain, originalResponse);
// }
// }
//
// if (mIsDebug) {
// final List<String> segmentList = request.url().encodedPathSegments();
// final String header = originalResponse.headers().toString();
// final int code = originalResponse.code();
// final boolean isSuccessful = originalResponse.isSuccessful();
// final String message = originalResponse.message();
// final String url = originalResponse.request().url().toString();
//
// if (responseBody != null && isParseable(responseBody.contentType())) {
// mPrinter.printJsonResponse(TimeUnit.NANOSECONDS.toMillis(t2 - t1), isSuccessful,
// code, header, responseBody.contentType(), bodyString, segmentList, message, url);
// } else {
// mPrinter.printFileResponse(TimeUnit.NANOSECONDS.toMillis(t2 - t1),
// isSuccessful, code, header, segmentList, message, url);
// }
// }
return originalResponse;
}
......
......@@ -4,9 +4,11 @@ import android.content.Context
import com.apm.insight.MonitorCrash
import com.apm.insight.log.VLog
import com.bytedance.apm.insight.ApmInsight
import com.bytedance.apm.insight.ApmInsightAgent
import com.bytedance.apm.insight.ApmInsightInitConfig
import com.bytedance.apm.insight.IDynamicParams
import com.meituan.android.walle.WalleChannelReader
import org.json.JSONObject
object Apm {
......@@ -46,6 +48,33 @@ object Apm {
crash?.reportCustomErr(msg, type, throwable)
}
}
fun reportEvent(event: String, dimension: String, value: String) {
try {
if (hasInit) {
val d = hashMapOf(dimension to value)
ApmInsightAgent.monitorEvent(event, d, hashMapOf())
}
} catch (throwable: Throwable) {
VLog.e("reportEvent", throwable.message)
}
}
fun reportEventWithExt(event: String, dimension: String, value: String, ext: Map<String, String>) {
try {
if (hasInit) {
val d = hashMapOf(dimension to value)
if (ext.isNotEmpty()) {
val json = JSONObject(ext)
ApmInsightAgent.monitorEvent(event, d, hashMapOf(), json)
} else {
ApmInsightAgent.monitorEvent(event, d, hashMapOf())
}
}
} catch (throwable: Throwable) {
VLog.e("reportEvent", throwable.message)
}
}
}
private class ApmParams(val crash: MonitorCrash?, val uidCall: () -> String?) : IDynamicParams() {
......
......@@ -194,16 +194,16 @@ class HttpConfig {
val message = resp.message()
val api = req.url().encodedPath()
if (!resp.isSuccessful) {
Apm.reportCustom("network_request_error", "${api}(${code},${message})", Exception("${api}(${code},${message})"))
Apm.reportEventWithExt("network_api", "resp_fail", api, mapOf("code" to code.toString(), "msg" to message))
} else {
try {
val body = resp.body() ?: return@Interceptor resp
val buffer = body.source().buffer()
if(!isPlaintext(buffer)) return@Interceptor resp
if (!isPlaintext(buffer)) return@Interceptor resp
val readString = buffer.clone().readString(Charset.forName("UTF-8"))
val fromJson = Gson().fromJson<BaseAPIResponse<Any>>(readString, BaseAPIResponse::class.java)
if (fromJson.code != "200" && fromJson.code != "0") {
Apm.reportCustom("network_business_error", "${api}(${fromJson.code},${fromJson.msg})", Exception("${api}(${fromJson.code},${fromJson.msg})"))
Apm.reportEventWithExt("network_api", "business_fail", api, mapOf("code" to code.toString(), "msg" to message))
}
} catch (throwable: Throwable) {
LogUtil.e(throwable.message)
......
package com.ydl.ydlcommon.event
class MeditationFloatEvent(
class MeditationFloatStopEvent(
val show: Boolean,
val stop: Boolean? = null,
val time: Long? = null
......
......@@ -1226,6 +1226,10 @@ public class NewH5Activity extends BaseActivity implements PtrHandler {
}
});
} else {
if (h5Params.getUrl()!=null && h5Params.getUrl().contains("user/payment/detail")){
//付款详情页 付款详情页_返回点击
ActionCountUtils.Companion.count("consult_order_pay_details_page|return_click");
}
if (h5Params.isSplash()) {
WebModularServiceUtils.Companion.startMain(NewH5Activity.this);
finish();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment