196 lines
6.8 KiB
Java
196 lines
6.8 KiB
Java
package com.onekeycall.videotablet.controller;
|
||
|
||
import com.google.gson.JsonObject;
|
||
import com.onekeycall.videotablet.entity.DeviceInfo;
|
||
import com.onekeycall.videotablet.entity.User;
|
||
import com.onekeycall.videotablet.result.Result;
|
||
import com.onekeycall.videotablet.service.DeviceSnService;
|
||
import com.onekeycall.videotablet.service.UserService;
|
||
import com.onekeycall.videotablet.utils.JwtUtil;
|
||
import com.onekeycall.videotablet.utils.DevicePushUtils;
|
||
import com.onekeycall.videotablet.utils.TextUtils;
|
||
import org.apache.commons.lang3.RandomStringUtils;
|
||
import org.slf4j.Logger;
|
||
import org.slf4j.LoggerFactory;
|
||
import org.springframework.beans.factory.annotation.Autowired;
|
||
import org.springframework.data.redis.core.RedisTemplate;
|
||
import org.springframework.web.bind.annotation.*;
|
||
|
||
import java.util.*;
|
||
import java.util.concurrent.TimeUnit;
|
||
|
||
@RestController
|
||
@RequestMapping("/sn")
|
||
public class BindSnController {
|
||
|
||
@Autowired
|
||
private JwtUtil jwtUtil;
|
||
@Autowired
|
||
private UserService userService;
|
||
@Autowired
|
||
private DeviceSnService deviceSnService;
|
||
|
||
@Autowired
|
||
private RedisTemplate<String, Object> redisTemplate;
|
||
|
||
Logger logger = LoggerFactory.getLogger(BindSnController.class);
|
||
|
||
|
||
/**
|
||
* 用户app发送绑定推送到手机
|
||
*
|
||
* @param authHeader
|
||
* @param deviceId
|
||
* @param userId
|
||
* @param sn
|
||
* @return
|
||
*/
|
||
@PostMapping("/bind_sn")
|
||
public Result bindSn(
|
||
@RequestHeader("Authorization") String authHeader, @RequestHeader("Device-ID") String deviceId,
|
||
@RequestParam(value = "user_id") String userId, @RequestParam(value = "sn") String sn) {
|
||
|
||
logger.info("bindSn: authHeader={}, deviceId={}, userId={}, sn={}", authHeader, deviceId, userId, sn);
|
||
if (!authHeader.startsWith("Bearer ")) {
|
||
return Result.error().message("Invalid Authorization header");
|
||
}
|
||
String token = authHeader.substring(7); // 去掉 "Bearer " 前缀
|
||
|
||
if (!jwtUtil.validateAccessToken(userId, token, deviceId)) {
|
||
return Result.error().message("Invalid token");
|
||
}
|
||
|
||
User user = userService.getUserByUserId(userId);
|
||
String userPhone = user.getPhone();
|
||
|
||
DeviceInfo deviceInfo = deviceSnService.findBySn(sn);
|
||
if (deviceInfo == null) {
|
||
return Result.error().message("sn not found");
|
||
}
|
||
|
||
if (!TextUtils.isEmpty(deviceInfo.getBindPhone())) {
|
||
return Result.error().message("sn already bind");
|
||
}
|
||
|
||
try {
|
||
String verifyKey = RandomStringUtils.randomAlphanumeric(32);
|
||
JsonObject params = new JsonObject();
|
||
params.addProperty("verify_key", verifyKey);
|
||
params.addProperty("phone", userPhone);
|
||
params.addProperty("expire_time", System.currentTimeMillis() + 60 * 1000);
|
||
|
||
// PushUtils.aliyunAsyncPush("1", params.toString(), sn);
|
||
DevicePushUtils.tpnsPush("1", params.toString(), sn);
|
||
redisTemplate.opsForValue().set(sn, verifyKey, 1, TimeUnit.MINUTES);
|
||
return Result.ok().message("send message success");
|
||
} catch (Exception e) {
|
||
e.printStackTrace();
|
||
return Result.error().message(e.getMessage());
|
||
}
|
||
|
||
}
|
||
|
||
/**
|
||
* 平板根据返回的数据绑定手机
|
||
*
|
||
* @param deviceId
|
||
* @param phone
|
||
* @param sn
|
||
* @param verifyKey
|
||
* @return
|
||
*/
|
||
@PostMapping("/device_bind")
|
||
public Result deviceBind(
|
||
@RequestHeader("Device-ID") String deviceId,
|
||
@RequestParam(value = "sn") String sn, @RequestParam(value = "phone") String phone,
|
||
@RequestParam(value = "verify_key") String verifyKey) {
|
||
|
||
User user = userService.getUserByPhone(phone);
|
||
if (user == null) {
|
||
return Result.notFound().message("user not found");
|
||
}
|
||
|
||
|
||
String redisVerifyKey = (String) redisTemplate.opsForValue().get(sn);
|
||
if (redisVerifyKey == null) {
|
||
return Result.notFound().message("verify key not found");
|
||
}
|
||
if (!Objects.equals(redisVerifyKey, verifyKey)) {
|
||
return Result.error().message("verify key is not same");
|
||
}
|
||
|
||
DeviceInfo oldDeviceInfo = deviceSnService.findBySn(sn);
|
||
if (oldDeviceInfo == null) {
|
||
return Result.notFound().message("sn not found");
|
||
}
|
||
|
||
if (!TextUtils.isEmpty(oldDeviceInfo.getBindPhone())) {
|
||
return Result.error().message("sn already bind");
|
||
}
|
||
|
||
String userId = user.getUserId();
|
||
String deviceSig = jwtUtil.generateDeviceSig(sn);
|
||
String deviceToken = jwtUtil.generateDeviceToken(sn, deviceId);
|
||
|
||
oldDeviceInfo.setBindPhone(phone);
|
||
oldDeviceInfo.setUserId(userId);
|
||
oldDeviceInfo.setDeviceAlias(user.getNickname() + "的平板");
|
||
oldDeviceInfo.setBindTime(new Date());
|
||
oldDeviceInfo.setDeviceModel(deviceId);
|
||
oldDeviceInfo.setBindSig(deviceSig);
|
||
oldDeviceInfo.setToken(deviceToken);
|
||
oldDeviceInfo.setSn(sn);
|
||
deviceSnService.save(oldDeviceInfo);
|
||
Map<String, Object> map = new LinkedHashMap<>();
|
||
map.put("phone", phone);
|
||
map.put("device_token", deviceToken);
|
||
map.put("device_sig", deviceSig);
|
||
return Result.ok().data(map).message("bind success");
|
||
}
|
||
|
||
/**
|
||
* 获取平板sn绑定状态
|
||
* 标准的通过平板获取接口,需要 Device-Token Device-ID Device-Sig
|
||
* @param deviceToken
|
||
* @param deviceId
|
||
* @param deviceSig
|
||
* @param sn
|
||
* @return
|
||
*/
|
||
// TODO: 2025/8/22 Device_Token在docker无法被接收到,使用Device-Token代替
|
||
@GetMapping("/get_bind_statu")
|
||
public Result getBindStatus(
|
||
@RequestHeader("Device-Token") String deviceToken, @RequestHeader("Device-ID") String deviceId,
|
||
@RequestHeader("Device-Sig") String deviceSig,
|
||
@RequestParam(value = "sn") String sn) {
|
||
|
||
if (!jwtUtil.validateDeviceToken(deviceToken, deviceId, sn)) {
|
||
return Result.error().message("Invalid token");
|
||
}
|
||
|
||
DeviceInfo deviceInfo = deviceSnService.findBySn(sn);
|
||
if (deviceInfo == null) {
|
||
return Result.notFound().message("sn not found");
|
||
}
|
||
|
||
if (!deviceInfo.getBindSig().equals(deviceSig)) {
|
||
return Result.error().message("device sig not match");
|
||
}
|
||
|
||
if (TextUtils.isEmpty(deviceInfo.getBindPhone())) {
|
||
return Result.error().message("sn not bind");
|
||
}
|
||
|
||
Map<String, Object> map = new LinkedHashMap<>();
|
||
map.put("bind_status", 1);
|
||
map.put("device_alias", deviceInfo.getDeviceAlias());
|
||
map.put("bind_phone", deviceInfo.getBindPhone());
|
||
map.put("user_id", deviceInfo.getUserId());
|
||
map.put("add_time", deviceInfo.getAddTime());
|
||
map.put("bind_time", deviceInfo.getBindTime());
|
||
|
||
return Result.ok().data(map).message("sn bind");
|
||
}
|
||
|
||
}
|