diff --git a/sql/sn_screenshot.sql b/sql/sn_screenshot.sql
new file mode 100644
index 00000000..c8db844a
--- /dev/null
+++ b/sql/sn_screenshot.sql
@@ -0,0 +1,31 @@
+-- =============================================================================
+-- 设备截图表(sys_sn_screenshot)
+-- 说明:设备【截图】记录表,存储设备上报的截图文件信息。
+-- =============================================================================
+CREATE TABLE IF NOT EXISTS `sys_sn_screenshot`
+(
+ `id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键ID',
+ `sn` VARCHAR(64) NOT NULL COMMENT '设备序列号',
+ `file_name` VARCHAR(255) DEFAULT NULL COMMENT '文件名称',
+ `origin_name` VARCHAR(255) DEFAULT NULL COMMENT '原始文件名(上传时的原始文件名)',
+ `mime_type` VARCHAR(64) DEFAULT NULL COMMENT '文件MIME类型',
+ `file_extension` VARCHAR(32) DEFAULT NULL COMMENT '文件扩展名',
+ `file_path` VARCHAR(500) DEFAULT NULL COMMENT '文件路径',
+ `file_size` BIGINT DEFAULT NULL COMMENT '文件大小(字节)',
+ `file_md5` VARCHAR(64) DEFAULT NULL COMMENT '文件MD5值',
+ `file_sha1` VARCHAR(64) DEFAULT NULL COMMENT '文件Sha1值',
+ `file_sha256` VARCHAR(64) DEFAULT NULL COMMENT '文件Sha256值',
+ `upload_time` DATETIME DEFAULT NULL COMMENT '上传时间',
+
+ -- ===================== 通用字段 =====================
+ `create_time` DATETIME DEFAULT NULL COMMENT '创建时间',
+ `update_time` DATETIME DEFAULT NULL COMMENT '更新时间',
+ `is_deleted` TINYINT DEFAULT 0 COMMENT '逻辑删除(0未删 1已删)',
+
+ PRIMARY KEY (`id`),
+ KEY `idx_sn` (`sn`),
+ KEY `idx_upload_time` (`upload_time`),
+ KEY `idx_is_deleted` (`is_deleted`)
+) ENGINE = InnoDB
+ DEFAULT CHARSET = utf8mb4
+ COMMENT = '设备截图表';
diff --git a/src/main/java/com/youlai/boot/client/controller/ClientContactController.java b/src/main/java/com/youlai/boot/client/controller/ClientContactController.java
new file mode 100644
index 00000000..46b6e547
--- /dev/null
+++ b/src/main/java/com/youlai/boot/client/controller/ClientContactController.java
@@ -0,0 +1,182 @@
+package com.youlai.boot.client.controller;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.youlai.boot.client.model.entity.ClientUser;
+import com.youlai.boot.client.service.ClientUserService;
+import com.youlai.boot.common.exception.BusinessException;
+import com.youlai.boot.common.result.Result;
+import com.youlai.boot.common.result.ResultCode;
+import com.youlai.boot.device.model.entity.SnDeviceInfo;
+import com.youlai.boot.device.model.form.ContactForm;
+import com.youlai.boot.device.model.vo.ContactVO;
+import com.youlai.boot.device.service.ContactService;
+import com.youlai.boot.device.service.DeviceService;
+import com.youlai.boot.framework.security.util.SecurityUtils;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.validation.Valid;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.util.StringUtils;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * 客户端(家属端)联系人控制层
+ *
+ *
将后台管理端 {@code ContactController} 的联系人管理能力移植到客户端:
+ * 家属端用户登录后可对已绑定设备查询、新增、修改、删除联系人,路径统一挂在
+ * {@code /api/v1/client/sn/contact} 下。
+ *
+ *
与 {@link ClientController} 一致:所有接口先通过 {@link #checkBound(String)}
+ * 校验当前登录的 client 用户是否绑定传入的设备 SN,再执行操作。
+ *
+ * @author TTSTD
+ * @since 2026/08/19
+ */
+@Tag(name = "客户端-联系人")
+@RestController
+@RequestMapping("/api/v1/client/sn/contact")
+@RequiredArgsConstructor
+@Slf4j
+public class ClientContactController {
+
+ private final ClientUserService clientUserService;
+ private final DeviceService deviceService;
+ private final ContactService contactService;
+
+ /**
+ * 校验当前登录的 client 用户是否绑定了传入的设备 SN。
+ *
+ * 绑定关系:设备表 {@code sys_sn.snMobile} 与 client 用户 {@code app_user.mobile} 一致即视为已绑定。
+ * 校验未通过时抛出 {@link BusinessException},由调用方转换为失败结果返回。
+ *
+ * @param sn 设备序列号
+ * @return 已绑定的设备记录
+ */
+ private SnDeviceInfo checkBound(String sn) {
+ if (!StringUtils.hasText(sn)) {
+ throw new BusinessException("设备序列号不能为空");
+ }
+
+ Long userId = SecurityUtils.getUserId();
+ ClientUser clientUser = clientUserService.getById(userId);
+ if (clientUser == null || !StringUtils.hasText(clientUser.getMobile())) {
+ throw new BusinessException("当前用户未绑定手机号,无法校验设备");
+ }
+
+ SnDeviceInfo deviceInfo = deviceService.getOne(
+ new LambdaQueryWrapper().eq(SnDeviceInfo::getSerialno, sn)
+ );
+ if (deviceInfo == null) {
+ throw new BusinessException("设备不存在");
+ }
+
+ if (!StringUtils.hasText(deviceInfo.getSnMobile())
+ || !deviceInfo.getSnMobile().equals(clientUser.getMobile())) {
+ log.warn("client用户 {} 未绑定设备 sn: {}", userId, sn);
+ throw new BusinessException("当前用户未绑定该设备");
+ }
+
+ return deviceInfo;
+ }
+
+ @Operation(summary = "联系人列表(家属端)")
+ @PreAuthorize("isAuthenticated()")
+ @GetMapping("/list")
+ public Result> getContactList(
+ @Parameter(description = "设备序列号") @RequestParam("sn") String sn
+ ) {
+ try {
+ checkBound(sn);
+ List result = contactService.getAllContacts(sn);
+ return Result.success(result);
+ } catch (BusinessException be) {
+ return Result.failed(be.getMessage());
+ } catch (Exception e) {
+ log.error("getContactList error, sn: {}", sn, e);
+ return Result.failed("获取联系人列表失败: " + e.getMessage());
+ }
+ }
+
+ @Operation(summary = "新增联系人(家属端)")
+ @PreAuthorize("isAuthenticated()")
+ @PostMapping("/insert")
+ public Result> saveContact(
+ @Parameter(description = "设备序列号") @RequestParam("sn") String sn,
+ @Valid @RequestBody ContactForm contactForm
+ ) {
+ try {
+ checkBound(sn);
+ Long contactId = contactService.saveContact(sn, contactForm);
+ if (contactId == null) {
+ return Result.failed(ResultCode.DUPLICATE_SUBMISSION, "该手机号已存在于当前设备的联系人中", contactForm);
+ }
+ return Result.success(contactId);
+ } catch (BusinessException be) {
+ return Result.failed(be.getMessage());
+ } catch (Exception e) {
+ log.error("saveContact error, sn: {}", sn, e);
+ return Result.failed("新增联系人失败: " + e.getMessage());
+ }
+ }
+
+ @Operation(summary = "获取联系人表单数据(家属端)")
+ @PreAuthorize("isAuthenticated()")
+ @GetMapping("/form")
+ public Result getContactForm(
+ @Parameter(description = "联系人ID") @RequestParam Long id,
+ @Parameter(description = "设备序列号") @RequestParam("sn") String sn
+ ) {
+ try {
+ checkBound(sn);
+ ContactForm formData = contactService.getContactForm(id, sn);
+ return Result.success(formData);
+ } catch (BusinessException be) {
+ return Result.failed(be.getMessage());
+ } catch (Exception e) {
+ log.error("getContactForm error, sn: {}, id: {}", sn, id, e);
+ return Result.failed("获取联系人信息失败: " + e.getMessage());
+ }
+ }
+
+ @Operation(summary = "修改联系人(家属端)")
+ @PreAuthorize("isAuthenticated()")
+ @PutMapping("/update")
+ public Result> updateContact(
+ @Parameter(description = "联系人ID") @RequestParam Long id,
+ @Parameter(description = "设备序列号") @RequestParam("sn") String sn,
+ @Valid @RequestBody ContactForm contactForm
+ ) {
+ try {
+ checkBound(sn);
+ return Result.judge(contactService.updateContact(id, sn, contactForm));
+ } catch (BusinessException be) {
+ return Result.failed(be.getMessage());
+ } catch (Exception e) {
+ log.error("updateContact error, sn: {}, id: {}", sn, id, e);
+ return Result.failed("修改联系人失败: " + e.getMessage());
+ }
+ }
+
+ @Operation(summary = "删除联系人(家属端)")
+ @PreAuthorize("isAuthenticated()")
+ @DeleteMapping("/delete")
+ public Result> deleteContact(
+ @Parameter(description = "联系人ID") @RequestParam Long id,
+ @Parameter(description = "设备序列号") @RequestParam("sn") String sn
+ ) {
+ try {
+ checkBound(sn);
+ return Result.judge(contactService.deleteContact(id, sn));
+ } catch (BusinessException be) {
+ return Result.failed(be.getMessage());
+ } catch (Exception e) {
+ log.error("deleteContact error, sn: {}, id: {}", sn, id, e);
+ return Result.failed("删除联系人失败: " + e.getMessage());
+ }
+ }
+}
diff --git a/src/main/java/com/youlai/boot/client/controller/ClientDeviceOpsController.java b/src/main/java/com/youlai/boot/client/controller/ClientDeviceOpsController.java
index b3b8e45c..83ffcda1 100644
--- a/src/main/java/com/youlai/boot/client/controller/ClientDeviceOpsController.java
+++ b/src/main/java/com/youlai/boot/client/controller/ClientDeviceOpsController.java
@@ -143,6 +143,24 @@ public class ClientDeviceOpsController {
}
}
+ @Operation(summary = "远程拍照(家属端)")
+ @PreAuthorize("isAuthenticated()")
+ @PostMapping("/take_photo")
+ public Result> takePhoto(
+ @Parameter(description = "设备序列号") @RequestParam("sn") String sn
+ ) {
+ try {
+ checkBound(sn);
+ boolean result = deviceService.takePhoto(sn);
+ return Result.judge(result);
+ } catch (BusinessException be) {
+ return Result.failed(be.getMessage());
+ } catch (Exception e) {
+ log.error("remoteCamera error, sn: {}", sn, e);
+ return Result.failed("设备截图失败: " + e.getMessage());
+ }
+ }
+
@Operation(summary = "设备重启(家属端)")
@PreAuthorize("isAuthenticated()")
@PostMapping("/reboot")
diff --git a/src/main/java/com/youlai/boot/device/controller/DeviceOpsController.java b/src/main/java/com/youlai/boot/device/controller/DeviceOpsController.java
index 46cf82c3..54721d2d 100644
--- a/src/main/java/com/youlai/boot/device/controller/DeviceOpsController.java
+++ b/src/main/java/com/youlai/boot/device/controller/DeviceOpsController.java
@@ -81,6 +81,14 @@ public class DeviceOpsController {
return Result.judge(result);
}
+ @Operation(summary = "相机拍照")
+ @PostMapping("/take_photo")
+ @Log(module = LogModuleEnum.DEVICE, value = ActionTypeEnum.SCREENSHOT)
+ public Result> takePhoto(@RequestParam String sn) {
+ boolean result = deviceService.takePhoto(sn);
+ return Result.judge(result);
+ }
+
@Operation(summary = "设备重启")
@PostMapping("/reboot")
@Log(module = LogModuleEnum.DEVICE, value = ActionTypeEnum.REBOOT)
diff --git a/src/main/java/com/youlai/boot/device/controller/MobileController.java b/src/main/java/com/youlai/boot/device/controller/MobileController.java
index fcd57b72..31e22b23 100644
--- a/src/main/java/com/youlai/boot/device/controller/MobileController.java
+++ b/src/main/java/com/youlai/boot/device/controller/MobileController.java
@@ -397,6 +397,11 @@ public class MobileController {
SnScreenshot screenshotInfo = new SnScreenshot();
screenshotInfo.setSn(sn);
+ // 保存原始文件名,便于追溯/调试
+ screenshotInfo.setOriginName(safeBaseName);
+ // 保存MIME类型与扩展名,便于前端筛选/预览
+ screenshotInfo.setMimeType(file.getContentType());
+ screenshotInfo.setFileExtension(fileExtension);
// fileName 仅存纯文件名;前端访问 URL = /static/screenshot/{fileName}(由 WebMvcConfig 静态映射)
screenshotInfo.setFileName(fileName);
// filePath 仅存相对子目录,避免耦合绝对路径
diff --git a/src/main/java/com/youlai/boot/device/model/entity/SnCameraPhoto.java b/src/main/java/com/youlai/boot/device/model/entity/SnCameraPhoto.java
new file mode 100644
index 00000000..5961eccf
--- /dev/null
+++ b/src/main/java/com/youlai/boot/device/model/entity/SnCameraPhoto.java
@@ -0,0 +1,72 @@
+package com.youlai.boot.device.model.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.youlai.boot.common.base.BaseEntity;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.time.LocalDateTime;
+
+/**
+ * 设备截图实体
+ */
+@TableName("sys_sn_camera_photo")
+@Getter
+@Setter
+public class SnCameraPhoto extends BaseEntity {
+
+ /**
+ * 设备序列号
+ */
+ private String sn;
+
+ /**
+ * 文件名称
+ */
+ private String fileName;
+
+ /**
+ * 原始文件名(上传时的原始文件名)
+ */
+ private String originName;
+
+ /**
+ * 文件MIME类型
+ */
+ private String mimeType;
+
+ /**
+ * 文件扩展名
+ */
+ private String fileExtension;
+
+ /**
+ * 文件路径
+ */
+ private String filePath;
+
+ /**
+ * 文件大小(字节)
+ */
+ private Long fileSize;
+
+ /**
+ * 文件MD5值
+ */
+ private String fileMd5;
+ /**
+ * 文件Sha1值
+ */
+
+ private String fileSha1;
+
+ /**
+ * 文件Sha256值
+ */
+ private String fileSha256;
+
+ /**
+ * 上传时间戳
+ */
+ private LocalDateTime uploadTime;
+}
diff --git a/src/main/java/com/youlai/boot/device/model/entity/SnScreenshot.java b/src/main/java/com/youlai/boot/device/model/entity/SnScreenshot.java
index a9b68324..75a8d43d 100644
--- a/src/main/java/com/youlai/boot/device/model/entity/SnScreenshot.java
+++ b/src/main/java/com/youlai/boot/device/model/entity/SnScreenshot.java
@@ -25,6 +25,21 @@ public class SnScreenshot extends BaseEntity {
*/
private String fileName;
+ /**
+ * 原始文件名(上传时的原始文件名)
+ */
+ private String originName;
+
+ /**
+ * 文件MIME类型
+ */
+ private String mimeType;
+
+ /**
+ * 文件扩展名
+ */
+ private String fileExtension;
+
/**
* 文件路径
*/
@@ -54,4 +69,9 @@ public class SnScreenshot extends BaseEntity {
* 上传时间戳
*/
private LocalDateTime uploadTime;
+
+ /**
+ * 逻辑删除标志(0未删除 1已删除)
+ */
+ private boolean isDeleted;
}
diff --git a/src/main/java/com/youlai/boot/device/model/vo/ScreenshotVO.java b/src/main/java/com/youlai/boot/device/model/vo/ScreenshotVO.java
index 092d79d0..265a7738 100644
--- a/src/main/java/com/youlai/boot/device/model/vo/ScreenshotVO.java
+++ b/src/main/java/com/youlai/boot/device/model/vo/ScreenshotVO.java
@@ -24,6 +24,15 @@ public class ScreenshotVO {
@Schema(description = "文件名称")
private String fileName;
+ @Schema(description = "原始文件名(上传时的原始文件名)")
+ private String originName;
+
+ @Schema(description = "文件MIME类型")
+ private String mimeType;
+
+ @Schema(description = "文件扩展名")
+ private String fileExtension;
+
@Schema(description = "文件大小(字节)")
private Long fileSize;
diff --git a/src/main/java/com/youlai/boot/device/service/DeviceService.java b/src/main/java/com/youlai/boot/device/service/DeviceService.java
index 04b0ef7b..51b56260 100644
--- a/src/main/java/com/youlai/boot/device/service/DeviceService.java
+++ b/src/main/java/com/youlai/boot/device/service/DeviceService.java
@@ -97,6 +97,7 @@ public interface DeviceService extends IService {
* @return 是否推送成功
*/
boolean screenSnapshot(String sn);
+ boolean takePhoto(String sn);
boolean deviceReboot(String sn);
boolean deviceShutdown(String sn);
diff --git a/src/main/java/com/youlai/boot/device/service/impl/DeviceServiceImpl.java b/src/main/java/com/youlai/boot/device/service/impl/DeviceServiceImpl.java
index ef90c182..d88b00a1 100644
--- a/src/main/java/com/youlai/boot/device/service/impl/DeviceServiceImpl.java
+++ b/src/main/java/com/youlai/boot/device/service/impl/DeviceServiceImpl.java
@@ -55,6 +55,20 @@ import java.util.Set;
@RequiredArgsConstructor
@Slf4j
public class DeviceServiceImpl extends ServiceImpl implements DeviceService {
+
+ private static final String DEVICE_REFRESH = "1";
+ private static final String DEVICE_SCREEN_SNAPSHOT = "2";
+ private static final String DEVICE_REBOOT = "3";
+ private static final String DEVICE_SHUTDOWN = "4";
+ private static final String DEVICE_LOCATE = "5";
+ private static final String DEVICE_RESTORE = "6";
+ private static final String DEVICE_DEVELOPER = "7";
+ private static final String DEVICE_APP_LAUNCH = "8";
+ private static final String DEVICE_APP_CLEAR_DATA = "9";
+ private static final String DEVICE_APP_UNINSTALL = "10";
+ private static final String DEVICE_APP_STOP = "11";
+ private static final String DEVICE_TAKE_PHOTO = "12";
+
PushApi pushApi = new PushApi.Builder()
.setAppKey("d779178d9900d4fb5d633678")
.setMasterSecret("be0e197d30fec7bec118a70d")
@@ -254,7 +268,7 @@ public class DeviceServiceImpl extends ServiceImpl i
@Override
public boolean deviceRefresh(String sn) {
- PushSendParam pushSendParam = getSinglePushSendParam(sn, "1", "deviceRefresh", "refresh");
+ PushSendParam pushSendParam = getSinglePushSendParam(sn, DEVICE_REFRESH, "deviceRefresh", "refresh");
try {
PushSendResult result = pushApi.send(pushSendParam);
log.info("send success:{}", result);
@@ -272,7 +286,24 @@ public class DeviceServiceImpl extends ServiceImpl i
@Override
public boolean screenSnapshot(String sn) {
- PushSendParam pushSendParam = getSinglePushSendParam(sn, "2", "screenSnapshot", "screenshot");
+ PushSendParam pushSendParam = getSinglePushSendParam(sn, DEVICE_SCREEN_SNAPSHOT, "screenSnapshot", "screenshot");
+ try {
+ PushSendResult result = pushApi.send(pushSendParam);
+ log.info("send success:{}", result);
+ return true;
+ } catch (ApiErrorException e) {
+ // 错误信息
+ int httpStatus = e.getStats(); // HTTP状态码
+ int errorCode = e.getApiError().getError().getCode(); // 错误码
+ String errorMessage = e.getApiError().getError().getMessage(); // 错误信息
+ log.error("send error, httpStatus:{} code:{}, message:{}", httpStatus, errorCode, errorMessage);
+ return false;
+ }
+ }
+
+ @Override
+ public boolean takePhoto(String sn) {
+ PushSendParam pushSendParam = getSinglePushSendParam(sn, DEVICE_TAKE_PHOTO, "takePhoto", "camera");
try {
PushSendResult result = pushApi.send(pushSendParam);
log.info("send success:{}", result);
@@ -289,7 +320,7 @@ public class DeviceServiceImpl extends ServiceImpl i
@Override
public boolean deviceReboot(String sn) {
- PushSendParam pushSendParam = getSinglePushSendParam(sn, "3", "deviceReboot", "reboot");
+ PushSendParam pushSendParam = getSinglePushSendParam(sn, DEVICE_REBOOT, "deviceReboot", "reboot");
try {
PushSendResult result = pushApi.send(pushSendParam);
log.info("send success:{}", result);
@@ -306,7 +337,7 @@ public class DeviceServiceImpl extends ServiceImpl i
@Override
public boolean deviceShutdown(String sn) {
- PushSendParam pushSendParam = getSinglePushSendParam(sn, "4", "deviceShutdown", "shutdown");
+ PushSendParam pushSendParam = getSinglePushSendParam(sn, DEVICE_SHUTDOWN, "deviceShutdown", "shutdown");
try {
PushSendResult result = pushApi.send(pushSendParam);
log.info("send success:{}", result);
@@ -323,7 +354,7 @@ public class DeviceServiceImpl extends ServiceImpl i
@Override
public boolean deviceLocate(String sn) {
- PushSendParam pushSendParam = getSinglePushSendParam(sn, "5", "deviceLocate", "locate");
+ PushSendParam pushSendParam = getSinglePushSendParam(sn, DEVICE_LOCATE, "deviceLocate", "locate");
try {
PushSendResult result = pushApi.send(pushSendParam);
log.info("send success:{}", result);
@@ -340,7 +371,7 @@ public class DeviceServiceImpl extends ServiceImpl i
@Override
public boolean restore(String sn) {
- PushSendParam pushSendParam = getSinglePushSendParam(sn, "6", "deviceRestore", "restore");
+ PushSendParam pushSendParam = getSinglePushSendParam(sn, DEVICE_RESTORE, "deviceRestore", "restore");
try {
PushSendResult result = pushApi.send(pushSendParam);
log.info("send success:{}", result);
@@ -357,7 +388,7 @@ public class DeviceServiceImpl extends ServiceImpl i
@Override
public boolean setDeviceDeveloper(String sn) {
- PushSendParam pushSendParam = getSinglePushSendParam(sn, "7", "deviceDeveloper", "developer");
+ PushSendParam pushSendParam = getSinglePushSendParam(sn, DEVICE_DEVELOPER, "deviceDeveloper", "developer");
try {
PushSendResult result = pushApi.send(pushSendParam);
log.info("send success:{}", result);
@@ -385,7 +416,7 @@ public class DeviceServiceImpl extends ServiceImpl i
@Override
public boolean launchApp(String sn, String packageName) {
- PushSendParam pushSendParam = getAppPushSendParam(sn, "8", "appLaunch", "launch", packageName);
+ PushSendParam pushSendParam = getAppPushSendParam(sn, DEVICE_APP_LAUNCH, "appLaunch", "launch", packageName);
try {
PushSendResult result = pushApi.send(pushSendParam);
log.info("send success:{}", result);
@@ -401,7 +432,7 @@ public class DeviceServiceImpl extends ServiceImpl i
@Override
public boolean clearAppData(String sn, String packageName) {
- PushSendParam pushSendParam = getAppPushSendParam(sn, "9", "appClearData", "clearData", packageName);
+ PushSendParam pushSendParam = getAppPushSendParam(sn, DEVICE_APP_CLEAR_DATA, "appClearData", "clearData", packageName);
try {
PushSendResult result = pushApi.send(pushSendParam);
log.info("send success:{}", result);
@@ -417,7 +448,7 @@ public class DeviceServiceImpl extends ServiceImpl i
@Override
public boolean uninstallApp(String sn, String packageName) {
- PushSendParam pushSendParam = getAppPushSendParam(sn, "10", "appUninstall", "uninstall", packageName);
+ PushSendParam pushSendParam = getAppPushSendParam(sn, DEVICE_APP_UNINSTALL, "appUninstall", "uninstall", packageName);
try {
PushSendResult result = pushApi.send(pushSendParam);
log.info("send success:{}", result);
@@ -433,7 +464,7 @@ public class DeviceServiceImpl extends ServiceImpl i
@Override
public boolean stopApp(String sn, String packageName) {
- PushSendParam pushSendParam = getAppPushSendParam(sn, "11", "appStop", "stop", packageName);
+ PushSendParam pushSendParam = getAppPushSendParam(sn, DEVICE_APP_STOP, "appStop", "stop", packageName);
try {
PushSendResult result = pushApi.send(pushSendParam);
log.info("send success:{}", result);