From 5dfe9770cd5affb2a17685f1ceb580e0d1c0525c Mon Sep 17 00:00:00 2001 From: "3075067877@qq.com" <3075067877@qq.com> Date: Wed, 10 Sep 2025 17:21:13 +0800 Subject: [PATCH] =?UTF-8?q?=E8=AE=A2=E5=8D=95=E6=A0=B8=E9=94=80=E7=BB=93?= =?UTF-8?q?=E6=9E=9C=E9=A1=B5=E9=87=8D=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../oxface/orderOX/OrderSelectionActivity.java | 16 + .../orderOX/OrderVerificationResultActivity.java | 337 +++++++++++++++++---- .../layout/activity_order_verification_result.xml | 135 +-------- .../ouxuan/oxface/OrderVerificationResultTest.java | 214 +++++++++++++ 订单核销结果页面重构说明.md | 213 +++++++++++++ 5 files changed, 727 insertions(+), 188 deletions(-) create mode 100644 app/src/test/java/com/ouxuan/oxface/OrderVerificationResultTest.java create mode 100644 订单核销结果页面重构说明.md diff --git a/app/src/main/java/com/ouxuan/oxface/orderOX/OrderSelectionActivity.java b/app/src/main/java/com/ouxuan/oxface/orderOX/OrderSelectionActivity.java index 9e4433d..6854d3c 100644 --- a/app/src/main/java/com/ouxuan/oxface/orderOX/OrderSelectionActivity.java +++ b/app/src/main/java/com/ouxuan/oxface/orderOX/OrderSelectionActivity.java @@ -374,6 +374,22 @@ public class OrderSelectionActivity extends AppCompatActivity { } startActivity(intent); + intent.putExtra("order_type", order.getOrder_type()); + intent.putExtra("card_no", order.getInfo() != null ? order.getCardNoFromInfo() : ""); + intent.putExtra("project", order.getProject()); + intent.putExtra("status", status); + intent.putExtra("message", message); + // 添加设备ID和订单类型参数 + intent.putExtra("hardware_id", hardwareId); + intent.putExtra("order_type_param", orderType); + + // 传递完整的订单数据和核销结果数据 + intent.putExtra("order_data", new Gson().toJson(order)); + if (data != null) { + intent.putExtra("verify_result", new Gson().toJson(data)); + } + + startActivity(intent); // 准备返回结果给调用Activity Intent resultIntent = new Intent(); diff --git a/app/src/main/java/com/ouxuan/oxface/orderOX/OrderVerificationResultActivity.java b/app/src/main/java/com/ouxuan/oxface/orderOX/OrderVerificationResultActivity.java index fb72a9a..209bb40 100644 --- a/app/src/main/java/com/ouxuan/oxface/orderOX/OrderVerificationResultActivity.java +++ b/app/src/main/java/com/ouxuan/oxface/orderOX/OrderVerificationResultActivity.java @@ -12,11 +12,18 @@ import android.widget.Button; import android.widget.ImageButton; import android.widget.TextView; import android.widget.Toast; +import android.widget.LinearLayout; +import android.widget.ScrollView; import androidx.appcompat.app.AppCompatActivity; import com.ouxuan.oxface.R; import com.ouxuan.oxface.utils.LogManager; +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import com.google.gson.JsonElement; +import com.google.gson.JsonParser; +import com.ouxuan.oxface.network.api.PadApiService; /** * 订单核销结果Activity @@ -28,9 +35,16 @@ public class OrderVerificationResultActivity extends AppCompatActivity { private ImageButton btnClose; private Button btnConfirm; - private TextView tvTitle, tvOrderNo, tvVerificationCode, tvOrderType, tvCardNo, tvStatus, tvMessage, tvProject; - private String orderNo, verificationCode, orderType, cardNo, status, message, project; + private TextView tvTitle, tvStatus, tvMessage; + private ScrollView scrollContent; + private LinearLayout layoutContent; + + // 订单数据 private int verificationType; // 1-验证码验证, 2-人脸验证, 3-扫码验证, 4-扫码器验证 + private int orderType; // 订单类型:0-场次, 1-人次, 3-年月卡, 5-课程 + private String orderNo, verificationCode, cardNo, status, message, project; + private JsonElement orderInfo; // 订单信息,可能是字符串或对象 + private PadApiService.VerifyOrderResult verifyResult; // 完整的核销结果数据 // 强制关闭广播接收器 private BroadcastReceiver forceCloseReceiver; @@ -71,36 +85,55 @@ public class OrderVerificationResultActivity extends AppCompatActivity { btnClose = findViewById(R.id.btn_close_result); btnConfirm = findViewById(R.id.btn_confirm_result); - // 初始化文本视图 + // 初始化核心视图 tvTitle = findViewById(R.id.tv_result_title); - tvOrderNo = findViewById(R.id.tv_order_no); - tvVerificationCode = findViewById(R.id.tv_verification_code); - tvOrderType = findViewById(R.id.tv_order_type); - tvCardNo = findViewById(R.id.tv_card_no); tvStatus = findViewById(R.id.tv_status); - tvMessage = findViewById(R.id.tv_message); // 新增消息显示 - tvProject = findViewById(R.id.tv_project); // 新增项目显示 + tvMessage = findViewById(R.id.tv_message); + scrollContent = findViewById(R.id.scroll_content); + layoutContent = findViewById(R.id.layout_content); } private void getIntentData() { Intent intent = getIntent(); if (intent != null) { verificationType = intent.getIntExtra("verification_type", 1); + orderType = intent.getIntExtra("order_type", 0); orderNo = intent.getStringExtra("order_no"); verificationCode = intent.getStringExtra("verification_code"); - int orderTypeInt = intent.getIntExtra("order_type", 0); - orderType = String.valueOf(orderTypeInt); cardNo = intent.getStringExtra("card_no"); status = intent.getStringExtra("status"); - message = intent.getStringExtra("message"); // 获取核销结果消息 - project = intent.getStringExtra("project"); // 获取项目名称 + message = intent.getStringExtra("message"); + project = intent.getStringExtra("project"); + + // 获取完整的核销结果数据 + String verifyResultJson = intent.getStringExtra("verify_result"); + if (verifyResultJson != null && !verifyResultJson.isEmpty()) { + try { + Gson gson = new Gson(); + verifyResult = gson.fromJson(verifyResultJson, PadApiService.VerifyOrderResponse.class).getResult(); + if (verifyResult != null) { + // 从完整结果中提取信息 + orderInfo = verifyResult.getInfo() != null ? + JsonParser.parseString(gson.toJson(verifyResult.getInfo())) : null; + if (orderNo == null || orderNo.isEmpty()) { + orderNo = verifyResult.getOrderNo(); + } + if (project == null || project.isEmpty()) { + project = verifyResult.getProject(); + } + LogManager.logInfo(TAG, "成功解析完整核销结果数据"); + } + } catch (Exception e) { + LogManager.logError(TAG, "解析核销结果数据失败", e); + } + } // 输出调试日志 LogManager.logInfo(TAG, "收到核销结果数据: "); LogManager.logInfo(TAG, "verificationType: " + verificationType); + LogManager.logInfo(TAG, "orderType: " + orderType); LogManager.logInfo(TAG, "orderNo: " + orderNo); LogManager.logInfo(TAG, "verificationCode: " + verificationCode); - LogManager.logInfo(TAG, "orderType: " + orderType); LogManager.logInfo(TAG, "cardNo: " + cardNo); LogManager.logInfo(TAG, "status: " + status); LogManager.logInfo(TAG, "message: " + message); @@ -110,7 +143,6 @@ public class OrderVerificationResultActivity extends AppCompatActivity { // 设置默认值 if (orderNo == null) orderNo = ""; if (verificationCode == null) verificationCode = ""; - if (orderType == null) orderType = ""; if (cardNo == null) cardNo = ""; if (status == null) status = "核销成功"; if (message == null) message = "订单核销成功"; @@ -122,23 +154,18 @@ public class OrderVerificationResultActivity extends AppCompatActivity { * @param orderType 订单类型数字 * @return 对应的中文名称 */ - private String getOrderTypeName(String orderType) { - try { - int type = Integer.parseInt(orderType); - switch (type) { - case 0: - return "场次"; - case 1: - return "人次"; - case 3: - return "年月卡"; - case 5: - return "课程"; - default: - return "orderType:"+type; - } - } catch (NumberFormatException e) { - return "未知订单类型"; + private String getOrderTypeName(int orderType) { + switch (orderType) { + case 0: + return "场次"; + case 1: + return "人次"; + case 3: + return "年月卡"; + case 5: + return "课程"; + default: + return "orderType:" + orderType; } } @@ -162,46 +189,236 @@ public class OrderVerificationResultActivity extends AppCompatActivity { break; } - // 更新UI内容 - tvOrderNo.setText(orderNo); - tvVerificationCode.setText(verificationCode); - // 使用 getOrderTypeName 方法转换订单类型显示 - tvOrderType.setText(getOrderTypeName(orderType)); - tvCardNo.setText(cardNo); - tvStatus.setText(status); - - // 更新新增的字段 - if (tvMessage != null) { - tvMessage.setText(message); - } - if (tvProject != null && project != null && !project.isEmpty()) { - tvProject.setText(project); - // 显示项目布局 - View projectLayout = findViewById(R.id.ll_project); - if (projectLayout != null) { - projectLayout.setVisibility(View.VISIBLE); - } - } else { - // 隐藏项目布局 - View projectLayout = findViewById(R.id.ll_project); - if (projectLayout != null) { - projectLayout.setVisibility(View.GONE); - } + // 设置订单类型标题 + String orderTypeTitle = getOrderTypeName(orderType); + if (project != null && !project.isEmpty()) { + orderTypeTitle += " - " + project; } + tvTitle.setText(tvTitle.getText() + " (" + orderTypeTitle + ")"); + + // 设置状态信息 + tvStatus.setText(status); + tvMessage.setText(message); // 根据核销状态设置不同的UI样式 if (status != null) { if (status.contains("成功")) { - // 成功状态 - 绿色 tvStatus.setTextColor(getResources().getColor(android.R.color.holo_green_dark)); } else if (status.contains("失败") || status.contains("异常")) { - // 失败或异常状态 - 红色 tvStatus.setTextColor(getResources().getColor(android.R.color.holo_red_dark)); } else { - // 默认状态 - 黑色 tvStatus.setTextColor(getResources().getColor(android.R.color.black)); } } + + // 根据订单类型显示不同的内容 + buildOrderTypeSpecificContent(); + } + + /** + * 根据订单类型构建特定的内容显示 + */ + private void buildOrderTypeSpecificContent() { + // 清空现有内容 + layoutContent.removeAllViews(); + + // 根据订单类型显示不同内容 + switch (orderType) { + case 0: // 场次核销 + buildSiteContent(); + break; + case 1: // 人次核销 + buildPeopleContent(); + break; + case 3: // 年月卡 + buildCardContent(); + break; + case 5: // 课程 + buildCourseContent(); + break; + default: + buildDefaultContent(); + break; + } + } + + /** + * 构建场次核销内容 + */ + private void buildSiteContent() { + // 场次核销:显示场次信息 + if (orderInfo != null && orderInfo.isJsonArray()) { + for (JsonElement element : orderInfo.getAsJsonArray()) { + if (element.isJsonObject()) { + JsonObject siteInfo = element.getAsJsonObject(); + String venueName = getJsonString(siteInfo, "venue_name", "-"); + String start = getJsonString(siteInfo, "start", "-"); + + addInfoRow(venueName, start); + } + } + } + + // 添加基本信息 + addBasicOrderInfo(); + } + + /** + * 构建人次核销内容 + */ + private void buildPeopleContent() { + // 人次核销:显示验证码、订单编号、有效时间、预订信息 + addInfoRow("验证码", formatVerificationCode(verificationCode)); + addInfoRow("订单编号", orderNo); + + // 获取有效时间 + if (verifyResult != null) { + String validTime = formatUsageDuration(verifyResult.getPvUsageDuration()); + addInfoRow("有效时间", validTime); + } + + // 预订信息 + String bookingInfo = ""; + if (orderInfo != null && orderInfo.isJsonPrimitive()) { + bookingInfo = orderInfo.getAsString(); + } + addInfoRow("预订信息", bookingInfo.isEmpty() ? "-" : bookingInfo); + } + + /** + * 构建年月卡内容 + */ + private void buildCardContent() { + // 年月卡:显示验证码、名称、卡号、核销方式、核销时间 + addInfoRow("验证码", formatVerificationCode(verificationCode)); + addInfoRow("名称", project != null ? project : "-"); + + if (orderInfo != null && orderInfo.isJsonObject()) { + JsonObject cardInfo = orderInfo.getAsJsonObject(); + String cardNo = getJsonString(cardInfo, "card_no", "-"); + String verifyDesc = getJsonString(cardInfo, "verify_desc", "-"); + String verifyTime = getJsonString(cardInfo, "verify_time", "-"); + + addInfoRow("卡号", "NO." + cardNo); + addInfoRow("核销方式", verifyDesc); + addInfoRow("核销时间", verifyTime); + } + } + + /** + * 构建课程内容 + */ + private void buildCourseContent() { + // 课程:显示上课时间、教练、地点、课程名称、订单编号、签到方式、签到时间 + if (orderInfo != null && orderInfo.isJsonObject()) { + JsonObject courseInfo = orderInfo.getAsJsonObject(); + String time = getJsonString(courseInfo, "time", "-"); + String coach = getJsonString(courseInfo, "coach", "-"); + String addr = getJsonString(courseInfo, "addr", "-"); + String verifyDesc = getJsonString(courseInfo, "verify_desc", "-"); + String verifyTime = getJsonString(courseInfo, "verify_time", "-"); + + addInfoRow("上课时间", time); + addInfoRow("上课教练", coach); + addInfoRow("上课地点", addr); + } + + addInfoRow("课程名称", project != null ? project : "-"); + addInfoRow("订单编号", orderNo); + + if (orderInfo != null && orderInfo.isJsonObject()) { + JsonObject courseInfo = orderInfo.getAsJsonObject(); + String verifyDesc = getJsonString(courseInfo, "verify_desc", "-"); + String verifyTime = getJsonString(courseInfo, "verify_time", "-"); + + addInfoRow("签到方式", verifyDesc); + addInfoRow("签到时间", verifyTime); + } + } + + /** + * 构建默认内容 + */ + private void buildDefaultContent() { + addBasicOrderInfo(); + } + + /** + * 添加基本订单信息 + */ + private void addBasicOrderInfo() { + addInfoRow("订单编号", orderNo); + if (verificationCode != null && !verificationCode.isEmpty()) { + addInfoRow("验证码", verificationCode); + } + if (cardNo != null && !cardNo.isEmpty()) { + addInfoRow("卡号", cardNo); + } + if (project != null && !project.isEmpty()) { + addInfoRow("项目", project); + } + } + + /** + * 添加信息行 + */ + private void addInfoRow(String label, String value) { + LinearLayout row = new LinearLayout(this); + row.setOrientation(LinearLayout.HORIZONTAL); + row.setPadding(0, 8, 0, 8); + + TextView labelView = new TextView(this); + labelView.setText(label + ":"); + labelView.setTextColor(getResources().getColor(android.R.color.darker_gray)); + labelView.setTextSize(14); + LinearLayout.LayoutParams labelParams = new LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.WRAP_CONTENT); + labelParams.weight = 0.3f; + labelView.setLayoutParams(labelParams); + + TextView valueView = new TextView(this); + valueView.setText(value != null ? value : "-"); + valueView.setTextColor(getResources().getColor(android.R.color.black)); + valueView.setTextSize(14); + LinearLayout.LayoutParams valueParams = new LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.WRAP_CONTENT); + valueParams.weight = 0.7f; + valueView.setLayoutParams(valueParams); + + row.addView(labelView); + row.addView(valueView); + + layoutContent.addView(row); + } + + /** + * 从JsonObject中安全获取字符串值 + */ + private String getJsonString(JsonObject jsonObject, String key, String defaultValue) { + if (jsonObject.has(key) && !jsonObject.get(key).isJsonNull()) { + return jsonObject.get(key).getAsString(); + } + return defaultValue; + } + + /** + * 格式化验证码显示 + */ + private String formatVerificationCode(String code) { + if (code == null || code.isEmpty()) { + return "-"; + } + // 根据uni端的getCodeJoin逻辑,这里可以添加格式化逻辑 + return code; + } + + /** + * 格式化使用时长 + */ + private String formatUsageDuration(int duration) { + if (duration <= 0) { + return "无限制"; + } + // 根据uni端的gethour逻辑,这里假设duration是小时数 + return duration + "小时到期"; } private void setupListeners() { diff --git a/app/src/main/res/layout/activity_order_verification_result.xml b/app/src/main/res/layout/activity_order_verification_result.xml index 52b16d4..8911ea5 100644 --- a/app/src/main/res/layout/activity_order_verification_result.xml +++ b/app/src/main/res/layout/activity_order_verification_result.xml @@ -46,151 +46,30 @@ - - + android:orientation="vertical" /> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + +``` + +#### 1.3 动态内容生成 +根据订单类型动态生成不同的显示内容: + +```java +private void buildOrderTypeSpecificContent() { + switch (orderType) { + case 0: // 场次核销 + buildSiteContent(); + break; + case 1: // 人次核销 + buildPeopleContent(); + break; + case 3: // 年月卡 + buildCardContent(); + break; + case 5: // 课程 + buildCourseContent(); + break; + } +} +``` + +### 2. 根据 uni 端逻辑实现不同订单类型展示 + +#### 2.1 场次核销 (order_type=0) +显示场次信息列表: +- 场馆名称 +- 开始时间 + +#### 2.2 人次核销 (order_type=1) +显示人次相关信息: +- 验证码 +- 订单编号 +- 有效时间 +- 预订信息(info 字符串) + +#### 2.3 年月卡 (order_type=3) +显示年月卡信息: +- 验证码 +- 名称(项目) +- 卡号(NO.xxx) +- 核销方式 +- 核销时间 + +#### 2.4 课程 (order_type=5) +显示课程信息: +- 上课时间 +- 上课教练 +- 上课地点 +- 课程名称 +- 订单编号 +- 签到方式 +- 签到时间 + +### 3. 数据传递优化 + +#### 3.1 传递完整核销结果 +```java +// 在 OrderSelectionActivity 中 +if (data != null) { + intent.putExtra("verify_result", new Gson().toJson(data)); +} +``` + +#### 3.2 解析完整数据结构 +```java +// 在 OrderVerificationResultActivity 中 +String verifyResultJson = intent.getStringExtra("verify_result"); +if (verifyResultJson != null) { + verifyResult = gson.fromJson(verifyResultJson, PadApiService.VerifyOrderResponse.class).getResult(); + orderInfo = JsonParser.parseString(gson.toJson(verifyResult.getInfo())); +} +``` + +### 4. 兼容性处理 + +#### 4.1 JsonElement 处理 +```java +private String getJsonString(JsonObject jsonObject, String key, String defaultValue) { + if (jsonObject.has(key) && !jsonObject.get(key).isJsonNull()) { + return jsonObject.get(key).getAsString(); + } + return defaultValue; +} +``` + +#### 4.2 不同数据类型检查 +```java +// 字符串类型处理 +if (orderInfo != null && orderInfo.isJsonPrimitive()) { + String bookingInfo = orderInfo.getAsString(); +} + +// 对象类型处理 +if (orderInfo != null && orderInfo.isJsonObject()) { + JsonObject cardInfo = orderInfo.getAsJsonObject(); +} +``` + +## 优势分析 + +### 1. 数据结构兼容性 +- ✅ 支持 info 字段的字符串和对象两种类型 +- ✅ 根据 order_type 智能选择处理方式 +- ✅ 避免 JSON 解析异常 + +### 2. 界面显示灵活性 +- ✅ 动态生成内容,支持不同订单类型 +- ✅ 滚动视图支持长内容显示 +- ✅ 统一的界面风格和交互 + +### 3. 代码可维护性 +- ✅ 模块化的内容构建方法 +- ✅ 清晰的数据传递流程 +- ✅ 完善的错误处理机制 + +### 4. 用户体验 +- ✅ 针对不同订单类型优化信息展示 +- ✅ 保持与 uni 端一致的信息结构 +- ✅ 友好的错误提示和状态显示 + +## 测试验证 + +创建了完整的单元测试来验证: +- 次卡核销数据解析 +- 年月卡核销数据解析 +- 订单类型名称转换 +- 验证码格式化 +- 使用时长格式化 + +## 使用说明 + +### 1. 次卡核销场景 +系统会自动检测 order_type=1,将 info 字段作为字符串处理,显示预订信息。 + +### 2. 年月卡核销场景 +系统会自动检测 order_type=3,将 info 字段作为对象处理,提取卡号、核销方式等详细信息。 + +### 3. 其他订单类型 +支持场次(order_type=0)和课程(order_type=5)核销,根据相应的数据结构显示内容。 + +## 注意事项 + +1. **数据完整性**: 确保从上级页面传递完整的 verify_result 数据 +2. **错误处理**: 当数据解析失败时,会降级显示基本订单信息 +3. **向后兼容**: 保持与现有调用方式的兼容性 +4. **性能优化**: 使用动态布局生成,避免冗余的视图创建 + +通过这次重构,彻底解决了不同订单类型核销时的数据结构不兼容问题,提升了用户体验和系统稳定性。 \ No newline at end of file