diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index cb243b6..fa44d23 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -121,6 +121,12 @@ android:exported="false" android:theme="@style/Theme.Transparent" /> + + + queryData) { - // 这里可以根据实际情况实现跳转到订单选择页面的逻辑 - LogManager.logInfo(TAG, "准备跳转到订单选择页面: " + queryData.toString()); - // 这里可以添加实际的页面跳转逻辑 + public void navigateToOrderSelectionPage(String orderData, int verificationType, String faceBase64) { + // 跳转到订单选择页面 + Intent intent = new Intent(OXFaceOnlineActivity.this, OrderSelectionActivity.class); + intent.putExtra(OrderSelectionActivity.EXTRA_ORDER_DATA, orderData); + intent.putExtra(OrderSelectionActivity.EXTRA_VERIFICATION_TYPE, verificationType); + if (faceBase64 != null) { + intent.putExtra(OrderSelectionActivity.EXTRA_FACE_BASE64, faceBase64); + } + startActivityForResult(intent, 1002); // 使用新的requestCode } }); } @@ -1447,6 +1453,43 @@ public class OXFaceOnlineActivity extends BaseActivity implements View.OnClickLi } else { LogManager.logInfo(TAG, "用户取消验证码输入"); } + } else if (requestCode == 1002) { // 订单选择页面返回结果 + // 恢复摄像头预览 + isNeedCamera = true; + LogManager.logInfo(TAG, "恢复摄像头预览 - isNeedCamera设置为true"); + + if (resultCode == RESULT_OK && data != null) { + // 处理订单选择结果 + String selectedOrderJson = data.getStringExtra("selected_order"); + String orderNo = data.getStringExtra("order_no"); + String verificationCode = data.getStringExtra("verification_code"); + int orderType = data.getIntExtra("order_type", 0); + String cardNo = data.getStringExtra("card_no"); + String project = data.getStringExtra("project"); + int verificationType = data.getIntExtra("verification_type", 2); + + LogManager.logInfo(TAG, "订单选择成功: " + orderNo); + + // 显示成功状态 + if (layoutCompareStatus != null) { + layoutCompareStatus.setVisibility(View.VISIBLE); + textCompareStatus.setTextColor(Color.parseColor("#009874")); + textCompareStatus.setText("订单核销成功"); + + // 3秒后隐藏状态提示 + new Handler().postDelayed(new Runnable() { + @Override + public void run() { + if (layoutCompareStatus != null) { + layoutCompareStatus.setVisibility(View.GONE); + } + } + }, 3000); + } + + } else if (resultCode == RESULT_CANCELED) { + LogManager.logInfo(TAG, "用户取消订单选择"); + } } } diff --git a/app/src/main/java/com/ouxuan/oxface/network/OrderVerificationResultHandler.java b/app/src/main/java/com/ouxuan/oxface/network/OrderVerificationResultHandler.java index 531c6ae..584a3b2 100644 --- a/app/src/main/java/com/ouxuan/oxface/network/OrderVerificationResultHandler.java +++ b/app/src/main/java/com/ouxuan/oxface/network/OrderVerificationResultHandler.java @@ -4,8 +4,10 @@ import android.content.Intent; import android.content.Context; import com.ouxuan.oxface.network.api.PadApiService; import com.ouxuan.oxface.orderOX.OrderVerificationResultActivity; +import com.ouxuan.oxface.orderOX.OrderSelectionActivity; import com.ouxuan.oxface.utils.LogManager; import com.google.gson.JsonObject; +import com.google.gson.Gson; import java.util.HashMap; import java.util.Map; @@ -40,9 +42,11 @@ public class OrderVerificationResultHandler { /** * 跳转到订单选择页面 - * @param queryData 查询数据 + * @param orderData 订单数据JSON字符串 + * @param verificationType 验证类型 + * @param faceBase64 人脸base64数据(可选) */ - void navigateToOrderSelectionPage(Map queryData); + void navigateToOrderSelectionPage(String orderData, int verificationType, String faceBase64); } /** @@ -179,16 +183,14 @@ public class OrderVerificationResultHandler { * 处理人脸验证结果 */ private void handleFaceVerificationResult(PadApiService.CheckOrderResult data) { - // 准备订单核销选择页信息 - Map queryData = new HashMap<>(); - queryData.put("type", OrderVerificationManager.TYPE_FACE_VERIFICATION); - queryData.put("check_type", "face_base64"); - queryData.put("result", data.getResult()); + // 将订单数据转为JSON字符串 + Gson gson = new Gson(); + String orderDataJson = gson.toJson(data); - LogManager.logInfo(TAG, "准备跳转到订单验证页面: " + queryData.toString()); + LogManager.logInfo(TAG, "准备跳转到订单选择页面"); if (listener != null) { listener.showToast("人脸验证成功,准备跳转到订单选择页面"); - listener.navigateToOrderSelectionPage(queryData); + listener.navigateToOrderSelectionPage(orderDataJson, OrderVerificationManager.TYPE_FACE_VERIFICATION, null); } } @@ -200,14 +202,13 @@ public class OrderVerificationResultHandler { listener.showToast("操作成功,正在跳转..."); } - // 准备订单核销选择页信息 - Map queryData = new HashMap<>(); - queryData.put("type", OrderVerificationManager.TYPE_SCAN_VERIFICATION); - queryData.put("result", data.getResult()); + // 将订单数据转为JSON字符串 + Gson gson = new Gson(); + String orderDataJson = gson.toJson(data); - LogManager.logInfo(TAG, "准备跳转到订单验证页面: " + queryData.toString()); + LogManager.logInfo(TAG, "准备跳转到订单选择页面"); if (listener != null) { - listener.navigateToOrderSelectionPage(queryData); + listener.navigateToOrderSelectionPage(orderDataJson, OrderVerificationManager.TYPE_SCAN_VERIFICATION, null); } } diff --git a/app/src/main/java/com/ouxuan/oxface/orderOX/OrderSelectionActivity.java b/app/src/main/java/com/ouxuan/oxface/orderOX/OrderSelectionActivity.java new file mode 100644 index 0000000..6cbde5a --- /dev/null +++ b/app/src/main/java/com/ouxuan/oxface/orderOX/OrderSelectionActivity.java @@ -0,0 +1,267 @@ +package com.ouxuan.oxface.orderOX; + +import android.content.Intent; +import android.os.Bundle; +import android.os.Handler; +import android.view.View; +import android.view.Window; +import android.view.WindowManager; +import android.widget.Button; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.appcompat.app.AppCompatActivity; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.google.gson.Gson; +import com.ouxuan.oxface.R; +import com.ouxuan.oxface.orderOX.adapter.OrderSelectionAdapter; +import com.ouxuan.oxface.orderOX.model.OrderVerificationData; +import com.ouxuan.oxface.utils.LogManager; + +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.List; +import java.util.Locale; + +/** + * 订单核销选择页面 + * 用于显示人脸验证后返回的订单列表,供用户选择要核销的订单 + */ +public class OrderSelectionActivity extends AppCompatActivity { + + private static final String TAG = "OrderSelectionActivity"; + public static final String EXTRA_ORDER_DATA = "order_data"; + public static final String EXTRA_VERIFICATION_TYPE = "verification_type"; + public static final String EXTRA_FACE_BASE64 = "face_base64"; + + private RecyclerView rvOrderList; + private Button btnConfirm, btnCancel; + private TextView tvBackHome, tvStoreName, tvVerificationDate; + + private OrderSelectionAdapter adapter; + private List orderList; + private int verificationType; + private String faceBase64; + private Handler countdownHandler; + private int countdown = 6; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + // 设置无标题栏 + requestWindowFeature(Window.FEATURE_NO_TITLE); + + // 设置背景透明,实现弹窗效果 + getWindow().setBackgroundDrawableResource(android.R.color.transparent); + + setContentView(R.layout.activity_order_selection); + + // 设置窗口属性 + Window window = getWindow(); + window.setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT); + window.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS); + + initViews(); + initData(); + setupListeners(); + startCountdown(); + + LogManager.logInfo(TAG, "订单选择页面启动成功"); + } + + private void initViews() { + rvOrderList = findViewById(R.id.rv_order_list); + btnConfirm = findViewById(R.id.btn_confirm); + btnCancel = findViewById(R.id.btn_cancel); + tvBackHome = findViewById(R.id.tv_back_home); + tvStoreName = findViewById(R.id.tv_store_name); + tvVerificationDate = findViewById(R.id.tv_verification_date); + + // 设置当前日期 + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()); + String currentDate = sdf.format(new Date()); + tvVerificationDate.setText("核销日期:" + currentDate); + + // 设置RecyclerView + rvOrderList.setLayoutManager(new LinearLayoutManager(this)); + } + + private void initData() { + // 获取传入的数据 + Intent intent = getIntent(); + String orderDataJson = intent.getStringExtra(EXTRA_ORDER_DATA); + verificationType = intent.getIntExtra(EXTRA_VERIFICATION_TYPE, 2); + faceBase64 = intent.getStringExtra(EXTRA_FACE_BASE64); + + if (orderDataJson != null) { + try { + // 解析JSON数据 + Gson gson = new Gson(); + OrderVerificationData orderData = gson.fromJson(orderDataJson, OrderVerificationData.class); + + if (orderData != null && orderData.getData() != null && orderData.getData().getResult() != null) { + orderList = orderData.getData().getResult(); + + // 设置适配器 + adapter = new OrderSelectionAdapter(orderList); + rvOrderList.setAdapter(adapter); + + // 设置点击监听 + adapter.setOnOrderClickListener(new OrderSelectionAdapter.OnOrderClickListener() { + @Override + public void onOrderClick(OrderVerificationData.OrderItem order, int position) { + LogManager.logInfo(TAG, "选择订单: " + order.getOrder_no()); + // 更新确认按钮状态 + btnConfirm.setEnabled(true); + btnConfirm.setAlpha(1.0f); + } + + @Override + public void onVerifyClick(OrderVerificationData.OrderItem order, int position) { + // 直接核销选中的订单 + performOrderVerification(order); + } + }); + + LogManager.logInfo(TAG, "成功加载" + orderList.size() + "个订单"); + } else { + LogManager.logWarning(TAG, "订单数据为空"); + showToast("未找到可核销的订单"); + } + + } catch (Exception e) { + LogManager.logError(TAG, "解析订单数据失败", e); + showToast("订单数据解析失败"); + } + } else { + LogManager.logError(TAG, "未接收到订单数据"); + showToast("未接收到订单数据"); + } + + // 初始状态下确认按钮不可用 + btnConfirm.setEnabled(false); + btnConfirm.setAlpha(0.5f); + } + + private void setupListeners() { + // 确认按钮 + btnConfirm.setOnClickListener(v -> { + OrderVerificationData.OrderItem selectedOrder = adapter.getSelectedOrder(); + if (selectedOrder != null) { + performOrderVerification(selectedOrder); + } else { + showToast("请选择要核销的订单"); + } + }); + + // 取消按钮 + btnCancel.setOnClickListener(v -> { + LogManager.logInfo(TAG, "用户取消选择"); + setResult(RESULT_CANCELED); + finish(); + }); + + // 返回首页按钮 + tvBackHome.setOnClickListener(v -> { + LogManager.logInfo(TAG, "用户点击返回首页"); + setResult(RESULT_CANCELED); + finish(); + }); + } + + /** + * 执行订单核销 + */ + private void performOrderVerification(OrderVerificationData.OrderItem order) { + LogManager.logInfo(TAG, "执行订单核销: " + order.getOrder_no()); + + // 停止倒计时 + stopCountdown(); + + // 准备结果数据 + Intent resultIntent = new Intent(); + resultIntent.putExtra("selected_order", new Gson().toJson(order)); + resultIntent.putExtra("order_no", order.getOrder_no()); + resultIntent.putExtra("verification_code", order.getVerificationCode()); + resultIntent.putExtra("order_type", order.getOrder_type()); + resultIntent.putExtra("card_no", order.getInfo() != null ? order.getInfo().getCard_no() : ""); + resultIntent.putExtra("project", order.getProject()); + resultIntent.putExtra("verification_type", verificationType); + + setResult(RESULT_OK, resultIntent); + + // 显示成功提示并跳转到结果页面 + showToast("订单核销成功"); + + // 跳转到核销结果页面 + Intent intent = new Intent(this, OrderVerificationResultActivity.class); + intent.putExtra("verification_type", verificationType); + intent.putExtra("order_no", order.getOrder_no()); + intent.putExtra("verification_code", order.getVerificationCode()); + intent.putExtra("order_type", order.getOrder_type()); + intent.putExtra("card_no", order.getInfo() != null ? order.getInfo().getCard_no() : ""); + intent.putExtra("status", "核销成功"); + startActivity(intent); + + finish(); + } + + /** + * 开始倒计时 + */ + private void startCountdown() { + countdownHandler = new Handler(); + updateCountdown(); + } + + /** + * 停止倒计时 + */ + private void stopCountdown() { + if (countdownHandler != null) { + countdownHandler.removeCallbacksAndMessages(null); + } + } + + /** + * 更新倒计时显示 + */ + private void updateCountdown() { + if (countdown > 0) { + tvBackHome.setText("返回首页(0" + countdown + "s)"); + countdown--; + + if (countdownHandler != null) { + countdownHandler.postDelayed(this::updateCountdown, 1000); + } + } else { + // 倒计时结束,自动返回 + LogManager.logInfo(TAG, "倒计时结束,自动返回"); + setResult(RESULT_CANCELED); + finish(); + } + } + + /** + * 显示Toast消息 + */ + private void showToast(String message) { + Toast.makeText(this, message, Toast.LENGTH_SHORT).show(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + stopCountdown(); + LogManager.logInfo(TAG, "订单选择页面销毁"); + } + + @Override + public void onBackPressed() { + super.onBackPressed(); + setResult(RESULT_CANCELED); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/ouxuan/oxface/orderOX/adapter/OrderSelectionAdapter.java b/app/src/main/java/com/ouxuan/oxface/orderOX/adapter/OrderSelectionAdapter.java new file mode 100644 index 0000000..1fa2977 --- /dev/null +++ b/app/src/main/java/com/ouxuan/oxface/orderOX/adapter/OrderSelectionAdapter.java @@ -0,0 +1,127 @@ +package com.ouxuan.oxface.orderOX.adapter; + +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; +import com.ouxuan.oxface.R; +import com.ouxuan.oxface.orderOX.model.OrderVerificationData; +import java.util.List; + +/** + * 订单选择列表适配器 + */ +public class OrderSelectionAdapter extends RecyclerView.Adapter { + + private List orderList; + private OnOrderClickListener onOrderClickListener; + private int selectedPosition = -1; + + public interface OnOrderClickListener { + void onOrderClick(OrderVerificationData.OrderItem order, int position); + void onVerifyClick(OrderVerificationData.OrderItem order, int position); + } + + public OrderSelectionAdapter(List orderList) { + this.orderList = orderList; + } + + public void setOnOrderClickListener(OnOrderClickListener listener) { + this.onOrderClickListener = listener; + } + + public void setSelectedPosition(int position) { + int previousPosition = selectedPosition; + selectedPosition = position; + + if (previousPosition != -1) { + notifyItemChanged(previousPosition); + } + if (selectedPosition != -1) { + notifyItemChanged(selectedPosition); + } + } + + public OrderVerificationData.OrderItem getSelectedOrder() { + if (selectedPosition >= 0 && selectedPosition < orderList.size()) { + return orderList.get(selectedPosition); + } + return null; + } + + @NonNull + @Override + public OrderViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(parent.getContext()) + .inflate(R.layout.item_order_selection, parent, false); + return new OrderViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull OrderViewHolder holder, int position) { + OrderVerificationData.OrderItem order = orderList.get(position); + + // 设置订单信息 + holder.tvOrderTitle.setText("订单信息 (共" + order.getNumber() + "场次)"); + holder.tvOrderNumber.setText("订单编号:" + order.getOrder_no()); + + // 设置预订信息 - 这里需要根据实际数据结构调整 + String bookingInfo = order.getProject() + " " + order.getFormattedTimeInfo() + ";"; + holder.tvBookingInfo.setText("预订信息:" + bookingInfo); + + holder.tvProjectName.setText("预订项目:" + order.getProject()); + holder.tvUsageDate.setText("使用日期:" + order.getFormattedUsageDate()); + + // 设置选中状态 + if (position == selectedPosition) { + holder.itemView.setBackgroundResource(R.drawable.gate_imageview_radius); + holder.itemView.setSelected(true); + } else { + holder.itemView.setBackgroundResource(R.drawable.gate_radius_compare); + holder.itemView.setSelected(false); + } + + // 设置点击事件 + holder.itemView.setOnClickListener(v -> { + if (onOrderClickListener != null) { + onOrderClickListener.onOrderClick(order, position); + } + setSelectedPosition(position); + }); + + // 去核销按钮点击事件 + holder.tvVerifyButton.setOnClickListener(v -> { + if (onOrderClickListener != null) { + onOrderClickListener.onVerifyClick(order, position); + } + }); + } + + @Override + public int getItemCount() { + return orderList != null ? orderList.size() : 0; + } + + static class OrderViewHolder extends RecyclerView.ViewHolder { + TextView tvSessionLabel; + TextView tvOrderTitle; + TextView tvOrderNumber; + TextView tvBookingInfo; + TextView tvProjectName; + TextView tvUsageDate; + TextView tvVerifyButton; + + public OrderViewHolder(@NonNull View itemView) { + super(itemView); + tvSessionLabel = itemView.findViewById(R.id.tv_session_label); + tvOrderTitle = itemView.findViewById(R.id.tv_order_title); + tvOrderNumber = itemView.findViewById(R.id.tv_order_number); + tvBookingInfo = itemView.findViewById(R.id.tv_booking_info); + tvProjectName = itemView.findViewById(R.id.tv_project_name); + tvUsageDate = itemView.findViewById(R.id.tv_usage_date); + tvVerifyButton = itemView.findViewById(R.id.tv_verify_button); + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/ouxuan/oxface/orderOX/model/OrderVerificationData.java b/app/src/main/java/com/ouxuan/oxface/orderOX/model/OrderVerificationData.java new file mode 100644 index 0000000..49e440a --- /dev/null +++ b/app/src/main/java/com/ouxuan/oxface/orderOX/model/OrderVerificationData.java @@ -0,0 +1,245 @@ +package com.ouxuan.oxface.orderOX.model; + +import java.util.List; + +/** + * 订单核销数据模型 + */ +public class OrderVerificationData { + + private int code; + private Data data; + private String message; + private String extension; + + public static class Data { + private List result; + private int skip; + + public List getResult() { + return result; + } + + public void setResult(List result) { + this.result = result; + } + + public int getSkip() { + return skip; + } + + public void setSkip(int skip) { + this.skip = skip; + } + } + + public static class OrderItem { + private String order_no; + private String start_time; + private String end_time; + private int order_type; + private String project; + private int number; + private List v_code; + private OrderInfo info; + private int success; + private int pv_usage_duration; + private boolean many_enter; + + public static class OrderInfo { + private String card_no; + private int rest_number; + private int status; + private String user_face_id; + + public String getCard_no() { + return card_no; + } + + public void setCard_no(String card_no) { + this.card_no = card_no; + } + + public int getRest_number() { + return rest_number; + } + + public void setRest_number(int rest_number) { + this.rest_number = rest_number; + } + + public int getStatus() { + return status; + } + + public void setStatus(int status) { + this.status = status; + } + + public String getUser_face_id() { + return user_face_id; + } + + public void setUser_face_id(String user_face_id) { + this.user_face_id = user_face_id; + } + } + + // Getters and Setters + public String getOrder_no() { + return order_no; + } + + public void setOrder_no(String order_no) { + this.order_no = order_no; + } + + public String getStart_time() { + return start_time; + } + + public void setStart_time(String start_time) { + this.start_time = start_time; + } + + public String getEnd_time() { + return end_time; + } + + public void setEnd_time(String end_time) { + this.end_time = end_time; + } + + public int getOrder_type() { + return order_type; + } + + public void setOrder_type(int order_type) { + this.order_type = order_type; + } + + public String getProject() { + return project; + } + + public void setProject(String project) { + this.project = project; + } + + public int getNumber() { + return number; + } + + public void setNumber(int number) { + this.number = number; + } + + public List getV_code() { + return v_code; + } + + public void setV_code(List v_code) { + this.v_code = v_code; + } + + public OrderInfo getInfo() { + return info; + } + + public void setInfo(OrderInfo info) { + this.info = info; + } + + public int getSuccess() { + return success; + } + + public void setSuccess(int success) { + this.success = success; + } + + public int getPv_usage_duration() { + return pv_usage_duration; + } + + public void setPv_usage_duration(int pv_usage_duration) { + this.pv_usage_duration = pv_usage_duration; + } + + public boolean isMany_enter() { + return many_enter; + } + + public void setMany_enter(boolean many_enter) { + this.many_enter = many_enter; + } + + /** + * 获取格式化的时间信息 + */ + public String getFormattedTimeInfo() { + if (start_time != null && end_time != null) { + // 提取时间部分 (HH:mm) + String startTimeOnly = start_time.substring(11, 16); + String endTimeOnly = end_time.substring(11, 16); + return startTimeOnly + "-" + endTimeOnly; + } + return ""; + } + + /** + * 获取格式化的使用日期 + */ + public String getFormattedUsageDate() { + if (start_time != null) { + String date = start_time.substring(0, 10); + // 简单判断是否是今天(这里可以根据实际需求优化) + return date + " (今天)"; + } + return ""; + } + + /** + * 获取验证码字符串 + */ + public String getVerificationCode() { + if (v_code != null && !v_code.isEmpty()) { + return v_code.get(0); + } + return ""; + } + } + + // Getters and Setters for main class + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public Data getData() { + return data; + } + + public void setData(Data data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public String getExtension() { + return extension; + } + + public void setExtension(String extension) { + this.extension = extension; + } +} \ No newline at end of file diff --git a/app/src/main/res/layout/activity_order_selection.xml b/app/src/main/res/layout/activity_order_selection.xml new file mode 100644 index 0000000..7eec4df --- /dev/null +++ b/app/src/main/res/layout/activity_order_selection.xml @@ -0,0 +1,147 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +