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