浏览代码

1。添加注销账户操作(手机,邮箱)
2。添加账户注销苹果验证操作,添加p8文件
3。添加user_delete_log字段
4。修改登陆返回appleid

a0000 2 年之前
父节点
当前提交
807422765b
共有 18 个文件被更改,包括 375 次插入16 次删除
  1. 5 1
      src/main/java/com/YuyeTech/HeartRate/enums/ResultEnum.java
  2. 4 3
      src/main/java/com/YuyeTech/HeartRate/game/controller/BackstageManagerController.java
  3. 16 4
      src/main/java/com/YuyeTech/HeartRate/game/controller/LoginController.java
  4. 4 0
      src/main/java/com/YuyeTech/HeartRate/game/userDeleteLog/pojo/UserDeleteLog.java
  5. 4 0
      src/main/java/com/YuyeTech/HeartRate/game/userDeleteLog/vo/UserDeleteLogSimpleVo.java
  6. 4 0
      src/main/java/com/YuyeTech/HeartRate/game/userDeleteLog/vo/UserDeleteLogVo.java
  7. 1 1
      src/main/java/com/YuyeTech/HeartRate/game/userinfo/controller/BackstageUserController.java
  8. 93 0
      src/main/java/com/YuyeTech/HeartRate/game/userinfo/controller/ManagerController.java
  9. 13 0
      src/main/java/com/YuyeTech/HeartRate/game/userinfo/controller/UserInfoController.java
  10. 2 1
      src/main/java/com/YuyeTech/HeartRate/game/userinfo/service/MainInfoService.java
  11. 20 1
      src/main/java/com/YuyeTech/HeartRate/game/userinfo/service/MainInfoServiceImpl.java
  12. 2 0
      src/main/java/com/YuyeTech/HeartRate/repository/FriendInfoRepository.java
  13. 2 0
      src/main/java/com/YuyeTech/HeartRate/service/FriendInfoService.java
  14. 12 0
      src/main/java/com/YuyeTech/HeartRate/service/impl/FriendInfoServiceImpl.java
  15. 171 2
      src/main/java/com/YuyeTech/HeartRate/utils/AppleUtil.java
  16. 8 3
      src/main/java/com/YuyeTech/HeartRate/utils/RedisSettingMap.java
  17. 8 0
      src/main/resources/application.yml
  18. 6 0
      src/main/resources/config/AuthKey_8G9994KW4L.p8

+ 5 - 1
src/main/java/com/YuyeTech/HeartRate/enums/ResultEnum.java

@@ -37,7 +37,11 @@ public enum ResultEnum {
 
     VERSION_CODE_ERROR(321,"version code 错误"),
 
-
+    APPLE_REVOKE_ERROR(322,"apple:注销用户失败!"),
+    REVOKE_ERROR(323,"注销用户方式异常!"),
+    WEIXIN_REVOKE_ERROR(324,"WEIXIN:注销用户失败!"),
+    PHONE_NUMBER_REVOKE_ERROR(324,"PHONE:注销用户失败!"),
+    BOX_EMAIL_REVOKE_ERROR(324,"WEIXIN:注销用户失败!"),
     //wallets
     WALLETS_GET_ERROR(401,"获取WALLETS错误"),
     WALLETS_MODIFY_ERROR(402,"修改WALLETS数据错误"),

+ 4 - 3
src/main/java/com/YuyeTech/HeartRate/game/controller/BackstageManagerController.java

@@ -3,6 +3,7 @@ package com.YuyeTech.HeartRate.game.controller;
 import com.YuyeTech.HeartRate.constant.CookieConstant;
 import com.YuyeTech.HeartRate.constant.RedisConstant;
 import com.YuyeTech.HeartRate.dataobject.AdminInfo;
+import com.YuyeTech.HeartRate.enums.RedisType;
 import com.YuyeTech.HeartRate.game.userinfo.projo.UserInfo;
 import com.YuyeTech.HeartRate.enums.ResultEnum;
 import com.YuyeTech.HeartRate.form.AdminForm;
@@ -133,8 +134,8 @@ public class BackstageManagerController {
         Cookie cookie = CookieUtil.get(request, CookieConstant.TOKEN);
         if (cookie != null) {
             //2. 清除redis
-            stringRedisTemplate.opsForValue().getOperations().delete(String.format(RedisConstant.TOKEN_PREFIX, cookie.getValue()));
-
+            //stringRedisTemplate.opsForValue().getOperations().delete(String.format(RedisConstant.TOKEN_PREFIX, cookie.getValue()));
+            redisSettingMap.deleteValue(RedisType.TOKEN,cookie.getValue());
             //3. 清除cookie
             CookieUtil.set(response, CookieConstant.TOKEN, null, 0);
         }
@@ -156,7 +157,7 @@ public class BackstageManagerController {
             }
         }
         //2.删除数据库数据
-        mainInfoService.deleteMainInfoById(userId);
+        mainInfoService.deleteMainInfoById(userId,"backstage_delete_user");
 
         map.put("msg", "删除用户信息成功");
         map.put("url", "/backstage_user/list");

+ 16 - 4
src/main/java/com/YuyeTech/HeartRate/game/controller/LoginController.java

@@ -140,7 +140,8 @@ public class LoginController {
         //检查redis 的token 是否存在,存在则删除
         String headToken = request.getHeader("token");
         if (StringUtils.isNotBlank(headToken)) {
-            Boolean bSuccess = redisTemplate.delete(String.format(RedisConstant.TOKEN_PREFIX, headToken));
+//            Boolean bSuccess = redisTemplate.delete(String.format(RedisConstant.TOKEN_PREFIX, headToken));
+            Boolean bSuccess = redisSettingMap.deleteValue(RedisType.TOKEN,headToken);
             if (!bSuccess) {
                 //删除不成功,redis不存在,是非法token
                 log.info("redis 没有对应的token");
@@ -164,6 +165,8 @@ public class LoginController {
                 wxInfo.setUserId(mainInfo.getUserId());
                 wxInfo.setOpenid(openid);
                 wxInfo.setUnionid(unionid);
+                wxInfo.setCreateTime(DateUtil.date());
+                wxInfo.setUpdateTime(DateUtil.date());
                 wxInfoService.addWxInfo(wxInfo);
             } else {
                 mainInfo = mainInfoService.findMainInfoById(wxInfo.getUserId());
@@ -240,7 +243,8 @@ public class LoginController {
         //检查redis 的token 是否存在,存在则删除
         String headToken = request.getHeader("token");
         if (StringUtils.isNotBlank(headToken)) {
-            Boolean bSuccess = redisTemplate.delete(String.format(RedisConstant.TOKEN_PREFIX, headToken));
+//            Boolean bSuccess = redisTemplate.delete(String.format(RedisConstant.TOKEN_PREFIX, headToken));
+            Boolean bSuccess = redisSettingMap.deleteValue(RedisType.TOKEN,headToken);
             if (!bSuccess) {
                 //删除不成功,redis不存在,是非法token
 //                throw new WxInfoException(ResultEnum.TOKEN_IS_ILLEGAL.getCode(), ResultEnum.TOKEN_IS_ILLEGAL.getMessage());
@@ -271,6 +275,8 @@ public class LoginController {
                     wxInfo = new WxInfo();
                     wxInfo.setUserId(mainInfo.getUserId());
                     wxInfo.setOpenid(session.getOpenid());
+                    wxInfo.setCreateTime(DateUtil.date());
+                    wxInfo.setUpdateTime(DateUtil.date());
                     wxInfoService.addWxInfo(wxInfo);
                 }
 
@@ -600,6 +606,8 @@ public class LoginController {
                 wxInfo.setUnionid(unionid);
                 wxInfo.setOpenid(openid);
                 wxInfo.setUserId(userId);
+                wxInfo.setCreateTime(DateUtil.date());
+                wxInfo.setUpdateTime(DateUtil.date());
                 wxInfoService.addWxInfo(wxInfo);
             } else {
                 //提示用户微信已被使用
@@ -857,7 +865,8 @@ public class LoginController {
 
         String headToken = request.getHeader("token");
         if (StringUtils.isNotBlank(headToken)) {
-            Boolean bSuccess = redisTemplate.delete(String.format(RedisConstant.TOKEN_PREFIX, headToken));
+//            Boolean bSuccess = redisTemplate.delete(String.format(RedisConstant.TOKEN_PREFIX, headToken));
+            Boolean bSuccess = redisSettingMap.deleteValue(RedisType.TOKEN,headToken);
             if (!bSuccess) {
                 //删除不成功,redis不存在,是非法token
                 log.info("redis 没有对应的token");
@@ -879,7 +888,8 @@ public class LoginController {
         //检查redis 的token 是否存在,存在则删除
         String headToken = request.getHeader("token");
         if (StringUtils.isNotBlank(headToken)) {
-            Boolean bSuccess = redisTemplate.delete(String.format(RedisConstant.TOKEN_PREFIX, headToken));
+//            Boolean bSuccess = redisTemplate.delete(String.format(RedisConstant.TOKEN_PREFIX, headToken));
+            Boolean bSuccess = redisSettingMap.deleteValue(RedisType.TOKEN,headToken);
             if (!bSuccess) {
                 //删除不成功,redis不存在,是非法token
                 log.info("redis 没有对应的token");
@@ -922,6 +932,8 @@ public class LoginController {
                 appleInfo = new AppleInfo();
                 appleInfo.setUserId(mainInfo.getUserId());
                 appleInfo.setAppleId(json.getString("sub"));
+                appleInfo.setCreateTime(DateUtil.date());
+                appleInfo.setUpdateTime(DateUtil.date());
                 appleInfoService.addAppleInfo(appleInfo);
             } else {
                 mainInfo = mainInfoService.findMainInfoById(appleInfo.getUserId());

+ 4 - 0
src/main/java/com/YuyeTech/HeartRate/game/userDeleteLog/pojo/UserDeleteLog.java

@@ -12,6 +12,8 @@ public class UserDeleteLog implements Serializable {
     @Id
     private String userId;//
 
+    private String username;//
+
     private String telephoneNumber;//电话
 
     private String email;//邮箱
@@ -24,6 +26,8 @@ public class UserDeleteLog implements Serializable {
 
     private Integer status;//0:挂起数据,1:已删除,2:已恢复
 
+    private String type;
+
     private Date createTime;//创建时间
 
     private Date updateTime;//修改时间

+ 4 - 0
src/main/java/com/YuyeTech/HeartRate/game/userDeleteLog/vo/UserDeleteLogSimpleVo.java

@@ -8,6 +8,8 @@ import java.util.Date;
 public class UserDeleteLogSimpleVo implements Serializable {
     private String userId;//
 
+    private String username;//
+
     private String telephoneNumber;//电话
 
     private String email;//邮箱
@@ -20,6 +22,8 @@ public class UserDeleteLogSimpleVo implements Serializable {
 
     private Integer status;//0:挂起数据,1:已删除,2:已恢复
 
+    private String type;
+
     private Date createTime;//创建时间
 
     private Date updateTime;//修改时间

+ 4 - 0
src/main/java/com/YuyeTech/HeartRate/game/userDeleteLog/vo/UserDeleteLogVo.java

@@ -8,6 +8,8 @@ import java.util.Date;
 public class UserDeleteLogVo extends PageCondition implements Serializable {
     private String userId;//
 
+    private String username;
+
     private String telephoneNumber;//电话
 
     private String email;//邮箱
@@ -20,6 +22,8 @@ public class UserDeleteLogVo extends PageCondition implements Serializable {
 
     private Integer status;//0:挂起数据,1:已删除,2:已恢复
 
+    private String type;
+
     private Date createTime;//创建时间
 
     private Date updateTime;//修改时间

+ 1 - 1
src/main/java/com/YuyeTech/HeartRate/game/userinfo/controller/BackstageUserController.java

@@ -101,7 +101,7 @@ public class BackstageUserController {
     @PostMapping("/deleteUser")
     public Result deleteUser(@RequestParam("userId") String userId) {
         //预删除数据库数据
-        String msg = mainInfoService.deleteMainInfoById(userId);
+        String msg = mainInfoService.deleteMainInfoById(userId,"deleteUser");
         return Result.of(msg);
     }
 

+ 93 - 0
src/main/java/com/YuyeTech/HeartRate/game/userinfo/controller/ManagerController.java

@@ -1,14 +1,29 @@
 package com.YuyeTech.HeartRate.game.userinfo.controller;
 
+import com.YuyeTech.HeartRate.VO.ResultVO;
+import com.YuyeTech.HeartRate.constant.RedisConstant;
+import com.YuyeTech.HeartRate.enums.RedisType;
+import com.YuyeTech.HeartRate.enums.ResultEnum;
+import com.YuyeTech.HeartRate.enums.UserEnum;
+import com.YuyeTech.HeartRate.game.TP_WxInfo.projo.WxInfo;
+import com.YuyeTech.HeartRate.game.TP_WxInfo.service.WxInfoService;
 import com.YuyeTech.HeartRate.game.gameInfo.service.GameInfoService;
+import com.YuyeTech.HeartRate.game.userinfo.projo.MainInfo;
+import com.YuyeTech.HeartRate.game.userinfo.projo.UserInfo;
 import com.YuyeTech.HeartRate.game.userinfo.service.MainInfoService;
 import com.YuyeTech.HeartRate.game.userinfo.service.UserInfoService;
 import com.YuyeTech.HeartRate.utils.AliyunOSSUtil;
+import com.YuyeTech.HeartRate.utils.AppleUtil;
+import com.YuyeTech.HeartRate.utils.RedisSettingMap;
+import com.YuyeTech.HeartRate.utils.ResultVOUtil;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.redis.core.StringRedisTemplate;
 import org.springframework.web.bind.annotation.*;
 
+import javax.servlet.http.HttpServletRequest;
+
 /**
  * 管理数据库数据
  *
@@ -35,6 +50,84 @@ public class ManagerController {
     @Autowired
     private UserInfoService userInfoService;
 
+    @Autowired
+    private RedisSettingMap redisSettingMap;
+
+    @Autowired
+    private WxInfoService wxInfoService;
+    /**
+     * 通过类型来判断删除
+     * 1。电话:密码或者验证码
+     * 2。邮箱:密码或者验证码
+     * 3。微信:微信授权code
+     * 4。苹果:苹果授权code
+     * @param userId
+     * @param code
+     * @param request
+     * @return
+     */
+    @PostMapping("/deleteUserByType")
+    public ResultVO deleteUserByType(@RequestParam("userId") String userId,
+                                     @RequestParam("type") String type,
+                                     @RequestParam("code") String code,
+                                     HttpServletRequest request){
+
+        if(type.equals("apple")){
+           if(!AppleUtil.appleRevoke(code))
+           {
+               return ResultVOUtil.error(ResultEnum.APPLE_REVOKE_ERROR.getCode(), ResultEnum.APPLE_REVOKE_ERROR.getMessage());
+           }
+        }else if(type.equals("weixin")){
+            WxInfo wxInfo = wxInfoService.findWxInfoByOpenid(code);
+            if(wxInfo == null){
+                return ResultVOUtil.error(ResultEnum.REVOKE_ERROR.getCode(), ResultEnum.REVOKE_ERROR.getMessage());
+            }
+        } else if(type.equals("phoneNumber") || type.equals("mailBox")){
+            //查询电话号码
+            MainInfo mainInfo = mainInfoService.findMainInfoById(userId);
+            if(mainInfo == null){
+                return ResultVOUtil.error(UserEnum.USER_PASSWORD_ERROR.getCode(), UserEnum.USER_PASSWORD_ERROR.getMessage());
+            }
+            String account = type.equals("phoneNumber")? mainInfo.getTelephoneNumber():mainInfo.getEmail();
+            String codeValue = redisSettingMap.getValue(RedisType.SMS,account);
+            if (!StringUtils.equals(codeValue, code)) {
+                return ResultVOUtil.error(UserEnum.USER_CODE_ERROR.getCode(), UserEnum.USER_CODE_ERROR.getMessage());
+            }
+            Boolean bSuccess =redisSettingMap.deleteValue(RedisType.SMS, account);
+            if (!bSuccess) {
+                //删除不成功,redis不存在
+                log.info("redis 没有对应的token");
+                return ResultVOUtil.error(ResultEnum.PHONE_NUMBER_REVOKE_ERROR.getCode(), ResultEnum.PHONE_NUMBER_REVOKE_ERROR.getMessage());
+            }
+        } else {
+            return ResultVOUtil.error(ResultEnum.REVOKE_ERROR.getCode(), ResultEnum.REVOKE_ERROR.getMessage());
+        }
+
+        //1.删除token
+        String headToken = request.getHeader("token");
+        log.info("{}",request.getParameterValues("userId")[0]);
+        if (StringUtils.isNotBlank(headToken)) {
+            log.info(String.format(RedisConstant.TOKEN_PREFIX, headToken));
+//            Boolean bSuccess = redisTemplate.delete(String.format(RedisConstant.TOKEN_PREFIX, headToken));
+            Boolean bSuccess = redisSettingMap.deleteValue(RedisType.TOKEN,headToken);
+            if (!bSuccess) {
+                //删除不成功,redis不存在,是非法token
+                log.info("redis 没有对应的token");
+                return ResultVOUtil.error(ResultEnum.TOKEN_IS_ILLEGAL.getCode(), ResultEnum.TOKEN_IS_ILLEGAL.getMessage());
+            }
+        }
+        //2.删除头像W
+        UserInfo userInfo = userInfoService.findUserInfoById(userId, false);
+        if (!userInfo.getAvatarUrl().equals("publicAvatar/defaultAvatar.png") && userInfo.getAvatarUrl() != null && userInfo.getAvatarUrl().length() != 0) {
+            if (aliyunOSSUtil.deleteBlog(userInfo.getAvatarUrl())) {
+                log.info("删除头像成功");
+            }
+        }
+        //3.删除数据库数据
+        mainInfoService.deleteMainInfoById(userId,type);
+
+        return ResultVOUtil.success();
+    }
 //    /**
 //     * 删除用户数据
 //     * @param userId

+ 13 - 0
src/main/java/com/YuyeTech/HeartRate/game/userinfo/controller/UserInfoController.java

@@ -8,6 +8,9 @@ import com.YuyeTech.HeartRate.dto.UserDTO;
 import com.YuyeTech.HeartRate.enums.ResultEnum;
 import com.YuyeTech.HeartRate.enums.UserEnum;
 import com.YuyeTech.HeartRate.exception.UserException;
+import com.YuyeTech.HeartRate.game.TP_AppleInfo.projo.AppleInfo;
+import com.YuyeTech.HeartRate.game.TP_AppleInfo.service.AppleInfoService;
+import com.YuyeTech.HeartRate.game.TP_AppleInfo.vo.AppleInfoVo;
 import com.YuyeTech.HeartRate.game.TP_WxInfo.projo.WxInfo;
 import com.YuyeTech.HeartRate.game.TP_WxInfo.service.WxInfoService;
 import com.YuyeTech.HeartRate.game.imageInfo.projo.Pictures;
@@ -65,6 +68,9 @@ public class UserInfoController {
     @Autowired
     private WxInfoService wxInfoService;
 
+    @Autowired
+    private AppleInfoService appleInfoService;
+
     @Autowired
     private WeightInfoService weightInfoService;
 
@@ -122,6 +128,13 @@ public class UserInfoController {
             map.put("openid", wxInfo.getOpenid());
         }
 
+        AppleInfoVo appleInfoVo = appleInfoService.getVo(userId);
+        if(appleInfoVo ==null){
+            map.put("appleid",null);
+        } else {
+            map.put("appleid",appleInfoVo.getAppleId());
+        }
+
         return ResultVOUtil.success(map);
     }
 

+ 2 - 1
src/main/java/com/YuyeTech/HeartRate/game/userinfo/service/MainInfoService.java

@@ -19,9 +19,10 @@ public interface MainInfoService extends CommonService<MainInfoVo, MainInfo, Str
     /**
      * 删除用户,目前只是挂起数据
      * @param userId
+     * @param type 删除的操作类型
      * @return
      */
-    String deleteMainInfoById(String userId);
+    String deleteMainInfoById(String userId,String type);
 
     /**
      * 恢复删除用户数据

+ 20 - 1
src/main/java/com/YuyeTech/HeartRate/game/userinfo/service/MainInfoServiceImpl.java

@@ -14,10 +14,12 @@ import com.YuyeTech.HeartRate.game.imageInfo.service.PicturesService;
 import com.YuyeTech.HeartRate.game.userDeleteLog.service.UserDeleteLogService;
 import com.YuyeTech.HeartRate.game.userDeleteLog.vo.UserDeleteLogVo;
 import com.YuyeTech.HeartRate.game.userinfo.projo.MainInfo;
+import com.YuyeTech.HeartRate.game.userinfo.projo.UserInfo;
 import com.YuyeTech.HeartRate.game.userinfo.repository.MainInfoRepository;
 import com.YuyeTech.HeartRate.game.userinfo.vo.MainInfoVo;
 import com.YuyeTech.HeartRate.game.TP_AppleInfo.service.AppleInfoService;
 import com.YuyeTech.HeartRate.game.TP_WxInfo.service.WxInfoService;
+import com.YuyeTech.HeartRate.service.FriendInfoService;
 import com.YuyeTech.HeartRate.utils.AliyunOSSUtil;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -56,6 +58,10 @@ public class MainInfoServiceImpl extends CommonServiceImpl<MainInfoVo, MainInfo,
     @Autowired
     private UserDeleteLogService userDeleteLogService;
 
+    @Autowired
+    private FriendInfoService friendInfoService;
+
+
 
     @Override
     public MainInfo findMainInfoById(String userId) {
@@ -105,7 +111,7 @@ public class MainInfoServiceImpl extends CommonServiceImpl<MainInfoVo, MainInfo,
      * @return
      */
     @Override
-    public String deleteMainInfoById(String userId) {
+    public String deleteMainInfoById(String userId,String type) {
         try {
             //记录挂起日志,
             UserDeleteLogVo userDeleteLog = userDeleteLogService.getVo(userId);
@@ -128,6 +134,14 @@ public class MainInfoServiceImpl extends CommonServiceImpl<MainInfoVo, MainInfo,
                 //正常状态下进行删除操作,先清空用户信息(包活wx登录和apple登录),然后记录一个日志
                 //此删除只是把用户关联的数据清空,暂时保留一份记录
                 userDeleteLog.setUserId(mainInfoVo.getUserId());
+
+                UserInfo userInfo = userInfoService.findUserInfoById(userId,false);
+
+                userDeleteLog.setUsername(userInfo.getUsername());
+                userInfo.setUsername("");
+                userInfo.setStatus(2);
+                userInfoService.addUserInfo(userInfo);
+
                 userDeleteLog.setTelephoneNumber(mainInfoVo.getTelephoneNumber());
                 mainInfoVo.setTelephoneNumber("");
                 userDeleteLog.setEmail(mainInfoVo.getEmail());
@@ -146,9 +160,14 @@ public class MainInfoServiceImpl extends CommonServiceImpl<MainInfoVo, MainInfo,
                     userDeleteLog.setUnionid(wxInfo.getUnionid());
                     wxInfoService.delete(wxInfo.getUserId());
                 }
+                //删除其他玩家添加的好友关系,friendID 字段相关删除即可。其他暂不做处理
+                //这里friendId 传入自己的id
+                friendInfoService.deleteFriendInfosByFriendId(userId);
+
                 userDeleteLog.setUpdateTime(DateUtil.date());
                 //记录一个log状态
                 userDeleteLog.setStatus(UserDeleteStatus.PENDING.ordinal());
+                userDeleteLog.setType(type);
                 userDeleteLogService.save(userDeleteLog);
                 super.save(mainInfoVo);
             }

+ 2 - 0
src/main/java/com/YuyeTech/HeartRate/repository/FriendInfoRepository.java

@@ -15,4 +15,6 @@ public interface FriendInfoRepository extends JpaRepository<FriendInfo,String> {
 
     void deleteByUserIdAndFriendId(String userId,String friendId);
 
+    void deleteAllByFriendId(String friendId);
+
 }

+ 2 - 0
src/main/java/com/YuyeTech/HeartRate/service/FriendInfoService.java

@@ -15,6 +15,8 @@ public interface FriendInfoService {
 
     void deleteFriendInfo(String userId,String friendId);
 
+    void deleteFriendInfosByFriendId(String friendId);
+
     void deleteById(String id);
 
 

+ 12 - 0
src/main/java/com/YuyeTech/HeartRate/service/impl/FriendInfoServiceImpl.java

@@ -8,6 +8,7 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.domain.Page;
 import org.springframework.data.domain.Pageable;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 
 @Service
 public class FriendInfoServiceImpl implements FriendInfoService {
@@ -37,6 +38,17 @@ public class FriendInfoServiceImpl implements FriendInfoService {
         friendInfoRepository.deleteByUserIdAndFriendId(userId, friendId);
     }
 
+    /**
+     * 这里传入的friendId就是用户自己的userId,用来删除别人添加自己好友的信息
+     * @param friendId
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void deleteFriendInfosByFriendId(String friendId) {
+        friendInfoRepository.deleteAllByFriendId(friendId);
+    }
+
+
     @Override
     public void deleteById(String id) {
         friendInfoRepository.deleteById(id);

+ 171 - 2
src/main/java/com/YuyeTech/HeartRate/utils/AppleUtil.java

@@ -5,11 +5,25 @@ import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.auth0.jwk.Jwk;
 import io.jsonwebtoken.*;
+import io.jsonwebtoken.impl.DefaultJwtBuilder;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.codec.binary.Base64;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.http.*;
+import org.springframework.util.LinkedMultiValueMap;
+import org.springframework.util.MultiValueMap;
 import org.springframework.web.client.RestTemplate;
 
+import java.io.*;
+import java.security.Key;
+import java.security.KeyFactory;
 import java.security.PublicKey;
+import java.security.spec.EncodedKeySpec;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.util.HashMap;
+import java.util.Map;
 
 /**
  * @author:slambb
@@ -17,17 +31,51 @@ import java.security.PublicKey;
  */
 
 @Slf4j
+@Configuration
 public class AppleUtil {
+    private static String APPLE_KEYS_URL;
+    //Revoke tokens
+    //由于苹果注册后,删除用户需要revoke tokens
+    public static String privateKeyStr;
+    private static String APPLE_REVOKE_TOKENS_URL;
+    private static String APPLE_AUTH_TOKENS_URL;
+    private static String APPLE_TEAM_ID;
+    private static String APPLE_KID;
+    private static String APPLE_BUNDLE_IDENTIFIER;
 
+    @Value("${apple.KEYS_URL}")
+    public void set_APPLE_KEYS_URL(String APPLE_KEYS_URL) {
+        AppleUtil.APPLE_KEYS_URL = APPLE_KEYS_URL;
+    }
+    @Value("${apple.REVOKE_TOKENS_URL}")
+    public void set_REVOKE_TOKENS_URL(String REVOKE_TOKENS_URL) {
+        AppleUtil.APPLE_REVOKE_TOKENS_URL = REVOKE_TOKENS_URL;
+    }
+    @Value("${apple.AUTH_TOKENS_URL}")
+    public void set_APPLE_AUTH_TOKENS_URL(String AUTH_TOKENS_URL) {
+        AppleUtil.APPLE_AUTH_TOKENS_URL = AUTH_TOKENS_URL;
+    }
+    @Value("${apple.TEAM_ID}")
+    public void set_APPLE_TEAM_ID(String TEAM_ID) {
+        AppleUtil.APPLE_TEAM_ID = TEAM_ID;
+    }
+    @Value("${apple.KID}")
+    public void set_APPLE_KID(String KID) {
+        AppleUtil.APPLE_KID = KID;
+    }
+    @Value("${apple.BUNDLE_IDENTIFIER}")
+    public void set_APPLE_BUNDLE_IDENTIFIER(String BUNDLE_IDENTIFIER) {
+        AppleUtil.APPLE_BUNDLE_IDENTIFIER = BUNDLE_IDENTIFIER;
+    }
     /**
      * 获取苹果的公钥
      * @return
      * @throws Exception
      */
     private static JSONArray getAuthKeys() throws Exception {
-        String url = "https://appleid.apple.com/auth/keys";
+//        String url = "https://appleid.apple.com/auth/keys";
         RestTemplate restTemplate = new RestTemplate();
-        JSONObject json = restTemplate.getForObject(url,JSONObject.class);
+        JSONObject json = restTemplate.getForObject(APPLE_KEYS_URL,JSONObject.class);
         JSONArray arr = json.getJSONArray("keys");
         return arr;
     }
@@ -107,4 +155,125 @@ public class AppleUtil {
         return  jsonObject;
     }
 
+
+    /**
+     * 获取p8文件中的内容
+     *
+     * @return
+     */
+    private static Key getPrivateKey() {
+        try {
+            ClassPathResource resource = new ClassPathResource("config/AuthKey_8G9994KW4L.p8");
+            InputStream inputStream = resource.getInputStream();
+            Reader reader = new InputStreamReader(inputStream, "utf-8");
+            BufferedReader br = new BufferedReader(reader);
+            String string = null;
+            StringBuffer sb = new StringBuffer();
+            while ((string = br.readLine()) != null) {
+                if (string.startsWith("---")) {
+                    continue;
+                }
+                sb.append(string);
+            }
+            br.close();
+
+            KeyFactory factory = KeyFactory.getInstance("EC");
+            EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(org.apache.commons.codec.binary.Base64.decodeBase64(sb.toString().replaceAll("\\n", "")));
+            return factory.generatePrivate(keySpec);
+        } catch (FileNotFoundException e) {
+            log.error("not find p8 file !=>{}", e.getMessage());
+            return null;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    /**
+     * 私钥加密后给苹果去验证,构造clientSecret,就是构造一个jwt字符串
+     * [获取私钥]
+     *
+     * @param iss team_id
+     * @param sub client_id
+     * @param kid access_token
+     * @return
+     */
+    public static String buildJwt(String iss, String sub, String kid) {
+        Map<String, Object> header = new HashMap<>();
+        header.put("alg", SignatureAlgorithm.ES256.getValue()); //SHA256withECDSA
+        header.put("kid", kid);
+
+        long iat = System.currentTimeMillis() / 1000; //以秒为单位
+        Map<String, Object> claims = new HashMap<>();
+        claims.put("iss", iss);// apple开发组id 问ios开发要
+        claims.put("iat", iat);
+        claims.put("exp", iat + 180 * 3600); //设置过期时间
+        claims.put("aud", "https://appleid.apple.com"); //固定值
+        claims.put("sub", sub);// Bundle Identifier
+        return new DefaultJwtBuilder().setHeader(header).setClaims(claims).signWith(SignatureAlgorithm.ES256, getPrivateKey()).compact();
+    }
+
+    /**
+     * 用户授权获取
+     *
+     * @param code
+     * @return
+     */
+    public static String getAuthToken(String code) {
+        if (code.isEmpty() ) {
+            return null;
+        }
+//        JSONObject jsonObject = null;
+        try {
+
+            privateKeyStr = buildJwt(APPLE_TEAM_ID, APPLE_BUNDLE_IDENTIFIER, APPLE_KID);
+            MultiValueMap<String, String> stringStringHashMap = new LinkedMultiValueMap<>();
+            stringStringHashMap.add("client_id", APPLE_BUNDLE_IDENTIFIER);
+            stringStringHashMap.add("client_secret", privateKeyStr);
+            stringStringHashMap.add("code", code);
+            stringStringHashMap.add("grant_type", "authorization_code");
+            HttpHeaders headers = new HttpHeaders();
+            headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
+            HttpEntity request = new HttpEntity<>(stringStringHashMap,headers);
+            RestTemplate restTemplate = new RestTemplate();
+            JSONObject jsonObject = restTemplate.postForObject(APPLE_AUTH_TOKENS_URL,request,JSONObject.class);
+            System.out.println(jsonObject);
+            return jsonObject.get("access_token").toString();
+        } catch (Exception e) {
+            System.out.println(e.getMessage());
+            throw new RuntimeException(e);
+        }
+
+    }
+
+    public static Boolean appleRevoke(String code) {
+        try {
+            String authToken = getAuthToken(code);
+            MultiValueMap<String, String> requestMap = new LinkedMultiValueMap<>();
+            requestMap.add("client_id", APPLE_BUNDLE_IDENTIFIER);
+            requestMap.add("client_secret", privateKeyStr);
+            requestMap.add("token", authToken);
+            requestMap.add("token_type_hint", "access_token");
+            HttpHeaders headers = new HttpHeaders();
+            headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
+            HttpEntity request = new HttpEntity<>(requestMap,headers);
+            RestTemplate restTemplate = new RestTemplate();
+            ResponseEntity<String> responseEntity = restTemplate.postForEntity(APPLE_REVOKE_TOKENS_URL,request,String.class);
+            int statusCode = responseEntity.getStatusCodeValue();
+            if (statusCode != 200) {
+                JSONObject jsonObject = JSON.parseObject(responseEntity.getBody());
+                String error = jsonObject.get("error").toString();
+                System.out.println("error --------- " + error);
+                if (!error.isEmpty()) {
+                    return false;
+                }
+            }
+        } catch (Exception e) {
+            log.error("revoke token error");
+            return false;
+        }
+        return true;
+    }
+
+
 }

+ 8 - 3
src/main/java/com/YuyeTech/HeartRate/utils/RedisSettingMap.java

@@ -39,7 +39,7 @@ public class RedisSettingMap {
 
     @Autowired
     private SysSettingLimitService sysSettingLimitService;
-    
+
 
     //动态设置一个RSA key保存
     private String rsaPublicKey = ":rsa:public";
@@ -179,7 +179,7 @@ public class RedisSettingMap {
      * @return
      */
     public String getSMSKey(String key){
-       return applicationName.concat(":").concat(String.format(RedisConstant.SMS_PREFIX, key));
+        return applicationName.concat(":").concat(String.format(RedisConstant.SMS_PREFIX, key));
     }
 
     /**
@@ -205,7 +205,7 @@ public class RedisSettingMap {
                 /**
                  * 获取短信key对应的值
                  */
-                 return redisTemplate.opsForValue().get(getSMSKey(key));
+                return redisTemplate.opsForValue().get(getSMSKey(key));
             case TOKEN:
                 /**
                  * 获取token的key对应userId
@@ -228,6 +228,11 @@ public class RedisSettingMap {
                  * 删除短信key的值
                  */
                 return redisTemplate.delete(getSMSKey(key));
+            case TOKEN:
+                /**
+                 * 删除token的值
+                 */
+                return redisTemplate.delete(getTokenKey(key));
             default: return null;
         }
     }

+ 8 - 0
src/main/resources/application.yml

@@ -123,3 +123,11 @@ RSA:
     privateKey: "MIIBVQIBADANBgkqhkiG9w0BAQEFAASCAT8wggE7AgEAAkEAjAwN8bgZS_ULhLAwvA5Gz_-l1f7xnt-2mufodT4bCNXsCF4eHDBWr7mQJu7_Ou4llIdj6AulJs0Iu6U1TqwlgQIDAQABAkAf3IY3ngizTTano2YTArR9kc3q16uk14S1zVkHg2-nHJ29ssveNeb8bPg012WhtNltIbr2MsL4_X-Rg7tmM8ihAiEAzSTAIl8SlmHXUnmsvXImq2nVDrIYuNutcpPtZq313d0CIQCuxAQDWEPzSuWhMg5T5YNUFbIFrpZ-5HmUl60lcFeF9QIhAKfjUscObcTbEAB0idWFTXZtp6teP_NR_bJOtDSbXCOVAiEApP1ayImYxOQNe6vVCPFhlY1R3rlfTPaHrXewN-siRc0CIH06t7CE3KQQKv1p1UdEJjPm685ES8IRuFdJEiGJZiex"
 
 cache: '{"user":60,"dept":30}'  #自定义某些缓存空间的过期时间
+
+apple:
+  KID: 8G9994KW4L
+  TEAM_ID: CT63XZVXP2
+  BUNDLE_IDENTIFIER: com.YuyeTech.HeartRate
+  REVOKE_TOKENS_URL: https://appleid.apple.com/auth/revoke
+  AUTH_TOKENS_URL: https://appleid.apple.com/auth/token
+  KEYS_URL: https://appleid.apple.com/auth/keys

+ 6 - 0
src/main/resources/config/AuthKey_8G9994KW4L.p8

@@ -0,0 +1,6 @@
+-----BEGIN PRIVATE KEY-----
+MIGTAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBHkwdwIBAQQgmXLh35Im/y8hL2k+
+nFMifKkzrJEosEe2/nK6Y89bPS+gCgYIKoZIzj0DAQehRANCAASVGIXHEqqkeum3
+YTFXYjqRlicL9CrGQYS/o2fr17C9CeTy5t+iZ+1g3WeSOTTNfOBU/z/PL4yncwpg
+Ti/u96i3
+-----END PRIVATE KEY-----