1.抖音获取授权用户视频

2.抖音点击视频标题跳转抖音播放
dev
862857010@qq.com 2 years ago
parent dd144a9e7f
commit 8a2a4a6bfb
  1. 37
      cjy-project/src/main/java/com/cjy/douyin/controller/DouyingConfigController.java
  2. 27
      cjy-project/src/main/java/com/cjy/douyin/domain/GetVideoVO.java
  3. 26
      cjy-project/src/main/java/com/cjy/douyin/domain/VideoInfo.java
  4. 4
      cjy-project/src/main/java/com/cjy/douyin/mapper/DouyingConfigMapper.java
  5. 103
      cjy-project/src/main/java/com/cjy/douyin/service/IDouyingConfigService.java
  6. 7
      cjy-project/src/main/java/com/cjy/douyin/service/impl/DouyingConfigServiceImpl.java
  7. 8
      cjy-project/src/main/resources/mapper/douyunconfig/DouyingConfigMapper.xml
  8. 35
      ruoyi-common/src/main/java/com/ruoyi/common/utils/http/HttpUtils.java
  9. 9
      ruoyi-quartz/src/main/java/com/ruoyi/quartz/mapper/DouYinMapper.java
  10. 48
      ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/impl/DouYinServiceImpl.java
  11. 1
      ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/DouYinTask.java
  12. 8
      ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/DouYinUTils.java
  13. 12
      ruoyi-quartz/src/main/resources/mapper/quartz/DouyinMapper.xml

@ -1,11 +1,19 @@
package com.cjy.douyin.controller;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletResponse;
import com.alibaba.fastjson2.JSONObject;
import com.cjy.douyin.domain.GetVideoVO;
import com.cjy.douyin.domain.VideoInfo;
import com.cjy.media.domain.WeiboConfig;
import com.cjy.media.util.WeiBoEncryption;
import com.ruoyi.common.utils.http.HttpUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
@ -115,8 +123,35 @@ public class DouyingConfigController extends BaseController {
DouyingConfig douyingConfig = douyingConfigService.selectDouyingConfigById(id);
String state = WeiBoEncryption.encrypt(douyingConfig.getClientId().toString(), rule);
String authUrl = "https://open.douyin.com/platform/oauth/connect?client_key=" + douyingConfig.getClientId() + "&state=" + state + "&redirect_uri="
+ URLEncoder.encode(douyingConfig.getRedirectUri(), "UTF-8") + "&scope=user_info,data.external.user&response_type=code";
+ URLEncoder.encode(douyingConfig.getRedirectUri(), "UTF-8") + "&scope=user_info,data.external.user,video.data.bind,video.list.bind&response_type=code";
return success(authUrl);
}
/**
* 获取视频id
* @param getVideoVO
* @return
* @throws Exception
*/
@PostMapping(value = "getVideo")
public AjaxResult getVideo(@RequestBody GetVideoVO getVideoVO) throws Exception {
String accessToken = douyingConfigService.selectDouyinAuthorizedInfoByOpenId(getVideoVO.getOpenId());
List<String> idList = new ArrayList<>();
idList.add(getVideoVO.getId());
JSONObject json = this.videoData(getVideoVO.getOpenId(), idList, accessToken);
JSONObject videoListDataJson = JSONObject.parseObject(json.get("data").toString());
List<VideoInfo> dataJsonList = videoListDataJson.getList("list", VideoInfo.class);
return success(dataJsonList.get(0).getShareUrl());
}
public JSONObject videoData(String openId, List<String> itemIds, String accessToken) {
String videoDataURL = "https://open.douyin.com/api/douyin/v1/video/video_data?open_id=" + openId;
Map<String, Object> paramsMap = new HashMap<>();
paramsMap.put("item_ids", itemIds);
String response = HttpUtils.callPostDouYinAPI(videoDataURL, paramsMap, accessToken);
JSONObject json = JSONObject.parseObject(response);
return json;
}
}

@ -0,0 +1,27 @@
package com.cjy.douyin.domain;
/**
* @author liangjiawei
* @createDate 2023/8/28
*/
public class GetVideoVO {
private String id;
private String openId;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getOpenId() {
return openId;
}
public void setOpenId(String openId) {
this.openId = openId;
}
}

@ -0,0 +1,26 @@
package com.cjy.douyin.domain;
/**
* @author liangjiawei
* @createDate 2023/8/28
*/
public class VideoInfo {
private String title;
private String shareUrl;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getShareUrl() {
return shareUrl;
}
public void setShareUrl(String shareUrl) {
this.shareUrl = shareUrl;
}
}

@ -1,6 +1,8 @@
package com.cjy.douyin.mapper;
import java.util.List;
import java.util.Map;
import com.cjy.douyin.domain.DouyingConfig;
/**
@ -58,4 +60,6 @@ public interface DouyingConfigMapper
* @return 结果
*/
public int deleteDouyingConfigByIds(Long[] ids);
String selectDouyinAuthorizedInfoByOpenId(String openid);
}

@ -1,61 +1,64 @@
package com.cjy.douyin.service;
import java.util.List;
import java.util.Map;
import com.cjy.douyin.domain.DouyingConfig;
/**
* 抖音配置Service接口
*
*
* @author liangjiawei
* @date 2023-08-10
*/
public interface IDouyingConfigService
{
/**
* 查询抖音配置
*
* @param id 抖音配置主键
* @return 抖音配置
*/
public DouyingConfig selectDouyingConfigById(Long id);
/**
* 查询抖音配置列表
*
* @param douyingConfig 抖音配置
* @return 抖音配置集合
*/
public List<DouyingConfig> selectDouyingConfigList(DouyingConfig douyingConfig);
/**
* 新增抖音配置
*
* @param douyingConfig 抖音配置
* @return 结果
*/
public int insertDouyingConfig(DouyingConfig douyingConfig);
/**
* 修改抖音配置
*
* @param douyingConfig 抖音配置
* @return 结果
*/
public int updateDouyingConfig(DouyingConfig douyingConfig);
/**
* 批量删除抖音配置
*
* @param ids 需要删除的抖音配置主键集合
* @return 结果
*/
public int deleteDouyingConfigByIds(Long[] ids);
/**
* 删除抖音配置信息
*
* @param id 抖音配置主键
* @return 结果
*/
public int deleteDouyingConfigById(Long id);
public interface IDouyingConfigService {
/**
* 查询抖音配置
*
* @param id 抖音配置主键
* @return 抖音配置
*/
public DouyingConfig selectDouyingConfigById(Long id);
/**
* 查询抖音配置列表
*
* @param douyingConfig 抖音配置
* @return 抖音配置集合
*/
public List<DouyingConfig> selectDouyingConfigList(DouyingConfig douyingConfig);
/**
* 新增抖音配置
*
* @param douyingConfig 抖音配置
* @return 结果
*/
public int insertDouyingConfig(DouyingConfig douyingConfig);
/**
* 修改抖音配置
*
* @param douyingConfig 抖音配置
* @return 结果
*/
public int updateDouyingConfig(DouyingConfig douyingConfig);
/**
* 批量删除抖音配置
*
* @param ids 需要删除的抖音配置主键集合
* @return 结果
*/
public int deleteDouyingConfigByIds(Long[] ids);
/**
* 删除抖音配置信息
*
* @param id 抖音配置主键
* @return 结果
*/
public int deleteDouyingConfigById(Long id);
String selectDouyinAuthorizedInfoByOpenId(String openid);
}

@ -1,6 +1,8 @@
package com.cjy.douyin.service.impl;
import java.util.List;
import java.util.Map;
import com.ruoyi.common.utils.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@ -92,4 +94,9 @@ public class DouyingConfigServiceImpl implements IDouyingConfigService
{
return douyingConfigMapper.deleteDouyingConfigById(id);
}
@Override
public String selectDouyinAuthorizedInfoByOpenId(String openid) {
return douyingConfigMapper.selectDouyinAuthorizedInfoByOpenId(openid);
}
}

@ -54,7 +54,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<include refid="selectDouyingConfigVo"/>
where id = #{id}
</select>
<select id="selectDouyinAuthorizedInfoByOpenId" resultType="java.lang.String">
SELECT
access_token as accessToken
FROM
douyin_authorized_info WHERE open_id=#{openid}
</select>
<insert id="insertDouyingConfig" parameterType="DouyingConfig" useGeneratedKeys="true" keyProperty="id">
insert into douying_config
<trim prefix="(" suffix=")" suffixOverrides=",">

@ -267,6 +267,41 @@ public class HttpUtils {
con.setRequestMethod("POST");
con.setDoOutput(true);
con.setRequestProperty("Content-Type", "application/json");
OutputStream os = con.getOutputStream();
os.write(requestBody.toString().getBytes());
os.flush();
os.close();
int responseCode = con.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuilder response = new StringBuilder();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
System.out.println("response " + response.toString());
return response.toString();
} else {
System.out.println("Error occurred. Response code: " + responseCode);
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static String callPostDouYinAPI(String url, Map<String, Object> params, String accessToken) {
try {
URL obj = new URL(url);
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("POST");
con.setDoOutput(true);
con.setRequestProperty("Content-Type", "application/json");
con.setRequestProperty("access-token", accessToken);
// 构建请求体
JSONObject requestBody = new JSONObject(params);
OutputStream os = con.getOutputStream();
os.write(requestBody.toString().getBytes());

@ -77,4 +77,13 @@ public interface DouYinMapper {
* @return
*/
int addDouYinVideoInFoList(@Param("list") List<DouYinVideoInFoDTO> list,@Param("openId") String openId,@Param("organCode") String organCode);
/**
* 单条插入
* @param douYinVideoInFoDTO
* @param openId
* @param organCode
* @return
*/
int addDouYinVideoInFo(@Param("data") DouYinVideoInFoDTO douYinVideoInFoDTO ,@Param("openId") String openId,@Param("organCode") String organCode);
}

@ -9,6 +9,7 @@ import com.ruoyi.quartz.domain.dto.*;
import com.ruoyi.quartz.mapper.DouYinMapper;
import com.ruoyi.quartz.service.DouYinService;
import com.ruoyi.quartz.util.DouYinUTils;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@ -20,6 +21,7 @@ import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
/**
* @author liangjiawei
@ -263,30 +265,34 @@ public class DouYinServiceImpl implements DouYinService {
@Override
public void getDouYinVideoInfo() {
List<DouYinAuthorizedInfoDTO> douYinAuthorizedInfoDTOList = this.getAllDouYinAuthorizedInfo();
int cursor = 0;
Long cursor = 0L;
int count = 10;
int isResume = 0;
List<DouYinVideoInFoDTO> addList = new ArrayList();
List<DouYinVideoInFoDTO> newAddList = new ArrayList();
for (DouYinAuthorizedInfoDTO item : douYinAuthorizedInfoDTOList) {
while (isResume == 0) {
JSONObject videoList = DouYinUTils.videoListURL(item.getOpenId(), cursor, count, item.getAccessToken());
JSONObject videoListDataJson = JSONObject.parseObject(videoList.toString());
if (videoListDataJson.get("error_code").equals("0")) {
cursor = videoListDataJson.getByte("cursor");
if (!videoListDataJson.get("has_more").equals("true")) {
JSONObject videoListDataJson = JSONObject.parseObject(videoList.get("data").toString());
if (videoListDataJson.get("error_code").toString().equals("0")) {
cursor = Long.parseLong(videoListDataJson.get("cursor").toString());
if (videoListDataJson.get("has_more").toString().equals("false")) {
isResume = 1;
}
//处理数据插入
List<DouYinVideoInFoDTO> dataJsonList = videoListDataJson.getList("list", DouYinVideoInFoDTO.class);
if (addList.size() < 1000) {
addList.addAll(dataJsonList);
if (newAddList.size() < 1000) {
newAddList.addAll(dataJsonList.stream().filter(i->i.getVideoStatus().equals("1")).collect(Collectors.toList()));
} else {
//批量插入视频信息
douYinMapper.addDouYinVideoInFoList(addList, item.getOpenId(), item.getOrganCode());
// douYinMapper.addDouYinVideoInFoList(newAddList, item.getOpenId(), item.getOrganCode());
this.addDouYinVideoInFo(newAddList, item.getOpenId(), item.getOrganCode());
//清空
dataJsonList.clear();
newAddList.clear();
//添加
addList.addAll(dataJsonList);
newAddList.addAll(dataJsonList.stream().filter(i->i.getVideoStatus().equals("1")).collect(Collectors.toList()));
}
} else {
DouyinErrorLogDTO douyinErrorLogDTO = new DouyinErrorLogDTO();
@ -294,11 +300,23 @@ public class DouYinServiceImpl implements DouYinService {
douyinErrorLogDTO.setDescribe("获取分享数量异常");
douYinMapper.adddouyinErrorLog(douyinErrorLogDTO);
}
if (!addList.isEmpty()) {
//批量插入视频信息
douYinMapper.addDouYinVideoInFoList(addList, item.getOpenId(), item.getOrganCode());
}
}
if (!newAddList.isEmpty()) {
//批量插入视频信息
this.addDouYinVideoInFo(newAddList, item.getOpenId(), item.getOrganCode());
// douYinMapper.addDouYinVideoInFoList(newAddList, item.getOpenId(), item.getOrganCode());
}
}
}
public void addDouYinVideoInFo(List<DouYinVideoInFoDTO> list, @Param("openId") String openId, @Param("organCode") String organCode){
list.stream().forEach(item->{
try {
douYinMapper.addDouYinVideoInFo(item,openId,organCode);
}catch (Exception e){
e.printStackTrace();
}
});
}
}

@ -30,6 +30,7 @@ public class DouYinTask {
}
//获取授权抖音号的视频数据
// @Scheduled(cron = "0 0/1 * * * ?")
public void getDouYinVideoInfo() {
douYinService.getDouYinVideoInfo();
}

@ -33,13 +33,13 @@ public class DouYinUTils {
private static String videoSituationCountURL = "https://open.douyin.com/data/external/user/item/";
//获取授权用户发布的视频
private static String videoListURL = "/api/douyin/v1/video/video_list/";
private static String videoListURL = "https://open.douyin.com/api/douyin/v1/video/video_list/";
//查询特定视频的视频数据
private static String videoDataURL = "https://open.douyin.com/api/douyin/v1/video/video_data/";
/**
* 获取指定微博数据
* 获取制定抖音数据
* @param openId
* @param itemIds
* @param accessToken
@ -50,7 +50,7 @@ public class DouYinUTils {
Map<String, Object> paramsMap =new HashMap<>();
paramsMap.put("item_ids",itemIds);
String response = HttpUtils.callDouYinAPI(videoDataURL + params,paramsMap, accessToken);
String response = HttpUtils.callPostDouYinAPI(videoDataURL + params,paramsMap, accessToken);
JSONObject json = JSONObject.parseObject(response);
return json;
}
@ -63,7 +63,7 @@ public class DouYinUTils {
* @param accessToken
* @return
*/
public static JSONObject videoListURL(String openId, int cursor,int count,String accessToken) {
public static JSONObject videoListURL(String openId, Long cursor,int count,String accessToken) {
String params = "?open_id=" + openId + "&cursor="+cursor+"&count="+count;
String response = HttpUtils.doDouYinGet(videoListURL + params, accessToken);
JSONObject json = JSONObject.parseObject(response);

@ -29,6 +29,18 @@
#{organCode}, #{openId})
</foreach>
</insert>
<insert id="addDouYinVideoInFo">
INSERT INTO douyin_video_info (item_id, media_type, title, cover, is_top,
create_time, is_reviewed, video_status, share_url, statistics, organ_code, open_id)
VALUES
(#{data.itemId}, #{data.mediaType}, #{data.title}, #{data.cover} , #{data.isTop} ,
#{data.createTime} ,
#{data.isReviewed} , #{data.videoStatus} , #{data.shareUrl} , #{data.statistics} ,
#{organCode}, #{openId})
</insert>
<update id="updateWeiBoAuthorizedToekn">
update douyin_authorized_info

Loading…
Cancel
Save