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
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.receive
import io.ktor.server.request.receiveText
import io.ktor.server.response.respondText
import io.ktor.server.routing.Routing
import io.ktor.server.routing.post
@ -31,8 +33,10 @@ fun Routing.bleRoutes(context: Context) {
*
*/
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)
}

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.content.Context;
import com.iflytop.profilometer.common.utils.GsonUtil;
import com.iflytop.profilometer.core.bluetooth.BleManager;
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.dao.ProfileRecordDao;
import com.iflytop.profilometer.dao.ProfileRecordPointSetDao;
import com.iflytop.profilometer.model.entity.ProfileRecordPointSet;
import java.util.HashMap;
import java.util.List;
@ -29,4 +31,13 @@ public class RecordApi {
dataMap.put("list", dataList);
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)
}
/**
*
*/
post("/api/record/list/search") {
}
/**
*
*/
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 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();
}
/**
* 同步任务列表
*/
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
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.post
/**
*
*/
fun Routing.syncRoutes(context: Context) {
val api = SyncApi(context)
@ -11,12 +19,30 @@ fun Routing.syncRoutes(context: Context) {
*
*/
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") {
val jsonResponse = api.emptyAll()
call.respondText(jsonResponse, ContentType.Application.Json)
}
@ -24,18 +50,23 @@ fun Routing.syncRoutes(context: Context) {
*
*/
post("/api/sync/empty-finish") {
val jsonResponse = api.emptyFinish()
call.respondText(jsonResponse, ContentType.Application.Json)
}
/**
*
*/
post("/api/sync/re-fail") {
val jsonResponse = api.reFail()
call.respondText(jsonResponse, ContentType.Application.Json)
}
/**
*
*/
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;
import com.iflytop.profilometer.common.utils.GsonUtil;
import java.util.HashMap;
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;
}
@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 查询同步任务记录
@SuppressLint("Range")
public SyncTask getSyncTaskById(long id) {

Loading…
Cancel
Save