package com.yidianling.ydl_pay.pay import android.annotation.SuppressLint import android.app.Activity import android.content.Intent import android.graphics.Point import android.support.v7.app.AlertDialog import android.text.Spannable import android.text.SpannableStringBuilder import android.text.TextUtils import android.text.style.ForegroundColorSpan import android.view.Gravity import android.view.LayoutInflater import android.view.View import com.ydl.ydlcommon.base.BaseActivity import com.ydl.ydlcommon.bean.StatusBarOptions import com.ydl.ydlcommon.data.PlatformDataManager import com.ydl.ydlcommon.data.http.RxUtils import com.ydl.ydlcommon.data.http.ThrowableConsumer import com.ydl.ydlcommon.modular.ModularServiceManager import com.ydl.ydlcommon.utils.log.LogHelper import com.yidianling.common.tools.LogUtil import com.yidianling.common.tools.ToastUtil import com.yidianling.im.api.service.IImService import com.yidianling.ydl_pay.R import com.yidianling.ydl_pay.common.bean.params.AliPayParam import com.yidianling.ydl_pay.common.bean.params.BalanceParam import com.yidianling.ydl_pay.common.bean.params.ChargePayParam import com.yidianling.ydl_pay.common.bean.params.WxPayParam import com.yidianling.ydl_pay.common.http.HttpUtils import com.yidianling.ydl_pay.pay.PayParams.CREATOR.INLET_NORMAL import com.yidianling.ydl_pay.pay.PayParams.CREATOR.INLET_TEST import com.yidianling.ydl_pay.pay.bean.PayStatus import com.yidianling.ydl_pay.pay.bean.RechargeParam import com.yidianling.ydl_pay.pay.bean.TestAddOrderBean import com.yidianling.ydl_pay.pay.bean.WXRechargeIdParam import com.yidianling.ydl_pay.pay.redpacket.RedPacketBean import com.yidianling.ydl_pay.pay.redpacket.RedPacketPayBean import com.yidianling.ydl_pay.pay.redpacket.RedPacketPopWindow import io.reactivex.Observable import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.functions.Consumer import io.reactivex.schedulers.Schedulers import kotlinx.android.synthetic.main.activity_pay.* import kotlinx.android.synthetic.main.pay_fragment_loading_dialog.view.* import java.text.DecimalFormat /** * 付款 * Created by softrice on 15/11/25. * Updated by Zhangwenchao on 18/4/19 * Updated by yuanWai on 18/10/25 rxJava 简直太恶心了(只是界面逻辑重新梳理了一下,理想状态是拆分成两个fragment来做 然后把rxJava替换掉,但是时间不够,先这样吧) */ class PayActivity : BaseActivity() { override fun getStatusViewOptions(): StatusBarOptions { return StatusBarOptions(true, statusBarDarkMode = true) } companion object { /** * 入参 * params 支付订单信息 正常入口传递 * params_redPacket 红包列表数据+支付金额 测评入口传递 */ private const val PARAMS = "params" private const val PARAMS_RED = "params_redPacket" /** * 支付类型 * 1.微信支付 2.支付宝支付 */ private const val PAY_WECHAT = 1 private const val PAY_ALI = 2 //传递订单号 目前除测评入口使用 fun newIntent(activity: Activity, payParams: PayParams): Intent { LogHelper.getInstance().writeLogSync("跳转到支付界面") val intent = Intent(activity, PayActivity::class.java) intent.putExtra(PARAMS, payParams) return intent } //传递红包列表数据 目前只有测评入口使用 这个入口进来的调支付时 会先调订单生成接口--再调微信、支付宝支付(串联的行为) fun newIntent(activity: Activity, redPacketPayBean: RedPacketPayBean): Intent { LogHelper.getInstance().writeLogSync("跳转到支付界面") val intent = Intent(activity, PayActivity::class.java) intent.putExtra(PARAMS_RED, redPacketPayBean) return intent } } //订单信息数据 private var payParams: PayParams? = null //红包列表数据+支付金额 private var redPacketPayBean: RedPacketPayBean? = null //入口 private var inlet = PayParams.INLET_NORMAL //红包列表弹窗 private var redPacketPopWindow: RedPacketPopWindow? = null //加载中弹窗 private var dialog: AlertDialog? = null private var dialogContentView: View? = null //红包id 默认为0 private var redPacketId: String? = "0" //使用红包金额 private var redPacketMoney: Float = 0f //使用红包文案 private var redPacketMoneyContent: String = "" //账户余额 private var balanceMoney: Float = 0f //支付金额 private var payMoney: Float = 0F //可使用余额 private var canBalanceMoney = 0F //支付类型 private var payType = PAY_ALI //测评下单数据bean private var testAddOrderBean: TestAddOrderBean? = null override fun layoutResId(): Int { return R.layout.activity_pay } //获取参数 private fun getParam() { if (null == intent) { return } if (intent.hasExtra(PARAMS)) { //订单信息数据 payParams = intent.getParcelableExtra(PARAMS) if (null != payParams && null != payParams!!.coupon_money && 0f != payParams!!.coupon_money) { inlet = payParams!!.inlet redPacketMoney = payParams!!.coupon_money val sb = StringBuffer() sb.append("-").append("¥").append(numFormat(payParams!!.coupon_money)) redPacketMoneyContent = sb.toString() } } else if (intent.hasExtra(PARAMS_RED)) { //红包列表数据 redPacketPayBean = intent.getParcelableExtra(PARAMS_RED) if (null != redPacketPayBean) { if (null != redPacketPayBean!!.payParams) { inlet = redPacketPayBean!!.payParams.inlet } if (null != redPacketPayBean!!.data && !redPacketPayBean!!.data.isEmpty()) { redPacketMoney = redPacketPayBean!!.data[0].coupon_money!! redPacketId = redPacketPayBean!!.data[0].id val sb = StringBuffer() sb.append("-").append("¥").append(numFormat(redPacketMoney)) redPacketMoneyContent = sb.toString() } } } } override fun initDataAndEvent() { //获取参数 getParam() //界面初始化 initView() //设置是否显示付款保障文案 setPaymentVisible() //设置付款保障文案 setPaymentText() } //初始化界面 private fun initView() { //设置是否显示红包 setRedPacketVisible() when (inlet) { INLET_NORMAL -> { //正常入口 if (null == payParams) { return } //设置类型标题 setTypeTitle(payParams!!.title) //设置支付金额 setTypeMoney(payParams!!.needPay) //底部支付按钮文案 setPayBtnText(payParams!!.btnPayText) if (payParams!!.type == PayParams.RECHARGE) { //界面类型 充值 ll_select_pay.visibility = View.VISIBLE ll_Balance.visibility = View.GONE tvRestPay.text = payParams!!.needPay.toString() //是否显示余额和红包之间 的间隔View isVisibleBalanceTop() } else { //界面类型 付款 //请求余额接口 requestMyBalance() } } INLET_TEST -> { //测评入口 付款 //请求余额接口 requestMyBalance() //设置支付金额 if (null == redPacketPayBean || null == redPacketPayBean!!.payParams) { return } setTypeTitle(redPacketPayBean!!.payParams.title) setTypeMoney(redPacketPayBean!!.payParams.needPay) setPayBtnText(redPacketPayBean!!.payParams.btnPayText) } } //客服 ll_kefu.setOnClickListener { // ModularServiceManager.provide(IMServiceImpl::class.java).startP2PXiaoYi(this) try { ModularServiceManager.provide(IImService::class.java).startP2PXiaoYi(this) } catch (e: Exception) { LogUtil.e(e.message) } } //选择红包 ll_redPacket.setOnClickListener { showRedPacketPopupWindow() } //默认选择微信支付 selectPayType(0) //选择微信支付 ll_wechat.setOnClickListener { selectPayType(0) } //选择支付宝支付 ll_alipay.setOnClickListener { selectPayType(1) } //去支付 rcb_pay.setOnClickListener { onClickPay() } } /** * 设置标题 */ private fun setTypeTitle(title: String) { tvType.text = title } /** * 设置支付金额 */ private fun setTypeMoney(needPay: Float) { val sb = StringBuffer() sb.append("¥").append(numFormat(needPay)) tvTypeMoney.text = sb.toString() } /** * 设置是否显示红包 */ private fun setRedPacketVisible() { if (TextUtils.isEmpty(redPacketMoneyContent)) { ll_redPacket.visibility = View.GONE } else { //如果 为 正常入口 且 有红包数额 那么说明 该订单 已锁定 就不能更改红包 故隐藏箭头 if (inlet == INLET_NORMAL) { tvRedPacketMore.visibility = View.GONE } else { tvRedPacketMore.visibility = View.VISIBLE } ll_redPacket.visibility = View.VISIBLE } } /** * 设置支付按钮文本 */ private fun setPayBtnText(text: String) { rcb_pay.text = text } /** * 请求账户余额接口 */ @SuppressLint("CheckResult") private fun requestMyBalance() { HttpUtils.getMyBalance(BalanceParam()) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .doOnSubscribe { showProgressDialog() } .doAfterTerminate { dismissProgressDialog() } .subscribe(Consumer { setData(it.data.balance) LogHelper.getInstance().writeLogSync( // "付款界面信息:金额 = " + payParams!!.needPay + // ", id = " + payParams!!.payId + // ", 类型 = " + payParams!!.title + "余额 = " + it.data.balance ) }, object : ThrowableConsumer() { override fun accept(msg: String) { ToastUtil.toastShort(msg) } }) } /** * 设置 是否显示付款保障文案 */ private fun setPaymentVisible() { when (inlet) { INLET_NORMAL -> { //正常入口 //设置是否显示付款保障 if (null != payParams && payParams!!.visibleIndemnity) { tv_hint_title.visibility = View.VISIBLE tv_hint_content.visibility = View.VISIBLE } } INLET_TEST -> { //测评入口 //设置是否显示付款保障 if (null != redPacketPayBean && redPacketPayBean!!.payParams.visibleIndemnity) { tv_hint_title.visibility = View.VISIBLE tv_hint_content.visibility = View.VISIBLE } } } } /** * 设置付款保障文案 */ private fun setPaymentText() { val globalInfo = PlatformDataManager.getRam().getGlobalInfo() if (globalInfo != null) { tv_hint_title.text = globalInfo.info.pay_notice.title tv_hint_content.text = globalInfo.info.pay_notice.content.replace("<br>", "\n") } } private var select = 0 private fun selectPayType(i: Int) { if (select == i) return select = i when (i) { 0 -> { iv_wechat.setImageResource(R.drawable.pay_img_select) iv_alipay.setImageResource(R.drawable.pay_img_no_select) payType = PAY_WECHAT } 1 -> { iv_alipay.setImageResource(R.drawable.pay_img_select) iv_wechat.setImageResource(R.drawable.pay_img_no_select) payType = PAY_ALI } } } /** * 设置余额 * @param balance 账户余额 */ private fun setData(balance: Float) { this.balanceMoney = balance when (inlet) { INLET_NORMAL -> { //正常入口 if (null == payParams) { return } //如果没有红包 并且 没有余额 那么隐藏掉这条线 if (0F == balance && TextUtils.isEmpty(redPacketMoneyContent)) { v_redPacketAndBalance.visibility = View.GONE } else { v_redPacketAndBalance.visibility = View.VISIBLE } resetPayMoney() } INLET_TEST -> { //测评入口 if (null == redPacketPayBean) { return } resetPayMoney() } } } /** * 重新计算 红包优惠 使用余额 还需支付 */ private fun resetPayMoney() { //设置红包文案 tvRedPacketMoney.text = redPacketMoneyContent //如果 可使用的余额 大于 付款金额 - 红包金额 when (inlet) { INLET_NORMAL -> { //正常入口 //如果 有红包 说明 是待支付过来的 if (redPacketMoney > 0) { calculation(payParams!!.needPay) } else { if (balanceMoney > payParams!!.needPay) { //可使用余额 = 付款金额 canBalanceMoney = payParams!!.needPay payMoney = 0F ll_select_pay.visibility = View.GONE } else { canBalanceMoney = balanceMoney payMoney = payParams!!.needPay - balanceMoney ll_select_pay.visibility = View.VISIBLE } } } INLET_TEST -> { //测评入口 calculation(redPacketPayBean?.payParams!!.needPay) } } //如果没有可用余额 则隐藏 if (balanceMoney == 0f) { ll_Balance.visibility = View.GONE } else { ll_Balance.visibility = View.VISIBLE } //设置 使用余额(可用¥X.XX) val balanceBuffer = StringBuffer() balanceBuffer.append("使用余额(可用¥").append(balanceMoney).append(")") val balanceBuilder = SpannableStringBuilder(balanceBuffer.toString()) balanceBuilder.setSpan( ForegroundColorSpan(resources.getColor(R.color.platform_color_999999)), 4, balanceBuffer.toString().length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE ) tvBalanceTitle.text = balanceBuilder //设置 可用余额 val useBalanceBuffer = StringBuffer() useBalanceBuffer.append("-¥").append(numFormat(canBalanceMoney)) tvUseBalance.text = useBalanceBuffer.toString() //设置 还需支付 tvRestPay.text = numFormat(payMoney) //如果没有可用余额 并且 没有红包 则隐藏还需支付 if (balanceMoney == 0F && (null == redPacketPayBean || null == redPacketPayBean!!.data || redPacketPayBean!!.data.isEmpty())) { rl_RestPay.visibility = View.GONE } else { rl_RestPay.visibility = View.VISIBLE } //是否显示余额和红包之间 的间隔View isVisibleBalanceTop() //设置 底部支付按钮文案 val payBuffer = StringBuffer() payBuffer.append("(¥").append(numFormat(payMoney)).append(")确认付款") setPayBtnText(payBuffer.toString()) } private fun isVisibleBalanceTop() { if (ll_redPacket.visibility == View.GONE && ll_Balance.visibility == View.GONE) { v_balanceTop.visibility = View.GONE } else { v_balanceTop.visibility = View.VISIBLE } } /** * 计算可使用余额 */ private fun calculation(needPay: Float) { when { redPacketMoney >= needPay -> { //如果红包金额 大于等于 付款金额 canBalanceMoney = 0F payMoney = 0F ll_select_pay.visibility = View.GONE } balanceMoney > needPay - redPacketMoney -> { //可使用余额 = 付款金额 - 使用的红包金额 canBalanceMoney = needPay - redPacketMoney payMoney = 0F ll_select_pay.visibility = View.GONE } else -> { canBalanceMoney = balanceMoney payMoney = needPay - redPacketMoney - balanceMoney ll_select_pay.visibility = View.VISIBLE } } } /** * 显示红包弹窗 */ private fun showRedPacketPopupWindow() { if (null == redPacketPayBean || null == redPacketPayBean!!.data || redPacketPayBean!!.data.isEmpty()) { return } if (null == redPacketPopWindow) { redPacketPopWindow = RedPacketPopWindow( PayActivity@ this, redPacketPayBean!!.data, object : RedPacketPopWindow.OnSelectListener { override fun select(bean: RedPacketBean?) { val sb = StringBuffer() if (null == bean) { sb.append(redPacketPayBean!!.data.size).append("个可用") redPacketId = "0" redPacketMoney = 0F } else { sb.append("-").append("¥").append(numFormat(bean.coupon_money!!)) redPacketId = bean.id redPacketMoney = bean.coupon_money } redPacketMoneyContent = sb.toString() resetPayMoney() } }) } else { redPacketPopWindow!!.bindData() } redPacketPopWindow!!.showBottom(rcb_pay) } /** * 格式化价格 */ private fun numFormat(money: Float): String { val decimalFormat = DecimalFormat("0.00")//构造方法的字符格式这里如果小数不足2位,会以0补足. return decimalFormat.format(money) } /** * 隐藏红包弹窗 */ private fun hideRedPacketPopupWindow() { if (null != redPacketPopWindow) { redPacketPopWindow!!.dismiss() } } /** * 点击支付 */ private fun onClickPay() { when (inlet) { INLET_NORMAL -> { //正常入口 if (null == payParams) { return } when (payParams!!.type) { PayParams.RECHARGE -> { //充值 recharge() } PayParams.PAY -> { //付款 choicePayment() } } } INLET_TEST -> { //测评入口 addOrder() } } } //选择支付方式 private fun choicePayment() { //支付金额为0 说明都抵扣了或者订单金额为0 使用余额支付 if (payMoney == 0F) { balancePay() } else { //使用微信 支付宝 支付 appPay() } } //测评下单 private fun addOrder() { // if (null == redPacketPayBean || null == redPacketPayBean!!.payParams) { // return // } // YdlDataManager.getHttp().addOrder(AddOrderParam(redPacketPayBean!!.payParams.payId, redPacketId!!)) // .compose(RxUtils.resultData()) // .observeOn(AndroidSchedulers.mainThread()) // .doOnSubscribe { showProgressDialog() } // .doAfterTerminate { dismissProgressDialog() } // .subscribe(Consumer { // testAddOrderBean = it // LogHelper.getInstance().writeLogSync("测评下单成功") // choicePayment() // }, object : ThrowableConsumer() { // override fun accept(msg: String) { // ToastUtil.toastShort(msg) // LogHelper.getInstance().writeLogSync("测评下单失败:$msg") // } // }) } var rechargeId: String? = null // 充值 @SuppressLint("CheckResult") private fun recharge() { if (null == payParams) { return } HttpUtils.recharge(RechargeParam(payParams!!.needPay.toInt().toString())) .subscribeOn(Schedulers.io()) .flatMap { rechargeId = it.data.rechargeId when (select) { 0 -> HttpUtils.wxRecharge(WXRechargeIdParam(it.data.rechargeId)) .compose(RxUtils.resultData()) .observeOn(AndroidSchedulers.mainThread()) .doOnNext { dismissProgressDialog() } .flatMap { RxPay.wxPay(this, it.option) } else -> RxPay.aliPay(this, it.data.aliSign) } } .observeOn(AndroidSchedulers.mainThread()) .doOnSubscribe { showProgressDialog("") } .doAfterTerminate { dismissProgressDialog() } .subscribe(Consumer { LogHelper.getInstance().writeLogSync("支付成功") ToastUtil.toastShort("支付成功") var intent = Intent() intent.putExtra("rechargeId", rechargeId) setResult(Activity.RESULT_OK, intent) finish() }, object : ThrowableConsumer() { override fun accept(msg: String) { ToastUtil.toastShort(msg) LogHelper.getInstance().writeLogSync("支付失败$msg") } }) } // 余额支付 private fun balancePay() { when (inlet) { INLET_NORMAL -> { //正常入口 balancePayById(payParams!!.payId) } INLET_TEST -> { //测评入口 balancePayById(testAddOrderBean!!.payId!!) } else -> { balancePayById(payParams!!.payId) } } } /** * 余额支付 * @param payId 支付Id */ @SuppressLint("CheckResult") private fun balancePayById(payId: String) { var bean = ChargePayParam() bean.payId = payId HttpUtils.payByCharge(bean) .compose(RxUtils.resultData()) .subscribeOn(Schedulers.newThread()) .observeOn(AndroidSchedulers.mainThread()) .doOnSubscribe { showProgressDialog() } .doAfterTerminate { dismissProgressDialog() } .subscribe(Consumer { LogHelper.getInstance().writeLogSync("支付成功") ToastUtil.toastShort("支付成功") setResult(Activity.RESULT_OK) finish() }, object : ThrowableConsumer() { override fun accept(msg: String) { ToastUtil.toastShort(msg) LogHelper.getInstance().writeLogSync("支付失败:$msg") } }) } /** * app 支付,微信或支付宝 */ @SuppressLint("CheckResult") private fun appPay() { Observable.just(select) .subscribeOn(Schedulers.io()) .flatMap { when (it) { 0 -> { wxPay() } else -> { aliPay() } } } .observeOn(AndroidSchedulers.mainThread()) .doOnSubscribe { showProgressDialog("") } .doAfterTerminate { dismissProgressDialog() } .subscribe(Consumer { LogHelper.getInstance().writeLogSync("支付成功") setResult(Activity.RESULT_OK) finish() }, object : ThrowableConsumer() { override fun accept(msg: String) { ToastUtil.toastShort(msg) LogHelper.getInstance().writeLogSync("支付失败:$msg") } }) } /** * 微信支付 */ private fun wxPay(): Observable<PayStatus>? { return when (inlet) { INLET_NORMAL -> { //正常入口 wxPayById(payParams!!.payId,payParams?.merchantType.toString()) } INLET_TEST -> { //测评入口 if (null != testAddOrderBean && !TextUtils.isEmpty(testAddOrderBean!!.payId!!)) { wxPayById(testAddOrderBean!!.payId!!,payParams?.merchantType.toString()) } else { null } } else -> { wxPayById(payParams!!.payId,payParams?.merchantType.toString()) } } } /** * 微信支付 * @param payId 支付id */ private fun wxPayById(payId: String,merchantType:String): Observable<PayStatus> { val bean = WxPayParam(payId, 1,merchantType) return HttpUtils.wxPay(bean) .compose(RxUtils.resultData()) .observeOn(AndroidSchedulers.mainThread()) .doOnNext { dismissProgressDialog() } .flatMap { RxPay.wxPay(this, it.option) } } /** * 支付宝支付 */ private fun aliPay(): Observable<PayStatus>? { return when (inlet) { INLET_NORMAL -> { //正常入口 aliPayById(payParams!!.payId) } INLET_TEST -> { //测评入口 if (null != testAddOrderBean && !TextUtils.isEmpty(testAddOrderBean!!.payId!!)) { aliPayById(testAddOrderBean!!.payId!!) } else { null } } else -> { aliPayById(payParams!!.payId) } } } /** * 支付宝支付 * @param payId 支付Id */ private fun aliPayById(payId: String): Observable<PayStatus> { var bean = AliPayParam(payId, 1) return HttpUtils.getAliPayOrderId(bean) .compose(RxUtils.resultData()) .flatMap { when (inlet) { INLET_NORMAL -> { RxPay.aliPay(this, it.aliSign) } INLET_TEST -> { RxPay.aliPay(this, it.aliSign) } else -> { RxPay.aliPay(this, it.aliSign) } } } } /** * 显示加载中弹窗 */ override fun showProgressDialog(str: String?) { if (dialog != null && dialog!!.isShowing) { return } if (dialog == null) { dialog = AlertDialog.Builder(PayActivity@ this) .create() } if (dialogContentView == null) { dialogContentView = LayoutInflater.from(this).inflate(R.layout.pay_fragment_loading_dialog, null) dialogContentView?.tvMsg?.visibility = View.GONE } dialog?.show() dialog?.window?.setContentView(dialogContentView) dialog?.window?.setGravity(Gravity.CENTER) val p = dialog?.window!!.attributes //获取对话框当前的参数值 var point = Point() windowManager.defaultDisplay.getSize(point)// 获取屏幕宽、高用 p.height = (point.y * 0.2).toInt() p.width = (point.x * 0.35).toInt() dialog?.window!!.attributes = p //设置生效 } /** * 隐藏加载中弹窗 */ override fun dismissProgressDialog() { if (dialog != null && dialog!!.isShowing) { dialog!!.dismiss() } } override fun onDestroy() { super.onDestroy() hideRedPacketPopupWindow() } }