Compare commits

...

2 Commits

@ -1,7 +1,6 @@
package com.example.tyre;
import androidx.appcompat.app.AppCompatActivity;
import android.annotation.SuppressLint;
import android.app.ProgressDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
@ -20,18 +19,22 @@ import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import com.android.hdhe.uhf.reader.UhfReader;
import com.android.hdhe.uhf.readerInterface.TagModel;
import com.example.tyre.entity.AjaxResult;
import com.example.tyre.adapter.CarRecordAdapter;
import com.example.tyre.databinding.ActivityTyreLayoutBinding;
import com.example.tyre.entity.BaseCar;
import com.example.tyre.entity.BaseTyre;
import com.example.tyre.entity.CarLifecycleDTO;
import com.example.tyre.entity.CarMaintenanceLifecycleDTO;
import com.example.tyre.entity.EPC;
import com.example.tyre.maintenance.base.MyRecultCall;
import com.example.tyre.maintenance.base.MyResult;
import com.example.tyre.maintenance.been.BaseTyre;
import com.example.tyre.util.CarSelectionDialog;
import com.example.tyre.util.CommonDialog;
import com.example.tyre.util.MyUrl;
import com.example.tyre.util.SharedPreferencesUtils;
import com.example.tyre.util.Util;
import com.google.android.material.textfield.TextInputEditText;
import com.google.android.material.textfield.TextInputLayout;
@ -51,44 +54,74 @@ import cn.pda.serialport.Tools;
import okhttp3.MediaType;
import okhttp3.RequestBody;
import com.example.tyre.databinding.ActivityTyreLayoutBinding;
public class TyreLayoutActivity extends AppCompatActivity {
private ActivityTyreLayoutBinding binding;
public class TyreLayoutActivity extends AppCompatActivity implements CarRecordAdapter.ItemClickCall {
// 防抖延迟时间 (毫秒)
private static final long DEBOUNCE_DELAY = 500;
public MediaType JSON = MediaType.parse("application/json; charset=utf-8");
TextInputEditText etPlateNumber;
Button btnRetrieve;
TextInputLayout tilPlateNumber;
long lastTime;
long nextTime;
String min = "EC0001012026010100000001"; // 左边界(包含)
String max = "EC0001012026010100100000"; // 右边界(包含)
private ActivityTyreLayoutBinding binding;
private ProgressDialog progressDialog;
private boolean isStart = true;
private boolean runFlag = true;
private boolean startFlag = false;
private UhfReader manager; // UHF manager,UHF Operating handle
private ArrayList<EPC> listEPC;
private ArrayList<String> listepc = new ArrayList<String>();
long lastTime;
long nextTime;
private Toast mToast;
private Toast toast;
private KeyReceiver keyReceiver;
String min = "EC0001012026010100000001"; // 左边界(包含)
String max = "EC0001012026010100100000"; // 右边界(包含)
// 1. 定义数据模型类 (对应后台返回的字段)
public static class TireData {
public String position; // 轮位名称
public String brand; // 品牌
public String spec; // 规格
public String installDate; // 安装日期
private CarRecordAdapter adapter;
// 用于存储最后一次扫描到的 EPC
private String lastScannedEpc;
// 用于处理防抖逻辑的 Handler
private Handler debounceHandler = new Handler(new Handler.Callback() {
@Override
public boolean handleMessage(Message msg) {
if (msg.what == 1 && lastScannedEpc != null) {
// 延迟时间到,执行查询
showLoadingDialog();
public TireData(String position, String brand, String spec, String installDate) {
this.position = position;
this.brand = brand;
this.spec = spec;
this.installDate = installDate;
// 查询车辆数据方法
findCar(lastScannedEpc);
lastScannedEpc = null; // 清空,等待下一次扫描
}
return true;
}
});
/**
*
*
* @param target
* @param min
* @param max
* @return true=false=
*/
public static boolean isInRange(String target, String min, String max) {
// 空值校验,避免空指针异常
if (target == null || min == null || max == null) {
return false;
}
// compareTo规则
// 1. 字符串相等返回0
// 2. 目标字符串 > 对比字符串 返回正数;
// 3. 目标字符串 < 对比字符串 返回负数。
// 因此target >= min 等价于 target.compareTo(min) >= 0
// target <= max 等价于 target.compareTo(max) <= 0。
return target.compareTo(min) >= 0 && target.compareTo(max) <= 0;
}
// 点击item
@Override
public void onClick(int position) {
}
@Override
@ -106,10 +139,12 @@ public class TyreLayoutActivity extends AppCompatActivity {
tilPlateNumber = binding.tilPlateNumber;
etPlateNumber.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {}
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
@ -120,11 +155,13 @@ public class TyreLayoutActivity extends AppCompatActivity {
String plateNumber = etPlateNumber.getText().toString().trim();
if (!plateNumber.isEmpty()) {
showLoadingDialog();
performSearch(plateNumber);
performSearchOld(plateNumber);
} else {
tilPlateNumber.setError("车牌号不能为空");
}
});
adapter = new CarRecordAdapter(this, this);
binding.setAdapter(adapter);
}
private void bindViews() {
@ -136,14 +173,14 @@ public class TyreLayoutActivity extends AppCompatActivity {
private void setupClickListeners() {
binding.btnRetrieve.setOnClickListener(v -> {
String PlateNumber = etPlateNumber.getText().toString();
if (PlateNumber == null || PlateNumber.isEmpty())
{
if (PlateNumber == null || PlateNumber.isEmpty()) {
new CommonDialog(TyreLayoutActivity.this).setMessage("请输入车牌号!").show();
return;
}
carBangding(PlateNumber);
});
}
@Override
public void onResume() {
super.onResume();
@ -155,34 +192,99 @@ public class TyreLayoutActivity extends AppCompatActivity {
registerReceiver();
}
@Override
public void onPause() {
startFlag = false;
super.onPause();
unregisterReceiver();
}
@Override
protected void onDestroy() {
startFlag = false;
runFlag = false;
super.onDestroy();
}
public MediaType JSON = MediaType.parse("application/json; charset=utf-8");
private void performSearch(String carNo) {
Map<String ,String> map=new HashMap<>();
private void selectInfo(String carNo) {
OkGo.<MyResult>get(MyUrl.url + "/tyre/car/lifecycle/" + carNo)
.execute(new MyRecultCall(progressDialog, this) {
@SuppressLint("NotifyDataSetChanged")
@Override
public void onSuccess(Response<MyResult> response) {
super.onSuccess(response);
MyResult body = response.body();
if (body.getCode() == 0) {
CarLifecycleDTO carLifecycleDTO =
new Gson().fromJson(body.getJson(), CarLifecycleDTO.class);
List<CarMaintenanceLifecycleDTO> maintenanceList =
carLifecycleDTO.getMaintenanceList();
if (maintenanceList != null && !maintenanceList.isEmpty()) {
adapter.setList(maintenanceList);
adapter.notifyDataSetChanged();
}
// 轮位显示
List<BaseTyre> mountedTyres = carLifecycleDTO.getMountedTyres();
mountedTyres.forEach(tire -> {
String wheelPostion = tire.getWheelPostion();
initTire(wheelPostion, tire);
});
// 显示里程
binding.selectInfoMileage.setText(carLifecycleDTO.getCar().getInputMileage());
}
}
});
}
// 初始化轮胎信息
private void initTire(String wheelPostion, com.example.tyre.maintenance.been.BaseTyre baseTyre) {
binding.setTire1(new com.example.tyre.maintenance.been.BaseTyre());
binding.setTire2(new com.example.tyre.maintenance.been.BaseTyre());
binding.setTire3(new com.example.tyre.maintenance.been.BaseTyre());
binding.setTire4(new com.example.tyre.maintenance.been.BaseTyre());
binding.setTire5(new com.example.tyre.maintenance.been.BaseTyre());
binding.setTire6(new com.example.tyre.maintenance.been.BaseTyre());
switch (wheelPostion) {
case "左前轮":
binding.setTire1(baseTyre);
break;
case "右前轮":
binding.setTire2(baseTyre);
break;
case "左外轮":
binding.setTire3(baseTyre);
break;
case "左内轮":
binding.setTire4(baseTyre);
break;
case "右内轮":
binding.setTire5(baseTyre);
break;
case "右外轮":
binding.setTire6(baseTyre);
break;
}
}
// 检索车牌号
private void performSearchOld(String carNo) {
Map<String, String> map = new HashMap<>();
map.put("carNo", carNo);
OkGo.<MyResult>post(MyUrl.url + "/tyre/car/PdaQueryCarList")
.tag(this)
.upRequestBody(RequestBody.create(JSON, new Gson().toJson(map)))
.params("carNo", carNo)
.execute(
new MyRecultCall(progressDialog,this){
new MyRecultCall(progressDialog, this) {
@Override
public void onSuccess(Response<MyResult> response) {
super.onSuccess(response);
var body = response.body();
if (body.getCode()==0) {
if (body.getCode() == 0) {
Gson gson = new Gson();
List<BaseCar> baseCarList =
@ -215,6 +317,7 @@ public class TyreLayoutActivity extends AppCompatActivity {
}
}*/);
}
private void showCarSelectionDialog(List<String> carNoList) {
CarSelectionDialog dialog = new CarSelectionDialog(this, carNoList);
dialog.setOnCarSelectedListener(new CarSelectionDialog.OnCarSelectedListener() {
@ -222,25 +325,45 @@ public class TyreLayoutActivity extends AppCompatActivity {
public void onCarSelected(String carNo) {
// 处理选中的车辆
etPlateNumber.setText(carNo);
selectInfo(carNo);// 检索车辆信息
}
});
dialog.show();
}
private void carBangding(String PlateNumber) {
OkGo.<String>post(MyUrl.url + "/tyre/tyre/getCarBingTire")
.tag(this).params("carNo", PlateNumber)
.execute(new StringCallback() {
@Override
public void onSuccess(Response<String> response) {
//hideLoadingDialog();
// hideLoadingDialog();
String body = response.body();
Gson gson=new Gson();
Gson gson = new Gson();
// List<BaseTyre> baseTyreList = gson.fromJson(body, BaseTyre.class);
List<BaseTyre> baseTyreList = gson.fromJson(body, new com.google.gson.reflect.TypeToken<List<BaseTyre>>(){}.getType());
List<BaseTyre> baseTyreList =
gson.fromJson(body, new com.google.gson.reflect.TypeToken<List<BaseTyre>>() {
}.getType());
bindDataToViews(baseTyreList);
}
});
}
// private void bindDataToViews(List<BaseTyre> dataList) {
// // 假设 dataList.get(0) 是左前轮dataList.get(1) 是右前轮...
// // 请根据你实际的列表顺序调整索引
//
// if (dataList.size() >= 2) {
// // 绑定左前轮
// updateTireView(findViewById(R.id.tire_left_front), dataList.get(0));
//
// // 绑定右前轮
// updateTireView(findViewById(R.id.tire_right_front), dataList.get(1));
//
// // 绑定其他轮胎...
// // updateTireView(findViewById(R.id.tire_left_mid), dataList.get(2));
// }
// }
private void findCar(String carNumber) {
OkGo.<String>post(MyUrl.url + "/tyre/car/queryCarByRfid").tag(this).params("rfid", carNumber).execute(new StringCallback() {
@Override
@ -254,7 +377,7 @@ public class TyreLayoutActivity extends AppCompatActivity {
// 空值处理:若字段为 null 则显示空字符串
String carNo = safeGetString(baseCar.getCarNo());
etPlateNumber.setText(carNo);
}else {
} else {
new CommonDialog(TyreLayoutActivity.this).setMessage("请检查车辆芯片绑定数据!").show();
}
} catch (JsonSyntaxException e) {
@ -263,9 +386,11 @@ public class TyreLayoutActivity extends AppCompatActivity {
}
});
}
private String safeGetString(String value) {
return value == null || "null".equals(value) ? "" : value;
}
/**
* Include
*/
@ -292,15 +417,15 @@ public class TyreLayoutActivity extends AppCompatActivity {
targetView = findViewById(R.id.tire_middle_left);
TextView viewById = targetView.findViewById(R.id.iv_tire_icon);
viewById.setText("左内轮");
}else if ("右内轮".equals(pos)) {
} else if ("右内轮".equals(pos)) {
targetView = findViewById(R.id.tire_middle_right);
TextView viewById = targetView.findViewById(R.id.iv_tire_icon);
viewById.setText("右内轮");
}else if ("左外轮".equals(pos)) {
} else if ("左外轮".equals(pos)) {
targetView = findViewById(R.id.tire_bottom_left);
TextView viewById = targetView.findViewById(R.id.iv_tire_icon);
viewById.setText("左外轮");
}else if ("右外轮".equals(pos)) {
} else if ("右外轮".equals(pos)) {
targetView = findViewById(R.id.tire_bottom_right);
TextView viewById = targetView.findViewById(R.id.iv_tire_icon);
viewById.setText("右外轮");
@ -312,26 +437,12 @@ public class TyreLayoutActivity extends AppCompatActivity {
}
}
}
// private void bindDataToViews(List<BaseTyre> dataList) {
// // 假设 dataList.get(0) 是左前轮dataList.get(1) 是右前轮...
// // 请根据你实际的列表顺序调整索引
//
// if (dataList.size() >= 2) {
// // 绑定左前轮
// updateTireView(findViewById(R.id.tire_left_front), dataList.get(0));
//
// // 绑定右前轮
// updateTireView(findViewById(R.id.tire_right_front), dataList.get(1));
//
// // 绑定其他轮胎...
// // updateTireView(findViewById(R.id.tire_left_mid), dataList.get(2));
// }
// }
/**
* UI
*
* @param container include View
* @param data
* @param data
*/
private void updateTireView(View container, BaseTyre data) {
if (container == null) return;
@ -345,7 +456,7 @@ public class TyreLayoutActivity extends AppCompatActivity {
if (tvBrand != null) tvBrand.setText("品牌: " + data.getTyreBrand());
if (tvSpec != null) tvSpec.setText("规格: " + data.getTyreModel());
if (tvSelfNo != null) tvSelfNo.setText("自编号: " + data.getSelfNo());
if (tvDate != null) tvDate.setText("日期: " + data.getCreateTime());
// if (tvDate != null) tvDate.setText("日期: " + data.getCreateTime());
}
private void addToList(final List<EPC> list, final String epc, final byte rssi) {
@ -361,7 +472,7 @@ public class TyreLayoutActivity extends AppCompatActivity {
list.add(epcTag);
listepc.add(epc);
}else {
} else {
for (int i = 0; i < list.size(); i++) {
EPC mEPC = list.get(i);
// list contain this epc
@ -383,20 +494,20 @@ public class TyreLayoutActivity extends AppCompatActivity {
}
// play sound
lastTime = SystemClock.elapsedRealtime();
lastTime = SystemClock.elapsedRealtime();
long time = lastTime - nextTime;
if (time >= 60) {
Util.play(1, 0);
nextTime = lastTime;
Log.e("TAG", "run: " + time);
}
if (listepc != null && !listepc.isEmpty()){
if (listepc != null && !listepc.isEmpty()) {
startFlag = false;
String currentEpc = listepc.get(0);
if (isInRange(currentEpc, min, max)) {
//请求后台 查询车辆信息
// 请求后台 查询车辆信息
// car.setText(currentEpc);
//请求后台
// 请求后台
debounceHandler.removeMessages(1);
lastScannedEpc = currentEpc;
debounceHandler.sendEmptyMessageDelayed(1, DEBOUNCE_DELAY);
@ -408,50 +519,52 @@ public class TyreLayoutActivity extends AppCompatActivity {
});
Log.e("EPC", "listepc:+ " + listepc);
}
/**
*
* @param target
* @param min
* @param max
* @return true=false=
*/
public static boolean isInRange(String target, String min, String max) {
// 空值校验,避免空指针异常
if (target == null || min == null || max == null) {
return false;
}
// compareTo规则
// 1. 字符串相等返回0
// 2. 目标字符串 > 对比字符串 返回正数;
// 3. 目标字符串 < 对比字符串 返回负数。
// 因此target >= min 等价于 target.compareTo(min) >= 0
// target <= max 等价于 target.compareTo(max) <= 0。
return target.compareTo(min) >= 0 && target.compareTo(max) <= 0;
}
// 防抖延迟时间 (毫秒)
private static final long DEBOUNCE_DELAY = 500;
// 用于存储最后一次扫描到的 EPC
private String lastScannedEpc;
// 用于处理防抖逻辑的 Handler
private Handler debounceHandler = new Handler(new Handler.Callback() {
@Override
public boolean handleMessage(Message msg) {
if (msg.what == 1 && lastScannedEpc != null) {
// 延迟时间到,执行查询
showLoadingDialog();
//查询车辆数据方法
findCar(lastScannedEpc);
lastScannedEpc = null; // 清空,等待下一次扫描
}
return true;
}
});
private void clearData() {
listEPC.removeAll(listEPC);
listepc.removeAll(listepc);
}
private void registerReceiver() {
keyReceiver = new KeyReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction("android.rfid.FUN_KEY");
filter.addAction("android.intent.action.FUN_KEY");
registerReceiver(keyReceiver, filter);
}
private void unregisterReceiver() {
unregisterReceiver(keyReceiver);
}
private void showLoadingDialog() {
progressDialog = new ProgressDialog(this);
progressDialog.setMessage("数据加载中...");
progressDialog.setCancelable(false);
progressDialog.show();
}
private void hideLoadingDialog() {
if (progressDialog != null && progressDialog.isShowing()) {
progressDialog.dismiss();
}
}
// 1. 定义数据模型类 (对应后台返回的字段)
public static class TireData {
public String position; // 轮位名称
public String brand; // 品牌
public String spec; // 规格
public String installDate; // 安装日期
public TireData(String position, String brand, String spec, String installDate) {
this.position = position;
this.brand = brand;
this.spec = spec;
this.installDate = installDate;
}
}
private class KeyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
@ -474,35 +587,26 @@ public class TyreLayoutActivity extends AppCompatActivity {
case KeyEvent.KEYCODE_F4:
case KeyEvent.KEYCODE_F5:
case 136:
//扫描
// 扫描
startFlag = true;
break;
}
}
}
}
private void registerReceiver() {
keyReceiver = new KeyReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction("android.rfid.FUN_KEY");
filter.addAction("android.intent.action.FUN_KEY");
registerReceiver(keyReceiver, filter);
}
private void unregisterReceiver() {
unregisterReceiver(keyReceiver);
}
class InventoryThread extends Thread {
private List<TagModel> tagList;
byte[] accessPassword = Tools.HexString2Bytes("00000000");
private List<TagModel> tagList;
@Override
public void run() {
super.run();
while (runFlag) {
if (startFlag) {
tagList = manager.inventoryRealTime(); //实时盘存
tagList = manager.inventoryRealTime(); // 实时盘存
if (tagList != null && !tagList.isEmpty()) {
//播放提示音
// 播放提示音
Util.play(1, 0);
for (TagModel tag : tagList) {
if (tag == null) {
@ -510,7 +614,8 @@ public class TyreLayoutActivity extends AppCompatActivity {
// String epcStr = new String(epc);
addToList(listEPC, epcStr, (byte) -1);
} else {
String epcStr = Tools.Bytes2HexString(tag.getmEpcBytes(), tag.getmEpcBytes().length);
String epcStr =
Tools.Bytes2HexString(tag.getmEpcBytes(), tag.getmEpcBytes().length);
// String epcStr = new String(epc);
byte rssi = tag.getmRssi();
addToList(listEPC, epcStr, rssi);
@ -529,16 +634,4 @@ public class TyreLayoutActivity extends AppCompatActivity {
}
}
}
private void showLoadingDialog() {
progressDialog = new ProgressDialog(this);
progressDialog.setMessage("数据加载中...");
progressDialog.setCancelable(false);
progressDialog.show();
}
private void hideLoadingDialog() {
if (progressDialog != null && progressDialog.isShowing()) {
progressDialog.dismiss();
}
}
}

@ -0,0 +1,79 @@
package com.example.tyre.adapter;
import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.databinding.DataBindingUtil;
import androidx.recyclerview.widget.RecyclerView;
import com.example.tyre.BR;
import com.example.tyre.R;
import com.example.tyre.databinding.ItemCarRecordBinding;
import com.example.tyre.entity.CarMaintenanceLifecycleDTO;
import com.example.tyre.maintenance.been.CheckInstanceFiles;
import java.util.List;
/**
* @author wanghao
* @date 2024/3/11
*/
public class CarRecordAdapter extends RecyclerView.Adapter<CarRecordAdapter.MyViewHolder> {
private List<CarMaintenanceLifecycleDTO> list;
private static Context context;
private LayoutInflater inflater;
private ItemClickCall clickCall;
public CarRecordAdapter(Context context, ItemClickCall clickCall) {
this.context = context;
this.clickCall = clickCall;
inflater = LayoutInflater.from(context);
}
public void setList(List<CarMaintenanceLifecycleDTO> list) {
this.list = list;
}
@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
ItemCarRecordBinding binding = DataBindingUtil.inflate(inflater, R.layout.item_car_record, parent, false);
return new MyViewHolder(binding);
}
// @SuppressLint("CheckResult")
@Override
public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
var item = list.get(position);
var binding = holder.binding;
binding.setVariable(BR.item, item);
}
@Override
public int getItemCount() {
return list==null?0:list.size();
}
class MyViewHolder extends RecyclerView.ViewHolder {
private ItemCarRecordBinding binding;
public MyViewHolder(ItemCarRecordBinding binding) {
super(binding.getRoot());
this.binding = binding;
}
}
public interface ItemClickCall {
void onClick(int position);
}
}

@ -0,0 +1,50 @@
package com.example.tyre.entity;
import java.io.Serializable;
import com.example.tyre.maintenance.been.BaseTyre;
import java.util.List;
/**
* DTO
* <p>
*
* 线
*
* </p>
*/
public class CarLifecycleDTO implements Serializable
{
private CarLifecycleSummaryDTO car;
/** 当前装车轮胎快照,数量较少(通常不超过车辆轮位数),随概要一次返回用于首屏快速展示。 */
private List<BaseTyre> mountedTyres ;
/** 车辆维保工单历史,随生命周期聚合接口返回,避免页面重复调用单独的维保列表接口。 */
private List<CarMaintenanceLifecycleDTO> maintenanceList ;
public List<BaseTyre> getMountedTyres() {
return mountedTyres;
}
public void setMountedTyres(List<BaseTyre> mountedTyres) {
this.mountedTyres = mountedTyres;
}
public List<CarMaintenanceLifecycleDTO> getMaintenanceList() {
return maintenanceList;
}
public void setMaintenanceList(List<CarMaintenanceLifecycleDTO> maintenanceList) {
this.maintenanceList = maintenanceList;
}
public CarLifecycleSummaryDTO getCar() {
return car;
}
public void setCar(CarLifecycleSummaryDTO car) {
this.car = car;
}
}

@ -0,0 +1,302 @@
package com.example.tyre.entity;
import java.math.BigDecimal;
import java.util.Date;
/**
* DTO
* <p>
* 线
* 便eventType
* INSTALL MAINTENANCE
* </p>
*/
public class CarLifecycleEventDTO
{
/** 事件类型字典值区分数据来源。例如INSTALL轮胎装卸、MAINTENANCE维保工单。 */
private String eventType;
/** 事件发生时间,统一取各来源表中的操作/创建时间,用于时间轴排序。 */
private Date eventTime;
/** 轮胎RFID编码仅在事件类型为轮胎装卸时有效。 */
private String tyreRfid;
/** 轮胎编号,业务展示用。 */
private String tyreNo;
/** 轮胎自编号,与 tyreNo 区分,用于内部管理。 */
private String selfNo;
/** 轮胎品牌。 */
private String tyreBrand;
/** 轮胎规格型号。 */
private String tyreModel;
/** 轮位名称,例如:左前轮、右后第二轴等,仅在装卸事件中有效。 */
private String wheelPostion;
/** 事件关联的行驶里程(字符串形式,保留原始录入格式)。 */
private String mileage;
/** 事件关联的花纹深度(毫米),用于磨损评估。 */
private String patternDepth;
/** 状态字典值,例如:工单状态、轮胎状态等,视 eventType 而定。 */
private String status;
/** 工单编号,仅在事件类型为维保工单时有效。 */
private String orderNo;
/** 类型编码,例如:维保类型字典值、操作类型字典值。 */
private String typeCode;
/** 修理厂/工厂名称,仅在维保工单事件中有效。 */
private String factoryName;
/** 录入里程(数值型),维保工单或质检记录中由用户录入的当前总里程。 */
private BigDecimal inputMileage;
/** 上次里程(数值型),维保工单中记录的上一次保养时的里程。 */
private BigDecimal lastMileage;
/** 保养/维修日期,维保工单事件中的计划或实际执行日期。 */
private Date maintainDate;
/** 事件描述/故障描述,维保工单中的故障现象或备注信息。 */
private String description;
/** 质检结果,仅在轮胎质检相关事件中有效。 */
private String result;
/** 维保/检测类型字典值,例如:一级保养、二级保养、日常巡检。 */
private String maintenanceType;
/** 轮胎里程记录开始时间,仅在里程类事件中有效。 */
private Date startTime;
/** 轮胎里程记录结束时间,仅在里程类事件中有效。 */
private Date endTime;
public String getEventType()
{
return eventType;
}
public void setEventType(String eventType)
{
this.eventType = eventType;
}
public Date getEventTime()
{
return eventTime;
}
public void setEventTime(Date eventTime)
{
this.eventTime = eventTime;
}
public String getTyreRfid()
{
return tyreRfid;
}
public void setTyreRfid(String tyreRfid)
{
this.tyreRfid = tyreRfid;
}
public String getTyreNo()
{
return tyreNo;
}
public void setTyreNo(String tyreNo)
{
this.tyreNo = tyreNo;
}
public String getSelfNo()
{
return selfNo;
}
public void setSelfNo(String selfNo)
{
this.selfNo = selfNo;
}
public String getTyreBrand()
{
return tyreBrand;
}
public void setTyreBrand(String tyreBrand)
{
this.tyreBrand = tyreBrand;
}
public String getTyreModel()
{
return tyreModel;
}
public void setTyreModel(String tyreModel)
{
this.tyreModel = tyreModel;
}
public String getWheelPostion()
{
return wheelPostion;
}
public void setWheelPostion(String wheelPostion)
{
this.wheelPostion = wheelPostion;
}
public String getMileage()
{
return mileage;
}
public void setMileage(String mileage)
{
this.mileage = mileage;
}
public String getPatternDepth()
{
return patternDepth;
}
public void setPatternDepth(String patternDepth)
{
this.patternDepth = patternDepth;
}
public String getStatus()
{
return status;
}
public void setStatus(String status)
{
this.status = status;
}
public String getOrderNo()
{
return orderNo;
}
public void setOrderNo(String orderNo)
{
this.orderNo = orderNo;
}
public String getTypeCode()
{
return typeCode;
}
public void setTypeCode(String typeCode)
{
this.typeCode = typeCode;
}
public String getFactoryName()
{
return factoryName;
}
public void setFactoryName(String factoryName)
{
this.factoryName = factoryName;
}
public BigDecimal getInputMileage()
{
return inputMileage;
}
public void setInputMileage(BigDecimal inputMileage)
{
this.inputMileage = inputMileage;
}
public BigDecimal getLastMileage()
{
return lastMileage;
}
public void setLastMileage(BigDecimal lastMileage)
{
this.lastMileage = lastMileage;
}
public Date getMaintainDate()
{
return maintainDate;
}
public void setMaintainDate(Date maintainDate)
{
this.maintainDate = maintainDate;
}
public String getDescription()
{
return description;
}
public void setDescription(String description)
{
this.description = description;
}
public String getResult()
{
return result;
}
public void setResult(String result)
{
this.result = result;
}
public String getMaintenanceType()
{
return maintenanceType;
}
public void setMaintenanceType(String maintenanceType)
{
this.maintenanceType = maintenanceType;
}
public Date getStartTime()
{
return startTime;
}
public void setStartTime(Date startTime)
{
this.startTime = startTime;
}
public Date getEndTime()
{
return endTime;
}
public void setEndTime(Date endTime)
{
this.endTime = endTime;
}
}

@ -0,0 +1,113 @@
package com.example.tyre.entity;
import java.io.Serializable;
import java.math.BigDecimal;
/**
* DTO
* <p>
*
* base_car / {@link BaseCarLifecycleMapper#selectLifecycleCar}
* </p>
*/
public class CarLifecycleSummaryDTO implements Serializable
{
private static final long serialVersionUID = 1L;
/** 车辆主键IDbase_car 表的唯一标识,用于后续子查询精确关联。 */
private Long carId;
/** 车牌号车辆的唯一业务标识例如粤B12345。 */
private String carNo;
/** 所属部门ID关联 sys_dept用于数据权限过滤。 */
private Long deptId;
/** 所属车队名称由部门ID关联翻译而来前端直接展示。 */
private String team;
/** 线路名称,车辆运营的公交/客运线路。 */
private String line;
/** 车型,例如:纯电动大巴、混合动力公交等字典值。 */
private String type;
/**
*
* <p>
* input_mileage
* 使 BigDecimal
* </p>
*/
private String inputMileage;
public Long getCarId()
{
return carId;
}
public void setCarId(Long carId)
{
this.carId = carId;
}
public String getCarNo()
{
return carNo;
}
public void setCarNo(String carNo)
{
this.carNo = carNo;
}
public Long getDeptId()
{
return deptId;
}
public void setDeptId(Long deptId)
{
this.deptId = deptId;
}
public String getTeam()
{
return team;
}
public void setTeam(String team)
{
this.team = team;
}
public String getLine()
{
return line;
}
public void setLine(String line)
{
this.line = line;
}
public String getType()
{
return type;
}
public void setType(String type)
{
this.type = type;
}
public String getInputMileage()
{
return inputMileage;
}
public void setInputMileage(String inputMileage)
{
this.inputMileage = inputMileage;
}
}

@ -0,0 +1,188 @@
package com.example.tyre.entity;
import java.io.Serializable;
/**
* DTO
* <p>
* Tab
* biz_maintenance_order plate_number
* </p>
*/
public class CarMaintenanceLifecycleDTO implements Serializable {
private static final long serialVersionUID = 1L;
/**
* ID biz_maintenance_order.order_id
*/
private Long orderId;
/**
* WB202401150001
*/
private String orderNo;
/**
* ID vehicle_id
*/
private Long vehicleId;
/**
*
*/
private String plateNumber;
/**
*
*/
private String typeCode;
private String typeName;
/**
*
*/
private String status;
/**
* /
*/
private String inputMileage;
/**
*
*/
private String lastMileage;
/**
* /
*/
private String maintainDate;
/**
*
*/
private String factoryName;
/**
* /
*/
private String description;
public String getTypeName() {
if (typeCode == null) {
typeName = "";
} else if (typeCode.equals("1")) {
typeName = "二级保养";
} else if (typeCode.equals("2")) {
typeName = "抢碎修";
} else if (typeCode.equals("3")) {
typeName = "拆报废车";
} else if (typeCode.equals("4")) {
typeName = "月检";
} else if (typeCode.equals("5")) {
typeName = "小修";
} else if (typeCode.equals("6")) {
typeName = "轮胎修补";
} else if (typeCode.equals("7")) {
typeName = "轮胎报废";
}
return typeName;
}
public Long getOrderId() {
return orderId;
}
public void setOrderId(Long orderId) {
this.orderId = orderId;
}
public String getOrderNo() {
return orderNo;
}
public void setOrderNo(String orderNo) {
this.orderNo = orderNo;
}
public Long getVehicleId() {
return vehicleId;
}
public void setVehicleId(Long vehicleId) {
this.vehicleId = vehicleId;
}
public String getPlateNumber() {
return plateNumber;
}
public void setPlateNumber(String plateNumber) {
this.plateNumber = plateNumber;
}
public String getTypeCode() {
return typeCode;
}
public void setTypeCode(String typeCode) {
this.typeCode = typeCode;
}
public String getStatus() {
if (status .equals("UNSTARTED")) {
return "未开始";
} else if (status .equals("PROCESSING")) {
return "执行中";
} else if (status .equals("COMPLETED")) {
return "已完成";
}
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getInputMileage() {
return inputMileage;
}
public void setInputMileage(String inputMileage) {
this.inputMileage = inputMileage;
}
public String getLastMileage() {
return lastMileage;
}
public void setLastMileage(String lastMileage) {
this.lastMileage = lastMileage;
}
public String getMaintainDate() {
return maintainDate;
}
public void setMaintainDate(String maintainDate) {
this.maintainDate = maintainDate;
}
public String getFactoryName() {
return factoryName;
}
public void setFactoryName(String factoryName) {
this.factoryName = factoryName;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}

@ -1,214 +1,398 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.core.widget.NestedScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
android:background="#F0F4F8"> <!-- 浅灰色背景提升质感 -->
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<androidx.constraintlayout.widget.ConstraintLayout
<data>
<variable
name="tire1"
type="com.example.tyre.maintenance.been.BaseTyre" />
<variable
name="tire2"
type="com.example.tyre.maintenance.been.BaseTyre" />
<variable
name="tire3"
type="com.example.tyre.maintenance.been.BaseTyre" />
<variable
name="tire4"
type="com.example.tyre.maintenance.been.BaseTyre" />
<variable
name="tire5"
type="com.example.tyre.maintenance.been.BaseTyre" />
<variable
name="tire6"
type="com.example.tyre.maintenance.been.BaseTyre" />
<variable
name="adapter"
type="com.example.tyre.adapter.CarRecordAdapter" />
</data>
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="12dp">
android:layout_height="match_parent"
android:background="#F0F4F8"
android:fillViewport="true"> <!-- 浅灰色背景提升质感 -->
<!-- 顶部:搜索卡片 -->
<com.google.android.material.card.MaterialCardView
android:id="@+id/card_search"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:cardCornerRadius="16dp"
app:cardElevation="4dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="12dp">
<!-- 顶部:搜索卡片 -->
<com.google.android.material.card.MaterialCardView
android:id="@+id/card_search"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardCornerRadius="16dp"
app:cardElevation="4dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="24dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginBottom="20dp"
android:text="公交车轮胎管理"
android:textColor="#202020"
android:textSize="18sp"
android:textStyle="bold" />
<!-- 车牌号输入 -->
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/til_plate_number"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.Dense"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:hint="请输入车牌号"
app:endIconDrawable="@mipmap/search_icon"
app:endIconMode="custom">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/et_plate_number"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="number"
android:maxLines="1" />
</com.google.android.material.textfield.TextInputLayout>
<Button
android:id="@+id/btn_retrieve"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="立即检索"
android:textSize="16sp"
app:cornerRadius="8dp" />
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="24dp">
android:layout_height="50dp"
android:layout_marginTop="12dp"
android:background="@drawable/card_bg"
android:padding="12dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="公交车轮胎管理"
android:textSize="18sp"
android:textStyle="bold"
android:layout_height="match_parent"
android:gravity="center"
android:text="车辆最新里程:"
android:textColor="#202020"
android:layout_gravity="center_horizontal"
android:layout_marginBottom="20dp"/>
<!-- 车牌号输入 -->
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/til_plate_number"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.Dense"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="请输入车牌号"
android:layout_marginBottom="16dp"
app:endIconMode="custom"
app:endIconDrawable="@mipmap/search_icon">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/et_plate_number"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="number"
android:maxLines="1" />
</com.google.android.material.textfield.TextInputLayout>
<Button
android:id="@+id/btn_retrieve"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="立即检索"
android:textSize="16sp"
app:cornerRadius="8dp" />
android:textStyle="bold" />
<TextView
android:id="@+id/select_info_mileage"
android:layout_width="100dp"
android:layout_height="match_parent"
android:gravity="center"
android:text="0"
android:textColor="#202020"
android:textSize="16sp"
android:textStyle="bold" />
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
<!-- 底部:三轴轮位图展示区 -->
<com.google.android.material.card.MaterialCardView
android:id="@+id/card_visual"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="16dp"
app:cardCornerRadius="16dp"
app:cardElevation="2dp"
app:layout_constraintTop_toBottomOf="@id/card_search"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent">
<androidx.constraintlayout.widget.ConstraintLayout
<!-- 底部:三轴轮位图展示区 -->
<com.google.android.material.card.MaterialCardView
android:id="@+id/card_visual"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp">
android:layout_marginTop="16dp"
android:visibility="gone"
app:cardCornerRadius="16dp"
app:cardElevation="2dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/card_search">
<!-- 辅助线:垂直中心线 (分隔左右轮胎) -->
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline_vertical_center"
android:layout_width="wrap_content"
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp">
<!-- 辅助线:垂直中心线 (分隔左右轮胎) -->
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline_vertical_center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.5" />
<!-- 辅助线:水平线 1 (第1轴位置) -->
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline_axis_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_begin="96dp" />
<!-- 辅助线:水平线 2 (第2轴位置) -->
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline_axis_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_end="235dp" />
<!-- 辅助线:水平线 3 (第3轴位置) -->
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline_axis_3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_begin="399dp" />
<!-- 车头指示 -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="🚗 车头方向"
android:textColor="#999999"
android:textSize="10sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<!-- ================= 第1轴 (前轴) ================= -->
<!-- 左侧轮胎 (1轴) -->
<include
android:id="@+id/tire_left_front"
layout="@layout/item_tire"
android:layout_width="0dp"
android:layout_height="120dp"
app:layout_constraintBottom_toBottomOf="@id/guideline_axis_1"
app:layout_constraintEnd_toStartOf="@id/guideline_vertical_center"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/guideline_axis_1" />
<!-- 右侧轮胎 (1轴) -->
<!-- ================= 第2轴 (中轴) ================= -->
<!-- 左侧轮胎 (2轴) -->
<include
android:id="@+id/tire_right_front"
layout="@layout/item_tire"
android:layout_width="0dp"
android:layout_height="120dp"
app:layout_constraintBottom_toBottomOf="@id/guideline_axis_1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toEndOf="@id/guideline_vertical_center"
app:layout_constraintTop_toTopOf="@id/guideline_axis_1" />
<include
android:id="@+id/tire_middle_left"
layout="@layout/item_tire"
android:layout_width="0dp"
android:layout_height="120dp"
app:layout_constraintBottom_toBottomOf="@id/guideline_axis_2"
app:layout_constraintEnd_toStartOf="@id/guideline_vertical_center"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/guideline_axis_2" />
<!-- 右侧轮胎 (2轴) -->
<include
android:id="@+id/tire_middle_right"
layout="@layout/item_tire"
android:layout_width="0dp"
android:layout_height="120dp"
app:layout_constraintBottom_toBottomOf="@id/guideline_axis_2"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@id/guideline_vertical_center"
app:layout_constraintTop_toTopOf="@id/guideline_axis_2" />
<!-- ================= 第3轴 (后轴) ================= -->
<!-- 左侧轮胎 (3轴) -->
<include
android:id="@+id/tire_bottom_left"
layout="@layout/item_tire"
android:layout_width="0dp"
android:layout_height="120dp"
app:layout_constraintBottom_toBottomOf="@id/guideline_axis_3"
app:layout_constraintEnd_toStartOf="@id/guideline_vertical_center"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/guideline_axis_3" />
<!-- 右侧轮胎 (3轴) -->
<include
android:id="@+id/tire_bottom_right"
layout="@layout/item_tire"
android:layout_width="0dp"
android:layout_height="120dp"
app:layout_constraintBottom_toBottomOf="@id/guideline_axis_3"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@id/guideline_vertical_center"
app:layout_constraintTop_toTopOf="@id/guideline_axis_3" />
</androidx.constraintlayout.widget.ConstraintLayout>
</com.google.android.material.card.MaterialCardView>
<LinearLayout
style="@style/layout_card_style"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.5" />
android:gravity="center">
<!-- 辅助线:水平线 1 (第1轴位置) -->
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline_axis_1"
android:layout_width="wrap_content"
<include
android:id="@+id/tireClick1"
layout="@layout/layout_trae_info"
android:layout_width="80dp"
android:layout_height="wrap_content"
app:data="@{tire1}"
app:locationOld='@{"左前轮"}' />
<View
android:layout_width="match_parent"
android:layout_height="3dp"
android:layout_weight="1"
android:background="#E3E6EC" />
<TextView
android:layout_width="30dp"
android:layout_height="30dp"
android:background="@drawable/bg_grey"
android:gravity="center"
android:text="1"
android:textStyle="bold" />
<View
android:layout_width="match_parent"
android:layout_height="3dp"
android:layout_weight="1"
android:background="#E3E6EC" />
<include
android:id="@+id/tireClick2"
layout="@layout/layout_trae_info"
android:layout_width="80dp"
android:layout_height="wrap_content"
app:data="@{tire2}"
app:locationOld='@{"右前轮"}' />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_begin="96dp" />
android:layout_marginTop="8dp"
android:gravity="center">
<!-- 辅助线:水平线 2 (第2轴位置) -->
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline_axis_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_begin="241dp" />
<include
android:id="@+id/tireClick3"
layout="@layout/layout_trae_info"
android:layout_width="80dp"
android:layout_height="wrap_content"
app:data="@{tire3}"
app:locationOld='@{"左外轮"}' />
<!-- 辅助线:水平线 3 (第3轴位置) -->
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline_axis_3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_begin="399dp" />
<include
android:id="@+id/tireClick4"
layout="@layout/layout_trae_info"
android:layout_width="80dp"
android:layout_height="wrap_content"
android:layout_marginStart="4dp"
app:data="@{tire4}"
app:locationOld='@{"左内轮"}' />
<!-- 车头指示 -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="🚗 车头方向"
android:textColor="#999999"
android:textSize="10sp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
<View
android:layout_width="match_parent"
android:layout_height="3dp"
android:layout_weight="1"
android:background="#E3E6EC" />
<!-- ================= 第1轴 (前轴) ================= -->
<!-- 左侧轮胎 (1轴) -->
<include
android:id="@+id/tire_left_front"
layout="@layout/item_tire"
android:layout_width="0dp"
android:layout_height="120dp"
app:layout_constraintBottom_toBottomOf="@id/guideline_axis_1"
app:layout_constraintEnd_toStartOf="@id/guideline_vertical_center"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/guideline_axis_1" />
<TextView
android:layout_width="30dp"
android:layout_height="30dp"
android:background="@drawable/bg_grey"
android:gravity="center"
android:text="2"
android:textStyle="bold" />
<!-- 右侧轮胎 (1轴) -->
<View
android:layout_width="match_parent"
android:layout_height="3dp"
android:layout_weight="1"
android:background="#E3E6EC" />
<!-- ================= 第2轴 (中轴) ================= -->
<!-- 左侧轮胎 (2轴) -->
<include
android:id="@+id/tire_right_front"
layout="@layout/item_tire"
android:layout_width="0dp"
android:layout_height="120dp"
app:layout_constraintBottom_toBottomOf="@id/guideline_axis_1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toEndOf="@id/guideline_vertical_center"
app:layout_constraintTop_toTopOf="@id/guideline_axis_1" />
<include
android:id="@+id/tireClick5"
layout="@layout/layout_trae_info"
android:layout_width="80dp"
android:layout_height="wrap_content"
app:data="@{tire5}"
app:locationOld='@{"右内轮"}' />
<include
android:id="@+id/tire_middle_left"
layout="@layout/item_tire"
android:layout_width="0dp"
android:layout_height="120dp"
app:layout_constraintTop_toTopOf="@id/guideline_axis_2"
app:layout_constraintBottom_toBottomOf="@id/guideline_axis_2"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@id/guideline_vertical_center"
app:layout_constraintHorizontal_bias="0.5" />
<include
android:id="@+id/tireClick6"
layout="@layout/layout_trae_info"
android:layout_width="80dp"
android:layout_height="wrap_content"
android:layout_marginStart="4dp"
app:data="@{tire6}"
app:locationOld='@{"右外轮"}' />
</LinearLayout>
<!-- 右侧轮胎 (2轴) -->
<include
android:id="@+id/tire_middle_right"
layout="@layout/item_tire"
android:layout_width="0dp"
android:layout_height="120dp"
app:layout_constraintTop_toTopOf="@id/guideline_axis_2"
app:layout_constraintBottom_toBottomOf="@id/guideline_axis_2"
app:layout_constraintStart_toEndOf="@id/guideline_vertical_center"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5" />
</LinearLayout>
<!-- ================= 第3轴 (后轴) ================= -->
<!-- 左侧轮胎 (3轴) -->
<include
android:id="@+id/tire_bottom_left"
layout="@layout/item_tire"
android:layout_width="0dp"
android:layout_height="120dp"
app:layout_constraintTop_toTopOf="@id/guideline_axis_3"
app:layout_constraintBottom_toBottomOf="@id/guideline_axis_3"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@id/guideline_vertical_center"
app:layout_constraintHorizontal_bias="0.5" />
<!-- 右侧轮胎 (3轴) -->
<include
android:id="@+id/tire_bottom_right"
layout="@layout/item_tire"
android:layout_width="0dp"
android:layout_height="120dp"
app:layout_constraintTop_toTopOf="@id/guideline_axis_3"
app:layout_constraintBottom_toBottomOf="@id/guideline_axis_3"
app:layout_constraintStart_toEndOf="@id/guideline_vertical_center"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5" />
</androidx.constraintlayout.widget.ConstraintLayout>
</com.google.android.material.card.MaterialCardView>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.core.widget.NestedScrollView>
<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="400dp"
android:layout_marginTop="12dp"
android:adapter="@{adapter}"
android:background="@drawable/card_bg"
android:padding="8dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
</LinearLayout>
</ScrollView>
</layout>

@ -0,0 +1,185 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable
name="item"
type="com.example.tyre.entity.CarMaintenanceLifecycleDTO" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:paddingBottom="16dp">
<!-- 左侧:时间轴线和圆点 -->
<LinearLayout
android:layout_width="24dp"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:orientation="vertical">
<!-- 圆点 -->
<View
android:layout_width="10dp"
android:layout_height="10dp"
android:background="@drawable/shape_circle_blue" />
<!-- 竖线 (默认显示,代码中会控制最后一条隐藏) -->
<View
android:id="@+id/view_line"
android:layout_width="2dp"
android:layout_height="0dp"
android:layout_marginTop="4dp"
android:layout_weight="1"
android:background="#E0E0E0" />
</LinearLayout>
<!-- 右侧:内容区域 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingStart="8dp">
<!-- 时间 -->
<TextView
android:id="@+id/tv_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{item.maintainDate}"
android:textColor="#999999"
android:textSize="13sp" />
<!-- 标题 (加粗) -->
<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text='@{item.getTypeName+""+item.orderNo}'
android:textColor="#333333"
android:textSize="15sp"
android:textStyle="bold" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp">
<TextView
android:layout_width="55dp"
android:layout_height="wrap_content"
android:text="工单号:"
android:textColor="#666666"
android:textSize="14sp" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@{item.orderNo}"
android:textColor="#666666"
android:textSize="14sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="维保类型:"
android:textColor="#666666"
android:textSize="14sp" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@{item.getTypeName}"
android:textColor="#666666"
android:textSize="14sp" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp">
<TextView
android:layout_width="55dp"
android:layout_height="wrap_content"
android:text="状态:"
android:textColor="#666666"
android:textSize="14sp" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@{item.status}"
android:textColor="#666666"
android:textSize="14sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="站点:"
android:textColor="#666666"
android:textSize="14sp" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@{item.factoryName}"
android:textColor="#666666"
android:textSize="14sp" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="录入里程:"
android:textColor="#666666"
android:textSize="14sp" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@{item.inputMileage}"
android:textColor="#666666"
android:textSize="14sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="上次里程:"
android:textColor="#666666"
android:textSize="14sp" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@{item.lastMileage}"
android:textColor="#666666"
android:textSize="14sp" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
</layout>
Loading…
Cancel
Save