增加上传apk安装信息,未加鉴权

This commit is contained in:
2025-09-05 09:53:21 +08:00
parent 5ce369db71
commit 153137379d
13 changed files with 186 additions and 155 deletions

View File

@@ -0,0 +1,13 @@
package com.onekeycall.videotablet.bean;
import com.onekeycall.videotablet.entity.ApkInfo;
import lombok.Data;
import java.util.List;
@Data
public class ApkUploadRequest {
private String sn;
private List<ApkInfo> apk_list;
}

View File

@@ -1,37 +0,0 @@
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<ApkInfo> getApksByDeviceId(@PathVariable String deviceId) {
return apkInfoService.getApkInfosByDeviceId(deviceId);
}
@PostMapping
public ApkInfo saveApkInfo(@RequestBody ApkInfo apkInfo) {
return apkInfoService.saveOrUpdateApkInfo(apkInfo);
}
@PostMapping("/batch")
public List<ApkInfo> saveApkInfos(@RequestBody List<ApkInfo> apkInfos) {
return apkInfoService.saveAllApkInfos(apkInfos);
}
@DeleteMapping("/{packageName}")
public void deleteApkInfo(@PathVariable String packageName) {
apkInfoService.deleteApkInfoByPackageName(packageName);
}
}

View File

@@ -0,0 +1,43 @@
package com.onekeycall.videotablet.controller;
import com.aliyun.core.annotation.Body;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.onekeycall.videotablet.bean.ApkUploadRequest;
import com.onekeycall.videotablet.entity.ApkInfo;
import com.onekeycall.videotablet.entity.DeviceApkInfo;
import com.onekeycall.videotablet.result.Result;
import com.onekeycall.videotablet.service.DeviceApkInfoService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/sn")
public class DeviceApkInfoController {
static Logger logger = LoggerFactory.getLogger(DeviceApkInfoController.class);
private final ObjectMapper objectMapper; // Spring默认已注入
public DeviceApkInfoController(ObjectMapper objectMapper) {
this.objectMapper = objectMapper;
}
@Autowired
private DeviceApkInfoService deviceApkInfoService;
@PostMapping("/upload_install_apks")
public Result uploadInstallApks(@RequestBody ApkUploadRequest request) {
String sn = request.getSn();
List<ApkInfo> apkList = request.getApk_list();
if (apkList == null || apkList.size() == 0) {
return Result.error().message("应用列表为空");
}
deviceApkInfoService.saveOrUpdateDeviceApkInfo(sn, apkList);
return Result.ok();
}
}

View File

@@ -2,10 +2,12 @@ package com.onekeycall.videotablet.controller;
import com.nimbusds.openid.connect.sdk.claims.UserInfo;
import com.onekeycall.videotablet.dto.TokenPair;
import com.onekeycall.videotablet.entity.DeviceApkInfo;
import com.onekeycall.videotablet.entity.DeviceInfo;
import com.onekeycall.videotablet.entity.DeviceLocation;
import com.onekeycall.videotablet.entity.User;
import com.onekeycall.videotablet.result.Result;
import com.onekeycall.videotablet.service.DeviceApkInfoService;
import com.onekeycall.videotablet.service.DeviceLocationService;
import com.onekeycall.videotablet.service.DeviceSnService;
import com.onekeycall.videotablet.service.UserService;
@@ -36,6 +38,8 @@ public class UserController {
private DeviceSnService deviceSnService;
@Autowired
private DeviceLocationService deviceLocationService;
@Autowired
private DeviceApkInfoService deviceApkInfoService;
Logger logger = LoggerFactory.getLogger(LoginController.class);
@@ -137,4 +141,10 @@ public class UserController {
return Result.ok().data("device_location", deviceLocation);
}
@GetMapping("/get_device_apk_list")
public Result getDeviceApkList(@RequestParam String sn) {
DeviceApkInfo deviceApkInfo = deviceApkInfoService.getDeviceApkInfoBySn(sn);
return Result.ok().data("deviceApkInfo", deviceApkInfo);
}
}

View File

@@ -1,43 +1,42 @@
package com.onekeycall.videotablet.entity;
import com.fasterxml.jackson.annotation.JsonProperty;
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接收
@JsonProperty("package_name")
@Field("package_name") // 可指定字段在数据库中的名称
private String packageName;
@JsonProperty("app_name")
@Field("app_name")
private String appName;
@JsonProperty("version_name")
@Field("version_name")
private String versionName;
@JsonProperty("version_code")
@Field("version_code")
private Integer versionCode;
private Long versionCode;
@JsonProperty("install_time")
@Field("install_time")
private Date installTime; // MongoDB支持Date类型[9,11](@ref)
private Date installTime; // MongoDB支持Date类型
@JsonProperty("last_update_time")
@Field("last_update_time")
private Date lastUpdateTime;
@JsonProperty("icon_url")
@Field("icon_url")
private String iconUrl;
private Long size; // APK大小单位可以是字节
// 建议增加一个字段标识该列表所属的设备或用户
@Indexed // 为设备ID创建索引
@Field("device_sn")
private String deviceSn;
private String md5;
}

View File

@@ -0,0 +1,32 @@
package com.onekeycall.videotablet.entity;
import lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.mapping.Field;
import java.util.Date;
import java.util.List;
@Data
@Document(collection = "device_apks") // 指定MongoDB集合名
public class DeviceApkInfo {
@Id
private String id; // MongoDB文档ID
@Field("sn")
private String sn; // 设备序列号
@Field("apk_list") // 指定数据库中字段名称为apk_list
private List<ApkInfo> apkList; // APK信息列表
@Field("create_time")
private Date createTime; // 记录创建时间
@Field("update_time")
private Date updateTime; // 记录最后更新时间
// 构造方法、Getter和Setter省略实际开发中必须要有
// 推荐使用Lombok的@Getter和@Setter简化代码
}

View File

@@ -1,28 +0,0 @@
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<ApkInfo, String> {
// MongoRepository<ApkInfo, String> 中String是主键类型
// 根据包名查找应用
ApkInfo findByPackageName(String packageName);
// 根据设备ID查找该设备的所有应用
List<ApkInfo> findByDeviceSn(String deviceSn);
// 查找安装时间在某个时间点之后的应用
List<ApkInfo> findByInstallTimeAfter(Date date);
// 自定义查询:查找应用名称包含特定字符串的应用
List<ApkInfo> findByAppNameLike(String appName);
// 你可以根据业务需求定义更多查询方法
// Spring Data MongoDB会根据方法名自动推导查询[2](@ref)
}

View File

@@ -0,0 +1,18 @@
package com.onekeycall.videotablet.repository;
import com.onekeycall.videotablet.entity.DeviceApkInfo;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface DeviceApkInfoRepository extends MongoRepository<DeviceApkInfo, String> {
// 根据序列号sn查找设备应用列表
DeviceApkInfo findDeviceApkInfoBySn(String sn);
// 判断某个序列号的记录是否存在
boolean existsBySn(String sn);
}

View File

@@ -1,74 +0,0 @@
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<ApkInfo> saveAllApkInfos(List<ApkInfo> apkInfos) {
return apkInfoRepository.saveAll(apkInfos);
}
/**
* 根据ID查询APK信息
*/
public ApkInfo getApkInfoById(String id) {
return apkInfoRepository.findById(id).orElse(null);
}
/**
* 根据设备ID查询该设备上的所有应用
*/
public List<ApkInfo> 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<ApkInfo> getAllApkInfos() {
return apkInfoRepository.findAll();
}
public List<ApkInfo> 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);
}
}

View File

@@ -0,0 +1,49 @@
package com.onekeycall.videotablet.service;
import com.onekeycall.videotablet.entity.ApkInfo;
import com.onekeycall.videotablet.entity.DeviceApkInfo;
import com.onekeycall.videotablet.repository.DeviceApkInfoRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Date;
import java.util.List;
@Service
public class DeviceApkInfoService {
@Autowired
private DeviceApkInfoRepository deviceApkInfoRepository;
/**
* 保存或更新设备APK列表信息
* 如果该sn已存在则更新其apkList和updateTime不存在则新增
*/
public void saveOrUpdateDeviceApkInfo(String sn, List<ApkInfo> apkList) {
DeviceApkInfo deviceApkInfo;
if (deviceApkInfoRepository.existsBySn(sn)) {
// 存在则更新
deviceApkInfo = deviceApkInfoRepository.findDeviceApkInfoBySn(sn);
deviceApkInfo.setApkList(apkList);
deviceApkInfo.setUpdateTime(new Date());
} else {
// 不存在则新增
deviceApkInfo = new DeviceApkInfo();
deviceApkInfo.setSn(sn);
deviceApkInfo.setApkList(apkList);
Date now = new Date();
deviceApkInfo.setCreateTime(now);
deviceApkInfo.setUpdateTime(now);
}
deviceApkInfoRepository.save(deviceApkInfo);
}
/**
* 根据序列号sn获取设备APK列表
*/
public DeviceApkInfo getDeviceApkInfoBySn(String sn) {
return deviceApkInfoRepository.findDeviceApkInfoBySn(sn);
}
}

View File

@@ -23,7 +23,7 @@ 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
spring.data.mongodb.uri=mongodb://fht:fanhuitong@139.199.77.221:27027/device_apks?authSource=admin&connectTimeoutMS=5000
# Hibernate配置
#spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MariaDBDialect

View File

@@ -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/device_apks?authSource=admin&connectTimeoutMS=5000
# Hibernate配置
#spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MariaDBDialect
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect

View File

@@ -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/device_apks?authSource=admin&connectTimeoutMS=5000
# Hibernate配置
#spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MariaDBDialect
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect