|
@@ -0,0 +1,169 @@
|
|
|
|
|
+package cn.com.ctop.job.bytedance.data.service.impl;
|
|
|
|
|
+
|
|
|
|
|
+import cn.com.ctop.job.bytedance.data.entity.BytedanceAdvertiserList;
|
|
|
|
|
+import cn.com.ctop.job.bytedance.data.mapper.AdminAdvertiserListMapper;
|
|
|
|
|
+import cn.com.ctop.job.bytedance.data.service.IAdminAdvertiserListService;
|
|
|
|
|
+import cn.com.ctop.job.bytedance.data.utils.Check;
|
|
|
|
|
+import cn.com.ctop.job.bytedance.data.utils.HttpUtils;
|
|
|
|
|
+import com.alibaba.fastjson.JSONArray;
|
|
|
|
|
+import com.alibaba.fastjson.JSONObject;
|
|
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
|
|
+
|
|
|
|
|
+import java.util.*;
|
|
|
|
|
+import java.util.concurrent.*;
|
|
|
|
|
+import java.util.stream.Collectors;
|
|
|
|
|
+@Service
|
|
|
|
|
+@Slf4j
|
|
|
|
|
+public class AdminAdvertiserListServiceImpl implements IAdminAdvertiserListService {
|
|
|
|
|
+
|
|
|
|
|
+ @Autowired
|
|
|
|
|
+ private AdminAdvertiserListMapper adminAdvertiserListMapper;
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public JSONObject bytedanceAdvertiserThreadPool(Integer totalPage, Integer pageSize, Long adminAdvertiserId, Long ccAccountId, String accessToken) {
|
|
|
|
|
+ ExecutorService executor = Executors.newFixedThreadPool(15);
|
|
|
|
|
+ // 3. 创建线程安全的结果收集器
|
|
|
|
|
+ List<Future<AdminAdvertiserListServiceImpl.PageResult>> futures = new ArrayList<>();
|
|
|
|
|
+
|
|
|
|
|
+ // 4. 提交分页任务
|
|
|
|
|
+ for (int page = 1; page <= totalPage; page++) {
|
|
|
|
|
+ final int currentPage = page;
|
|
|
|
|
+ Callable<AdminAdvertiserListServiceImpl.PageResult> task = () -> {
|
|
|
|
|
+ try {
|
|
|
|
|
+ List<String> bytedanceAccountList = getBytedanceAccountList(adminAdvertiserId, ccAccountId, accessToken, currentPage, 100, 1);
|
|
|
|
|
+ return new AdminAdvertiserListServiceImpl.PageResult(currentPage, bytedanceAccountList);
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ e.printStackTrace();
|
|
|
|
|
+ return new AdminAdvertiserListServiceImpl.PageResult(currentPage, Collections.emptyList());
|
|
|
|
|
+ }
|
|
|
|
|
+ };
|
|
|
|
|
+ futures.add(executor.submit(task));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 5. 处理结果
|
|
|
|
|
+ List<AdminAdvertiserListServiceImpl.PageResult> results = new ArrayList<>();
|
|
|
|
|
+ for (Future<AdminAdvertiserListServiceImpl.PageResult> future : futures) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ results.add(future.get());
|
|
|
|
|
+ } catch (InterruptedException | ExecutionException e) {
|
|
|
|
|
+ e.printStackTrace();
|
|
|
|
|
+ log.error("多线程请求数据失败:" + e.getMessage());
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 6. 关闭线程池
|
|
|
|
|
+ executor.shutdown();
|
|
|
|
|
+ try {
|
|
|
|
|
+ executor.awaitTermination(1, TimeUnit.MINUTES);
|
|
|
|
|
+ } catch (InterruptedException e) {
|
|
|
|
|
+ throw new RuntimeException(e);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 7. 排序并合并结果
|
|
|
|
|
+ results.sort(Comparator.comparingInt(AdminAdvertiserListServiceImpl.PageResult::getPageNumber));
|
|
|
|
|
+ List<String> finalData = results.stream()
|
|
|
|
|
+ .flatMap(r -> r.getData().stream())
|
|
|
|
|
+ .collect(Collectors.toList());
|
|
|
|
|
+
|
|
|
|
|
+ JSONObject returnJson = new JSONObject();
|
|
|
|
|
+ returnJson.put("code", 200);
|
|
|
|
|
+ returnJson.put("total", finalData.size());
|
|
|
|
|
+ returnJson.put("message", "多线程请求字节账户列表成功");
|
|
|
|
|
+ return returnJson;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public JSONObject getBytedanceAccountListTotal(Long adminAdvertiserId, Long ccAccountId, String accessToken, Integer page, Integer pageSize) {
|
|
|
|
|
+ JSONObject returnJson = new JSONObject();
|
|
|
|
|
+ Integer totalPage = 0;
|
|
|
|
|
+ Map<String, Object> paramsMap = new HashMap<>();
|
|
|
|
|
+ paramsMap.put("cc_account_id", ccAccountId);
|
|
|
|
|
+ paramsMap.put("page", page);
|
|
|
|
|
+ paramsMap.put("page_size", pageSize);
|
|
|
|
|
+ Map<String, String> headers = new HashMap<>();
|
|
|
|
|
+ headers.put("Access-Token", accessToken);
|
|
|
|
|
+ String s = HttpUtils.httpGet("https://ad.oceanengine.com/open_api/2/customer_center/advertiser/list/", paramsMap, headers);
|
|
|
|
|
+ JSONObject jsonObject = JSONObject.parseObject(s);
|
|
|
|
|
+ Integer code = jsonObject.getInteger("code");
|
|
|
|
|
+ List<BytedanceAdvertiserList> advertiserLists = new ArrayList<>();
|
|
|
|
|
+ if (code == 0) {
|
|
|
|
|
+ JSONObject data = jsonObject.getJSONObject("data");
|
|
|
|
|
+ if (!Check.isNull(data)) {
|
|
|
|
|
+ JSONObject pageInfo = data.getJSONObject("page_info");
|
|
|
|
|
+ if (!Check.isNull(pageInfo)) {
|
|
|
|
|
+ totalPage = pageInfo.getInteger("total_page");
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+ returnJson.put("totalPage", totalPage);
|
|
|
|
|
+ return returnJson;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 分页结果包装类
|
|
|
|
|
+ static class PageResult {
|
|
|
|
|
+ private final int pageNumber;
|
|
|
|
|
+ private final List<String> data;
|
|
|
|
|
+
|
|
|
|
|
+ public PageResult(int pageNumber, List<String> data) {
|
|
|
|
|
+ this.pageNumber = pageNumber;
|
|
|
|
|
+ this.data = data;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public int getPageNumber() {
|
|
|
|
|
+ return pageNumber;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public List<String> getData() {
|
|
|
|
|
+ return data;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ private List<String> getBytedanceAccountList(Long adminAdvertiserId, Long ccAccountId, String accessToken, Integer page, Integer pageSize, Integer requestCount) {
|
|
|
|
|
+ if (requestCount > 3) {
|
|
|
|
|
+ log.error("重试次数大于3次,跳出本页数据请求任务,adminAdvertiserId:{}", adminAdvertiserId);
|
|
|
|
|
+ List<String> data = new ArrayList<>();
|
|
|
|
|
+ data.add("page:" + page);
|
|
|
|
|
+ return data;
|
|
|
|
|
+ }
|
|
|
|
|
+ Map<String, Object> paramsMap = new HashMap<>();
|
|
|
|
|
+ paramsMap.put("cc_account_id", ccAccountId);
|
|
|
|
|
+ paramsMap.put("page", page);
|
|
|
|
|
+ paramsMap.put("page_size", pageSize);
|
|
|
|
|
+ Map<String, String> headers = new HashMap<>();
|
|
|
|
|
+ headers.put("Access-Token", accessToken);
|
|
|
|
|
+ String s = HttpUtils.httpGet("https://ad.oceanengine.com/open_api/2/customer_center/advertiser/list/", paramsMap, headers);
|
|
|
|
|
+ JSONObject jsonObject = JSONObject.parseObject(s);
|
|
|
|
|
+ Integer code = jsonObject.getInteger("code");
|
|
|
|
|
+ List<BytedanceAdvertiserList> advertiserLists = new ArrayList<>();
|
|
|
|
|
+ if (code == 0) {
|
|
|
|
|
+ JSONObject data = jsonObject.getJSONObject("data");
|
|
|
|
|
+ if (!Check.isNull(data)) {
|
|
|
|
|
+ JSONArray list = data.getJSONArray("list");
|
|
|
|
|
+ if (!Check.isNull(list)) {
|
|
|
|
|
+ for (int i = 0; i < list.size(); i++) {
|
|
|
|
|
+ BytedanceAdvertiserList advertiserList = new BytedanceAdvertiserList();
|
|
|
|
|
+ JSONObject advertiserInfo = list.getJSONObject(i);
|
|
|
|
|
+ advertiserList.setAdminAdvertiserId(adminAdvertiserId);
|
|
|
|
|
+ advertiserList.setAdvertiserId(advertiserInfo.getLong("advertiser_id"));
|
|
|
|
|
+ advertiserList.setAdvertiserName(advertiserInfo.getString("advertiser_name"));
|
|
|
|
|
+ advertiserList.setAdvertiserType(advertiserInfo.getString("advertiser_type"));
|
|
|
|
|
+ advertiserLists.add(advertiserList);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ log.error("请求字节账户列表失败,进入重试任务,当前请求次数:{}", requestCount);
|
|
|
|
|
+ getBytedanceAccountList(adminAdvertiserId, ccAccountId, accessToken, page, pageSize, requestCount + 1);
|
|
|
|
|
+ }
|
|
|
|
|
+ if (!Check.isNull(advertiserLists)) {
|
|
|
|
|
+ adminAdvertiserListMapper.replaceBytedanceAdvertiserLists(advertiserLists);
|
|
|
|
|
+ log.info("字节账户数据插入成功,当前页数:{},数据条数:{}", page, advertiserLists.size());
|
|
|
|
|
+ }
|
|
|
|
|
+ List<String> data = new ArrayList<>();
|
|
|
|
|
+ data.add("page:" + page);
|
|
|
|
|
+ return data;
|
|
|
|
|
+ }
|
|
|
|
|
+}
|