yumeng 3 週間 前
親
コミット
bd71b54780

+ 6 - 5
nj_job-bytedance/src/main/java/cn/com/ctop/job/bytedance/data/service/IAdminAdvertiserListService.java

@@ -5,11 +5,12 @@ import com.alibaba.fastjson.JSONObject;
 import java.util.List;
 
 public interface IAdminAdvertiserListService {
-    JSONObject bytedanceAdvertiserThreadPool(Integer totalPage, Integer pageSize, Long adminAdvertiserId, Long ccAccountId, String accessToken);
-
-    void clearAdminAdvertiserList(Long adminAdvertiserId);
-
-    JSONObject getBytedanceAccountListTotal(Long advertiserId, Long advertiserId1, String accessToken, Integer pageNum, Integer pageSize);
+    /**
+     * 与字节授权回调同口径的全量同步:先经 oauth2/advertiser/get 展开授权主体下全部
+     * 纵横管家/操作员组织,再按 account_source=AD 分页拉取组织内投放账户,
+     * 全部成功才清理该管家名下不在列表中的存量账户
+     */
+    JSONObject bytedanceAdvertiserSync(Long adminAdvertiserId, String accessToken);
 
     List<JSONObject> getAdvertiserInfos();
 

+ 254 - 126
nj_job-bytedance/src/main/java/cn/com/ctop/job/bytedance/data/service/impl/AdminAdvertiserListServiceImpl.java

@@ -14,7 +14,6 @@ import org.springframework.stereotype.Service;
 
 import java.util.*;
 import java.util.concurrent.*;
-import java.util.stream.Collectors;
 
 @Service
 @Slf4j
@@ -23,102 +22,247 @@ public class AdminAdvertiserListServiceImpl implements IAdminAdvertiserListServi
     @Autowired
     private AdminAdvertiserListMapper adminAdvertiserListMapper;
 
+    private static final String OAUTH2_ADVERTISER_GET_URL = "https://ad.oceanengine.com/open_api/oauth2/advertiser/get/";
+    private static final String CC_ADVERTISER_LIST_URL = "https://ad.oceanengine.com/open_api/2/customer_center/advertiser/list/";
+    private static final int CC_PAGE_RETRY_LIMIT = 3;
+
     @Override
-    public JSONObject bytedanceAdvertiserThreadPool(Integer totalPage, Integer pageSize, Long adminAdvertiserId, Long ccAccountId, String accessToken) {
-        ExecutorService executor = Executors.newFixedThreadPool(5);
-        // 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<Long> bytedanceAccountList = getBytedanceAccountList(adminAdvertiserId, ccAccountId, accessToken, currentPage, 100, 1);
-                    // 拉取失败(含重试超限)返回 null,该页视为失败
-                    return new AdminAdvertiserListServiceImpl.PageResult(currentPage, bytedanceAccountList);
-                } catch (Exception e) {
-                    e.printStackTrace();
-                    return new AdminAdvertiserListServiceImpl.PageResult(currentPage, null);
-                }
-            };
-            futures.add(executor.submit(task));
+    public JSONObject bytedanceAdvertiserSync(Long adminAdvertiserId, String accessToken) {
+        JSONObject returnJson = new JSONObject();
+        // 1. 拉授权主体列表,确定要展开的组织集合(与字节授权回调同口径)
+        JSONObject authResult = getBytedanceAuthAdvertisers(accessToken);
+        Integer authCode = authResult.getInteger("code");
+        if (authCode == null || authCode != 0) {
+            returnJson.put("code", 500);
+            returnJson.put("message", "获取字节授权主体列表失败,跳过本次同步");
+            return returnJson;
+        }
+        Long oauthAdminAdvertiserId = authResult.getLong("adminAdvertiserId");
+        if (oauthAdminAdvertiserId == null) {
+            returnJson.put("code", 500);
+            returnJson.put("message", "授权主体中未获取到CUSTOMER_ADMIN纵横管家,跳过本次同步");
+            return returnJson;
+        }
+        if (!oauthAdminAdvertiserId.equals(adminAdvertiserId)) {
+            log.error("入参管家{}与授权主体CUSTOMER_ADMIN{}不一致,跳过本次同步,请检查XXL任务参数", adminAdvertiserId, oauthAdminAdvertiserId);
+            returnJson.put("code", 500);
+            returnJson.put("message", "入参管家与授权主体CUSTOMER_ADMIN不一致,跳过本次同步");
+            return returnJson;
+        }
+        List<Long> customerAccounts = authResult.getJSONArray("customerAccounts").toJavaList(Long.class);
+        List<BytedanceAdvertiserList> normalAccounts = authResult.getJSONArray("normalAccounts")
+                .toJavaList(BytedanceAdvertiserList.class);
+        log.info("授权主体下纵横管家/操作员数:{},NORMAL投放主体数:{},adminAdvertiserId:{}",
+                customerAccounts.size(), normalAccounts.size(), adminAdvertiserId);
+
+        // 2. 串行拉各组织第 1 页确定总页数(每组织仅 1 次请求,代价可忽略)
+        int pageSize = 100;
+        List<CcOrgFetchPlan> plans = new ArrayList<>();
+        boolean allSuccess = true;
+        for (Long ccAccountId : customerAccounts) {
+            CcPageResult firstPage = fetchCcAdvertiserPageWithRetry(adminAdvertiserId, ccAccountId, accessToken, 1, pageSize);
+            if (firstPage == null) {
+                // 组织首页拉取失败时账户集合不完整,本次不做失效清理,避免误删
+                log.warn("纵横组织首页拉取失败,该组织本次跳过:ccAccountId={}", ccAccountId);
+                allSuccess = false;
+                continue;
+            }
+            plans.add(new CcOrgFetchPlan(ccAccountId, Math.max(firstPage.getTotalPage(), 1), firstPage.getIds()));
         }
 
-        // 5. 处理结果
-        List<AdminAdvertiserListServiceImpl.PageResult> results = new ArrayList<>();
-        for (Future<AdminAdvertiserListServiceImpl.PageResult> future : futures) {
+        // 3. 全部组织的其余分页提交线程池并行拉取
+        ExecutorService executor = Executors.newFixedThreadPool(10);
+        List<Future<CcPageResult>> futures = new ArrayList<>();
+        for (CcOrgFetchPlan plan : plans) {
+            for (int page = 2; page <= plan.getTotalPage(); page++) {
+                final int currentPage = page;
+                futures.add(executor.submit(() -> fetchCcAdvertiserPageWithRetry(adminAdvertiserId, plan.getCcAccountId(), accessToken, currentPage, pageSize)));
+            }
+        }
+        Map<Long, Map<Integer, List<Long>>> idsByOrgPage = new HashMap<>();
+        for (Future<CcPageResult> future : futures) {
             try {
-                results.add(future.get());
+                CcPageResult result = future.get();
+                if (result == null || result.getIds() == null) {
+                    allSuccess = false;
+                    continue;
+                }
+                idsByOrgPage.computeIfAbsent(result.getCcAccountId(), key -> new HashMap<>()).put(result.getPageNumber(), result.getIds());
             } catch (InterruptedException | ExecutionException e) {
-                e.printStackTrace();
-                log.error("多线程请求数据失败:" + e.getMessage());
+                allSuccess = false;
+                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<Long> finalData = results.stream()
-                .filter(r -> r.getData() != null)
-                .flatMap(r -> r.getData().stream())
-                .collect(Collectors.toList());
+        // 4. 按组织顺序、页序合并,多组织账户取并集
+        Set<Long> mergedIds = new LinkedHashSet<>();
+        for (CcOrgFetchPlan plan : plans) {
+            mergedIds.addAll(plan.getFirstPageIds());
+            Map<Integer, List<Long>> orgPages = idsByOrgPage.getOrDefault(plan.getCcAccountId(), Collections.emptyMap());
+            for (int page = 2; page <= plan.getTotalPage(); page++) {
+                List<Long> ids = orgPages.get(page);
+                if (ids != null) {
+                    mergedIds.addAll(ids);
+                }
+            }
+        }
+        // 授权主体自身的NORMAL投放账户并入(与字节授权回调同口径:自营企业号也是投放主体)
+        for (BytedanceAdvertiserList normalAccount : normalAccounts) {
+            mergedIds.add(normalAccount.getAdvertiserId());
+        }
+        if (!normalAccounts.isEmpty()) {
+            adminAdvertiserListMapper.replaceBytedanceAdvertiserLists(normalAccounts);
+        }
 
-        JSONObject returnJson = new JSONObject();
-        returnJson.put("code", 200);
-        returnJson.put("total", finalData.size());
-        returnJson.put("message", "多线程请求字节账户列表成功");
-        // 全量同步:所有分页均拉取成功时,删除该管家下已不在账户列表中的存量账户;任一分页失败则跳过,防止误删
-        boolean allSuccess = results.stream().allMatch(r -> r.getData() != null);
-        if (allSuccess && !finalData.isEmpty()) {
-            adminAdvertiserListMapper.deleteNotInAdvertiserList(adminAdvertiserId, finalData);
-            returnJson.put("message", "多线程请求字节账户列表成功,已同步删除过期账户");
-        } else if (!allSuccess) {
-            returnJson.put("code", 500);
-            returnJson.put("message", "存在拉取失败分页,跳过本次存量账户清理");
+        // 5. 全量同步:所有组织分页均拉取成功才清理存量;任一分页失败则跳过,防止误删
+        if (allSuccess) {
+            if (mergedIds.isEmpty()) {
+                // 全部组织确认已无账户,按全量同步语义清空该管家存量账户
+                adminAdvertiserListMapper.deleteNotInAdvertiserList(adminAdvertiserId, null);
+            } else {
+                adminAdvertiserListMapper.deleteNotInAdvertiserList(adminAdvertiserId, new ArrayList<>(mergedIds));
+            }
         }
+        returnJson.put("code", allSuccess ? 200 : 500);
+        returnJson.put("total", mergedIds.size());
+        returnJson.put("message", allSuccess ? "全量同步成功,已同步删除过期账户" : "存在拉取失败分页,跳过本次存量账户清理");
         return returnJson;
     }
 
-    @Override
-    public void clearAdminAdvertiserList(Long adminAdvertiserId) {
-        adminAdvertiserListMapper.deleteNotInAdvertiserList(adminAdvertiserId, null);
+    /**
+     * 拉取字节授权主体列表(oauth2/advertiser/get),返回:
+     * code            接口返回码;
+     * adminAdvertiserId  CUSTOMER_ADMIN 纵横管家(归属管家,与字节授权回调一致取最后一个);
+     * customerAccounts   CUSTOMER_ADMIN/CUSTOMER_OPERATOR 去重后的组织账户ID列表;
+     * normalAccounts     NORMAL 角色投放主体(自营企业号)
+     */
+    private JSONObject getBytedanceAuthAdvertisers(String accessToken) {
+        JSONObject result = new JSONObject();
+        Map<String, Object> paramsMap = new HashMap<>();
+        paramsMap.put("access_token", accessToken);
+        String s = HttpUtils.httpGet(OAUTH2_ADVERTISER_GET_URL, paramsMap, null);
+        JSONObject jsonObject = JSONObject.parseObject(s);
+        Integer code = Check.isNull(jsonObject) ? null : jsonObject.getInteger("code");
+        result.put("code", code);
+        if (code == null || code != 0) {
+            log.error("获取字节授权主体列表失败: {}", jsonObject);
+            return result;
+        }
+        Long adminAdvertiserId = null;
+        List<Long> customerAccounts = new ArrayList<>();
+        Set<Long> customerAccountSeen = new HashSet<>();
+        List<JSONObject> normalNodes = new ArrayList<>();
+        JSONObject data = jsonObject.getJSONObject("data");
+        JSONArray advertisers = Check.isNull(data) ? null : data.getJSONArray("list");
+        if (!Check.isNull(advertisers)) {
+            for (int i = 0; i < advertisers.size(); i++) {
+                JSONObject advertiser = advertisers.getJSONObject(i);
+                Long advertiserId = advertiser.getLong("advertiser_id");
+                String accountRole = advertiser.getString("account_role");
+                if (advertiserId == null) {
+                    continue;
+                }
+                // 与字节授权回调同口径:CUSTOMER_ADMIN/CUSTOMER_OPERATOR 作为纵横管家展开组织
+                if ("CUSTOMER_ADMIN".equals(accountRole)) {
+                    adminAdvertiserId = advertiserId;
+                }
+                if ("CUSTOMER_ADMIN".equals(accountRole) || "CUSTOMER_OPERATOR".equals(accountRole)) {
+                    if (customerAccountSeen.add(advertiserId)) {
+                        customerAccounts.add(advertiserId);
+                    }
+                } else if ("NORMAL".equals(accountRole)) {
+                    normalNodes.add(advertiser);
+                }
+            }
+        }
+        // 归属管家确定后再组装NORMAL账户,避免授权主体列表中NORMAL排在CUSTOMER_ADMIN之前时归属为空
+        List<BytedanceAdvertiserList> normalAccounts = new ArrayList<>();
+        for (JSONObject normalNode : normalNodes) {
+            BytedanceAdvertiserList normalAccount = new BytedanceAdvertiserList();
+            normalAccount.setAdminAdvertiserId(adminAdvertiserId);
+            normalAccount.setAdvertiserId(normalNode.getLong("advertiser_id"));
+            normalAccount.setAdvertiserName(normalNode.getString("advertiser_name"));
+            normalAccount.setAdvertiserType(normalNode.getString("account_role"));
+            normalAccounts.add(normalAccount);
+        }
+        result.put("adminAdvertiserId", adminAdvertiserId);
+        result.put("customerAccounts", customerAccounts);
+        result.put("normalAccounts", normalAccounts);
+        return result;
     }
 
-    @Override
-    public JSONObject getBytedanceAccountListTotal(Long adminAdvertiserId, Long ccAccountId, String accessToken, Integer page, Integer pageSize) {
-        JSONObject returnJson = new JSONObject();
-        Integer totalPage = 0;
+    /**
+     * 拉取纵横组织单页(最多重试 CC_PAGE_RETRY_LIMIT 次),成功返回分页结果,失败返回 null
+     */
+    private CcPageResult fetchCcAdvertiserPageWithRetry(Long adminAdvertiserId, Long ccAccountId, String accessToken, int page, int pageSize) {
+        CcPageResult result = null;
+        int attempt = 0;
+        while (result == null && attempt < CC_PAGE_RETRY_LIMIT) {
+            attempt++;
+            try {
+                result = fetchCcAdvertiserPage(adminAdvertiserId, ccAccountId, accessToken, page, pageSize);
+            } catch (Exception e) {
+                log.error("请求字节纵横组织账户第{}页异常,ccAccountId:{},第{}次尝试", page, ccAccountId, attempt, e);
+            }
+        }
+        return result;
+    }
+
+    /**
+     * 拉取纵横组织单页(account_source=AD,与字节授权回调同口径),成功分页结果入库并返回,失败返回 null
+     */
+    private CcPageResult fetchCcAdvertiserPage(Long adminAdvertiserId, Long ccAccountId, String accessToken, int page, int pageSize) {
+        try {
+            Thread.sleep(100L);
+        } catch (InterruptedException e) {
+            Thread.currentThread().interrupt();
+            return null;
+        }
         Map<String, Object> paramsMap = new HashMap<>();
         paramsMap.put("cc_account_id", ccAccountId);
         paramsMap.put("page", page);
         paramsMap.put("page_size", pageSize);
+        paramsMap.put("account_source", "AD");
         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);
+        String s = HttpUtils.httpGet(CC_ADVERTISER_LIST_URL, paramsMap, headers);
         JSONObject jsonObject = JSONObject.parseObject(s);
         Integer code = Check.isNull(jsonObject) ? null : jsonObject.getInteger("code");
+        if (code == null || code != 0) {
+            log.error("请求字节纵横组织账户列表失败,ccAccountId:{},page:{},code:{},返回信息:{}", ccAccountId, page, code, jsonObject);
+            return null;
+        }
+        JSONObject data = jsonObject.getJSONObject("data");
+        if (Check.isNull(data)) {
+            return new CcPageResult(ccAccountId, page, 0, new ArrayList<>());
+        }
+        int totalPage = 0;
+        JSONObject pageInfo = data.getJSONObject("page_info");
+        if (!Check.isNull(pageInfo) && pageInfo.getInteger("total_page") != null) {
+            totalPage = pageInfo.getInteger("total_page");
+        }
         List<BytedanceAdvertiserList> advertiserLists = new ArrayList<>();
-        if (code != null && 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");
-                }
+        JSONArray list = data.getJSONArray("list");
+        if (!Check.isNull(list)) {
+            for (int i = 0; i < list.size(); i++) {
+                JSONObject advertiserInfo = list.getJSONObject(i);
+                BytedanceAdvertiserList advertiserList = new BytedanceAdvertiserList();
+                advertiserList.setAdminAdvertiserId(adminAdvertiserId);
+                advertiserList.setAdvertiserId(advertiserInfo.getLong("advertiser_id"));
+                advertiserList.setAdvertiserName(advertiserInfo.getString("advertiser_name"));
+                advertiserList.setAdvertiserType(advertiserInfo.getString("advertiser_type"));
+                advertiserLists.add(advertiserList);
             }
-
         }
-        returnJson.put("totalPage", totalPage);
-        returnJson.put("code", code);
-        return returnJson;
+        if (!advertiserLists.isEmpty()) {
+            adminAdvertiserListMapper.replaceBytedanceAdvertiserLists(advertiserLists);
+        }
+        List<Long> ids = new ArrayList<>();
+        for (BytedanceAdvertiserList advertiserList : advertiserLists) {
+            ids.add(advertiserList.getAdvertiserId());
+        }
+        return new CcPageResult(ccAccountId, page, totalPage, ids);
     }
 
     @Override
@@ -193,75 +337,59 @@ public class AdminAdvertiserListServiceImpl implements IAdminAdvertiserListServi
         return adminAdvertiserListMapper.getNotAgentAdvertiserList();
     }
 
-    // 分页结果包装类
-    static class PageResult {
-        private final int pageNumber;
-        private final List<Long> data;
+    // 组织拉取计划:第 1 页已解析账户ID + 总页数
+    static class CcOrgFetchPlan {
+        private final Long ccAccountId;
+        private final int totalPage;
+        private final List<Long> firstPageIds;
 
-        public PageResult(int pageNumber, List<Long> data) {
-            this.pageNumber = pageNumber;
-            this.data = data;
+        CcOrgFetchPlan(Long ccAccountId, int totalPage, List<Long> firstPageIds) {
+            this.ccAccountId = ccAccountId;
+            this.totalPage = totalPage;
+            this.firstPageIds = firstPageIds;
         }
 
-        public int getPageNumber() {
-            return pageNumber;
+        public Long getCcAccountId() {
+            return ccAccountId;
         }
 
-        public List<Long> getData() {
-            return data;
+        public int getTotalPage() {
+            return totalPage;
+        }
+
+        public List<Long> getFirstPageIds() {
+            return firstPageIds;
         }
     }
 
+    // 单页拉取结果:ids 为 null 表示重试后仍失败
+    static class CcPageResult {
+        private final Long ccAccountId;
+        private final int pageNumber;
+        private final int totalPage;
+        private final List<Long> ids;
 
-    private List<Long> getBytedanceAccountList(Long adminAdvertiserId, Long ccAccountId, String accessToken, Integer page, Integer pageSize, Integer requestCount) throws InterruptedException {
-        try {
-            Thread.sleep(100);
-        } catch (InterruptedException e) {
-            throw new RuntimeException(e);
+        CcPageResult(Long ccAccountId, int pageNumber, int totalPage, List<Long> ids) {
+            this.ccAccountId = ccAccountId;
+            this.pageNumber = pageNumber;
+            this.totalPage = totalPage;
+            this.ids = ids;
         }
-        if (requestCount > 3) {
-            log.error("重试次数大于3次,跳出本页数据请求任务,adminAdvertiserId:{}", adminAdvertiserId);
-            return null;
+
+        public Long getCcAccountId() {
+            return ccAccountId;
         }
-        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 = Check.isNull(jsonObject) ? null : jsonObject.getInteger("code");
-        List<BytedanceAdvertiserList> advertiserLists = new ArrayList<>();
-        if (code != null && 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);
-            Thread.sleep(1000);
-            return getBytedanceAccountList(adminAdvertiserId, ccAccountId, accessToken, page, pageSize, requestCount + 1);
+
+        public int getPageNumber() {
+            return pageNumber;
         }
-        if (!Check.isNull(advertiserLists)) {
-            adminAdvertiserListMapper.replaceBytedanceAdvertiserLists(advertiserLists);
-            log.info("字节账户数据插入成功,当前页数:{},数据条数:{}", page, advertiserLists.size());
+
+        public int getTotalPage() {
+            return totalPage;
         }
-        List<Long> data = new ArrayList<>();
-        for (BytedanceAdvertiserList advertiserList : advertiserLists) {
-            data.add(advertiserList.getAdvertiserId());
+
+        public List<Long> getIds() {
+            return ids;
         }
-        return data;
     }
 }

+ 2 - 19
nj_job-bytedance/src/main/java/cn/com/ctop/job/bytedance/handler/AdminAdvertiserListJob.java

@@ -37,29 +37,12 @@ public class AdminAdvertiserListJob {
         String[] s = param.split("_");
         Long advertiserId = Long.valueOf(s[0]);
         String accessToken = s[1];
-        Integer pageSize = 100;
         adminService.submit(new Runnable() {
             @Override
             public void run() {
                 log.info("刷新管家账户下账户列表开始,AdminAdvertiserId:{}", advertiserId);
-                JSONObject totalJson = adminAdvertiserListService.getBytedanceAccountListTotal(advertiserId, advertiserId, accessToken, 1, pageSize);
-                if (!Check.isNull(totalJson)) {
-                    Integer totalPage = totalJson.getInteger("totalPage");
-                    Integer code = totalJson.getInteger("code");
-                    log.info("管家账户ID:{},总页数:{},接口返回码:{}", advertiserId, totalPage, code);
-                    if (code != null && code == 0) {
-                        if (totalPage != 0) {
-                            JSONObject result = adminAdvertiserListService.bytedanceAdvertiserThreadPool(totalPage, pageSize, advertiserId, advertiserId, accessToken);
-                            log.info("字节多线程获取账户返回结果:{}", result);
-                        } else {
-                            // 接口确认该管家账户下已无账户,按全量同步语义清空其存量账户
-                            adminAdvertiserListService.clearAdminAdvertiserList(advertiserId);
-                            log.info("管家账户ID:{},账户数已为0,已清空该管家存量账户", advertiserId);
-                        }
-                    } else {
-                        log.error("管家账户ID:{},获取账户列表失败,接口返回码:{},跳过本次同步", advertiserId, code);
-                    }
-                }
+                JSONObject result = adminAdvertiserListService.bytedanceAdvertiserSync(advertiserId, accessToken);
+                log.info("管家账户ID:{},账户全量同步结果:{}", advertiserId, result);
             }
         });