package com.ycl.controller.dingding; import cn.hutool.core.util.ObjectUtil; import com.alibaba.fastjson.JSONObject; import com.alibaba.xxpt.gateway.shared.api.request.OapiMediaUploadRequest; import com.alibaba.xxpt.gateway.shared.api.response.OapiMediaUploadResponse; import com.alibaba.xxpt.gateway.shared.client.http.ExecutableClient; import com.alibaba.xxpt.gateway.shared.client.http.GetClient; import com.alibaba.xxpt.gateway.shared.client.http.IntelligentPostClient; import com.alibaba.xxpt.gateway.shared.client.http.PostClient; import com.aliyun.oss.OSS; import com.aliyun.oss.OSSClientBuilder; import com.aliyun.oss.common.utils.StringUtils; import com.aliyun.oss.model.ObjectMetadata; import com.ycl.api.CommonResult; import com.ycl.bo.AdminUserDetails; import com.ycl.common.dingding.DingCommon; import com.ycl.config.DdTest; import com.ycl.config.DingConfig; import com.ycl.controller.BaseController; import com.ycl.dto.video.OssFileDto; import com.ycl.entity.dingding.DingUserInfo; import com.ycl.service.auth.AuthService; import com.ycl.service.ding.BookRemarkService; import com.ycl.service.ding.DingService; import com.ycl.service.oss.OssService; import com.ycl.utils.ConstantPropertiesUtils; import com.ycl.utils.common.RandomUtils; import com.ycl.vo.AddressBookVO; import com.ycl.vo.NewAddressBookVO; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; 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.http.HttpEntity; import org.apache.http.client.methods.CloseableHttpResponse; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.MediaType; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.commons.CommonsMultipartFile; import javax.annotation.Resource; import java.io.*; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import static com.ycl.common.constant.DingConst.*; @RestController @RequestMapping("/ding") @Api(tags = "钉钉") @Slf4j public class DingController extends BaseController { @Autowired private DingCommon dingCommon; @Value("${jwt.tokenHead}") private String tokenHead; /** * DING 免登 * 根据临时授权码和access_token获取用户信息 * * @author cjx */ @Autowired private AuthService authService; @Autowired private DingService dingService; @Autowired private BookRemarkService bookRemarkService; @Resource private ExecutableClient executableClient; @Resource private DingConfig dingConfig; @Autowired private OssService ossService; @ApiOperation(value = "根据钉钉授权码获取token") @GetMapping("/dingLogin") public CommonResult dingLogin(@RequestParam String code) { log.info("一键登录参数code--------------->{}", code); HashMap map = new HashMap<>(); //获取用户信息 DingUserInfo dingUser = dingCommon.getDingUserInfo(code); //按ding登录 log.info("用户信息------------------->{}", dingUser); String token = authService.dingLogin(dingUser); map.put("token", token); map.put("tokenHead", tokenHead); map.put("accountId", dingUser.getAccountId()); return CommonResult.success(map); } @ApiOperation(value = "根据钉钉授权码获取jsapiToken") @GetMapping("/dingTicker") public CommonResult dingTicker() { String accessToken = getToken(); String ticket = getTiker(accessToken); HashMap map = new HashMap<>(); map.put("accessToken", accessToken); map.put("ticket", ticket); return CommonResult.success(map); } private String getToken() { //调用API GetClient getTokenClient = executableClient.newGetClient(GET_TOKEN); //设置参数 getTokenClient.addParameter("appkey", dingConfig.getAppKey()); getTokenClient.addParameter("appsecret", dingConfig.getAppSecret()); String apiResult = getTokenClient.get(); return parsingResult(apiResult); } private String getTiker(String accToken) { //调用API PostClient postClient = executableClient.newPostClient(GET_TIKER); //设置参数 if (ObjectUtil.isNotNull(accToken)) { postClient.addParameter("accessToken", accToken); postClient.addParameter("appkey", dingConfig.getAppKey()); postClient.addParameter("appsecret", dingConfig.getAppSecret()); String apiResult = postClient.post(); return parsingResult(apiResult); } return null; } private String parsingResult(String apiResult) { if (ObjectUtil.isNotNull(apiResult)) { JSONObject resJson = JSONObject.parseObject(apiResult); if (resJson.getBoolean("success")) { JSONObject content = resJson.getJSONObject("content"); if (content.getBoolean("success")) { JSONObject dataObj = content.getJSONObject("data"); String accessToken = dataObj.getString("accessToken"); return accessToken; } } else { log.error(resJson.toJSONString()); } } return null; } @ApiOperation(value = "通讯录") @GetMapping("/addressBook") public CommonResult> getAddressBook() { AdminUserDetails user = (AdminUserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); return CommonResult.success(dingService.getAddressBook(user.getUserId())); } @ApiOperation(value = "通讯录递归") @GetMapping("/addressBookById") public CommonResult> getAddressBook(@RequestParam("id") Long id) { AdminUserDetails user = (AdminUserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); return CommonResult.success(dingService.getAddressBookByParentId(id, user.getUserId())); } @ApiOperation(value = "通讯录递归") @GetMapping("/getDddressBook") public CommonResult getNewAddressBook(@RequestParam("id") Long id) { AdminUserDetails user = (AdminUserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); return CommonResult.success(dingService.getAddressBookById(id, user.getUserId())); } @ApiOperation(value = "修改通讯录备注") @PutMapping("/remark") public CommonResult updateRemark(@RequestParam("userId") Long userId, @RequestParam("remark") String remark) { AdminUserDetails user = (AdminUserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); return CommonResult.success(bookRemarkService.updateRemark(user, userId, remark)); } @PostMapping("/oss/sign") public CommonResult ossSign(@RequestBody OssFileDto dto) { if (StringUtils.isNullOrEmpty(dto.getMediaId()) || StringUtils.isNullOrEmpty(dto.getExtension())) { return CommonResult.failed("参数不能为空!"); } ExecutableClient executableClient = DdTest.getExecutableClient(); CloseableHttpResponse response = null; OSS ossClient = null; DateTimeFormatter dtf2 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); System.out.println("开始获取--" + dtf2.format(LocalDateTime.now())); try { //从钉钉获取视频流 String api = "/media/download"; GetClient getClient = executableClient.newGetClient(api); //从redis获取token String token = getToken(); //设置参数 getClient.addParameter("access_token", token); getClient.addParameter("media_id", dto.getMediaId()); response = getClient.getB(); HttpEntity entity = response.getEntity(); InputStream is = entity.getContent(); // MultipartFile file = getMultipartFile(is, fileName); String url = ossService.uploadImages(is, dto.getExtension(),0); return CommonResult.success(url); } catch (Exception e) { e.printStackTrace(); System.out.println(e.getMessage()); } finally { if (ossClient != null) { ossClient.shutdown(); } if (response != null) { try { response.close(); } catch (Exception e) { System.out.println(e); } } } return null; } @ApiOperation(value = "获取视频") @GetMapping("/getVideo/{mediaId}") public CommonResult getVideo(@PathVariable String mediaId) { String accessToken = getToken(); MultipartFile file = getDownload(accessToken, mediaId); String url = ossService.uploadImages(file); return CommonResult.success(url); } private MultipartFile getDownload(String access_token, String media_id) { CloseableHttpResponse response = null; try { String api = "/media/download"; GetClient getClient = executableClient.newGetClient(api); //设置参数 getClient.addParameter("access_token", access_token); getClient.addParameter("media_id", media_id); response = getClient.getB(); HttpEntity entity = response.getEntity(); InputStream is = entity.getContent(); DateTimeFormatter dtf2 = DateTimeFormatter.ofPattern("yyyyMMddHHmmss"); String strDate2 = dtf2.format(LocalDateTime.now()); String fileName = strDate2 + RandomUtils.generateRandomInt(4) + ".MOV"; return getMultipartFile(is, fileName); } catch (Exception e) { System.out.println(e); } finally { if (response != null) { try { //特别提醒:需要调用response的close方法关闭网络连接!!! response.close(); } catch (Exception e) { System.out.println(e); } } } return null; } /** * 获取封装得MultipartFile * * @param inputStream inputStream * @param fileName fileName * @return MultipartFile */ public MultipartFile getMultipartFile(InputStream inputStream, String fileName) { FileItem fileItem = createFileItem(inputStream, fileName); //CommonsMultipartFile是feign对multipartFile的封装,但是要FileItem类对象 return new CommonsMultipartFile(fileItem); } /** * FileItem类对象创建 * * @param inputStream inputStream * @param fileName fileName * @return FileItem */ public FileItem createFileItem(InputStream inputStream, String fileName) { FileItemFactory factory = new DiskFileItemFactory(16, null); DateTimeFormatter dtf2 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); String strDate2 = dtf2.format(LocalDateTime.now()); String textFieldName = strDate2 + RandomUtils.generateRandomInt(4); 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; } }