diff --git a/pom.xml b/pom.xml
index f807715..4349ba1 100644
--- a/pom.xml
+++ b/pom.xml
@@ -79,6 +79,10 @@
org.springframework.boot
spring-boot-starter-data-jpa
+
+ org.springframework.boot
+ spring-boot-starter-data-mongodb
+
org.springframework.boot
spring-boot-starter-security
diff --git a/src/main/java/com/onekeycall/videotablet/controller/ApkInfoController.java b/src/main/java/com/onekeycall/videotablet/controller/ApkInfoController.java
new file mode 100644
index 0000000..e562aab
--- /dev/null
+++ b/src/main/java/com/onekeycall/videotablet/controller/ApkInfoController.java
@@ -0,0 +1,37 @@
+package com.onekeycall.videotablet.controller;
+
+
+import com.onekeycall.videotablet.entity.ApkInfo;
+import com.onekeycall.videotablet.service.ApkInfoService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+@RestController
+@RequestMapping("/api/apks")
+public class ApkInfoController {
+
+ @Autowired
+ private ApkInfoService apkInfoService;
+
+ @GetMapping("/device/{deviceId}")
+ public List getApksByDeviceId(@PathVariable String deviceId) {
+ return apkInfoService.getApkInfosByDeviceId(deviceId);
+ }
+
+ @PostMapping
+ public ApkInfo saveApkInfo(@RequestBody ApkInfo apkInfo) {
+ return apkInfoService.saveOrUpdateApkInfo(apkInfo);
+ }
+
+ @PostMapping("/batch")
+ public List saveApkInfos(@RequestBody List apkInfos) {
+ return apkInfoService.saveAllApkInfos(apkInfos);
+ }
+
+ @DeleteMapping("/{packageName}")
+ public void deleteApkInfo(@PathVariable String packageName) {
+ apkInfoService.deleteApkInfoByPackageName(packageName);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/onekeycall/videotablet/controller/LoginController.java b/src/main/java/com/onekeycall/videotablet/controller/LoginController.java
index 5fdcf9d..a18d4dd 100644
--- a/src/main/java/com/onekeycall/videotablet/controller/LoginController.java
+++ b/src/main/java/com/onekeycall/videotablet/controller/LoginController.java
@@ -91,7 +91,7 @@ public class LoginController {
return Result.ok().data(Collections.singletonMap("token", tokenPair.toMap()));
} catch (Exception e) {
e.printStackTrace();
- return Result.error().message("登录失败");
+ return Result.error().message("登录失败:密码错误");
}
}
diff --git a/src/main/java/com/onekeycall/videotablet/entity/ApkInfo.java b/src/main/java/com/onekeycall/videotablet/entity/ApkInfo.java
new file mode 100644
index 0000000..ff1db54
--- /dev/null
+++ b/src/main/java/com/onekeycall/videotablet/entity/ApkInfo.java
@@ -0,0 +1,43 @@
+package com.onekeycall.videotablet.entity;
+
+import lombok.Data;
+import org.springframework.data.mongodb.core.index.Indexed;
+import org.springframework.data.mongodb.core.mapping.Document;
+import org.springframework.data.mongodb.core.mapping.Field;
+import org.springframework.data.annotation.Id;
+
+import java.util.Date;
+
+@Data
+@Document(collection = "apk_info") // 指定集合名
+public class ApkInfo {
+ @Id // 标识主键
+ private String id; // MongoDB默认使用ObjectId,这里用String接收
+
+ @Field("package_name") // 可指定字段在数据库中的名称
+ private String packageName;
+
+ @Field("app_name")
+ private String appName;
+
+ @Field("version_name")
+ private String versionName;
+
+ @Field("version_code")
+ private Integer versionCode;
+
+ @Field("install_time")
+ private Date installTime; // MongoDB支持Date类型[9,11](@ref)
+
+ @Field("last_update_time")
+ private Date lastUpdateTime;
+
+ private Long size; // APK大小,单位可以是字节
+
+ // 建议增加一个字段标识该列表所属的设备或用户
+ @Indexed // 为设备ID创建索引
+ @Field("device_sn")
+ private String deviceSn;
+
+
+}
diff --git a/src/main/java/com/onekeycall/videotablet/repository/ApkInfoRepository.java b/src/main/java/com/onekeycall/videotablet/repository/ApkInfoRepository.java
new file mode 100644
index 0000000..b107b26
--- /dev/null
+++ b/src/main/java/com/onekeycall/videotablet/repository/ApkInfoRepository.java
@@ -0,0 +1,28 @@
+package com.onekeycall.videotablet.repository;
+
+import com.onekeycall.videotablet.entity.ApkInfo;
+import org.springframework.data.mongodb.repository.MongoRepository;
+import org.springframework.stereotype.Repository;
+
+import java.util.Date;
+import java.util.List;
+
+@Repository
+public interface ApkInfoRepository extends MongoRepository {
+ // MongoRepository 中String是主键类型
+
+ // 根据包名查找应用
+ ApkInfo findByPackageName(String packageName);
+
+ // 根据设备ID查找该设备的所有应用
+ List findByDeviceSn(String deviceSn);
+
+ // 查找安装时间在某个时间点之后的应用
+ List findByInstallTimeAfter(Date date);
+
+ // 自定义查询:查找应用名称包含特定字符串的应用
+ List findByAppNameLike(String appName);
+
+ // 你可以根据业务需求定义更多查询方法
+ // Spring Data MongoDB会根据方法名自动推导查询[2](@ref)
+}
diff --git a/src/main/java/com/onekeycall/videotablet/service/ApkInfoService.java b/src/main/java/com/onekeycall/videotablet/service/ApkInfoService.java
new file mode 100644
index 0000000..d81ffbd
--- /dev/null
+++ b/src/main/java/com/onekeycall/videotablet/service/ApkInfoService.java
@@ -0,0 +1,74 @@
+package com.onekeycall.videotablet.service;
+
+import com.onekeycall.videotablet.entity.ApkInfo;
+import com.onekeycall.videotablet.repository.ApkInfoRepository;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Sort;
+import org.springframework.data.mongodb.core.MongoTemplate;
+import org.springframework.data.mongodb.core.query.Criteria;
+import org.springframework.data.mongodb.core.query.Query;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+@Service
+public class ApkInfoService {
+
+ @Autowired
+ private ApkInfoRepository apkInfoRepository;
+
+ @Autowired
+ private MongoTemplate mongoTemplate;
+
+ /**
+ * 保存或更新APK信息(如果ID存在则更新,不存在则新增)
+ */
+ public ApkInfo saveOrUpdateApkInfo(ApkInfo apkInfo) {
+ return apkInfoRepository.save(apkInfo);
+ }
+
+ /**
+ * 批量保存APK列表(例如从一台设备同步所有应用)
+ */
+ public List saveAllApkInfos(List apkInfos) {
+ return apkInfoRepository.saveAll(apkInfos);
+ }
+
+ /**
+ * 根据ID查询APK信息
+ */
+ public ApkInfo getApkInfoById(String id) {
+ return apkInfoRepository.findById(id).orElse(null);
+ }
+
+ /**
+ * 根据设备ID查询该设备上的所有应用
+ */
+ public List getApkInfosByDeviceId(String deviceSn) {
+ return apkInfoRepository.findByDeviceSn(deviceSn);
+ }
+
+ /**
+ * 根据包名删除应用信息
+ */
+ public void deleteApkInfoByPackageName(String packageName) {
+ ApkInfo apkInfo = apkInfoRepository.findByPackageName(packageName);
+ if (apkInfo != null) {
+ apkInfoRepository.delete(apkInfo);
+ }
+ }
+
+ /**
+ * 获取所有APK信息
+ */
+ public List getAllApkInfos() {
+ return apkInfoRepository.findAll();
+ }
+
+ public List findTop5ByDeviceIdOrderBySizeDesc(String deviceSn) {
+ Query query = Query.query(Criteria.where("device_Sn").is(deviceSn))
+ .with(Sort.by(Sort.Direction.DESC, "size"))
+ .limit(5);
+ return mongoTemplate.find(query, ApkInfo.class);
+ }
+}
\ No newline at end of file
diff --git a/src/main/resources/application-debug.properties b/src/main/resources/application-debug.properties
index 24eea01..0847148 100644
--- a/src/main/resources/application-debug.properties
+++ b/src/main/resources/application-debug.properties
@@ -22,6 +22,9 @@ spring.data.redis.lettuce.pool.max-active=8
spring.data.redis.lettuce.pool.max-wait=1ms
spring.data.redis.lettuce.shutdown-timeout=100ms
+#MongoDB
+spring.data.mongodb.uri=mongodb://fht:fanhuitong@139.199.77.221:27027/apk_installation_records
+
# Hibernate配置
#spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MariaDBDialect
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect