From 37d6de2b33880931057d2091a42507c3f37a5b9c Mon Sep 17 00:00:00 2001 From: chengkun <2500338766@qq.com> Date: Fri, 22 Apr 2022 20:19:11 +0800 Subject: [PATCH] =?UTF-8?q?feature1.0.0:img=E6=9C=8D=E5=8A=A1=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E5=AE=8C=E6=88=90=E5=B0=8F=E7=A8=8B=E5=BA=8F=E7=99=BB?= =?UTF-8?q?=E5=BD=95;=E5=9B=BE=E7=89=87=E5=8E=8B=E7=BC=A9=E4=B8=8A?= =?UTF-8?q?=E4=BC=A0;?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bnyer-common/bnyer-common-core/pom.xml | 9 +- .../common/core/annotation/TokenCheck.java | 18 ++ .../com/bnyer/common/core/utils/Sm4Util.java | 57 +++++ bnyer-services/bnyer-file/pom.xml | 6 + .../file/controller/SysFileController.java | 38 +++- .../com/bnyer/file/service/MinioService.java | 29 +++ .../file/service/MinioSysFileServiceImpl.java | 29 ++- .../java/com/bnyer/file/utils/ImgUtil.java | 131 +++++++++++ .../com/bnyer/img/config/TiktokConfig.java | 21 +- .../bnyer/img/constants/RedisKeyConstant.java | 5 + .../img/controller/TiktokMiniController.java | 36 ++- .../img/controller/TiktokUserController.java | 31 ++- .../com/bnyer/img/dto/TiktokBindPhoneDto.java | 31 +++ .../com/bnyer/img/dto/TiktokCreaterDto.java | 37 +++ .../com/bnyer/img/dto/TiktokLoginDto.java | 27 +++ .../bnyer/img/handler/TokenCheckHandler.java | 54 +++++ .../bnyer/img/service/TiktokUserService.java | 26 ++- .../service/impl/TiktokUserServiceImpl.java | 214 +++++++++++++++++- .../com/bnyer/img/vo/TiktokUserInfoVo.java | 36 +++ .../bnyer/img/vo/TiktokUserPhoneInfoVo.java | 24 ++ pom.xml | 7 + 21 files changed, 826 insertions(+), 40 deletions(-) create mode 100644 bnyer-common/bnyer-common-core/src/main/java/com/bnyer/common/core/annotation/TokenCheck.java create mode 100644 bnyer-common/bnyer-common-core/src/main/java/com/bnyer/common/core/utils/Sm4Util.java create mode 100644 bnyer-services/bnyer-file/src/main/java/com/bnyer/file/service/MinioService.java create mode 100644 bnyer-services/bnyer-file/src/main/java/com/bnyer/file/utils/ImgUtil.java create mode 100644 bnyer-services/bnyer-img/src/main/java/com/bnyer/img/dto/TiktokBindPhoneDto.java create mode 100644 bnyer-services/bnyer-img/src/main/java/com/bnyer/img/dto/TiktokCreaterDto.java create mode 100644 bnyer-services/bnyer-img/src/main/java/com/bnyer/img/dto/TiktokLoginDto.java create mode 100644 bnyer-services/bnyer-img/src/main/java/com/bnyer/img/handler/TokenCheckHandler.java create mode 100644 bnyer-services/bnyer-img/src/main/java/com/bnyer/img/vo/TiktokUserInfoVo.java create mode 100644 bnyer-services/bnyer-img/src/main/java/com/bnyer/img/vo/TiktokUserPhoneInfoVo.java diff --git a/bnyer-common/bnyer-common-core/pom.xml b/bnyer-common/bnyer-common-core/pom.xml index 2646dd5..7b77ecf 100644 --- a/bnyer-common/bnyer-common-core/pom.xml +++ b/bnyer-common/bnyer-common-core/pom.xml @@ -10,7 +10,7 @@ 4.0.0 bnyer-common-core - + bnyer-common-core核心模块 @@ -22,7 +22,7 @@ org.springframework.cloud spring-cloud-starter-openfeign - + org.springframework.cloud @@ -124,6 +124,11 @@ lombok + + cn.hutool + hutool-all + + diff --git a/bnyer-common/bnyer-common-core/src/main/java/com/bnyer/common/core/annotation/TokenCheck.java b/bnyer-common/bnyer-common-core/src/main/java/com/bnyer/common/core/annotation/TokenCheck.java new file mode 100644 index 0000000..288396d --- /dev/null +++ b/bnyer-common/bnyer-common-core/src/main/java/com/bnyer/common/core/annotation/TokenCheck.java @@ -0,0 +1,18 @@ +package com.bnyer.common.core.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 小程序用户token检测注解 + * + * @author chengkun + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface TokenCheck +{ + +} \ No newline at end of file diff --git a/bnyer-common/bnyer-common-core/src/main/java/com/bnyer/common/core/utils/Sm4Util.java b/bnyer-common/bnyer-common-core/src/main/java/com/bnyer/common/core/utils/Sm4Util.java new file mode 100644 index 0000000..986e3c5 --- /dev/null +++ b/bnyer-common/bnyer-common-core/src/main/java/com/bnyer/common/core/utils/Sm4Util.java @@ -0,0 +1,57 @@ +package com.bnyer.common.core.utils; + +import cn.hutool.crypto.symmetric.SymmetricCrypto; +import org.bouncycastle.jce.provider.BouncyCastleProvider; + +import javax.crypto.KeyGenerator; +import java.security.SecureRandom; +import java.util.Base64; + +/** + * @author kevin + * @date 2020/10/22 17:19 + */ +public class Sm4Util { + private static byte[] sm4Key; + + public static void utilInit(String key) { + sm4Key = Base64.getDecoder().decode(key); + } + + /** + * SM4加密 + * + * @param src + * @return + */ + public static String sm4Encryption(String src) { + //账户加密 + SymmetricCrypto sm4 = new SymmetricCrypto("SM4/ECB/PKCS5Padding", sm4Key); + byte[] bytes = sm4.encrypt(src); + return Base64.getEncoder().encodeToString(bytes); + } + + /** + * SM4加密 + * + * @param src + * @return + */ + public static String sm4Decrypt(String src) { + //账户加密 + SymmetricCrypto sm4 = new SymmetricCrypto("SM4/ECB/PKCS5Padding", sm4Key); + byte[] bytes = sm4.decrypt(src); + return new String(bytes); + } + /** + * @explain + * @param keySize + * @return + * @throws Exception + */ + public static byte[] generateKey(int keySize) throws Exception { + KeyGenerator kg = KeyGenerator.getInstance("SM4", BouncyCastleProvider.PROVIDER_NAME); + kg.init(keySize, new SecureRandom()); + return kg.generateKey().getEncoded(); + } +} diff --git a/bnyer-services/bnyer-file/pom.xml b/bnyer-services/bnyer-file/pom.xml index 657ad41..236049c 100644 --- a/bnyer-services/bnyer-file/pom.xml +++ b/bnyer-services/bnyer-file/pom.xml @@ -65,6 +65,12 @@ com.dimensionalnode bnyer-common-swagger + + + net.coobird + thumbnailator + 0.4.8 + diff --git a/bnyer-services/bnyer-file/src/main/java/com/bnyer/file/controller/SysFileController.java b/bnyer-services/bnyer-file/src/main/java/com/bnyer/file/controller/SysFileController.java index f34bc24..6f2775e 100644 --- a/bnyer-services/bnyer-file/src/main/java/com/bnyer/file/controller/SysFileController.java +++ b/bnyer-services/bnyer-file/src/main/java/com/bnyer/file/controller/SysFileController.java @@ -1,15 +1,19 @@ package com.bnyer.file.controller; +import com.bnyer.common.core.domain.R; +import com.bnyer.common.core.utils.file.FileUtils; +import com.bnyer.file.service.ISysFileService; +import com.bnyer.file.service.MinioService; +import com.bnyer.system.api.domain.SysFile; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; -import com.bnyer.common.core.domain.R; -import com.bnyer.common.core.utils.file.FileUtils; -import com.bnyer.file.service.ISysFileService; -import com.bnyer.system.api.domain.SysFile; + +import java.util.ArrayList; +import java.util.List; /** * 文件请求处理 @@ -24,6 +28,9 @@ public class SysFileController @Autowired private ISysFileService sysFileService; + @Autowired + private MinioService minioService; + /** * 文件上传请求 */ @@ -45,4 +52,27 @@ public class SysFileController return R.fail(e.getMessage()); } } + + /** + * 批量压缩上传图片 + */ + @PostMapping("uploadBatch") + public R> uploadBatch(MultipartFile[] files) + { + try + { + List list = new ArrayList<>(); + for (MultipartFile file : files) { + String url = minioService.uploadFileByThumb(file); + list.add(url); + } + // 上传并返回访问地址 + return R.ok(list); + } + catch (Exception e) + { + log.error("上传文件失败", e); + return R.fail(e.getMessage()); + } + } } \ No newline at end of file diff --git a/bnyer-services/bnyer-file/src/main/java/com/bnyer/file/service/MinioService.java b/bnyer-services/bnyer-file/src/main/java/com/bnyer/file/service/MinioService.java new file mode 100644 index 0000000..17fea5b --- /dev/null +++ b/bnyer-services/bnyer-file/src/main/java/com/bnyer/file/service/MinioService.java @@ -0,0 +1,29 @@ +package com.bnyer.file.service; + +import org.springframework.web.multipart.MultipartFile; + +import java.io.InputStream; + +/** + * @author chengkun + * @date 2022/4/22 19:33 + */ +public interface MinioService { + + /** + * 文件上传接口 + * + * @param file 上传的文件 + * @return 访问地址 + * @throws Exception + */ + public String uploadFile(MultipartFile file) throws Exception; + + /** + * 压缩图片上传 + * @param file 文件 + * @return - + * @throws Exception + */ + String uploadFileByThumb(MultipartFile file) throws Exception; +} diff --git a/bnyer-services/bnyer-file/src/main/java/com/bnyer/file/service/MinioSysFileServiceImpl.java b/bnyer-services/bnyer-file/src/main/java/com/bnyer/file/service/MinioSysFileServiceImpl.java index e79959e..2379b47 100644 --- a/bnyer-services/bnyer-file/src/main/java/com/bnyer/file/service/MinioSysFileServiceImpl.java +++ b/bnyer-services/bnyer-file/src/main/java/com/bnyer/file/service/MinioSysFileServiceImpl.java @@ -1,6 +1,9 @@ package com.bnyer.file.service; +import com.bnyer.common.core.exception.ServiceException; import com.bnyer.file.config.MinioConfig; +import com.bnyer.file.utils.ImgUtil; +import net.coobird.thumbnailator.Thumbnails; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; @@ -8,13 +11,16 @@ import com.bnyer.file.utils.FileUploadUtils; import io.minio.MinioClient; import io.minio.PutObjectArgs; +import java.awt.image.BufferedImage; +import java.io.InputStream; + /** * Minio 文件存储 * * @author ruoyi */ @Service -public class MinioSysFileServiceImpl implements ISysFileService +public class MinioSysFileServiceImpl implements MinioService { @Autowired private MinioConfig minioConfig; @@ -42,4 +48,25 @@ public class MinioSysFileServiceImpl implements ISysFileService client.putObject(args); return minioConfig.getUrl() + "/" + minioConfig.getBucketName() + "/" + fileName; } + + @Override + public String uploadFileByThumb(MultipartFile file) throws Exception { + boolean b = ImgUtil.isPicture(file.getName()); + if(!b){ + throw new ServiceException("文件类型不是图片类型,上传失败!"); + } + BufferedImage image = ImgUtil.toBufferedImage(file); + BufferedImage bufferedImage = Thumbnails.of(image).size(700, 467).asBufferedImage(); + InputStream inputStream = ImgUtil.bufferedImageToInputStream(bufferedImage); + String fileName = FileUploadUtils.extractFilename(file); + MultipartFile multipartFile = ImgUtil.getMultipartFile(inputStream, fileName); + PutObjectArgs args = PutObjectArgs.builder() + .bucket(minioConfig.getBucketName()) + .object(multipartFile.getName()) + .stream(multipartFile.getInputStream(), multipartFile.getSize(), -1) + .contentType(multipartFile.getContentType()) + .build(); + client.putObject(args); + return minioConfig.getUrl() + "/" + minioConfig.getBucketName() + "/" + multipartFile.getName(); + } } diff --git a/bnyer-services/bnyer-file/src/main/java/com/bnyer/file/utils/ImgUtil.java b/bnyer-services/bnyer-file/src/main/java/com/bnyer/file/utils/ImgUtil.java new file mode 100644 index 0000000..6dfb9ed --- /dev/null +++ b/bnyer-services/bnyer-file/src/main/java/com/bnyer/file/utils/ImgUtil.java @@ -0,0 +1,131 @@ +package com.bnyer.file.utils; + +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.fileupload.FileItem; +import org.apache.commons.fileupload.FileItemFactory; +import org.apache.commons.fileupload.disk.DiskFileItemFactory; +import org.apache.commons.lang3.StringUtils; +import org.springframework.http.MediaType; +import org.springframework.web.multipart.MultipartFile; +import org.springframework.web.multipart.commons.CommonsMultipartFile; + +import javax.imageio.ImageIO; +import java.awt.image.BufferedImage; +import java.io.*; + +/** + * 图片处理工具类 + * @author chengkun + * @date 2022/4/22 18:05 + */ +@Slf4j +public class ImgUtil { + + /** + * 将MultipartFile类转为BufferedImage对象 + * @param file 文件 + * @return - + */ + public static BufferedImage toBufferedImage(MultipartFile file) { + BufferedImage srcImage = null; + try { + FileInputStream in = (FileInputStream) file.getInputStream(); + srcImage = javax.imageio.ImageIO.read(in); + } catch (IOException e) { + + } + return srcImage; + } + + /** + * 将BufferedImage转为InputStream + * @param image 图片 + * @return - + */ + public static InputStream bufferedImageToInputStream(BufferedImage image){ + ByteArrayOutputStream os = new ByteArrayOutputStream(); + try { + ImageIO.write(image, "jpg", os); + InputStream input = new ByteArrayInputStream(os.toByteArray()); + return input; + } catch (IOException e) { + log.error("提示:",e); + } + return null; + } + + /** + * 获取封装得MultipartFile + * + * @param inputStream inputStream + * @param fileName fileName + * @return MultipartFile + */ + public static MultipartFile getMultipartFile(InputStream inputStream, String fileName) { + FileItem fileItem = createFileItem(inputStream, fileName); + return new CommonsMultipartFile(fileItem); + } + + /** + * FileItem类对象创建 + * + * @param inputStream inputStream + * @param fileName fileName + * @return FileItem + */ + public static FileItem createFileItem(InputStream inputStream, String fileName) { + FileItemFactory factory = new DiskFileItemFactory(16, null); + String textFieldName = "file"; + FileItem item = factory.createItem(textFieldName, MediaType.MULTIPART_FORM_DATA_VALUE, true, fileName); + int bytesRead = 0; + byte[] buffer = new byte[8192]; + OutputStream os = null; + //使用输出流输出输入流的字节 + try { + os = item.getOutputStream(); + while ((bytesRead = inputStream.read(buffer, 0, 8192)) != -1) { + os.write(buffer, 0, bytesRead); + } + inputStream.close(); + } catch (IOException e) { + log.error("Stream copy exception", e); + throw new IllegalArgumentException("文件上传失败"); + } finally { + if (os != null) { + try { + os.close(); + } catch (IOException e) { + log.error("Stream close exception", e); + + } + } + if (inputStream != null) { + try { + inputStream.close(); + } catch (IOException e) { + log.error("Stream close exception", e); + } + } + } + + return item; + } + + /** + * 判断文件是否为图片 + */ + public static boolean isPicture(String imgName) { + boolean flag = false; + if (StringUtils.isBlank(imgName)) { + return false; + } + String[] arr = {"bmp", "dib", "gif", "jfif", "jpe", "jpeg", "jpg", "png", "tif", "tiff", "ico"}; + for (String item : arr) { + if (item.equals(imgName)) { + flag = true; + break; + } + } + return flag; + } +} diff --git a/bnyer-services/bnyer-img/src/main/java/com/bnyer/img/config/TiktokConfig.java b/bnyer-services/bnyer-img/src/main/java/com/bnyer/img/config/TiktokConfig.java index 5ac8bdd..be3768d 100644 --- a/bnyer-services/bnyer-img/src/main/java/com/bnyer/img/config/TiktokConfig.java +++ b/bnyer-services/bnyer-img/src/main/java/com/bnyer/img/config/TiktokConfig.java @@ -1,9 +1,14 @@ package com.bnyer.img.config; +import com.bnyer.img.handler.TokenCheckHandler; import lombok.Getter; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +import javax.annotation.Resource; /** * @author chengkun @@ -12,7 +17,7 @@ import org.springframework.context.annotation.Configuration; @Configuration @ConfigurationProperties(prefix = "bnyer.img.tiktok") @Getter -public class TiktokConfig { +public class TiktokConfig implements WebMvcConfigurer { @Value("${bnyer.img.tiktok.appId}") private String appId; @@ -26,9 +31,19 @@ public class TiktokConfig { @Value("${bnyer.img.tiktok.tokenUrl}") public String tokenUrl; + @Resource + private TokenCheckHandler tokenCheckHandler; + /** 不需要拦截地址 */ + public static final String[] excludeUrls = { "/mini/tiktok/login", "/mini/tiktok/insertFeedback"}; + @Override + public void addInterceptors(InterceptorRegistry registry) { + // 注册Token拦截器 + registry.addInterceptor(tokenCheckHandler) + .addPathPatterns("/**") + .excludePathPatterns(excludeUrls) + .order(-10); - - + } } diff --git a/bnyer-services/bnyer-img/src/main/java/com/bnyer/img/constants/RedisKeyConstant.java b/bnyer-services/bnyer-img/src/main/java/com/bnyer/img/constants/RedisKeyConstant.java index 8ad29b8..676764b 100644 --- a/bnyer-services/bnyer-img/src/main/java/com/bnyer/img/constants/RedisKeyConstant.java +++ b/bnyer-services/bnyer-img/src/main/java/com/bnyer/img/constants/RedisKeyConstant.java @@ -26,4 +26,9 @@ public class RedisKeyConstant { * 抖音小程序图片点赞数量键 */ public static final String TIKTOK_IMG_LIKE_NUM_KEY = "bnyer.tiktok.likeNum"; + + /** + * 抖音小程序用户登录键 + */ + public static final String TIKTOK_USER_LOGIN_KEY = "bnyer.titok.user:"; } diff --git a/bnyer-services/bnyer-img/src/main/java/com/bnyer/img/controller/TiktokMiniController.java b/bnyer-services/bnyer-img/src/main/java/com/bnyer/img/controller/TiktokMiniController.java index a12decc..c4abac2 100644 --- a/bnyer-services/bnyer-img/src/main/java/com/bnyer/img/controller/TiktokMiniController.java +++ b/bnyer-services/bnyer-img/src/main/java/com/bnyer/img/controller/TiktokMiniController.java @@ -1,6 +1,7 @@ package com.bnyer.img.controller; import com.alibaba.fastjson.JSON; +import com.bnyer.common.core.annotation.TokenCheck; import com.bnyer.common.core.web.controller.BaseController; import com.bnyer.common.core.web.domain.AjaxResult; import com.bnyer.img.domain.Feedback; @@ -20,7 +21,7 @@ import java.util.List; @Api("img-抖音平台-【小程序】接口") @RestController -@RequestMapping("/tiktok") +@RequestMapping("/mini/tiktok") @Slf4j public class TiktokMiniController extends BaseController { @@ -45,6 +46,7 @@ public class TiktokMiniController extends BaseController { @Autowired private TiktokLikeService tiktokLikeService; + @TokenCheck @ApiOperation(value="查询banner列表") @GetMapping(value = "/listBanner") public AjaxResult listBanner(){ @@ -60,12 +62,14 @@ public class TiktokMiniController extends BaseController { return AjaxResult.success(feedBackService.insert(feedback)); } + @TokenCheck @ApiOperation(value="查询type列表") @GetMapping(value = "/listType") public AjaxResult listType(){ return AjaxResult.success(typeService.queryList()); } + @TokenCheck @ApiOperation(value="新增TiktokImg") @PostMapping(value = "/insertTiktokImg") public AjaxResult insertTiktokImg(@Validated @RequestBody @ApiParam("TiktokImg对象") TiktokImgMiniDto dto){ @@ -75,6 +79,7 @@ public class TiktokMiniController extends BaseController { return AjaxResult.success(tiktokImgService.insert(tiktokImg)); } + @TokenCheck @ApiOperation(value="修改TiktokImg") @PostMapping(value = "/updateTiktokImg") public AjaxResult updateTiktokImg(@Validated @RequestBody @ApiParam("TiktokImg对象") TiktokImgMiniDto dto){ @@ -84,6 +89,7 @@ public class TiktokMiniController extends BaseController { return AjaxResult.success(tiktokImgService.update(dto.extractParam())); } + @TokenCheck @ApiOperation(value="删除TiktokImg") @DeleteMapping(value = "/deleteTiktokImg/{ids}") public AjaxResult deleteTiktokImg(@PathVariable @ApiParam("主键ids") List ids){ @@ -91,30 +97,35 @@ public class TiktokMiniController extends BaseController { return AjaxResult.success(tiktokImgService.delete(ids)); } + @TokenCheck @ApiOperation(value="查询指定用户对内的图片集合") @PostMapping(value = "/listTiktokImgIn") public AjaxResult listTiktokImgIn(@Validated @RequestBody @ApiParam("TiktokImg对象") TiktokImgListMiniDto dto){ return AjaxResult.success(tiktokImgService.queryInList(dto.getUserId(),dto.getTypeId())); } + @TokenCheck @ApiOperation(value="查询指定用户对外的图片集合") @PostMapping(value = "/listTiktokImgOut") public AjaxResult listTiktokImgOut(@Validated @RequestBody @ApiParam("TiktokImg对象") TiktokImgListMiniDto dto){ return AjaxResult.success(tiktokImgService.queryOutList(dto.getUserId(),dto.getTypeId())); } + @TokenCheck @ApiOperation(value="查询小程序审核通过图片详情") @GetMapping(value = "/detailsTiktokImg/{id}") public AjaxResult detailsTiktokImg(@ApiParam("图片id") @PathVariable Long id){ return AjaxResult.success(tiktokImgService.queryImgDetails(String.valueOf(id))); } + @TokenCheck @ApiOperation(value="查询小程序用户图片列表") @GetMapping(value = "/tiktokUserImgs") public AjaxResult tiktokUserImgs(){ return AjaxResult.success(tiktokUserService.queryUserImgList()); } + @TokenCheck @ApiOperation(value="收藏") @PostMapping(value = "/tiktokCollect") public AjaxResult tiktokCollect(@Validated @RequestBody @ApiParam("收藏对象") CollectionDto dto){ @@ -123,6 +134,7 @@ public class TiktokMiniController extends BaseController { return AjaxResult.success(); } + @TokenCheck @ApiOperation(value="取消收藏") @PostMapping(value = "/tiktokUnCollect") public AjaxResult tiktokUnCollect(@Validated @RequestBody @ApiParam("收藏对象") CollectionDto dto){ @@ -131,6 +143,7 @@ public class TiktokMiniController extends BaseController { return AjaxResult.success(); } + @TokenCheck @ApiOperation(value="查询是否收藏过") @PostMapping(value = "/judgeTiktokCollect") public AjaxResult judgeTiktokCollect(@Validated @RequestBody @ApiParam("收藏对象") CollectionDto dto){ @@ -138,6 +151,7 @@ public class TiktokMiniController extends BaseController { return AjaxResult.success(tiktokCollectionService.judgeCollect(dto.getUserId(),dto.getImgId())); } + @TokenCheck @ApiOperation(value="查看用户收藏列表") @PostMapping(value = "/listTiktokCollection") public AjaxResult listTiktokCollection(@Validated @RequestBody @ApiParam("用户收藏对象") CollectionUserDto dto){ @@ -145,6 +159,7 @@ public class TiktokMiniController extends BaseController { return AjaxResult.success(tiktokCollectionService.getCollectionByUserId(dto.getUserId())); } + @TokenCheck @ApiOperation(value="点赞") @PostMapping(value = "/tiktokLike") public AjaxResult tiktokLike(@Validated @RequestBody @ApiParam("点赞对象") CollectionDto dto){ @@ -153,6 +168,7 @@ public class TiktokMiniController extends BaseController { return AjaxResult.success(); } + @TokenCheck @ApiOperation(value="取消点赞") @PostMapping(value = "/tiktokUnLike") public AjaxResult tiktokUnLike(@Validated @RequestBody @ApiParam("点赞对象") CollectionDto dto){ @@ -161,10 +177,28 @@ public class TiktokMiniController extends BaseController { return AjaxResult.success(); } + @TokenCheck @ApiOperation(value="查询是否点赞过") @PostMapping(value = "/judgeTiktokLike") public AjaxResult judgeTiktokLike(@Validated @RequestBody @ApiParam("点赞对象") CollectionDto dto){ log.debug("查询是否点赞过参数为:{}", JSON.toJSONString(dto)); return AjaxResult.success(tiktokLikeService.judgeLike(dto.getUserId(),dto.getImgId())); } + + + @ApiOperation(value="用户登录") + @PostMapping(value = "/login") + public AjaxResult login(@Validated @RequestBody @ApiParam("登录对象") TiktokLoginDto dto){ + log.debug("用户登录参数为:{}", JSON.toJSONString(dto)); + return AjaxResult.success(tiktokUserService.login(dto)); + } + + @TokenCheck + @ApiOperation(value="绑定手机号") + @PostMapping(value = "/bindPhone") + public AjaxResult bindPhone(@Validated @RequestBody @ApiParam("绑定对象") TiktokBindPhoneDto dto){ + log.debug("绑定手机号参数为:{}", JSON.toJSONString(dto)); + tiktokUserService.bindPhone(dto); + return AjaxResult.success(); + } } diff --git a/bnyer-services/bnyer-img/src/main/java/com/bnyer/img/controller/TiktokUserController.java b/bnyer-services/bnyer-img/src/main/java/com/bnyer/img/controller/TiktokUserController.java index a8d8295..8e48c60 100644 --- a/bnyer-services/bnyer-img/src/main/java/com/bnyer/img/controller/TiktokUserController.java +++ b/bnyer-services/bnyer-img/src/main/java/com/bnyer/img/controller/TiktokUserController.java @@ -1,10 +1,12 @@ package com.bnyer.img.controller; import com.alibaba.fastjson.JSON; +import com.bnyer.common.core.utils.Sm4Util; import com.bnyer.common.core.web.controller.BaseController; import com.bnyer.common.core.web.domain.AjaxResult; import com.bnyer.common.core.web.page.TableDataInfo; import com.bnyer.img.domain.TiktokUser; +import com.bnyer.img.dto.TiktokCreaterDto; import com.bnyer.img.dto.TiktokUserDto; import com.bnyer.img.dto.TiktokUserPageDto; import com.bnyer.img.service.TiktokUserService; @@ -33,24 +35,28 @@ public class TiktokUserController extends BaseController { public TableDataInfo list(TiktokUserPageDto dto){ startPage(); List tiktokUsers = tiktokUserService.queryPage(dto); + for (TiktokUser tiktokUser : tiktokUsers) { + tiktokUser.setPhone(Sm4Util.sm4Decrypt(tiktokUser.getPhone())); + tiktokUser.setTiktokCode(Sm4Util.sm4Decrypt(tiktokUser.getTiktokCode())); + } return getDataTable(tiktokUsers); } //@RequiresPermissions("system:config:list") - @ApiOperation(value="新增user") + @ApiOperation(value="成为艺术家") @PostMapping(value = "/insert") - public AjaxResult insert(@Validated @RequestBody @ApiParam("user对象") TiktokUserDto dto){ - log.debug("新增user参数为:{}", JSON.toJSONString(dto)); - return AjaxResult.success(tiktokUserService.insert(dto.extractParam())); + public AjaxResult insert(@Validated @RequestBody @ApiParam("user对象") TiktokCreaterDto dto){ + log.debug("成为艺术家参数为:{}", JSON.toJSONString(dto)); + return AjaxResult.success(tiktokUserService.insertCreator(dto)); } //@RequiresPermissions("system:config:list") - @ApiOperation(value="修改user") - @PostMapping(value = "/update") - public AjaxResult update(@Validated @RequestBody @ApiParam("user对象") TiktokUserDto dto){ - log.debug("修改user参数为:{}", JSON.toJSONString(dto)); - return AjaxResult.success(tiktokUserService.update(dto.extractParam())); - } +// @ApiOperation(value="修改user") +// @PostMapping(value = "/update") +// public AjaxResult update(@Validated @RequestBody @ApiParam("user对象") TiktokUserDto dto){ +// log.debug("修改user参数为:{}", JSON.toJSONString(dto)); +// return AjaxResult.success(tiktokUserService.update(dto.extractParam())); +// } //@RequiresPermissions("system:config:list") @ApiOperation(value="删除user") @@ -64,6 +70,9 @@ public class TiktokUserController extends BaseController { @ApiOperation(value="查询user详情") @GetMapping(value = "/details/{id}") public AjaxResult details(@PathVariable @ApiParam("主键id") Long id){ - return AjaxResult.success(tiktokUserService.queryDetails(id)); + TiktokUser tiktokUser = tiktokUserService.queryDetails(id); + tiktokUser.setPhone(Sm4Util.sm4Decrypt(tiktokUser.getPhone())); + tiktokUser.setTiktokCode(Sm4Util.sm4Decrypt(tiktokUser.getTiktokCode())); + return AjaxResult.success(tiktokUser); } } diff --git a/bnyer-services/bnyer-img/src/main/java/com/bnyer/img/dto/TiktokBindPhoneDto.java b/bnyer-services/bnyer-img/src/main/java/com/bnyer/img/dto/TiktokBindPhoneDto.java new file mode 100644 index 0000000..0b0e9ac --- /dev/null +++ b/bnyer-services/bnyer-img/src/main/java/com/bnyer/img/dto/TiktokBindPhoneDto.java @@ -0,0 +1,31 @@ +package com.bnyer.img.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Getter; +import lombok.Setter; + +import javax.validation.constraints.NotNull; +import java.io.Serializable; + +@Getter +@Setter +@ApiModel("抖音登录入参") +public class TiktokBindPhoneDto implements Serializable { + + @NotNull(message = "用户Id不能为空!") + @ApiModelProperty(value = "用户Id") + private Long userId; + + @NotNull(message = "加密数据不能为空!") + @ApiModelProperty(value = "加密数据") + private String encryptedData; + + @NotNull(message = "sessionKey不能为空!") + @ApiModelProperty(value = "sessionKey") + private String sessionKey; + + @NotNull(message = "加密算法向量不能为空!") + @ApiModelProperty(value = "加密算法向量") + private String iv; +} diff --git a/bnyer-services/bnyer-img/src/main/java/com/bnyer/img/dto/TiktokCreaterDto.java b/bnyer-services/bnyer-img/src/main/java/com/bnyer/img/dto/TiktokCreaterDto.java new file mode 100644 index 0000000..7cd22c0 --- /dev/null +++ b/bnyer-services/bnyer-img/src/main/java/com/bnyer/img/dto/TiktokCreaterDto.java @@ -0,0 +1,37 @@ +package com.bnyer.img.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Getter; +import lombok.Setter; + +import javax.validation.constraints.NotNull; +import java.io.Serializable; + +/** + * @author chengkun + * @date 2022/4/22 16:06 + */ +@Getter +@Setter +@ApiModel("抖音艺术家接收类") +public class TiktokCreaterDto implements Serializable { + + @NotNull(message = "抖音号不能为空") + @ApiModelProperty(value="抖音号") + private String tiktokNum; + + @NotNull(message = "搜索码不能为空") + @ApiModelProperty(value="搜索码") + private String scanCode; + + @ApiModelProperty(value="邀请码") + private String inviteCode; + + @NotNull(message = "手机号不能为空!") + @ApiModelProperty(value="手机号") + private String phone; + + @ApiModelProperty(value="简介") + private String intro; +} diff --git a/bnyer-services/bnyer-img/src/main/java/com/bnyer/img/dto/TiktokLoginDto.java b/bnyer-services/bnyer-img/src/main/java/com/bnyer/img/dto/TiktokLoginDto.java new file mode 100644 index 0000000..4a6f681 --- /dev/null +++ b/bnyer-services/bnyer-img/src/main/java/com/bnyer/img/dto/TiktokLoginDto.java @@ -0,0 +1,27 @@ +package com.bnyer.img.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Getter; +import lombok.Setter; + +import javax.validation.constraints.NotNull; +import java.io.Serializable; + +@Getter +@Setter +@ApiModel("抖音登录入参") +public class TiktokLoginDto implements Serializable { + + @NotNull(message = "code不能为空!") + @ApiModelProperty(value = "微信code") + private String code; + + @NotNull(message = "加密数据不能为空!") + @ApiModelProperty(value = "加密数据") + private String encryptedData; + + @NotNull(message = "加密算法向量不能为空!") + @ApiModelProperty(value = "加密算法向量") + private String iv; +} diff --git a/bnyer-services/bnyer-img/src/main/java/com/bnyer/img/handler/TokenCheckHandler.java b/bnyer-services/bnyer-img/src/main/java/com/bnyer/img/handler/TokenCheckHandler.java new file mode 100644 index 0000000..1c0ba66 --- /dev/null +++ b/bnyer-services/bnyer-img/src/main/java/com/bnyer/img/handler/TokenCheckHandler.java @@ -0,0 +1,54 @@ +package com.bnyer.img.handler; + +import com.bnyer.common.core.annotation.TokenCheck; +import com.bnyer.common.core.exception.ServiceException; +import com.bnyer.common.redis.service.RedisService; +import com.bnyer.img.constants.RedisKeyConstant; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.web.method.HandlerMethod; +import org.springframework.web.servlet.HandlerInterceptor; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * @author chengkun + * @date 2022/4/22 15:04 + */ +@Component +public class TokenCheckHandler implements HandlerInterceptor { + + String tokenKey = RedisKeyConstant.TIKTOK_USER_LOGIN_KEY; + + @Autowired + private RedisService redisService; + + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { + + // 判断访问的方法上是否有注解 + HandlerMethod handlerMethod = (HandlerMethod) handler; + boolean tokenCheck = handlerMethod.hasMethodAnnotation(TokenCheck.class); + + // 尝试从请求头从获取token值 + String token = request.getHeader("token"); + if(StringUtils.isEmpty(token)){ + if(tokenCheck){ + throw new ServiceException("token为空,无权访问!"); + } + } + String[] split = token.split("#"); + //从token中获取openId + String openId = split[1]; + //组装redisKey + String redisKey = tokenKey+openId; + //判断redis中是否存在该key,存在则放行,不存在则过期 + if(redisService.hasKey(redisKey)){ + return true; + }else{ + throw new ServiceException("token失效,请重新授权!"); + } + } +} diff --git a/bnyer-services/bnyer-img/src/main/java/com/bnyer/img/service/TiktokUserService.java b/bnyer-services/bnyer-img/src/main/java/com/bnyer/img/service/TiktokUserService.java index 89e79bd..cb29aef 100644 --- a/bnyer-services/bnyer-img/src/main/java/com/bnyer/img/service/TiktokUserService.java +++ b/bnyer-services/bnyer-img/src/main/java/com/bnyer/img/service/TiktokUserService.java @@ -1,27 +1,32 @@ package com.bnyer.img.service; import com.bnyer.img.domain.TiktokUser; +import com.bnyer.img.dto.TiktokBindPhoneDto; +import com.bnyer.img.dto.TiktokCreaterDto; +import com.bnyer.img.dto.TiktokLoginDto; import com.bnyer.img.dto.TiktokUserPageDto; import com.bnyer.img.vo.TiktokSessionInfoVo; +import com.bnyer.img.vo.TiktokUserPhoneInfoVo; import com.bnyer.img.vo.TiktokUserVo; import java.util.List; +import java.util.Map; public interface TiktokUserService { /** - * 新增抖音用户 - * @param tiktokUser 抖音用户 + * 新增艺术家 + * @param dto 艺术家参数 * @return - */ - int insert(TiktokUser tiktokUser); + int insertCreator(TiktokCreaterDto dto); /** * 修改抖音用户 * @param tiktokUser 抖音用户 * @return - */ - int update(TiktokUser tiktokUser); + //int update(TiktokUser tiktokUser); /** * 批量删除抖音用户 @@ -51,9 +56,16 @@ public interface TiktokUserService { List queryUserImgList(); /** - * 查询tiktok小程序sessionInfo - * @param code 登录凭证code + * 抖音登录参数 + * @param dto 登录参数 * @return - */ - TiktokSessionInfoVo getSessionInfo(String code); + Map login(TiktokLoginDto dto); + + + /** + * 绑定手机号 + * @param dto 绑定对象参数 + */ + void bindPhone(TiktokBindPhoneDto dto); } diff --git a/bnyer-services/bnyer-img/src/main/java/com/bnyer/img/service/impl/TiktokUserServiceImpl.java b/bnyer-services/bnyer-img/src/main/java/com/bnyer/img/service/impl/TiktokUserServiceImpl.java index daa68ab..d0f6ea8 100644 --- a/bnyer-services/bnyer-img/src/main/java/com/bnyer/img/service/impl/TiktokUserServiceImpl.java +++ b/bnyer-services/bnyer-img/src/main/java/com/bnyer/img/service/impl/TiktokUserServiceImpl.java @@ -2,29 +2,38 @@ package com.bnyer.img.service.impl; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.bnyer.common.core.exception.ServiceException; +import com.bnyer.common.core.utils.Sm4Util; import com.bnyer.common.core.utils.StringUtils; +import com.bnyer.common.core.utils.uuid.IdUtils; import com.bnyer.common.redis.service.RedisService; import com.bnyer.img.config.TiktokConfig; import com.bnyer.img.constants.RedisKeyConstant; import com.bnyer.img.constants.TiktokConstant; import com.bnyer.img.domain.TiktokImg; import com.bnyer.img.domain.TiktokUser; +import com.bnyer.img.dto.TiktokBindPhoneDto; +import com.bnyer.img.dto.TiktokCreaterDto; +import com.bnyer.img.dto.TiktokLoginDto; import com.bnyer.img.dto.TiktokUserPageDto; import com.bnyer.img.feign.TiktokFeign; import com.bnyer.img.mapper.TiktokImgMapper; import com.bnyer.img.mapper.TiktokUserMapper; import com.bnyer.img.service.TiktokUserService; import com.bnyer.img.vo.TiktokSessionInfoVo; +import com.bnyer.img.vo.TiktokUserInfoVo; +import com.bnyer.img.vo.TiktokUserPhoneInfoVo; import com.bnyer.img.vo.TiktokUserVo; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import javax.annotation.Resource; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import javax.crypto.Cipher; +import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.SecretKeySpec; +import java.util.*; import java.util.concurrent.TimeUnit; @Service @@ -46,16 +55,67 @@ public class TiktokUserServiceImpl implements TiktokUserService { @Autowired private TiktokFeign tiktokFeign; - @Override - public int insert(TiktokUser tiktokUser) { - return 0; + /** + * 检查搜索码是否重复 + * @param scanCode 搜索码 + * @return - + */ + private boolean checkScanCode(String scanCode){ + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.eq(TiktokUser::getScanCode, scanCode); + List tiktokUsers = tiktokUserMapper.selectList(wrapper); + if(tiktokUsers.size() > 0){ + return true; + }else{ + return false; + } + } + + /** + * 检查用户是否绑定过手机号 + * @param phone 手机号 + * @return - + */ + private boolean checkPhone(String phone){ + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.eq(TiktokUser::getPhone, phone); + List tiktokUsers = tiktokUserMapper.selectList(wrapper); + if(tiktokUsers.size() > 0){ + return true; + }else{ + return false; + } } @Override - public int update(TiktokUser tiktokUser) { - return 0; + public int insertCreator(TiktokCreaterDto dto) { + //检查手机号是否存在 + boolean b1 = checkPhone(Sm4Util.sm4Encryption(dto.getPhone())); + if(!b1){ + throw new ServiceException("用户尚未绑定手机号,请手动绑定!"); + } + //检查搜索码是否重复 + boolean b = this.checkScanCode(dto.getScanCode()); + if(b){ + throw new ServiceException("搜索码重复,请重新编辑!"); + } + TiktokUser user = new TiktokUser(); + user.setIntro(dto.getIntro()); + user.setScanCode(dto.getScanCode()); + user.setInviteCode(dto.getInviteCode()); + user.setTiktokNumber(dto.getTiktokNum()); + LambdaUpdateWrapper updateWrapper = new LambdaUpdateWrapper<>(); + updateWrapper.eq(TiktokUser::getPhone, Sm4Util.sm4Encryption(dto.getPhone())); + int update = tiktokUserMapper.update(user, updateWrapper); + log.info("用户【{}】成为艺术家成功!",dto.getPhone()); + return update; } +// @Override +// public int update(TiktokUser tiktokUser) { +// return 0; +// } + @Override public int delete(List ids) { int delete = tiktokUserMapper.deleteBatchIds(ids); @@ -72,7 +132,7 @@ public class TiktokUserServiceImpl implements TiktokUserService { public List queryPage(TiktokUserPageDto dto) { LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); wrapper.like(StringUtils.isNotNull(dto.getUsername()), TiktokUser::getUsername, dto.getUsername()); - wrapper.eq(StringUtils.isNotNull(dto.getPhone()),TiktokUser::getPhone, dto.getPhone()); + wrapper.eq(StringUtils.isNotNull(dto.getPhone()),TiktokUser::getPhone, Sm4Util.sm4Encryption(dto.getPhone())); wrapper.eq(StringUtils.isNotNull(dto.getTiktokNumber()), TiktokUser::getTiktokNumber, dto.getTiktokNumber()); wrapper.eq(StringUtils.isNotNull(dto.getScanCode()), TiktokUser::getScanCode, dto.getScanCode()); wrapper.eq(StringUtils.isNotNull(dto.getInviteCode()), TiktokUser::getInviteCode, dto.getInviteCode()); @@ -98,8 +158,12 @@ public class TiktokUserServiceImpl implements TiktokUserService { return tiktokUserVo; } - @Override - public TiktokSessionInfoVo getSessionInfo(String code) { + /** + * 获取用户openId及sessionKey + * @param code 登录凭证code + * @return - + */ + private TiktokSessionInfoVo getSessionInfo(String code) { Map params = new HashMap(8); params.put("appid", tiktokConfig.getAppId()); params.put("secret", tiktokConfig.getSecret()); @@ -118,4 +182,132 @@ public class TiktokUserServiceImpl implements TiktokUserService { result.setUnionId(data.getString("unionid")); return result; } + + /** + * 获取用户敏感信息 + * @param sessionKey - + * @param encryptedData 敏感数据 + * @param iv 加密向量 + * @return - + */ + private TiktokUserInfoVo getUserInfo(String sessionKey,String encryptedData,String iv){ + Base64.Decoder decoder = Base64.getDecoder(); + byte[] sessionKeyBytes = decoder.decode(sessionKey); + byte[] ivBytes = decoder.decode(iv); + byte[] encryptedBytes = decoder.decode(encryptedData); + + Cipher cipher = null; + try { + cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); + SecretKeySpec skeySpec = new SecretKeySpec(sessionKeyBytes, "AES"); + IvParameterSpec ivSpec = new IvParameterSpec(ivBytes); + cipher.init(Cipher.DECRYPT_MODE, skeySpec, ivSpec); + byte[] ret = cipher.doFinal(encryptedBytes); + if (null != ret && ret.length > 0) { + String result = new String(ret, "UTF-8"); + return JSONObject.parseObject(result,TiktokUserInfoVo.class); + } + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + + /** + * 保存用户 + * @param openId 抖音id + * @param sessionKey - + * @param encryptedData 敏感信息数据 + * @param iv 加密向量 + * @return - + */ + private TiktokUser saveUserInfo(String openId,String sessionKey,String encryptedData,String iv){ + //获取敏感信息 + TiktokUserInfoVo userInfo = this.getUserInfo(sessionKey, encryptedData, iv); + TiktokUser user = new TiktokUser(); + user.setUsername(userInfo.getNickName()); + user.setImg(userInfo.getAvatarUrl()); + user.setTiktokCode(Sm4Util.sm4Encryption(openId)); + user.setIsHot("0"); + user.setIsShow("1"); + user.setCreateTime(new Date()); + user.setUpdateTime(new Date()); + tiktokUserMapper.insert(user); + log.info("抖音用户【{}】创建成功!",user.getId()); + return user; + } + + @Override + public Map login(TiktokLoginDto dto) { + TiktokSessionInfoVo sessionInfo = this.getSessionInfo(dto.getCode()); + //检查数据库中是否存在该openId,存在则直接设置会话状态登录;不存在则新增 + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.eq(sessionInfo.getOpenId() != null,TiktokUser::getTiktokCode,dto.getCode()); + TiktokUser tiktokUser = tiktokUserMapper.selectOne(wrapper); + if(tiktokUser == null){ + //新用户,新增 + tiktokUser = this.saveUserInfo(sessionInfo.getOpenId(), sessionInfo.getSessionKey(), dto.getEncryptedData(), dto.getIv()); + } + //设置会话状态 + String redisKey = RedisKeyConstant.TIKTOK_USER_LOGIN_KEY+sessionInfo.getOpenId(); + //存在该登录态则删除刷新 + if(redisService.hasKey(redisKey)){ + redisService.deleteObject(redisKey); + } + StringBuffer sb = new StringBuffer(); + String randomId = IdUtils.fastSimpleUUID(); + sb.append(randomId).append("#").append(sessionInfo.getOpenId()); + //设置登录会话 + redisService.setCacheObject(redisKey,sb.toString(),30L, TimeUnit.DAYS); + Map map = new HashMap<>(2); + map.put("token", sb.toString()); + map.put("userInfo",tiktokUser); + return map; + } + + @Override + public void bindPhone(TiktokBindPhoneDto dto) { + TiktokUserPhoneInfoVo phoneInfo = this.getPhone(dto.getSessionKey(), dto.getEncryptedData(), dto.getIv()); + if(phoneInfo != null){ + TiktokUser user = new TiktokUser(); + user.setId(dto.getUserId()); + user.setPhone(Sm4Util.sm4Encryption(phoneInfo.getPhoneNumber())); + tiktokUserMapper.updateById(user); + log.info("获取用户【{}】手机号成功!",dto.getUserId()); + }else{ + log.error("获取用户【{}】手机号失败!",dto.getUserId()); + throw new ServiceException("用户手机号绑定失败!"); + } + } + + + /** + * 获取用户手机号 + * @param sessionKey - + * @param encryptedData 敏感信息 + * @param iv 加密向量 + * @return - + */ + private TiktokUserPhoneInfoVo getPhone(String sessionKey, String encryptedData, String iv) { + Base64.Decoder decoder = Base64.getDecoder(); + byte[] sessionKeyBytes = decoder.decode(sessionKey); + byte[] ivBytes = decoder.decode(iv); + byte[] encryptedBytes = decoder.decode(encryptedData); + + Cipher cipher = null; + try { + cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); + SecretKeySpec skeySpec = new SecretKeySpec(sessionKeyBytes, "AES"); + IvParameterSpec ivSpec = new IvParameterSpec(ivBytes); + cipher.init(Cipher.DECRYPT_MODE, skeySpec, ivSpec); + byte[] ret = cipher.doFinal(encryptedBytes); + if (null != ret && ret.length > 0) { + String result = new String(ret, "UTF-8"); + return JSONObject.parseObject(result,TiktokUserPhoneInfoVo.class); + } + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } } diff --git a/bnyer-services/bnyer-img/src/main/java/com/bnyer/img/vo/TiktokUserInfoVo.java b/bnyer-services/bnyer-img/src/main/java/com/bnyer/img/vo/TiktokUserInfoVo.java new file mode 100644 index 0000000..9d8f449 --- /dev/null +++ b/bnyer-services/bnyer-img/src/main/java/com/bnyer/img/vo/TiktokUserInfoVo.java @@ -0,0 +1,36 @@ +package com.bnyer.img.vo; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Getter; +import lombok.Setter; + +import java.io.Serializable; + + +@Getter +@Setter +@ApiModel("抖音平台用户响应类") +public class TiktokUserInfoVo implements Serializable { + + @ApiModelProperty(value="用户昵称") + private String nickName; + + @ApiModelProperty(value="用户头像网络地址") + private String avatarUrl; + + @ApiModelProperty(value="用户性别,0: 未知;1:男性;2:女性") + private String gender; + + @ApiModelProperty(value="用户所在城市") + private String city; + + @ApiModelProperty(value="用户所在省份") + private String province; + + @ApiModelProperty(value="用户所在国家") + private String country; + + @ApiModelProperty(value="用户openId") + private String openId; +} diff --git a/bnyer-services/bnyer-img/src/main/java/com/bnyer/img/vo/TiktokUserPhoneInfoVo.java b/bnyer-services/bnyer-img/src/main/java/com/bnyer/img/vo/TiktokUserPhoneInfoVo.java new file mode 100644 index 0000000..690f4cf --- /dev/null +++ b/bnyer-services/bnyer-img/src/main/java/com/bnyer/img/vo/TiktokUserPhoneInfoVo.java @@ -0,0 +1,24 @@ +package com.bnyer.img.vo; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Getter; +import lombok.Setter; + +import java.io.Serializable; + + +@Getter +@Setter +@ApiModel("抖音平台用户响应类") +public class TiktokUserPhoneInfoVo implements Serializable { + + @ApiModelProperty(value="用户绑定的手机号") + private String phoneNumber; + + @ApiModelProperty(value="没有区号的手机号") + private String purePhoneNumber; + + @ApiModelProperty(value="区号") + private String countryCode; +} diff --git a/pom.xml b/pom.xml index ace6274..4bd5e73 100644 --- a/pom.xml +++ b/pom.xml @@ -41,6 +41,7 @@ 3.2.2 2.12.2 1.18.12 + 5.8.0.M3 @@ -245,6 +246,12 @@ ${bnyer.version} + + cn.hutool + hutool-all + ${hutool.version} + +