From c05bc90529f04b27ac71c556dc38513b6a0e7892 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E5=87=A4=E5=90=89?= Date: Wed, 9 Apr 2025 23:46:20 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E5=96=84=E5=90=8C=E6=AD=A5=E5=8A=9F?= =?UTF-8?q?=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/iflytop/profilometer/api/sync/SyncApi.java | 55 +++++++++++++- .../iflytop/profilometer/api/sync/SyncRoutes.kt | 11 +++ .../core/db/helper/MyDatabaseHelper.java | 7 +- .../profilometer/core/sync/UploadManager.java | 83 +++++++++++++++++----- .../com/iflytop/profilometer/dao/SyncTaskDao.java | 5 ++ .../profilometer/model/entity/SyncTask.java | 9 +++ 6 files changed, 149 insertions(+), 21 deletions(-) diff --git a/app/src/main/java/com/iflytop/profilometer/api/sync/SyncApi.java b/app/src/main/java/com/iflytop/profilometer/api/sync/SyncApi.java index faa5150..b8e573a 100644 --- a/app/src/main/java/com/iflytop/profilometer/api/sync/SyncApi.java +++ b/app/src/main/java/com/iflytop/profilometer/api/sync/SyncApi.java @@ -3,11 +3,14 @@ package com.iflytop.profilometer.api.sync; import android.content.Context; import com.iflytop.profilometer.common.constant.SyncStatusType; +import com.iflytop.profilometer.common.enums.SyncStatus; import com.iflytop.profilometer.common.result.Result; import com.iflytop.profilometer.core.system.SystemService; import com.iflytop.profilometer.dao.ProfileRecordDao; +import com.iflytop.profilometer.dao.ProfileRecordPointSetDao; import com.iflytop.profilometer.dao.SyncTaskDao; import com.iflytop.profilometer.model.entity.ProfileRecordDescription; +import com.iflytop.profilometer.model.entity.ProfileRecordPointSet; import com.iflytop.profilometer.model.entity.SyncTask; import java.util.HashMap; @@ -47,7 +50,13 @@ public class SyncApi { ProfileRecordDao profileRecordDao = new ProfileRecordDao(context); for (int i = 0; i < ids.size(); i++) { Long id = ids.getLong(i); + SyncTask syncTask = syncTaskDao.getSyncTaskById(id); + if (syncTask != null) { + continue; + } ProfileRecordDescription profileRecordDescription = profileRecordDao.getProfileRecordById(id); + profileRecordDescription.setSyncStatus(SyncStatus.wait); + profileRecordDao.updateProfileRecord(profileRecordDescription); syncTaskDao.insertSyncTask(profileRecordDescription); SystemService.getInstance().getUploadManager().addUploadId(id); } @@ -55,6 +64,45 @@ public class SyncApi { } /** + * 测量记录详情 + */ + + public String detail(Long id) { + SyncTaskDao syncTaskDao = new SyncTaskDao(context); + ProfileRecordPointSetDao profileRecordPointSetDao = new ProfileRecordPointSetDao(context); + SyncTask syncTask = syncTaskDao.getSyncTaskById(id); + ProfileRecordPointSet pointSet = profileRecordPointSetDao.getProfileRecordPointSetByUuid(syncTask.getUuid()); + Map map = new HashMap<>(); + map.put("id", syncTask.getId()); + map.put("uuid", syncTask.getUuid()); + map.put("operator", syncTask.getOperator()); + map.put("name", syncTask.getName()); + map.put("tljCode", syncTask.getTljCode()); + map.put("gwdCode", syncTask.getGwdCode()); + map.put("xmCode", syncTask.getXmCode()); + map.put("stationCode", syncTask.getStationCode()); + map.put("dataType", syncTask.getDataType()); + map.put("dataSource", syncTask.getDataSource()); + map.put("railSize", syncTask.getRailSize()); + map.put("lineClassify", syncTask.getLineClassify()); + map.put("batch", syncTask.getBatch()); + map.put("xbCode", syncTask.getXbCode()); + map.put("mileage", syncTask.getMileage()); + map.put("unitType", syncTask.getUnitType()); + map.put("extraDesc", syncTask.getExtraDesc()); + map.put("syncStatus", syncTask.getSyncStatus()); + map.put("turnoutNum", syncTask.getTurnoutNum()); + map.put("sleeperNum", syncTask.getSleeperNum()); + map.put("radius", syncTask.getRadius()); + map.put("errorMsg", syncTask.getErrorMsg()); + + map.put("leftPoints", pointSet.getLeftPoints()); + map.put("rightPoints", pointSet.getRightPoints()); + map.put("createTime", syncTask.getCreateTime()); + return Result.success(map); + } + + /** * 清空同步任务列表 */ public String emptyAll() { @@ -75,7 +123,12 @@ public class SyncApi { map.put("fail", fail);//同步失败数量 int total = syncTaskDao.getSyncTaskCount(); map.put("total", total);//总数量 - map.put("status", SyncStatusType.PAUSED); + int queueSize = SystemService.getInstance().getUploadManager().getUploadQueue().size(); + if (queueSize > 0) { + map.put("status", SyncStatusType.UPLOADING); + } else { + map.put("status", SyncStatusType.FINISHED); + } return Result.success(map); } diff --git a/app/src/main/java/com/iflytop/profilometer/api/sync/SyncRoutes.kt b/app/src/main/java/com/iflytop/profilometer/api/sync/SyncRoutes.kt index b7afc99..3a99185 100644 --- a/app/src/main/java/com/iflytop/profilometer/api/sync/SyncRoutes.kt +++ b/app/src/main/java/com/iflytop/profilometer/api/sync/SyncRoutes.kt @@ -39,6 +39,17 @@ fun Routing.syncRoutes(context: Context) { } /** + * 同步记录详情 + */ + post("/api/sync/detail") { + val requestBody = call.receiveText() + val jsonObj = JSONUtil.parseObj(requestBody) + val id = jsonObj.getLong("id") + val jsonResponse = api.detail(id) + call.respondText(jsonResponse, ContentType.Application.Json) + } + + /** * 获取同步任务剩余数量与状态 */ post("/api/sync/progress") { diff --git a/app/src/main/java/com/iflytop/profilometer/core/db/helper/MyDatabaseHelper.java b/app/src/main/java/com/iflytop/profilometer/core/db/helper/MyDatabaseHelper.java index 226dfed..32a547a 100644 --- a/app/src/main/java/com/iflytop/profilometer/core/db/helper/MyDatabaseHelper.java +++ b/app/src/main/java/com/iflytop/profilometer/core/db/helper/MyDatabaseHelper.java @@ -7,7 +7,7 @@ import android.database.sqlite.SQLiteOpenHelper; public class MyDatabaseHelper extends SQLiteOpenHelper { private static final String DATABASE_NAME = "app.db"; - private static final int DATABASE_VERSION = 8; // 升级版本号 + private static final int DATABASE_VERSION = 9; // 升级版本号 // 表名 public static final String TABLE_APP_USER = "app_user"; @@ -126,8 +126,9 @@ public class MyDatabaseHelper extends SQLiteOpenHelper { + "radius TEXT, " + "sync_status TEXT, " + "turnout_num TEXT, " - + "sleeper_num TEXT," - + "extraDesc TEXT" + + "sleeper_num TEXT, " + + "extraDesc TEXT, " + + "error_msg TEXT" + ");"; // 新增:基础数据表建表语句 diff --git a/app/src/main/java/com/iflytop/profilometer/core/sync/UploadManager.java b/app/src/main/java/com/iflytop/profilometer/core/sync/UploadManager.java index 0c83749..46d7700 100644 --- a/app/src/main/java/com/iflytop/profilometer/core/sync/UploadManager.java +++ b/app/src/main/java/com/iflytop/profilometer/core/sync/UploadManager.java @@ -9,9 +9,11 @@ import com.iflytop.profilometer.core.migration.measure.drawer.type.XYPoint; import com.iflytop.profilometer.core.websocket.WebSocketManager; import com.iflytop.profilometer.dao.ProfileRecordDao; import com.iflytop.profilometer.dao.ProfileRecordPointSetDao; +import com.iflytop.profilometer.dao.SyncTaskDao; import com.iflytop.profilometer.dao.SystemConfigDao; import com.iflytop.profilometer.model.entity.ProfileRecordDescription; import com.iflytop.profilometer.model.entity.ProfileRecordPointSet; +import com.iflytop.profilometer.model.entity.SyncTask; import com.iflytop.profilometer.model.entity.SystemConfig; import java.io.ByteArrayInputStream; @@ -53,7 +55,19 @@ public class UploadManager { try { // 阻塞获取任务,队列为空时会一直等待 Long uploadId = uploadQueue.take(); - processUpload(uploadId); + boolean result = false; + try { + result = processUpload(uploadId); + } catch (Exception e) { + fail++; + } + Map itemMap = new HashMap<>(); + itemMap.put("type", "sync-item-finish"); + Map itemDataMap = new HashMap<>(); + itemDataMap.put("id", uploadId); + itemDataMap.put("success", result); + itemMap.put("data", itemDataMap); + WebSocketManager.send(JSONUtil.toJsonStr(itemMap)); Map map = new HashMap<>(); map.put("type", "sync-progress"); @@ -62,11 +76,13 @@ public class UploadManager { dataMap.put("remaining", remainingTasks); dataMap.put("fail", fail); if (uploadQueue.isEmpty()) { + fail = 0; dataMap.put("status", SyncStatusType.FINISHED); } else { dataMap.put("status", SyncStatusType.UPLOADING); } - WebSocketManager.send(JSONUtil.toJsonStr(dataMap)); + map.put("data", dataMap); + WebSocketManager.send(JSONUtil.toJsonStr(map)); } catch (InterruptedException e) { // 如果希望线程一直运行,不退出则不break,可加上延时后继续循环 @@ -92,17 +108,19 @@ public class UploadManager { uploadThread.start(); } - private void processUpload(Long uploadId) { + private boolean processUpload(Long uploadId) { ProfileRecordDao profileRecordDao = new ProfileRecordDao(ProfilometerApplication.getContext()); ProfileRecordPointSetDao profileRecordPointSetDao = new ProfileRecordPointSetDao(ProfilometerApplication.getContext()); ProfileRecordDescription profileRecordDescription = profileRecordDao.getProfileRecordById(uploadId); - if (profileRecordDescription.getSyncStatus() != SyncStatus.wait) { - return; + if (profileRecordDescription.getSyncStatus() == SyncStatus.finish) { + return true; } SystemConfigDao systemConfigDao = new SystemConfigDao(ProfilometerApplication.getContext()); SystemConfig serverConfig = systemConfigDao.getSystemConfigByKey(SystemConfigType.SERVER); String serverPath = serverConfig.getConfigValue(); + SyncTaskDao syncTaskDao = new SyncTaskDao(ProfilometerApplication.getContext()); + SyncTask syncTask = syncTaskDao.getSyncTaskById(uploadId); ProfileRecordPointSet profileRecordPointSet = profileRecordPointSetDao.getProfileRecordPointSetByUuid(profileRecordDescription.getUuid()); String leftPointJsonStr = profileRecordPointSet.getLeftPoints(); String rightPointJsonStr = profileRecordPointSet.getLeftPoints(); @@ -116,15 +134,15 @@ public class UploadManager { String zipName = ""; if (profileRecordDescription.getDataSource().equals("XLDC")) { // 文件名生成 线名-行别里程股别半径-日期 - fileName = profileRecordDescription.getXmCode() + "-" + profileRecordDescription.getXbCode()+ profileRecordDescription.getMileage()+ - profileRecordDescription.getUnitType() + (profileRecordDescription.getRadius() == null || profileRecordDescription.getRadius().isEmpty() ? "" : profileRecordDescription.getRadius()) + - "-" + profileRecordDescription.getCreateTime().format(DateTimeFormatter.ofPattern("yyyyMMdd"))+ ".ban"; + fileName = profileRecordDescription.getXmCode() + "-" + profileRecordDescription.getXbCode() + profileRecordDescription.getMileage() + + profileRecordDescription.getUnitType() + (profileRecordDescription.getRadius() == null || profileRecordDescription.getRadius().isEmpty() ? "" : profileRecordDescription.getRadius()) + + "-" + profileRecordDescription.getCreateTime().format(DateTimeFormatter.ofPattern("yyyyMMdd")) + ".ban"; zipName = "线路廓形数据" + "-" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")) + ".zip"; } else if (profileRecordDescription.getDataSource().equals("DCDC")) { // 文件名生成 线名-站名-行别-道岔号-枕木号-股别-日期 - fileName = profileRecordDescription.getXmCode() + "-" + profileRecordDescription.getStationCode() +"-"+ profileRecordDescription.getXbCode() + - "-"+ profileRecordDescription.getTurnoutNum() +"-"+ profileRecordDescription.getSleeperNum() +"-"+ profileRecordDescription.getUnitType() + - "-"+ profileRecordDescription.getCreateTime().format(DateTimeFormatter.ofPattern("yyyyMMdd"))+ ".ban"; + fileName = profileRecordDescription.getXmCode() + "-" + profileRecordDescription.getStationCode() + "-" + profileRecordDescription.getXbCode() + + "-" + profileRecordDescription.getTurnoutNum() + "-" + profileRecordDescription.getSleeperNum() + "-" + profileRecordDescription.getUnitType() + + "-" + profileRecordDescription.getCreateTime().format(DateTimeFormatter.ofPattern("yyyyMMdd")) + ".ban"; zipName = "道岔廓形数据" + "-" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")) + ".zip"; } byte[] banByte = pointToBanFile(mergedPoints, fileName); @@ -154,17 +172,32 @@ public class UploadManager { JSONObject resultJsonObject = JSONUtil.parseObj(resultStr); if (resultJsonObject.getBool("success")) {//成功 profileRecordDescription.setSyncStatus(SyncStatus.finish); + syncTask.setSyncStatus(SyncStatus.finish); + profileRecordDao.updateProfileRecord(profileRecordDescription); + syncTaskDao.updateSyncTask(syncTask); + return true; } else { if (resultJsonObject.getInt("code") == 501) {//成功 profileRecordDescription.setSyncStatus(SyncStatus.finish); + syncTask.setSyncStatus(SyncStatus.finish); + profileRecordDao.updateProfileRecord(profileRecordDescription); + syncTaskDao.updateSyncTask(syncTask); + return true; } else {//失败 fail++; profileRecordDescription.setSyncStatus(SyncStatus.fail); + syncTask.setSyncStatus(SyncStatus.fail); + syncTask.setErrorMsg(resultJsonObject.getStr("message")); + profileRecordDao.updateProfileRecord(profileRecordDescription); + syncTaskDao.updateSyncTask(syncTask); + return false; } } - profileRecordDao.updateProfileRecord(profileRecordDescription); + } else { + return false; } } catch (IOException ignored) { + return false; } } else if (profileRecordDescription.getDataSource().equals("DCDC")) { formMap.put("tljCode", profileRecordDescription.getTljCode()); @@ -186,19 +219,31 @@ public class UploadManager { JSONObject resultJsonObject = JSONUtil.parseObj(resultStr); if (resultJsonObject.getBool("success")) {//成功 profileRecordDescription.setSyncStatus(SyncStatus.finish); + profileRecordDao.updateProfileRecord(profileRecordDescription); + syncTaskDao.updateSyncTask(syncTask); + return true; } else { if (resultJsonObject.getInt("code") == 501) {//成功 profileRecordDescription.setSyncStatus(SyncStatus.finish); + profileRecordDao.updateProfileRecord(profileRecordDescription); + syncTaskDao.updateSyncTask(syncTask); + return true; } else {//失败 fail++; profileRecordDescription.setSyncStatus(SyncStatus.fail); + profileRecordDao.updateProfileRecord(profileRecordDescription); + syncTaskDao.updateSyncTask(syncTask); + return false; } } - profileRecordDao.updateProfileRecord(profileRecordDescription); + } else { + return false; } - } catch (IOException e) { - throw new RuntimeException(e); + } catch (IOException ignored) { + return false; } + } else { + return false; } } @@ -235,7 +280,7 @@ public class UploadManager { * @param banFiles 存放在内存中的 ban 文件列表,每个 ban 文件包含文件名和对应的内容 * @return ZIP 压缩包数据对应的字节数组,如果压缩出现异常则返回 null。 */ - public static byte[] compressionToZipBytes(List banFiles) { + private static byte[] compressionToZipBytes(List banFiles) { try (ByteArrayOutputStream baos = new ByteArrayOutputStream(); ZipOutputStream zos = new ZipOutputStream(baos)) { for (BanFile banFile : banFiles) { @@ -270,7 +315,7 @@ public class UploadManager { * @param data 内存中完整的文件数据 * @throws IOException 如果在数据处理过程中发生异常 */ - public static void precalc(ZipEntry entry, byte[] data) throws IOException { + private static void precalc(ZipEntry entry, byte[] data) throws IOException { // 未压缩大小 long uncompressed = data.length; int method = entry.getMethod(); @@ -306,4 +351,8 @@ public class UploadManager { } entry.setCrc(crc.getValue()); } + + public BlockingQueue getUploadQueue() { + return uploadQueue; + } } diff --git a/app/src/main/java/com/iflytop/profilometer/dao/SyncTaskDao.java b/app/src/main/java/com/iflytop/profilometer/dao/SyncTaskDao.java index 7b94f95..5421bba 100644 --- a/app/src/main/java/com/iflytop/profilometer/dao/SyncTaskDao.java +++ b/app/src/main/java/com/iflytop/profilometer/dao/SyncTaskDao.java @@ -84,6 +84,7 @@ public class SyncTaskDao { values.put("turnout_num", task.getTurnoutNum()); values.put("sleeper_num", task.getSleeperNum()); values.put("radius", task.getRadius()); + values.put("error_msg", task.getErrorMsg()); values.put("sync_status", task.getSyncStatus().name()); int rows = db.update(MyDatabaseHelper.TABLE_SYNC_TASK, values, "id = ?", new String[]{String.valueOf(task.getId())}); db.close(); @@ -136,6 +137,7 @@ public class SyncTaskDao { task.setTurnoutNum(cursor.getString(cursor.getColumnIndex("turnout_num"))); task.setSleeperNum(cursor.getString(cursor.getColumnIndex("sleeper_num"))); task.setRadius(cursor.getString(cursor.getColumnIndex("radius"))); + task.setErrorMsg(cursor.getString(cursor.getColumnIndex("error_msg"))); String syncStatus = cursor.getString(cursor.getColumnIndex("sync_status")); if (syncStatus != null) { @@ -192,6 +194,7 @@ public class SyncTaskDao { task.setTurnoutNum(cursor.getString(cursor.getColumnIndex("turnout_num"))); task.setSleeperNum(cursor.getString(cursor.getColumnIndex("sleeper_num"))); task.setRadius(cursor.getString(cursor.getColumnIndex("radius"))); + task.setErrorMsg(cursor.getString(cursor.getColumnIndex("error_msg"))); String syncStatus = cursor.getString(cursor.getColumnIndex("sync_status")); if (syncStatus != null) { @@ -296,6 +299,7 @@ public class SyncTaskDao { task.setTurnoutNum(cursor.getString(cursor.getColumnIndex("turnout_num"))); task.setSleeperNum(cursor.getString(cursor.getColumnIndex("sleeper_num"))); task.setRadius(cursor.getString(cursor.getColumnIndex("radius"))); + task.setErrorMsg(cursor.getString(cursor.getColumnIndex("error_msg"))); String syncStatus = cursor.getString(cursor.getColumnIndex("sync_status")); if (syncStatus != null) { @@ -341,6 +345,7 @@ public class SyncTaskDao { task.setTurnoutNum(cursor.getString(cursor.getColumnIndex("turnout_num"))); task.setSleeperNum(cursor.getString(cursor.getColumnIndex("sleeper_num"))); task.setRadius(cursor.getString(cursor.getColumnIndex("radius"))); + task.setErrorMsg(cursor.getString(cursor.getColumnIndex("error_msg"))); String syncStatus = cursor.getString(cursor.getColumnIndex("sync_status")); if (syncStatus != null) { diff --git a/app/src/main/java/com/iflytop/profilometer/model/entity/SyncTask.java b/app/src/main/java/com/iflytop/profilometer/model/entity/SyncTask.java index df76170..dc9ee3a 100644 --- a/app/src/main/java/com/iflytop/profilometer/model/entity/SyncTask.java +++ b/app/src/main/java/com/iflytop/profilometer/model/entity/SyncTask.java @@ -24,6 +24,7 @@ public class SyncTask extends BaseEntity { private String turnoutNum; private String sleeperNum; private SyncStatus syncStatus; // 同步状态字段 + private String errorMsg; public String getUuid() { return uuid; @@ -184,4 +185,12 @@ public class SyncTask extends BaseEntity { public void setRadius(String radius) { this.radius = radius; } + + public String getErrorMsg() { + return errorMsg; + } + + public void setErrorMsg(String errorMsg) { + this.errorMsg = errorMsg; + } }