@@ -0,0 +1,75 @@ | |||
package com.huntersun.vkyes.etcopencard.project.api.bean; | |||
/** | |||
* 设备注销支付二维码响应数据 | |||
*/ | |||
public class DeviceCancelQrCodeResponse { | |||
private int code; | |||
private DeviceCancelQrCodeData data; | |||
private String message; | |||
public DeviceCancelQrCodeResponse() { | |||
} | |||
public DeviceCancelQrCodeResponse(int code, DeviceCancelQrCodeData data, String message) { | |||
this.code = code; | |||
this.data = data; | |||
this.message = message; | |||
} | |||
public int getCode() { | |||
return code; | |||
} | |||
public void setCode(int code) { | |||
this.code = code; | |||
} | |||
public DeviceCancelQrCodeData getData() { | |||
return data; | |||
} | |||
public void setData(DeviceCancelQrCodeData data) { | |||
this.data = data; | |||
} | |||
public String getMessage() { | |||
return message; | |||
} | |||
public void setMessage(String message) { | |||
this.message = message; | |||
} | |||
/** | |||
* 设备注销支付二维码数据 | |||
*/ | |||
public static class DeviceCancelQrCodeData { | |||
private long amount; // 订单金额,单位:分 | |||
private String qrbase64; // 二维码Base64编码 | |||
public DeviceCancelQrCodeData() { | |||
} | |||
public DeviceCancelQrCodeData(long amount, String qrbase64) { | |||
this.amount = amount; | |||
this.qrbase64 = qrbase64; | |||
} | |||
public long getAmount() { | |||
return amount; | |||
} | |||
public void setAmount(long amount) { | |||
this.amount = amount; | |||
} | |||
public String getQrbase64() { | |||
return qrbase64; | |||
} | |||
public void setQrbase64(String qrbase64) { | |||
this.qrbase64 = qrbase64; | |||
} | |||
} | |||
} |
@@ -334,6 +334,7 @@ public class IFCode { | |||
public static final String IFCODE_DEVICE_CANCEL_QUERY = "iaw/deviceCancel/query";//设备注销条件查询 | |||
public static final String IFCODE_VEHICLE_QUERY_DEVICE = "iaw/api/vehicleInfo/queryDevice";//查看车辆设备(卡、签、人信息) | |||
public static final String IFCODE_DEVICE_CANCEL_APPLY = "iaw/api/deviceCancel/apply";//设备注销申请 | |||
public static final String IFCODE_DEVICE_CANCEL_GET_QR_CODE = "iaw/deviceCancel/getQrCode";//获取设备注销支付二维码 | |||
public static final String IFCODE_DIVICE_CANCLE_REFUNDINFO_PAGE = "iaw/api/refundInfo/page";// 分页查询车辆注销退费信息 | |||
public static final String IFCODE_DIVICE_CANCLE_REFUNDINFO_ADDORUPDATE = "iaw/api/refundInfo/addOrUpdate";// 增加修改退费账号 | |||
@@ -32,13 +32,15 @@ import retrofit2.Response; | |||
/** | |||
* Date :2023-03-16 | |||
* Description:ETC注销 -支付二维码(暂无用) | |||
* Description:ETC注销 -支付二维码 | |||
*/ | |||
@Deprecated | |||
public class LogoutEtcPayActivity extends AppActivity { | |||
private ActivityLogoutEtcPayBinding binding; | |||
private ResultBean.BizContent curBizContent; | |||
private long amount = 0; // 支付金额(分) | |||
private String qrBase64 = ""; // 二维码Base64数据 | |||
private String orderNo = ""; // 订单号 | |||
@Override | |||
protected View getLayoutView() { | |||
@@ -48,12 +50,20 @@ public class LogoutEtcPayActivity extends AppActivity { | |||
@Override | |||
protected void initView() { | |||
// 接收传递的参数 | |||
String dataJson = getIntent().getStringExtra("dataJson"); | |||
if (!FunHelper.isEmpty(dataJson)) { | |||
curBizContent = JSON.parseObject(dataJson, ResultBean.BizContent.class); | |||
} | |||
amount = getIntent().getLongExtra("amount", 0); | |||
qrBase64 = getIntent().getStringExtra("qrBase64"); | |||
orderNo = getIntent().getStringExtra("orderNo"); | |||
binding.text.setText("¥ " + (Integer.parseInt(FunHelper.isEmpty(curBizContent.getAmount()) ? "0" : curBizContent.getAmount()) * 0.01)); | |||
// 显示支付金额 | |||
String amountText = "¥ " + FunHelper.getPriceWith2Num(Double.parseDouble(FunHelper.changeF2Y(amount))); | |||
binding.text.setText(amountText); | |||
binding.paid.setOnClickListener(new View.OnClickListener() { | |||
@Override | |||
public void onClick(View view) { | |||
@@ -64,85 +74,64 @@ public class LogoutEtcPayActivity extends AppActivity { | |||
@Override | |||
protected void initData() { | |||
getPayCode(); | |||
showQrCode(); | |||
} | |||
/** | |||
* 获取支付二维码 | |||
* 显示支付二维码 | |||
*/ | |||
private void getPayCode() { | |||
FatherBean<SendTheVerificationCodeBean> fatherBean = new FatherBean<>(); | |||
fatherBean.bizContent = new SendTheVerificationCodeBean(); | |||
fatherBean.bizContent.setCardId(""); //储值卡编号 | |||
fatherBean.bizContent.setOrderNum(""); //充值单编号 | |||
fatherBean.bizContent.setBody("储值卡充值"); | |||
fatherBean.bizContent.setPayConfigId(Constants.PAY_CONFIG_ID); //支付配置编号 | |||
MyRetrofit.newInstanceGZ(this, IFCode.IFCODE811, fatherBean.bizContent, new MyRetrofit.ReturnResult() { | |||
@SuppressLint("SetTextI18n") | |||
@Override | |||
public void onSuccess(ResultBean resultBean, ResultBean.BizContent bizContent) { | |||
hideDialog(); | |||
//二维码生成 | |||
Bitmap bitmap = QRCode.createQRCodeBitmap(bizContent.getCodeUrl(), 800, 800, | |||
private void showQrCode() { | |||
if (!FunHelper.isEmpty(qrBase64)) { | |||
try { | |||
// 首先尝试将Base64解码为图片 | |||
byte[] decodedBytes = android.util.Base64.decode(qrBase64, android.util.Base64.DEFAULT); | |||
Bitmap bitmap = android.graphics.BitmapFactory.decodeByteArray(decodedBytes, 0, decodedBytes.length); | |||
if (bitmap != null) { | |||
// 如果成功解码为图片,直接显示 | |||
Drawable drawable = new BitmapDrawable(bitmap); | |||
binding.image.setImageDrawable(drawable); | |||
} else { | |||
// 如果解码失败,将qrBase64作为二维码内容生成二维码 | |||
Bitmap qrBitmap = QRCode.createQRCodeBitmap(qrBase64, 800, 800, | |||
"UTF-8", "H", "1", Color.BLACK, Color.WHITE); | |||
Drawable qrDrawable = new BitmapDrawable(qrBitmap); | |||
binding.image.setImageDrawable(qrDrawable); | |||
} | |||
} catch (Exception e) { | |||
e.printStackTrace(); | |||
// 如果Base64解析失败,尝试直接使用qrBase64作为二维码内容 | |||
Bitmap bitmap = QRCode.createQRCodeBitmap(qrBase64, 800, 800, | |||
"UTF-8", "H", "1", Color.BLACK, Color.WHITE); | |||
Drawable drawable = new BitmapDrawable(bitmap); | |||
binding.image.setImageDrawable(drawable); | |||
try { | |||
binding.text.setText("¥ " + (Double.valueOf(bizContent.getTotalFee()) * 0.01)); | |||
} catch (Exception ignored) { | |||
} | |||
} | |||
}); | |||
} else { | |||
// 如果没有二维码数据,显示提示 | |||
binding.image.setImageResource(R.mipmap.icon_lotgout_etc_hint); | |||
} | |||
} | |||
/** | |||
* 支付 | |||
* 支付状态检查 | |||
*/ | |||
private void pay() { | |||
binding.paid.setEnabled(false); | |||
// 使用原有的储值卡充值-查询支付结果接口 | |||
FatherBean<SendTheVerificationCodeBean> fatherBean = new FatherBean<>(); | |||
fatherBean.bizContent = new SendTheVerificationCodeBean(); | |||
fatherBean.bizContent.setOrderNum(""); | |||
fatherBean.bizContent.setCardId(""); | |||
fatherBean.bizContent.setPayConfigId(Constants.PAY_CONFIG_ID); //支付配置编号 | |||
binding.paid.setEnabled(false); | |||
//储值卡充值-查询支付结果 | |||
fatherBean.bizContent.setOrderNum(orderNo); // 使用订单号 | |||
fatherBean.bizContent.setCardId(""); // 储值卡编号(设备注销可能不需要) | |||
fatherBean.bizContent.setPayConfigId(Constants.PAY_CONFIG_ID); // 支付配置编号 | |||
// 储值卡充值-查询支付结果 | |||
MyRetrofit.newInstanceGZ(this, IFCode.IFCODE812, fatherBean.bizContent, new MyRetrofit.ReturnResult() { | |||
@Override | |||
public void onSuccess(ResultBean resultBean, ResultBean.BizContent bizContent) { | |||
hideDialog(); | |||
binding.paid.setEnabled(true); | |||
String msg = ""; | |||
switch (bizContent.getTradeState()) { | |||
case "SUCCESS": //支付成功 | |||
toast("支付成功!"); | |||
Bundle bundle = new Bundle(); | |||
bundle.putString("from", "1"); | |||
jumpToPage(CommonDealSuccessActivity.class, bundle); | |||
finish(); | |||
break; | |||
case "PAYING": //支付中 | |||
msg = "订单支付中..."; | |||
break; | |||
case "FAILED": //支付失败 | |||
msg = "支付失败"; | |||
break; | |||
case "UNPAY": //未支付 | |||
msg = "用户还未完成支付"; | |||
break; | |||
case "CLOSED": //已关闭 | |||
msg = "已关闭"; | |||
break; | |||
case "CANCELED": //已撤销 | |||
msg = "支付已取消"; | |||
break; | |||
case "REFUND": //转入退费 | |||
msg = "转入退费"; | |||
break; | |||
} | |||
if (!Objects.equals(bizContent.getTradeState(), "SUCCESS")) { | |||
new Utils().showMessDialog(getActivity(), msg, dialog -> { | |||
}); | |||
} | |||
handlePaymentStatus(bizContent.getTradeState()); | |||
} | |||
@Override | |||
@@ -152,4 +141,42 @@ public class LogoutEtcPayActivity extends AppActivity { | |||
} | |||
}); | |||
} | |||
/** | |||
* 处理支付状态 | |||
*/ | |||
private void handlePaymentStatus(String tradeState) { | |||
String msg = ""; | |||
switch (tradeState) { | |||
case "SUCCESS": //支付成功 | |||
toast("支付成功!"); | |||
Bundle bundle = new Bundle(); | |||
bundle.putString("from", "1"); | |||
jumpToPage(CommonDealSuccessActivity.class, bundle); | |||
finish(); | |||
break; | |||
case "PAYING": //支付中 | |||
msg = "订单支付中..."; | |||
break; | |||
case "FAILED": //支付失败 | |||
msg = "支付失败"; | |||
break; | |||
case "UNPAY": //未支付 | |||
msg = "用户还未完成支付"; | |||
break; | |||
case "CLOSED": //已关闭 | |||
msg = "已关闭"; | |||
break; | |||
case "CANCELED": //已撤销 | |||
msg = "支付已取消"; | |||
break; | |||
case "REFUND": //转入退费 | |||
msg = "转入退费"; | |||
break; | |||
} | |||
if (!Objects.equals(tradeState, "SUCCESS")) { | |||
new Utils().showMessDialog(getActivity(), msg, dialog -> { | |||
}); | |||
} | |||
} | |||
} |
@@ -51,6 +51,9 @@ public class LogoutEtcStep1Activity extends AppActivity { | |||
// 搜索工具 | |||
private SearchCarInfoUtils searchCarInfoUtils; | |||
// 注销条件查询结果 | |||
private DeviceCancelQueryResponse.DeviceCancelQueryData cancelQueryData; | |||
@Override | |||
protected View getLayoutView() { | |||
@@ -219,6 +222,9 @@ public class LogoutEtcStep1Activity extends AppActivity { | |||
private void showCancelConditionDialog(DeviceCancelQueryResponse.DeviceCancelQueryData data) { | |||
LogUtils.i("注销条件弹窗", "开始显示弹窗,数据: " + new Gson().toJson(data)); | |||
// 保存注销条件查询结果 | |||
this.cancelQueryData = data; | |||
// 构建弹窗内容 | |||
StringBuilder content = new StringBuilder(); | |||
content.append("产品名称:").append(data.getProductName()).append("\n"); | |||
@@ -278,6 +284,14 @@ public class LogoutEtcStep1Activity extends AppActivity { | |||
// 跳转到ETC注销第二步界面 | |||
Intent intent = new Intent(this, LogoutEtcStep2Activity.class); | |||
intent.putExtra("dataJson", dataJson); | |||
// 传递违约金信息(从注销条件查询结果中获取) | |||
if (cancelQueryData != null) { | |||
intent.putExtra("cancelAmount", cancelQueryData.getCancelAmount()); | |||
intent.putExtra("needPayment", cancelQueryData.isCancel()); | |||
LogUtils.i("跳转第二步", "传递违约金信息 - 金额: " + cancelQueryData.getCancelAmount() + "分, 需要支付: " + cancelQueryData.isCancel()); | |||
} | |||
startActivity(intent); | |||
} catch (Exception e) { | |||
LogUtils.e("跳转第二步", "跳转异常: " + e.getMessage()); |
@@ -14,9 +14,11 @@ import com.alibaba.fastjson.JSON; | |||
import com.alibaba.fastjson.JSONObject; | |||
import com.google.gson.Gson; | |||
import com.blankj.utilcode.util.LogUtils; | |||
import com.hjq.toast.ToastUtils; | |||
import com.huntersun.vkyes.etcopencard.BuildConfig; | |||
import com.huntersun.vkyes.etcopencard.R; | |||
import com.huntersun.vkyes.etcopencard.databinding.ActivityLogoutEtcStep2Binding; | |||
import com.huntersun.vkyes.etcopencard.src.other.AppConfig; | |||
import com.huntersun.vkyes.etcopencard.project.api.Api; | |||
import com.huntersun.vkyes.etcopencard.project.api.Converter; | |||
import com.huntersun.vkyes.etcopencard.project.api.MyRetrofit; | |||
@@ -288,6 +290,10 @@ public class LogoutEtcStep2Activity extends AppActivity { | |||
intent.putExtra("userName", curBizContent.getName()); | |||
intent.putExtra("vehicleId", curBizContent.getVehicleId()); | |||
// 传递违约金信息 | |||
intent.putExtra("cancelAmount", getIntent().getLongExtra("cancelAmount", 0)); | |||
intent.putExtra("needPayment", getIntent().getBooleanExtra("needPayment", false)); | |||
startActivity(intent); | |||
}else {//储值卡 | |||
Intent intent = new Intent(LogoutEtcStep2Activity.this,LogOffBackFeeInfoListActivity.class); | |||
@@ -319,6 +325,10 @@ public class LogoutEtcStep2Activity extends AppActivity { | |||
intent.putExtra("userName", curBizContent.getName()); | |||
intent.putExtra("vehicleId", curBizContent.getVehicleId()); | |||
// 传递违约金信息 | |||
intent.putExtra("cancelAmount", getIntent().getLongExtra("cancelAmount", 0)); | |||
intent.putExtra("needPayment", getIntent().getBooleanExtra("needPayment", false)); | |||
startActivity(intent); | |||
} | |||
} |
@@ -4,6 +4,10 @@ import androidx.appcompat.app.AppCompatActivity; | |||
import androidx.core.widget.NestedScrollView; | |||
import android.content.Intent; | |||
import android.graphics.Bitmap; | |||
import android.graphics.Color; | |||
import android.graphics.drawable.BitmapDrawable; | |||
import android.graphics.drawable.Drawable; | |||
import android.os.Bundle; | |||
import android.util.Log; | |||
import android.view.View; | |||
@@ -20,11 +24,13 @@ import com.huntersun.vkyes.etcopencard.project.api.bean.EnumBean; | |||
import com.huntersun.vkyes.etcopencard.project.api.bean.IFCode; | |||
import com.huntersun.vkyes.etcopencard.project.api.bean.ResultBean; | |||
import com.huntersun.vkyes.etcopencard.project.api.bean.SendTheVerificationCodeBean; | |||
import com.huntersun.vkyes.etcopencard.project.api.bean.DeviceCancelQrCodeResponse; | |||
import com.huntersun.vkyes.etcopencard.project.bluetooth.BluetoothWriteCardWriteTab; | |||
import com.huntersun.vkyes.etcopencard.project.dialog.ConfirmDialog; | |||
import com.huntersun.vkyes.etcopencard.project.tool.MyShared; | |||
import com.huntersun.vkyes.etcopencard.project.utils.Constants; | |||
import com.huntersun.vkyes.etcopencard.project.tool.Utils; | |||
import com.huntersun.vkyes.etcopencard.project.tool.QRCode; | |||
import com.huntersun.vkyes.etcopencard.project.utils.FunHelper; | |||
import com.huntersun.vkyes.etcopencard.src.aop.SingleClick; | |||
import com.huntersun.vkyes.etcopencard.src.app.AppActivity; | |||
@@ -82,6 +88,11 @@ public class LogoutEtcStep3Activity extends AppActivity { | |||
private String customerId; | |||
private String userName; | |||
private String vehicleId; | |||
// 违约金相关 | |||
private long cancelAmount = 0; // 违约金金额(分) | |||
private String orderNo = ""; // 订单号 | |||
private boolean needPayment = false; // 是否需要支付违约金 | |||
@Override | |||
protected View getLayoutView() { | |||
@@ -120,6 +131,10 @@ public class LogoutEtcStep3Activity extends AppActivity { | |||
userName = getIntent().getStringExtra("userName"); | |||
vehicleId = getIntent().getStringExtra("vehicleId"); | |||
// 接收违约金信息 | |||
cancelAmount = getIntent().getLongExtra("cancelAmount", 0); | |||
needPayment = getIntent().getBooleanExtra("needPayment", false); | |||
curBizContent = JSONObject.parseObject(getIntent().getStringExtra("content"), ResultBean.BizContent.class); | |||
} catch (JsonParseException e) { | |||
// toast("json数据加载错误"); | |||
@@ -350,7 +365,21 @@ public class LogoutEtcStep3Activity extends AppActivity { | |||
@Override | |||
public void onSuccess(ResultBean resultBean, ResultBean.BizContent bizContent) { | |||
Log.i(this.getClass().getSimpleName(), "设备注销申请 响应数据:" + JSONObject.toJSONString(resultBean)); | |||
confirmLogoutEtc(0); | |||
// 解析响应数据,获取订单号 | |||
if (resultBean.getData() != null) { | |||
try { | |||
String dataStr = JSONObject.toJSONString(resultBean.getData()); | |||
JSONObject dataObj = JSONObject.parseObject(dataStr); | |||
orderNo = dataObj.getString("orderNo"); | |||
Log.i(this.getClass().getSimpleName(), "获取到订单号: " + orderNo); | |||
} catch (Exception e) { | |||
Log.e(this.getClass().getSimpleName(), "解析订单号失败: " + e.getMessage()); | |||
} | |||
} | |||
// 检查是否需要支付违约金 | |||
checkPenaltyPayment(); | |||
} | |||
@Override | |||
@@ -398,6 +427,110 @@ public class LogoutEtcStep3Activity extends AppActivity { | |||
} | |||
/** | |||
* 检查是否需要支付违约金 | |||
*/ | |||
private void checkPenaltyPayment() { | |||
// 使用从Step1传递过来的违约金信息 | |||
Log.i(this.getClass().getSimpleName(), "违约金检查 - 金额: " + cancelAmount + "分, 需要支付: " + needPayment); | |||
if (needPayment && cancelAmount > 0) { | |||
// 需要支付违约金,获取支付二维码 | |||
getPaymentQrCode(); | |||
} else { | |||
// 不需要支付违约金,直接完成注销 | |||
confirmLogoutEtc(0); | |||
} | |||
} | |||
/** | |||
* 获取支付二维码 | |||
*/ | |||
private void getPaymentQrCode() { | |||
if (FunHelper.isEmpty(orderNo)) { | |||
Log.e(this.getClass().getSimpleName(), "订单号为空,无法获取支付二维码"); | |||
ToastUtils.show("订单号为空,无法获取支付二维码"); | |||
return; | |||
} | |||
showDialog("获取支付二维码中..."); | |||
HashMap<String, Object> params = new HashMap<>(); | |||
params.put("accessToken", MyShared.getInstance().get(MyShared.ACCESSTOKEN, "")); | |||
params.put("loginSource", Constants.LOGIN_SOURCE); | |||
params.put("orderNo", orderNo); | |||
params.put("staffId", MyShared.getInstance().get(MyShared.STAFFID, "")); | |||
Log.i(this.getClass().getSimpleName(), "获取支付二维码 请求参数:" + JSONObject.toJSONString(params)); | |||
MyRetrofit.newInstanceGZ(this, IFCode.IFCODE_DEVICE_CANCEL_GET_QR_CODE, params, new MyRetrofit.ReturnResult() { | |||
@Override | |||
public void onSuccess(ResultBean resultBean, ResultBean.BizContent bizContent) { | |||
hideDialog(); | |||
Log.i(this.getClass().getSimpleName(), "获取支付二维码 响应数据:" + JSONObject.toJSONString(resultBean)); | |||
// 解析二维码数据 | |||
parseQrCodeResponse(resultBean); | |||
} | |||
@Override | |||
public void onError(Response<Result> resp) { | |||
hideDialog(); | |||
Log.e(this.getClass().getSimpleName(), "获取支付二维码失败: " + (resp != null ? resp.message() : "未知错误")); | |||
ToastUtils.show("获取支付二维码失败,请重试"); | |||
} | |||
}); | |||
} | |||
/** | |||
* 解析二维码响应数据 | |||
*/ | |||
private void parseQrCodeResponse(ResultBean resultBean) { | |||
try { | |||
if (resultBean.getData() != null) { | |||
String dataStr = JSONObject.toJSONString(resultBean.getData()); | |||
DeviceCancelQrCodeResponse response = JSONObject.parseObject(dataStr, DeviceCancelQrCodeResponse.class); | |||
if (response.getCode() == 0 && response.getData() != null) { | |||
DeviceCancelQrCodeResponse.DeviceCancelQrCodeData qrData = response.getData(); | |||
showPaymentQrCode(qrData.getQrbase64(), qrData.getAmount()); | |||
} else { | |||
ToastUtils.show("获取支付二维码失败: " + response.getMessage()); | |||
} | |||
} else { | |||
ToastUtils.show("获取支付二维码失败:响应数据为空"); | |||
} | |||
} catch (Exception e) { | |||
Log.e(this.getClass().getSimpleName(), "解析二维码响应失败: " + e.getMessage()); | |||
ToastUtils.show("解析支付二维码失败"); | |||
} | |||
} | |||
/** | |||
* 显示支付二维码 | |||
*/ | |||
private void showPaymentQrCode(String qrBase64, long amount) { | |||
try { | |||
// 显示支付金额 | |||
String amountText = "¥ " + FunHelper.getPriceWith2Num(Double.parseDouble(FunHelper.changeF2Y(amount))); | |||
// 跳转到专门的支付界面 | |||
Intent intent = new Intent(this, LogoutEtcPayActivity.class); | |||
intent.putExtra("dataJson", JSONObject.toJSONString(curBizContent)); | |||
intent.putExtra("amount", amount); | |||
intent.putExtra("qrBase64", qrBase64); | |||
intent.putExtra("orderNo", orderNo); | |||
startActivity(intent); | |||
Log.i(this.getClass().getSimpleName(), "跳转到支付界面,金额: " + amountText); | |||
} catch (Exception e) { | |||
Log.e(this.getClass().getSimpleName(), "跳转支付界面失败: " + e.getMessage()); | |||
ToastUtils.show("跳转支付界面失败"); | |||
} | |||
} | |||
@Override | |||
protected void onDestroy() { | |||
super.onDestroy(); |