Browse Source

完善同步任务接口

master
白凤吉 4 months ago
parent
commit
37dc7a63fe
  1. 8
      app/src/main/java/com/iflytop/profilometer/api/ble/BleRoutes.kt
  2. 1
      app/src/main/java/com/iflytop/profilometer/api/ble/BleWebsocketManager.java
  3. 11
      app/src/main/java/com/iflytop/profilometer/api/record/RecordApi.java
  4. 12
      app/src/main/java/com/iflytop/profilometer/api/record/RecordRoutes.kt
  5. 66
      app/src/main/java/com/iflytop/profilometer/api/sync/SyncApi.java
  6. 31
      app/src/main/java/com/iflytop/profilometer/api/sync/SyncRoutes.kt
  7. 2
      app/src/main/java/com/iflytop/profilometer/common/result/Result.java
  8. 94
      app/src/main/java/com/iflytop/profilometer/common/utils/GsonUtil.java
  9. 113
      app/src/main/java/com/iflytop/profilometer/dao/SyncTaskDao.java

8
app/src/main/java/com/iflytop/profilometer/api/ble/BleRoutes.kt

@ -1,9 +1,11 @@
package com.iflytop.profilometer.api.ble package com.iflytop.profilometer.api.ble
import android.content.Context import android.content.Context
import cn.hutool.json.JSONUtil
import io.ktor.http.ContentType import io.ktor.http.ContentType
import io.ktor.server.application.call import io.ktor.server.application.call
import io.ktor.server.request.receive import io.ktor.server.request.receive
import io.ktor.server.request.receiveText
import io.ktor.server.response.respondText import io.ktor.server.response.respondText
import io.ktor.server.routing.Routing import io.ktor.server.routing.Routing
import io.ktor.server.routing.post import io.ktor.server.routing.post
@ -31,8 +33,10 @@ fun Routing.bleRoutes(context: Context) {
* *
*/ */
post("/api/ble/connect") { post("/api/ble/connect") {
val params = call.receive<Map<String, String>>()
val jsonResponse = api.connect(params["mac"])
val requestBody = call.receiveText()
val jsonObj = JSONUtil.parseObj(requestBody)
val mac = jsonObj.getStr("mac")
val jsonResponse = api.connect(mac)
call.respondText(jsonResponse, ContentType.Application.Json) call.respondText(jsonResponse, ContentType.Application.Json)
} }

1
app/src/main/java/com/iflytop/profilometer/api/ble/BleWebsocketManager.java

@ -4,7 +4,6 @@ import android.annotation.SuppressLint;
import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothDevice;
import android.content.Context; import android.content.Context;
import com.iflytop.profilometer.common.utils.GsonUtil;
import com.iflytop.profilometer.core.bluetooth.BleManager; import com.iflytop.profilometer.core.bluetooth.BleManager;
import com.iflytop.profilometer.core.websocket.WebSocketManager; import com.iflytop.profilometer.core.websocket.WebSocketManager;

11
app/src/main/java/com/iflytop/profilometer/api/record/RecordApi.java

@ -4,6 +4,8 @@ import android.content.Context;
import com.iflytop.profilometer.common.result.Result; import com.iflytop.profilometer.common.result.Result;
import com.iflytop.profilometer.dao.ProfileRecordDao; import com.iflytop.profilometer.dao.ProfileRecordDao;
import com.iflytop.profilometer.dao.ProfileRecordPointSetDao;
import com.iflytop.profilometer.model.entity.ProfileRecordPointSet;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
@ -29,4 +31,13 @@ public class RecordApi {
dataMap.put("list", dataList); dataMap.put("list", dataList);
return Result.success(dataMap); return Result.success(dataMap);
} }
/**
* 测量记录详情
*/
public String detail(Long id){
ProfileRecordPointSetDao profileRecordPointSetDao = new ProfileRecordPointSetDao(context);
ProfileRecordPointSet pointSet = profileRecordPointSetDao.getProfileRecordPointSetById(id);
return Result.success(pointSet);
}
} }

12
app/src/main/java/com/iflytop/profilometer/api/record/RecordRoutes.kt

@ -28,17 +28,15 @@ fun Routing.recordRoutes(context: Context) {
call.respondText(jsonResponse, ContentType.Application.Json) call.respondText(jsonResponse, ContentType.Application.Json)
} }
/**
*
*/
post("/api/record/list/search") {
}
/** /**
* *
*/ */
post("/api/record/detail") { post("/api/record/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)
} }
/** /**

66
app/src/main/java/com/iflytop/profilometer/api/sync/SyncApi.java

@ -2,6 +2,18 @@ package com.iflytop.profilometer.api.sync;
import android.content.Context; import android.content.Context;
import com.iflytop.profilometer.common.result.Result;
import com.iflytop.profilometer.dao.ProfileRecordDao;
import com.iflytop.profilometer.dao.SyncTaskDao;
import com.iflytop.profilometer.model.entity.ProfileRecordDescription;
import com.iflytop.profilometer.model.entity.SyncTask;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import cn.hutool.json.JSONArray;
/** /**
* 数据上传 * 数据上传
*/ */
@ -12,5 +24,59 @@ public class SyncApi {
this.context = context.getApplicationContext(); this.context = context.getApplicationContext();
} }
/**
* 同步任务列表
*/
public String list(int pageNum, int size) {
SyncTaskDao syncTaskDao = new SyncTaskDao(context);
int total = syncTaskDao.getSyncTaskCount();
List<SyncTask> syncTaskList = syncTaskDao.getSyncTasks(pageNum, size);
Map<String, Object> dataMap = new HashMap<>();
dataMap.put("total", total);
dataMap.put("list", syncTaskList);
return Result.success(dataMap);
}
/**
* 添加同步任务
*/
public String add(JSONArray ids) {
SyncTaskDao syncTaskDao = new SyncTaskDao(context);
ProfileRecordDao profileRecordDao = new ProfileRecordDao(context);
for (int i = 0; i < ids.size(); i++) {
Long id = ids.getLong(i);
ProfileRecordDescription profileRecordDescription = profileRecordDao.getProfileRecordById(id);
syncTaskDao.insertSyncTask(profileRecordDescription);
}
return Result.success();
}
/**
* 清空同步任务列表
*/
public String emptyAll() {
SyncTaskDao syncTaskDao = new SyncTaskDao(context);
syncTaskDao.clearSyncTasks();
return Result.success();
}
/**
* 清空已完成的同步任务
*/
public String emptyFinish() {
SyncTaskDao syncTaskDao = new SyncTaskDao(context);
syncTaskDao.deleteFinishedSyncTasks();
return Result.success();
}
public String reFail() {
SyncTaskDao syncTaskDao = new SyncTaskDao(context);
List<SyncTask> syncTaskList = syncTaskDao.getUnfinishedSyncTasks();
for (SyncTask syncTask : syncTaskList) {
}
return Result.success();
}
} }

31
app/src/main/java/com/iflytop/profilometer/api/sync/SyncRoutes.kt

@ -1,9 +1,17 @@
package com.iflytop.profilometer.api.sync package com.iflytop.profilometer.api.sync
import android.content.Context import android.content.Context
import cn.hutool.json.JSONUtil
import io.ktor.http.ContentType
import io.ktor.server.application.call
import io.ktor.server.request.receiveText
import io.ktor.server.response.respondText
import io.ktor.server.routing.Routing import io.ktor.server.routing.Routing
import io.ktor.server.routing.post import io.ktor.server.routing.post
/**
*
*/
fun Routing.syncRoutes(context: Context) { fun Routing.syncRoutes(context: Context) {
val api = SyncApi(context) val api = SyncApi(context)
@ -11,12 +19,30 @@ fun Routing.syncRoutes(context: Context) {
* *
*/ */
post("/api/sync/list") { post("/api/sync/list") {
val requestBody = call.receiveText()
val jsonObj = JSONUtil.parseObj(requestBody)
val pageNum = jsonObj.getInt("pageNum", 1)
val size = jsonObj.getInt("size", 10)
val jsonResponse = api.list(pageNum, size)
call.respondText(jsonResponse, ContentType.Application.Json)
}
/**
*
*/
post("/api/sync/add") {
val requestBody = call.receiveText()
val jsonObj = JSONUtil.parseObj(requestBody)
val ids = jsonObj.getJSONArray("ids")
val jsonResponse = api.add(ids)
call.respondText(jsonResponse, ContentType.Application.Json)
} }
/** /**
* *
*/ */
post("/api/sync/empty-all") { post("/api/sync/empty-all") {
val jsonResponse = api.emptyAll()
call.respondText(jsonResponse, ContentType.Application.Json)
} }
@ -24,18 +50,23 @@ fun Routing.syncRoutes(context: Context) {
* *
*/ */
post("/api/sync/empty-finish") { post("/api/sync/empty-finish") {
val jsonResponse = api.emptyFinish()
call.respondText(jsonResponse, ContentType.Application.Json)
} }
/** /**
* *
*/ */
post("/api/sync/re-fail") { post("/api/sync/re-fail") {
val jsonResponse = api.reFail()
call.respondText(jsonResponse, ContentType.Application.Json)
} }
/** /**
* *
*/ */
post("/api/sync/upload-ktj") { post("/api/sync/upload-ktj") {
} }
} }

2
app/src/main/java/com/iflytop/profilometer/common/result/Result.java

@ -1,8 +1,6 @@
package com.iflytop.profilometer.common.result; package com.iflytop.profilometer.common.result;
import com.iflytop.profilometer.common.utils.GsonUtil;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;

94
app/src/main/java/com/iflytop/profilometer/common/utils/GsonUtil.java

@ -1,94 +0,0 @@
package com.iflytop.profilometer.common.utils;
import com.google.gson.*;
import com.google.gson.reflect.TypeToken;
import java.lang.reflect.Type;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
public class GsonUtil {
// 定义日期格式
private static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern(DATE_FORMAT);
// 创建 LocalDateTime 的序列化器
private static final JsonSerializer<LocalDateTime> localDateTimeSerializer = new JsonSerializer<LocalDateTime>() {
@Override
public JsonElement serialize(LocalDateTime src, Type typeOfSrc, JsonSerializationContext context) {
return new JsonPrimitive(src.format(formatter));
}
};
// 创建 LocalDateTime 的反序列化器
private static final JsonDeserializer<LocalDateTime> localDateTimeDeserializer = new JsonDeserializer<LocalDateTime>() {
@Override
public LocalDateTime deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException {
return LocalDateTime.parse(json.getAsString(), formatter);
}
};
// 使用 GsonBuilder 注册 LocalDateTime 的适配器同时设置 java.util.Date 的格式
private static final Gson gson = new GsonBuilder()
.registerTypeAdapter(LocalDateTime.class, localDateTimeSerializer)
.registerTypeAdapter(LocalDateTime.class, localDateTimeDeserializer)
.setDateFormat(DATE_FORMAT)
.create();
/**
* 对象转 JSON 字符串
*
* @param object 要转换的对象
* @return 对象对应的 JSON 字符串若对象为 null 则返回空字符串
*/
public static String toJson(Object object) {
if (object == null) {
return "";
}
return gson.toJson(object);
}
/**
* JSON 字符串转对象
*
* @param json JSON 字符串
* @param clazz 目标对象的 Class 类型
* @param <T> 目标对象的类型
* @return 转换后的对象转换失败时返回 null
*/
public static <T> T fromJson(String json, Class<T> clazz) {
if (json == null || json.isEmpty()) {
return null;
}
try {
return gson.fromJson(json, clazz);
} catch (JsonSyntaxException e) {
e.printStackTrace();
return null;
}
}
/**
* JSON 字符串转 List 对象
*
* @param json JSON 字符串
* @param clazz List 中元素的 Class 类型
* @param <T> List 中元素的类型
* @return 转换后的 List 对象转换失败时返回 null
*/
public static <T> List<T> fromJsonToList(String json, Class<T> clazz) {
if (json == null || json.isEmpty()) {
return null;
}
try {
// 利用 TypeToken 获取泛型类型
Type type = TypeToken.getParameterized(List.class, clazz).getType();
return gson.fromJson(json, type);
} catch (JsonSyntaxException e) {
e.printStackTrace();
return null;
}
}
}

113
app/src/main/java/com/iflytop/profilometer/dao/SyncTaskDao.java

@ -112,6 +112,119 @@ public class SyncTaskDao {
return list; return list;
} }
@SuppressLint("Range")
public List<SyncTask> getSyncTasks(int pageNum, int size) {
List<SyncTask> list = new ArrayList<>();
SQLiteDatabase db = dbHelper.getReadableDatabase();
int offset = (pageNum - 1) * size;
// 使用 LIMIT OFFSET 实现分页排序采用 create_time 倒序排列
String limitClause = offset + ", " + size;
Cursor cursor = db.query(
MyDatabaseHelper.TABLE_SYNC_TASK, // 表名
null, // 查询所有列
null, // selection
null, // selectionArgs
null, // groupBy
null, // having
"create_time DESC", // orderBy按照 create_time 降序排列
limitClause // 分页参数
);
if (cursor.moveToFirst()) {
do {
SyncTask task = new SyncTask();
task.setId(cursor.getLong(cursor.getColumnIndex("id")));
task.setUuid(cursor.getString(cursor.getColumnIndex("uuid")));
task.setOperatorName(cursor.getString(cursor.getColumnIndex("operator_name")));
task.setTrackShapeCode(cursor.getString(cursor.getColumnIndex("track_shape_code")));
task.setVerificationMethodCode(cursor.getString(cursor.getColumnIndex("verification_method_code")));
task.setName(cursor.getString(cursor.getColumnIndex("name")));
task.setLineName(cursor.getString(cursor.getColumnIndex("line_name")));
task.setLocation(cursor.getString(cursor.getColumnIndex("location")));
task.setDirection(cursor.getString(cursor.getColumnIndex("direction")));
String syncStatus = cursor.getString(cursor.getColumnIndex("sync_status"));
if (syncStatus != null) {
task.setSyncStatus(SyncStatus.valueOf(syncStatus));
}
task.setCreateTime(LocalDateTime.parse(cursor.getString(cursor.getColumnIndex("create_time")), FORMATTER));
task.setUpdateTime(LocalDateTime.parse(cursor.getString(cursor.getColumnIndex("update_time")), FORMATTER));
list.add(task);
} while (cursor.moveToNext());
}
cursor.close();
db.close();
return list;
}
public int getSyncTaskCount() {
int count = 0;
SQLiteDatabase db = dbHelper.getReadableDatabase();
Cursor cursor = db.rawQuery("SELECT COUNT(*) FROM " + MyDatabaseHelper.TABLE_SYNC_TASK, null);
if (cursor.moveToFirst()) {
count = cursor.getInt(0);
}
cursor.close();
db.close();
return count;
}
/**
* 删除所有 sync_status 字段值为 "finish" 的同步任务记录
* @return 被删除的记录数
*/
public int deleteFinishedSyncTasks() {
SQLiteDatabase db = dbHelper.getWritableDatabase();
// 注意此处比较值为 "finish"若枚举常量为大写 FINISH请相应修改
int rows = db.delete(MyDatabaseHelper.TABLE_SYNC_TASK, "sync_status = ?", new String[]{"finish"});
db.close();
return rows;
}
/**
* 获取所有 sync_status 字段值不等于 "finish" 的同步任务记录 create_time 倒序排列
* @return 同步任务记录列表
*/
@SuppressLint("Range")
public List<SyncTask> getUnfinishedSyncTasks() {
List<SyncTask> list = new ArrayList<>();
SQLiteDatabase db = dbHelper.getReadableDatabase();
// create_time 倒序排列
Cursor cursor = db.query(
MyDatabaseHelper.TABLE_SYNC_TASK,
null,
"sync_status <> ?",
new String[]{"finish"},
null,
null,
"create_time DESC"
);
if (cursor.moveToFirst()) {
do {
SyncTask task = new SyncTask();
task.setId(cursor.getLong(cursor.getColumnIndex("id")));
task.setUuid(cursor.getString(cursor.getColumnIndex("uuid")));
task.setOperatorName(cursor.getString(cursor.getColumnIndex("operator_name")));
task.setTrackShapeCode(cursor.getString(cursor.getColumnIndex("track_shape_code")));
task.setVerificationMethodCode(cursor.getString(cursor.getColumnIndex("verification_method_code")));
task.setName(cursor.getString(cursor.getColumnIndex("name")));
task.setLineName(cursor.getString(cursor.getColumnIndex("line_name")));
task.setLocation(cursor.getString(cursor.getColumnIndex("location")));
task.setDirection(cursor.getString(cursor.getColumnIndex("direction")));
String syncStatus = cursor.getString(cursor.getColumnIndex("sync_status"));
if (syncStatus != null) {
task.setSyncStatus(SyncStatus.valueOf(syncStatus));
}
task.setCreateTime(LocalDateTime.parse(cursor.getString(cursor.getColumnIndex("create_time")), FORMATTER));
task.setUpdateTime(LocalDateTime.parse(cursor.getString(cursor.getColumnIndex("update_time")), FORMATTER));
list.add(task);
} while (cursor.moveToNext());
}
cursor.close();
db.close();
return list;
}
// 根据 id 查询同步任务记录 // 根据 id 查询同步任务记录
@SuppressLint("Range") @SuppressLint("Range")
public SyncTask getSyncTaskById(long id) { public SyncTask getSyncTaskById(long id) {

Loading…
Cancel
Save