Prechádzať zdrojové kódy

Merge branch 'master' into test

# Conflicts:
#	jeecg-boot-base-common/src/main/java/org/jeecg/common/util/DateUtils.java
yumeng 5 rokov pred
rodič
commit
23fef04c34
46 zmenil súbory, kde vykonal 2255 pridanie a 698 odobranie
  1. 94 4
      jeecg-boot-base-common/src/main/java/org/jeecg/common/util/DateUtils.java
  2. 2 2
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/controller/EduLessonController.java
  3. 250 0
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/controller/EduLessonNewController.java
  4. 34 33
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/controller/KuaishouAgentAccountController.java
  5. 100 0
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/entity/EduLessonNew.java
  6. 10 1
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/job/BytedancePlanHourlyReportLoadJob.java
  7. 15 0
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/mapper/EduLessonNewMapper.java
  8. 5 0
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/mapper/xml/EduLessonNewMapper.xml
  9. 15 0
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/service/IEduLessonNewService.java
  10. 19 0
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/service/impl/EduLessonNewServiceImpl.java
  11. 1 0
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/service/impl/RefreshTokenServiceImpl.java
  12. 3 2
      module-common/src/main/java/cn/com/ctop/common/module/mapper/xml/CtopOauthTokenMapper.xml
  13. 4 0
      module-common/src/main/java/cn/com/ctop/common/module/utils/CtopAdConstant.java
  14. 5 0
      module-common/src/main/java/cn/com/ctop/common/module/utils/KuaishouInterfaceConstant.java
  15. 254 0
      module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/batch/controller/KuaishouAccountBudgetController.java
  16. 53 0
      module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/batch/entity/KuaishouAccountBudget.java
  17. 17 0
      module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/batch/mapper/KuaishouAccountBudgetMapper.java
  18. 5 0
      module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/batch/mapper/xml/KuaishouAccountBudgetMapper.xml
  19. 23 0
      module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/batch/service/IKuaishouAccountBudgetService.java
  20. 85 0
      module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/batch/service/impl/KuaishouAccountBudgetServiceImpl.java
  21. 168 0
      module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/batch/vue/KuaishouAccountBudgetList.vue
  22. 5 7
      module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/report/entity/KuaishouAgentAccount.java
  23. 96 13
      module-report/src/main/java/cn/com/ctop/bytedance/controller/BytedanceReportController.java
  24. 242 0
      module-report/src/main/java/cn/com/ctop/bytedance/controller/BytedanceReportMaterialRetryController.java
  25. 15 31
      module-report/src/main/java/cn/com/ctop/bytedance/controller/ReportController.java
  26. 6 0
      module-report/src/main/java/cn/com/ctop/bytedance/entity/BytedanceDailyReportTask.java
  27. 109 6
      module-report/src/main/java/cn/com/ctop/bytedance/entity/BytedanceReportMaterialDaily.java
  28. 62 0
      module-report/src/main/java/cn/com/ctop/bytedance/entity/BytedanceReportMaterialRetry.java
  29. 7 0
      module-report/src/main/java/cn/com/ctop/bytedance/mapper/BytedanceDailyReportTaskMapper.java
  30. 5 0
      module-report/src/main/java/cn/com/ctop/bytedance/mapper/BytedancePlanDailyReportMapper.java
  31. 7 0
      module-report/src/main/java/cn/com/ctop/bytedance/mapper/BytedanceReportMaterialDailyMapper.java
  32. 14 0
      module-report/src/main/java/cn/com/ctop/bytedance/mapper/BytedanceReportMaterialRetryMapper.java
  33. 32 5
      module-report/src/main/java/cn/com/ctop/bytedance/mapper/xml/AccountReportMapper.xml
  34. 108 1
      module-report/src/main/java/cn/com/ctop/bytedance/mapper/xml/BytedanceDailyReportTaskMapper.xml
  35. 41 0
      module-report/src/main/java/cn/com/ctop/bytedance/mapper/xml/BytedanceReportMaterialDailyMapper.xml
  36. 5 0
      module-report/src/main/java/cn/com/ctop/bytedance/mapper/xml/BytedanceReportMaterialRetryMapper.xml
  37. 2 0
      module-report/src/main/java/cn/com/ctop/bytedance/service/IBytedancePlanDailyReportService.java
  38. 14 0
      module-report/src/main/java/cn/com/ctop/bytedance/service/IBytedanceReportMaterialRetryService.java
  39. 7 3
      module-report/src/main/java/cn/com/ctop/bytedance/service/IBytedanceReportService.java
  40. 5 7
      module-report/src/main/java/cn/com/ctop/bytedance/service/IReportService.java
  41. 28 0
      module-report/src/main/java/cn/com/ctop/bytedance/service/impl/AccountReportServiceImpl.java
  42. 6 0
      module-report/src/main/java/cn/com/ctop/bytedance/service/impl/BytedancePlanDailyReportServiceImpl.java
  43. 19 0
      module-report/src/main/java/cn/com/ctop/bytedance/service/impl/BytedanceReportMaterialRetryServiceImpl.java
  44. 143 91
      module-report/src/main/java/cn/com/ctop/bytedance/service/impl/BytedanceReportServiceImpl.java
  45. 108 489
      module-report/src/main/java/cn/com/ctop/bytedance/service/impl/ReportServiceImpl.java
  46. 7 3
      performance-appraisal/src/main/java/cn/com/ctop/performanceappraisal/controller/PerformanceOptimizerController.java

+ 94 - 4
jeecg-boot-base-common/src/main/java/org/jeecg/common/util/DateUtils.java

@@ -777,9 +777,9 @@ public class DateUtils extends PropertyEditorSupport {
         return sdf.format(calendar.getTime());
     }
 
-    public static void main(String[] args) throws ParseException {
-        System.out.println(DateUtils.addDay("2020-01-03", 7));
-    }
+    //public static void main(String[] args) throws ParseException {
+    //    System.out.println(DateUtils.addDay( "2020-01-03",  7));
+    //}
 
     public static Date addDay(Date date, int day) {
         Calendar calendar = Calendar.getInstance();
@@ -1198,7 +1198,97 @@ public class DateUtils extends PropertyEditorSupport {
 
         return resultMap;
     }
-}
 
+    /***
+     * 两日期之间相差天数
+     * @param dateStart
+     * @param dateEnd
+     * @return
+     */
+    public static long getDiscrepantDays(String dateStart, String dateEnd){
+        //设置转换的日期格式
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+
+        //结束时间
+        Date startDate = null;
+        Date endDate = null;
+        try {
+            //开始时间
+            startDate = sdf.parse(dateStart);
+            endDate = sdf.parse(dateEnd);
+        } catch (ParseException e) {
+            e.printStackTrace();
+        }
+
+        //得到相差的天数 betweenDate
+        long betweenDate = (endDate.getTime() - startDate.getTime())/(60*60*24*1000);
+
+        //打印控制台相差的天数
+        System.out.println(betweenDate);
+        return betweenDate;
+    }
+
+    /***
+     * 两个日期之间间隔的月数(不考虑日期的情况)
+     */
+    public static int calDiffMonth(Date start, Date end){
+        GregorianCalendar startCalendar = new GregorianCalendar();
+        startCalendar.setTime(start);
+        GregorianCalendar endCalendar = new GregorianCalendar();
+        endCalendar.setTime(end);
+
+        int startYear=startCalendar.get(Calendar.YEAR);
+        int startMonth=startCalendar.get(Calendar.MONTH)+1;
+        int startDay=startCalendar.get(Calendar.DAY_OF_MONTH);
+        int endYear=endCalendar.get(Calendar.YEAR);
+        int endMonth=endCalendar.get(Calendar.MONTH)+1;
+        int endDay=endCalendar.get(Calendar.DAY_OF_MONTH);
+
+        return (endYear-startYear)*12 + (endMonth - startMonth);
+    }
+
+    public static int getDaysOfMonth(int year, int month) {
+        Calendar calendar = Calendar.getInstance();
+        calendar.set(year, month - 1, 1);
+        return calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
+    }
+
+    public static int getFirstDateOfMonth(int year, int month) {
+        Calendar calendar = Calendar.getInstance();
+        calendar.set(year, month - 1, 1);
+        return calendar.getActualMinimum(Calendar.DAY_OF_MONTH);
+    }
+
+    /**
+     * 获取指定日期下个月的第一天
+     * @param dateStr
+     * @param format
+     * @return
+     */
+    public static Map<String, String> getMaxMinDaysOfAddMonth(String dateStr,String format, int addMonth){
+        SimpleDateFormat sdf = new SimpleDateFormat(format);
+        Map<String, String> dateMap = new HashMap<>();
+        try {
+            Date date = sdf.parse(dateStr);
+            Calendar calendar = Calendar.getInstance();
+            calendar.setTime(date);
+            calendar.add(Calendar.MONTH, addMonth);
+            calendar.set(Calendar.DAY_OF_MONTH,1);
+            dateMap.put("startDate", sdf.format(calendar.getTime()));
+
+            calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DATE));
+            dateMap.put("endDate", sdf.format(calendar.getTime()));
+            return dateMap;
+        } catch (ParseException e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    public static void main(String[] args) throws ParseException {
+        System.out.println(calDiffMonth(DateUtils.parseDate("2019-04-01","yyyy-MM-dd"),new Date()));
+    }
+
+}
 
 

+ 2 - 2
jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/controller/EduLessonController.java

@@ -40,7 +40,7 @@ public class EduLessonController {
     @GetMapping(value = "/system/lesson")
     public Result<List<String>> getSystemLessonList() {
         Result<List<String>> result = new Result<>();
-        List<String> list = eduLessonService.getTitleList("系统操作");
+        List<String> list = eduLessonService.getTitleList("汇创视频培训");
         result.setResult(list);
         result.setSuccess(true);
         return result;
@@ -49,7 +49,7 @@ public class EduLessonController {
     @GetMapping(value = "/system/topic")
     public Result<List<String>> getSystemTopicList(String title) {
         Result<List<String>> result = new Result<>();
-        List<String> list = eduLessonService.getTopicList("系统操作", title);
+        List<String> list = eduLessonService.getTopicList("汇创视频培训", title);
         result.setResult(list);
         result.setSuccess(true);
         return result;

+ 250 - 0
jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/controller/EduLessonNewController.java

@@ -0,0 +1,250 @@
+package org.jeecg.modules.ctop.controller;
+
+import cn.com.ctop.common.module.utils.CtopAdConstant;
+import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.common.aspect.annotation.AutoLog;
+import org.jeecg.common.system.query.QueryGenerator;
+import org.jeecg.common.util.oConvertUtils;
+import org.jeecg.modules.ctop.entity.EduLessonNew;
+import org.jeecg.modules.ctop.service.IEduLessonNewService;
+import org.jeecgframework.poi.excel.ExcelImportUtil;
+import org.jeecgframework.poi.excel.def.NormalExcelConstants;
+import org.jeecgframework.poi.excel.entity.ExportParams;
+import org.jeecgframework.poi.excel.entity.ImportParams;
+import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.multipart.MultipartHttpServletRequest;
+import org.springframework.web.servlet.ModelAndView;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 内部培训视频信息
+ *
+ * @author jeecg-boot
+ * @version V1.0
+ * @date 2020-04-22
+ */
+@Slf4j
+@Api(tags = "内部培训视频信息")
+@RestController
+@RequestMapping("/ctop/eduLessonNew")
+public class EduLessonNewController {
+    @Autowired
+    private IEduLessonNewService eduLessonNewService;
+
+    /**
+     * 分页列表查询
+     *
+     * @param eduLessonNew
+     * @param pageNo
+     * @param pageSize
+     * @param req
+     * @return
+     */
+    @AutoLog(value = "内部培训视频信息-分页列表查询")
+    @ApiOperation(value = "内部培训视频信息-分页列表查询", notes = "内部培训视频信息-分页列表查询")
+    @GetMapping(value = "/list")
+    public Result<IPage<EduLessonNew>> queryPageList(EduLessonNew eduLessonNew,
+                                                     @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
+                                                     @RequestParam(name = "pageSize", defaultValue = "1000") Integer pageSize,
+                                                     HttpServletRequest req) {
+        Result<IPage<EduLessonNew>> result = new Result<>();
+        eduLessonNew.setEnabled(CtopAdConstant.COMMON_STATUS_ENABLED);
+        QueryWrapper<EduLessonNew> queryWrapper = QueryGenerator.initQueryWrapper(eduLessonNew, req.getParameterMap());
+        Page<EduLessonNew> page = new Page<>(pageNo, pageSize);
+        IPage<EduLessonNew> pageList = eduLessonNewService.page(page, queryWrapper);
+        result.setSuccess(true);
+        result.setResult(pageList);
+        return result;
+    }
+
+    /**
+     * 添加
+     *
+     * @param eduLessonNew
+     * @return
+     */
+    @AutoLog(value = "内部培训视频信息-添加")
+    @ApiOperation(value = "内部培训视频信息-添加", notes = "内部培训视频信息-添加")
+    @PostMapping(value = "/add")
+    public Result<EduLessonNew> add(@RequestBody EduLessonNew eduLessonNew) {
+        Result<EduLessonNew> result = new Result<EduLessonNew>();
+        try {
+            eduLessonNewService.save(eduLessonNew);
+            result.success("添加成功!");
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+            result.error500("操作失败");
+        }
+        return result;
+    }
+
+    /**
+     * 编辑
+     *
+     * @param eduLessonNew
+     * @return
+     */
+    @AutoLog(value = "内部培训视频信息-编辑")
+    @ApiOperation(value = "内部培训视频信息-编辑", notes = "内部培训视频信息-编辑")
+    @PutMapping(value = "/edit")
+    public Result<EduLessonNew> edit(@RequestBody EduLessonNew eduLessonNew) {
+        Result<EduLessonNew> result = new Result<EduLessonNew>();
+        EduLessonNew eduLessonNewEntity = eduLessonNewService.getById(eduLessonNew.getId());
+        if (eduLessonNewEntity == null) {
+            result.error500("未找到对应实体");
+        } else {
+            boolean ok = eduLessonNewService.updateById(eduLessonNew);
+            if (ok) {
+                result.success("修改成功!");
+            }
+        }
+
+        return result;
+    }
+
+    /**
+     * 通过id删除
+     *
+     * @param id
+     * @return
+     */
+    @AutoLog(value = "内部培训视频信息-通过id删除")
+    @ApiOperation(value = "内部培训视频信息-通过id删除", notes = "内部培训视频信息-通过id删除")
+    @DeleteMapping(value = "/delete")
+    public Result<?> delete(@RequestParam(name = "id", required = true) String id) {
+        try {
+            eduLessonNewService.removeById(id);
+        } catch (Exception e) {
+            log.error("删除失败", e.getMessage());
+            return Result.error("删除失败!");
+        }
+        return Result.ok("删除成功!");
+    }
+
+    /**
+     * 批量删除
+     *
+     * @param ids
+     * @return
+     */
+    @AutoLog(value = "内部培训视频信息-批量删除")
+    @ApiOperation(value = "内部培训视频信息-批量删除", notes = "内部培训视频信息-批量删除")
+    @DeleteMapping(value = "/deleteBatch")
+    public Result<EduLessonNew> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
+        Result<EduLessonNew> result = new Result<EduLessonNew>();
+        if (ids == null || "".equals(ids.trim())) {
+            result.error500("参数不识别!");
+        } else {
+            this.eduLessonNewService.removeByIds(Arrays.asList(ids.split(",")));
+            result.success("删除成功!");
+        }
+        return result;
+    }
+
+    /**
+     * 通过id查询
+     *
+     * @param id
+     * @return
+     */
+    @AutoLog(value = "内部培训视频信息-通过id查询")
+    @ApiOperation(value = "内部培训视频信息-通过id查询", notes = "内部培训视频信息-通过id查询")
+    @GetMapping(value = "/queryById")
+    public Result<EduLessonNew> queryById(@RequestParam(name = "id", required = true) String id) {
+        Result<EduLessonNew> result = new Result<EduLessonNew>();
+        EduLessonNew eduLessonNew = eduLessonNewService.getById(id);
+        if (eduLessonNew == null) {
+            result.error500("未找到对应实体");
+        } else {
+            result.setResult(eduLessonNew);
+            result.setSuccess(true);
+        }
+        return result;
+    }
+
+    /**
+     * 导出excel
+     *
+     * @param request
+     * @param response
+     */
+    @RequestMapping(value = "/exportXls")
+    public ModelAndView exportXls(HttpServletRequest request, HttpServletResponse response) {
+        // Step.1 组装查询条件
+        QueryWrapper<EduLessonNew> queryWrapper = null;
+        try {
+            String paramsStr = request.getParameter("paramsStr");
+            if (oConvertUtils.isNotEmpty(paramsStr)) {
+                String deString = URLDecoder.decode(paramsStr, "UTF-8");
+                EduLessonNew eduLessonNew = JSON.parseObject(deString, EduLessonNew.class);
+                queryWrapper = QueryGenerator.initQueryWrapper(eduLessonNew, request.getParameterMap());
+            }
+        } catch (UnsupportedEncodingException e) {
+            e.printStackTrace();
+        }
+
+        //Step.2 AutoPoi 导出Excel
+        ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
+        List<EduLessonNew> pageList = eduLessonNewService.list(queryWrapper);
+        //导出文件名称
+        mv.addObject(NormalExcelConstants.FILE_NAME, "内部培训视频信息列表");
+        mv.addObject(NormalExcelConstants.CLASS, EduLessonNew.class);
+        mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("内部培训视频信息列表数据", "导出人:Jeecg", "导出信息"));
+        mv.addObject(NormalExcelConstants.DATA_LIST, pageList);
+        return mv;
+    }
+
+    /**
+     * 通过excel导入数据
+     *
+     * @param request
+     * @param response
+     * @return
+     */
+    @RequestMapping(value = "/importExcel", method = RequestMethod.POST)
+    public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
+        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
+        Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
+        for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
+            MultipartFile file = entity.getValue();
+            ImportParams params = new ImportParams();
+            params.setTitleRows(2);
+            params.setHeadRows(1);
+            params.setNeedSave(true);
+            try {
+                List<EduLessonNew> listEduLessonNews = ExcelImportUtil.importExcel(file.getInputStream(), EduLessonNew.class, params);
+                eduLessonNewService.saveBatch(listEduLessonNews);
+                return Result.ok("文件导入成功!数据行数:" + listEduLessonNews.size());
+            } catch (Exception e) {
+                log.error(e.getMessage(), e);
+                return Result.error("文件导入失败:" + e.getMessage());
+            } finally {
+                try {
+                    file.getInputStream().close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+        return Result.ok("文件导入失败!");
+    }
+
+}

+ 34 - 33
jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/controller/KuaishouAgentAccountController.java

@@ -1,40 +1,40 @@
 package org.jeecg.modules.ctop.controller;
 
-import java.io.OutputStream;
-import java.util.*;
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.net.URLDecoder;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
 import cn.com.ctop.common.module.utils.ExportExcelUtils;
-import org.apache.poi.xssf.usermodel.XSSFWorkbook;
-import org.jeecg.common.api.vo.Result;
-import org.jeecg.common.system.query.QueryGenerator;
-import org.jeecg.common.aspect.annotation.AutoLog;
-import org.jeecg.common.util.oConvertUtils;
 import cn.com.ctop.kuaishou.modules.report.entity.KuaishouAgentAccount;
 import cn.com.ctop.kuaishou.modules.report.service.IKuaishouAgentAccountService;
+import com.alibaba.fastjson.JSON;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
 import lombok.extern.slf4j.Slf4j;
-
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.common.aspect.annotation.AutoLog;
+import org.jeecg.common.system.query.QueryGenerator;
+import org.jeecg.common.util.DateUtils;
+import org.jeecg.common.util.oConvertUtils;
 import org.jeecgframework.poi.excel.ExcelImportUtil;
-import org.jeecgframework.poi.excel.def.NormalExcelConstants;
-import org.jeecgframework.poi.excel.entity.ExportParams;
 import org.jeecgframework.poi.excel.entity.ImportParams;
 import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
-
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.multipart.MultipartFile;
 import org.springframework.web.multipart.MultipartHttpServletRequest;
 import org.springframework.web.servlet.ModelAndView;
-import com.alibaba.fastjson.JSON;
-import io.swagger.annotations.Api;
-import io.swagger.annotations.ApiOperation;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
 
  /**
  * 快手代理商账户表
@@ -49,7 +49,7 @@ import io.swagger.annotations.ApiOperation;
 public class KuaishouAgentAccountController {
 	@Autowired
 	private IKuaishouAgentAccountService kuaishouAgentAccountService;
-	
+
 	/**
 	  * 分页列表查询
 	 * @param kuaishouAgentAccount
@@ -73,7 +73,7 @@ public class KuaishouAgentAccountController {
 		result.setResult(pageList);
 		return result;
 	}
-	
+
 	/**
 	  *   添加
 	 * @param kuaishouAgentAccount
@@ -93,8 +93,8 @@ public class KuaishouAgentAccountController {
 		}
 		return result;
 	}
-	
-	/**
+
+     /**
 	  *  编辑
 	 * @param kuaishouAgentAccount
 	 * @return
@@ -113,11 +113,11 @@ public class KuaishouAgentAccountController {
 				result.success("修改成功!");
 			}
 		}
-		
-		return result;
+
+        return result;
 	}
-	
-	/**
+
+     /**
 	  *   通过id删除
 	 * @param id
 	 * @return
@@ -134,8 +134,8 @@ public class KuaishouAgentAccountController {
 		}
 		return Result.ok("删除成功!");
 	}
-	
-	/**
+
+     /**
 	  *  批量删除
 	 * @param ids
 	 * @return
@@ -153,8 +153,8 @@ public class KuaishouAgentAccountController {
 		}
 		return result;
 	}
-	
-	/**
+
+     /**
 	  * 通过id查询
 	 * @param id
 	 * @return
@@ -212,6 +212,7 @@ public class KuaishouAgentAccountController {
 			rowData.add(kuaishouAgentAccount.getDirectRebate());
 			rowData.add(kuaishouAgentAccount.getTotalBalance());
 			rowData.add(kuaishouAgentAccount.getCorporationName());
+            rowData.add(DateUtils.formatDate(kuaishouAgentAccount.getCreateTime()));
 			if(kuaishouAgentAccount.getReviewStatus() == 1){
 				rowData.add("审核中");
 			}else if(kuaishouAgentAccount.getReviewStatus() == 2){
@@ -222,7 +223,7 @@ public class KuaishouAgentAccountController {
 			result.add(rowData);
 		}
 	  }
-	  String[] accountHeaders = {"广告主ID", "用户ID", "广告主名称", "现金余额", "信用余额", "返点余额", "框返余额", "激励余额", "总余额", "公司名称", "审核状态"};
+      String[] accountHeaders = {"广告主ID", "用户ID", "广告主名称", "现金余额", "信用余额", "返点余额", "框返余额", "激励余额", "总余额", "公司名称", "开户时间", "审核状态"};
 	  OutputStream os = response.getOutputStream();
 	  ExportExcelUtils eeu = new ExportExcelUtils();
 	  XSSFWorkbook workbook = new XSSFWorkbook();

+ 100 - 0
jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/entity/EduLessonNew.java

@@ -0,0 +1,100 @@
+package org.jeecg.modules.ctop.entity;
+
+import cn.com.ctop.common.module.utils.CtopAdConstant;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+import org.jeecgframework.poi.excel.annotation.Excel;
+
+import java.util.Date;
+
+/**
+ * 内部培训视频信息
+ *
+ * @author jeecg-boot
+ * @version V1.0
+ * @date 2020-04-22
+ */
+@Data
+@TableName("ctop_edu_lesson_new")
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value = "ctop_edu_lesson_new对象", description = "内部培训视频信息")
+public class EduLessonNew {
+
+    /**
+     * id
+     */
+    @TableId(type = IdType.UUID)
+    @ApiModelProperty(value = "id")
+    private Integer id;
+    /**
+     * name
+     */
+    @Excel(name = "name", width = 15)
+    @ApiModelProperty(value = "name")
+    private String name;
+    /**
+     * 文件类型
+     */
+    @Excel(name = "文件类型", width = 15)
+    @ApiModelProperty(value = "文件类型")
+    private Integer fileType;
+    /**
+     * 节点类型
+     */
+    @Excel(name = "节点类型", width = 15)
+    @ApiModelProperty(value = "节点类型")
+    private Integer nodeType;
+    /**
+     * 父id
+     */
+    @Excel(name = "父id", width = 15)
+    @ApiModelProperty(value = "父id")
+    private Integer parentId;
+    /**
+     * author
+     */
+    @Excel(name = "author", width = 15)
+    @ApiModelProperty(value = "author")
+    private String author;
+    /**
+     * desc
+     */
+    @Excel(name = "desc", width = 15)
+    @ApiModelProperty(value = "desc")
+    private String desc;
+    /**
+     * fileId
+     */
+    @Excel(name = "fileId", width = 15)
+    @ApiModelProperty(value = "fileId")
+    private String fileId;
+    /**
+     * enabled
+     */
+    @Excel(name = "enabled", width = 15)
+    @ApiModelProperty(value = "enabled")
+    private Integer enabled;
+    /**
+     * createTime
+     */
+    @ApiModelProperty(value = "createTime")
+    private Date createTime;
+    /**
+     * updateTime
+     */
+    @ApiModelProperty(value = "updateTime")
+    private Date updateTime;
+
+    public EduLessonNew() {
+        this.enabled = CtopAdConstant.COMMON_STATUS_ENABLED;
+        this.createTime = new Date();
+        this.updateTime = new Date();
+    }
+}

+ 10 - 1
jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/job/BytedancePlanHourlyReportLoadJob.java

@@ -1,5 +1,6 @@
 package org.jeecg.modules.ctop.job;
 
+import cn.com.ctop.bytedance.service.IBytedancePlanDailyReportService;
 import cn.com.ctop.bytedance.service.IReportService;
 import cn.com.ctop.common.module.entity.CtopOauthToken;
 import cn.com.ctop.common.module.service.ICtopOauthTokenService;
@@ -64,9 +65,17 @@ public class BytedancePlanHourlyReportLoadJob implements Job {
         } catch (InterruptedException e) {
             e.printStackTrace();
         }
-        //清洗玫瑰相亲渠道号数据
+        //清洗缘多多数据渠道号
+        if (null != hour && "00".equals(hour)) {
+            Date lastday = DateUtils.addDay(getDate, -1);
+            planDailyReportService.cleanYddHourlyChannelCode(113, lastday);
+        }
+        planDailyReportService.cleanYddHourlyChannelCode(113, getDate);
 
         log.info("头条计划时报数据获取完成");
         executorService.shutdown();
     }
+
+    @Autowired
+    private IBytedancePlanDailyReportService planDailyReportService;
 }

+ 15 - 0
jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/mapper/EduLessonNewMapper.java

@@ -0,0 +1,15 @@
+package org.jeecg.modules.ctop.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.jeecg.modules.ctop.entity.EduLessonNew;
+
+/**
+ * 内部培训视频信息
+ *
+ * @author: jeecg-boot
+ * @date: 2020-04-22
+ * @cersion: V1.0
+ */
+public interface EduLessonNewMapper extends BaseMapper<EduLessonNew> {
+
+}

+ 5 - 0
jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/mapper/xml/EduLessonNewMapper.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="org.jeecg.modules.ctop.mapper.EduLessonNewMapper">
+
+</mapper>

+ 15 - 0
jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/service/IEduLessonNewService.java

@@ -0,0 +1,15 @@
+package org.jeecg.modules.ctop.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.jeecg.modules.ctop.entity.EduLessonNew;
+
+/**
+ * 内部培训视频信息
+ *
+ * @author jeecg-boot
+ * @version V1.0
+ * @date 2020-04-22
+ */
+public interface IEduLessonNewService extends IService<EduLessonNew> {
+
+}

+ 19 - 0
jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/service/impl/EduLessonNewServiceImpl.java

@@ -0,0 +1,19 @@
+package org.jeecg.modules.ctop.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.jeecg.modules.ctop.entity.EduLessonNew;
+import org.jeecg.modules.ctop.mapper.EduLessonNewMapper;
+import org.jeecg.modules.ctop.service.IEduLessonNewService;
+import org.springframework.stereotype.Service;
+
+/**
+ * 内部培训视频信息
+ *
+ * @author jeecg-boot
+ * @version V1.0
+ * @date 2020-04-22
+ */
+@Service
+public class EduLessonNewServiceImpl extends ServiceImpl<EduLessonNewMapper, EduLessonNew> implements IEduLessonNewService {
+
+}

+ 1 - 0
jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/service/impl/RefreshTokenServiceImpl.java

@@ -31,6 +31,7 @@ public class RefreshTokenServiceImpl implements IRefreshTokenService {
         log.info("需要刷新token列表长度:{}", oauthTokens.size());
         if (!Check.isNull(oauthTokens)) {
             for (CtopOauthToken oauthToken : oauthTokens) {
+                log.info("刷新token,accountId:{}", oauthToken.getAccountId());
                 //头条
                 if (CtopAdConstant.PLATFORM_TYPE_BYTEDANCE.equals(oauthToken.getMediaId().trim())) {
                     oauthTokenService.getByteDanceAccessToken(String.valueOf(oauthToken.getAccountId()));

+ 3 - 2
module-common/src/main/java/cn/com/ctop/common/module/mapper/xml/CtopOauthTokenMapper.xml

@@ -11,12 +11,13 @@
         <result column="refresh_token" property="refreshToken" jdbcType="VARCHAR"/>
         <result column="access_token_expires_in" property="accessTokenExpiresIn" jdbcType="TIMESTAMP"/>
         <result column="refresh_token_expires_in" property="refreshTokenExpiresIn" jdbcType="TIMESTAMP"/>
+        <result column="agent_type" property="agentType" jdbcType="INTEGER"/>
         <result column="create_time" property="createTime" jdbcType="TIMESTAMP"/>
         <result column="update_time" property="updateTime" jdbcType="TIMESTAMP"/>
     </resultMap>
 
     <sql id="Base_Column_List">
-        id,media_id,advertiser_id,account_id,access_token,refresh_token,access_token_expires_in,refresh_token_expires_in,create_time,update_time
+        id,media_id,advertiser_id,account_id,access_token,refresh_token,access_token_expires_in,refresh_token_expires_in,agent_type,create_time,update_time
    </sql>
 
     <select id="selectAll" resultMap="BaseResultMap">
@@ -87,7 +88,7 @@
     </select>
 
     <select id="selectToutiaoToken" resultType="cn.com.ctop.common.module.entity.CtopOauthToken">
-        select  t1.*
+        select t1.*
         from ctop_oauth_token t1
         left join ctop_user_allocation t2
         on t1.account_id = t2.account_id

+ 4 - 0
module-common/src/main/java/cn/com/ctop/common/module/utils/CtopAdConstant.java

@@ -67,4 +67,8 @@ public class CtopAdConstant {
     public static final String BYTEDANCE_GENDER_TYPE_GENDER_MALE = "GENDER_MALE";
     public static final String BYTEDANCE_GENDER_TYPE_GENDER_FEMALE = "GENDER_FEMALE";
 
+
+    public static final Integer COMMON_STATUS_ENABLED = 1;
+
+    public static final Integer COMMON_STATUS_NOT_ENABLED = 0;
 }

+ 5 - 0
module-common/src/main/java/cn/com/ctop/common/module/utils/KuaishouInterfaceConstant.java

@@ -85,6 +85,11 @@ public class KuaishouInterfaceConstant {
     public static final String APP_LIST = "/rest/openapi/v1/file/ad/app/list";
 
     /**
+     * 账户日预算查询
+     */
+    public static final String ACCOUNT_BUDGET = "/rest/openapi/v1/advertiser/budget/get";
+
+    /**
      * 获取账户余额
      */
     public static final String FUND_GET = "/rest/openapi/v1/advertiser/fund/get";

+ 254 - 0
module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/batch/controller/KuaishouAccountBudgetController.java

@@ -0,0 +1,254 @@
+package cn.com.ctop.kuaishou.modules.batch.controller;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import cn.com.ctop.kuaishou.modules.batch.entity.KuaishouAccountBudget;
+import cn.com.ctop.kuaishou.modules.batch.service.IKuaishouAccountBudgetService;
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.common.system.query.QueryGenerator;
+import org.jeecg.common.aspect.annotation.AutoLog;
+import org.jeecg.common.util.oConvertUtils;
+
+import java.util.Date;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import lombok.extern.slf4j.Slf4j;
+
+import org.jeecgframework.poi.excel.ExcelImportUtil;
+import org.jeecgframework.poi.excel.def.NormalExcelConstants;
+import org.jeecgframework.poi.excel.entity.ExportParams;
+import org.jeecgframework.poi.excel.entity.ImportParams;
+import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.multipart.MultipartHttpServletRequest;
+import org.springframework.web.servlet.ModelAndView;
+import com.alibaba.fastjson.JSON;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+
+ /**
+ * 账户日预算
+ * @author jeecg-boot
+ * @date   2020-04-26
+ * @version V1.0
+ */
+@Slf4j
+@Api(tags="账户日预算")
+@RestController
+@RequestMapping("/batch/kuaishouAccountBudget")
+public class KuaishouAccountBudgetController {
+	@Autowired
+	private IKuaishouAccountBudgetService kuaishouAccountBudgetService;
+	
+	/**
+	  * 分页列表查询
+	 * @param kuaishouAccountBudget
+	 * @param pageNo
+	 * @param pageSize
+	 * @param req
+	 * @return
+	 */
+	@AutoLog(value = "账户日预算-分页列表查询")
+	@ApiOperation(value="账户日预算-分页列表查询", notes="账户日预算-分页列表查询")
+	@GetMapping(value = "/list")
+	public Result<IPage<KuaishouAccountBudget>> queryPageList(KuaishouAccountBudget kuaishouAccountBudget,
+															  @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
+															  @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
+															  HttpServletRequest req) {
+		Result<IPage<KuaishouAccountBudget>> result = new Result<IPage<KuaishouAccountBudget>>();
+		QueryWrapper<KuaishouAccountBudget> queryWrapper = QueryGenerator.initQueryWrapper(kuaishouAccountBudget, req.getParameterMap());
+		Page<KuaishouAccountBudget> page = new Page<KuaishouAccountBudget>(pageNo, pageSize);
+		IPage<KuaishouAccountBudget> pageList = kuaishouAccountBudgetService.page(page, queryWrapper);
+		result.setSuccess(true);
+		result.setResult(pageList);
+		return result;
+	}
+	
+	/**
+	  *   添加
+	 * @param kuaishouAccountBudget
+	 * @return
+	 */
+	@AutoLog(value = "账户日预算-添加")
+	@ApiOperation(value="账户日预算-添加", notes="账户日预算-添加")
+	@PostMapping(value = "/add")
+	public Result<KuaishouAccountBudget> add(@RequestBody KuaishouAccountBudget kuaishouAccountBudget) {
+		Result<KuaishouAccountBudget> result = new Result<KuaishouAccountBudget>();
+		try {
+			kuaishouAccountBudgetService.save(kuaishouAccountBudget);
+			result.success("添加成功!");
+		} catch (Exception e) {
+			log.error(e.getMessage(),e);
+			result.error500("操作失败");
+		}
+		return result;
+	}
+	
+	/**
+	  *  编辑
+	 * @param kuaishouAccountBudget
+	 * @return
+	 */
+	@AutoLog(value = "账户日预算-编辑")
+	@ApiOperation(value="账户日预算-编辑", notes="账户日预算-编辑")
+	@PutMapping(value = "/edit")
+	public Result<KuaishouAccountBudget> edit(@RequestBody KuaishouAccountBudget kuaishouAccountBudget) {
+		Result<KuaishouAccountBudget> result = new Result<KuaishouAccountBudget>();
+		KuaishouAccountBudget kuaishouAccountBudgetEntity = kuaishouAccountBudgetService.getById(kuaishouAccountBudget.getId());
+		if(kuaishouAccountBudgetEntity==null) {
+			result.error500("未找到对应实体");
+		}else {
+			boolean ok = kuaishouAccountBudgetService.updateById(kuaishouAccountBudget);
+			if(ok) {
+				result.success("修改成功!");
+			}
+		}
+		
+		return result;
+	}
+	
+	/**
+	  *   通过id删除
+	 * @param id
+	 * @return
+	 */
+	@AutoLog(value = "账户日预算-通过id删除")
+	@ApiOperation(value="账户日预算-通过id删除", notes="账户日预算-通过id删除")
+	@DeleteMapping(value = "/delete")
+	public Result<?> delete(@RequestParam(name="id",required=true) String id) {
+		try {
+			kuaishouAccountBudgetService.removeById(id);
+		} catch (Exception e) {
+			log.error("删除失败",e.getMessage());
+			return Result.error("删除失败!");
+		}
+		return Result.ok("删除成功!");
+	}
+	
+	/**
+	  *  批量删除
+	 * @param ids
+	 * @return
+	 */
+	@AutoLog(value = "账户日预算-批量删除")
+	@ApiOperation(value="账户日预算-批量删除", notes="账户日预算-批量删除")
+	@DeleteMapping(value = "/deleteBatch")
+	public Result<KuaishouAccountBudget> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
+		Result<KuaishouAccountBudget> result = new Result<KuaishouAccountBudget>();
+		if(ids==null || "".equals(ids.trim())) {
+			result.error500("参数不识别!");
+		}else {
+			this.kuaishouAccountBudgetService.removeByIds(Arrays.asList(ids.split(",")));
+			result.success("删除成功!");
+		}
+		return result;
+	}
+	
+	/**
+	  * 通过id查询
+	 * @param id
+	 * @return
+	 */
+	@AutoLog(value = "账户日预算-通过id查询")
+	@ApiOperation(value="账户日预算-通过id查询", notes="账户日预算-通过id查询")
+	@GetMapping(value = "/queryById")
+	public Result<KuaishouAccountBudget> queryById(@RequestParam(name="id",required=true) String id) {
+		Result<KuaishouAccountBudget> result = new Result<KuaishouAccountBudget>();
+		KuaishouAccountBudget kuaishouAccountBudget = kuaishouAccountBudgetService.getById(id);
+		if(kuaishouAccountBudget==null) {
+			result.error500("未找到对应实体");
+		}else {
+			result.setResult(kuaishouAccountBudget);
+			result.setSuccess(true);
+		}
+		return result;
+	}
+
+  /**
+      * 导出excel
+   *
+   * @param request
+   * @param response
+   */
+  @RequestMapping(value = "/exportXls")
+  public ModelAndView exportXls(HttpServletRequest request, HttpServletResponse response) {
+      // Step.1 组装查询条件
+      QueryWrapper<KuaishouAccountBudget> queryWrapper = null;
+      try {
+          String paramsStr = request.getParameter("paramsStr");
+          if (oConvertUtils.isNotEmpty(paramsStr)) {
+              String deString = URLDecoder.decode(paramsStr, "UTF-8");
+              KuaishouAccountBudget kuaishouAccountBudget = JSON.parseObject(deString, KuaishouAccountBudget.class);
+              queryWrapper = QueryGenerator.initQueryWrapper(kuaishouAccountBudget, request.getParameterMap());
+          }
+      } catch (UnsupportedEncodingException e) {
+          e.printStackTrace();
+      }
+
+      //Step.2 AutoPoi 导出Excel
+      ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
+      List<KuaishouAccountBudget> pageList = kuaishouAccountBudgetService.list(queryWrapper);
+      //导出文件名称
+      mv.addObject(NormalExcelConstants.FILE_NAME, "账户日预算列表");
+      mv.addObject(NormalExcelConstants.CLASS, KuaishouAccountBudget.class);
+      mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("账户日预算列表数据", "导出人:Jeecg", "导出信息"));
+      mv.addObject(NormalExcelConstants.DATA_LIST, pageList);
+      return mv;
+  }
+
+  /**
+      * 通过excel导入数据
+   *
+   * @param request
+   * @param response
+   * @return
+   */
+  @RequestMapping(value = "/importExcel", method = RequestMethod.POST)
+  public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
+      MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
+      Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
+      for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
+          MultipartFile file = entity.getValue();
+          ImportParams params = new ImportParams();
+          params.setTitleRows(2);
+          params.setHeadRows(1);
+          params.setNeedSave(true);
+          try {
+              List<KuaishouAccountBudget> listKuaishouAccountBudgets = ExcelImportUtil.importExcel(file.getInputStream(), KuaishouAccountBudget.class, params);
+              kuaishouAccountBudgetService.saveBatch(listKuaishouAccountBudgets);
+              return Result.ok("文件导入成功!数据行数:" + listKuaishouAccountBudgets.size());
+          } catch (Exception e) {
+              log.error(e.getMessage(),e);
+              return Result.error("文件导入失败:"+e.getMessage());
+          } finally {
+              try {
+                  file.getInputStream().close();
+              } catch (IOException e) {
+                  e.printStackTrace();
+              }
+          }
+      }
+      return Result.ok("文件导入失败!");
+  }
+
+
+	 @RequestMapping("/getAccountBudget")
+	 public void getAccountBudget() throws IOException {
+		 String accessToken = "f5254e5c3a230d9e690628e1f90763b7";
+		 Long advertiserId = 1022694L;
+		 kuaishouAccountBudgetService.getAccountBudget(advertiserId, accessToken);
+
+	 }
+
+}

+ 53 - 0
module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/batch/entity/KuaishouAccountBudget.java

@@ -0,0 +1,53 @@
+package cn.com.ctop.kuaishou.modules.batch.entity;
+
+import java.io.Serializable;
+import java.util.Date;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.annotation.TableField;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import org.springframework.format.annotation.DateTimeFormat;
+import org.jeecgframework.poi.excel.annotation.Excel;
+
+/**
+ * 账户日预算
+ * @author jeecg-boot
+ * @date   2020-04-26
+ * @version V1.0
+ */
+@Data
+@TableName("ctop_kuaishou_account_budget")
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value="ctop_kuaishou_account_budget对象", description="账户日预算")
+public class KuaishouAccountBudget {
+    
+	@TableId(type = IdType.AUTO)
+    @ApiModelProperty(value = "id")
+	private Long id;
+	@Excel(name = "accountId", width = 15)
+    @ApiModelProperty(value = "accountId")
+	private Long accountId;
+	@Excel(name = "dayBudget", width = 15)
+    @ApiModelProperty(value = "dayBudget")
+	private String dayBudget;
+	@Excel(name = "dayBudgetSchedule", width = 15)
+    @ApiModelProperty(value = "dayBudgetSchedule")
+	private String dayBudgetSchedule;
+	@Excel(name = "createTime", width = 20, format = "yyyy-MM-dd HH:mm:ss")
+	@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
+    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
+    @ApiModelProperty(value = "createTime")
+	private Date createTime;
+	@Excel(name = "updateTime", width = 20, format = "yyyy-MM-dd HH:mm:ss")
+	@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
+    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
+    @ApiModelProperty(value = "updateTime")
+	private Date updateTime;
+}

+ 17 - 0
module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/batch/mapper/KuaishouAccountBudgetMapper.java

@@ -0,0 +1,17 @@
+package cn.com.ctop.kuaishou.modules.batch.mapper;
+
+import java.util.List;
+
+import cn.com.ctop.kuaishou.modules.batch.entity.KuaishouAccountBudget;
+import org.apache.ibatis.annotations.Param;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * 账户日预算
+ * @author: jeecg-boot
+ * @date:   2020-04-26
+ * @cersion: V1.0
+ */
+public interface KuaishouAccountBudgetMapper extends BaseMapper<KuaishouAccountBudget> {
+
+}

+ 5 - 0
module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/batch/mapper/xml/KuaishouAccountBudgetMapper.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="cn.com.ctop.kuaishou.modules.batch.mapper.KuaishouAccountBudgetMapper">
+
+</mapper>

+ 23 - 0
module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/batch/service/IKuaishouAccountBudgetService.java

@@ -0,0 +1,23 @@
+package cn.com.ctop.kuaishou.modules.batch.service;
+
+import cn.com.ctop.kuaishou.modules.batch.entity.KuaishouAccountBudget;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ * 账户日预算
+ * @author jeecg-boot
+ * @date   2020-04-26
+ * @version V1.0
+ */
+public interface IKuaishouAccountBudgetService extends IService<KuaishouAccountBudget> {
+
+
+    /**
+     * 获取账户日预算
+     *
+     * @param advertiserId
+     * @param accessToken
+     */
+    void getAccountBudget(Long advertiserId, String accessToken);
+
+}

+ 85 - 0
module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/batch/service/impl/KuaishouAccountBudgetServiceImpl.java

@@ -0,0 +1,85 @@
+package cn.com.ctop.kuaishou.modules.batch.service.impl;
+
+
+import cn.com.ctop.common.module.utils.Check;
+import cn.com.ctop.common.module.utils.HttpUtils;
+import cn.com.ctop.common.module.utils.KuaishouInterfaceConstant;
+import cn.com.ctop.common.module.utils.PropertiesUtils;
+import cn.com.ctop.kuaishou.modules.batch.entity.KuaishouAccountBudget;
+import cn.com.ctop.kuaishou.modules.batch.mapper.KuaishouAccountBudgetMapper;
+import cn.com.ctop.kuaishou.modules.batch.service.IKuaishouAccountBudgetService;
+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 com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 账户日预算
+ * @author jeecg-boot
+ * @date   2020-04-26
+ * @version V1.0
+ */
+@Slf4j
+@Service
+public class KuaishouAccountBudgetServiceImpl extends ServiceImpl<KuaishouAccountBudgetMapper, KuaishouAccountBudget> implements IKuaishouAccountBudgetService {
+
+
+    @Autowired
+    KuaishouAccountBudgetMapper accountBudgetMapper;
+
+
+    /**
+     * 获取账户日预算结果
+     * @param advertiserId
+     * @param accessToken
+     * @return
+     */
+    @Override
+    public void getAccountBudget(Long advertiserId, String accessToken) {
+        try {
+            String url = PropertiesUtils.getConfig("kuaishou_api_url") + KuaishouInterfaceConstant.ACCOUNT_BUDGET;
+            Map<String, String> headers = new HashMap<>();
+            headers.put("Access-Token", accessToken);
+            headers.put("Content-Type", "application/json");
+            JSONObject json = new JSONObject();
+            json.put("advertiser_id", advertiserId);
+            String result = HttpUtils.kuaiShouhttpPostRequest(url, json.toJSONString(), headers);
+            JSONObject resultJson = JSONObject.parseObject(result);
+            if (!Check.isNull(resultJson)) {
+                Integer code = resultJson.getInteger("code");
+                if (code == 0) {
+                    Map<String, Object> deleteMap = new HashMap<>();
+                    deleteMap.put("account_id", advertiserId);
+                    accountBudgetMapper.deleteByMap(deleteMap);
+                    JSONObject data = resultJson.getJSONObject("data");
+                    if (!Check.isNull(data)) {
+                        KuaishouAccountBudget budget = new KuaishouAccountBudget();
+                        budget.setAccountId(advertiserId);
+                        budget.setDayBudget(data.get("day_budget").toString());
+                        JSONArray jsonArr = data.getJSONArray("day_budget_schedule");
+                        if (!Check.isNull(jsonArr)) {
+                            budget.setDayBudgetSchedule(jsonArr.toString());
+                        }
+                        budget.setCreateTime(new Date());
+                        accountBudgetMapper.insert(budget);
+
+                    }
+                } else {
+                    log.error("获取账户日预算失败,返回信息:{}", resultJson);
+                }
+            } else {
+                log.error("获取账户日预算返回结果为空");
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+    }
+}

+ 168 - 0
module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/batch/vue/KuaishouAccountBudgetList.vue

@@ -0,0 +1,168 @@
+<template>
+  <a-card :bordered="false">
+
+    <!-- 查询区域 -->
+    <div class="table-page-search-wrapper">
+      <a-form layout="inline">
+        <a-row :gutter="24">
+
+          <a-col :md="6" :sm="8">
+            <a-form-item label="accountId">
+              <a-input placeholder="请输入accountId" v-model="queryParam.accountId"></a-input>
+            </a-form-item>
+          </a-col>
+          <a-col :md="6" :sm="8">
+            <a-form-item label="dayBudget">
+              <a-input placeholder="请输入dayBudget" v-model="queryParam.dayBudget"></a-input>
+            </a-form-item>
+          </a-col>
+        <template v-if="toggleSearchStatus">
+        <a-col :md="6" :sm="8">
+            <a-form-item label="dayBudgetSchedule">
+              <a-input placeholder="请输入dayBudgetSchedule" v-model="queryParam.dayBudgetSchedule"></a-input>
+            </a-form-item>
+          </a-col>
+          </template>
+          <a-col :md="6" :sm="8" >
+            <span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
+              <a-button type="primary" @click="searchQuery" icon="search">查询</a-button>
+              <a-button type="primary" @click="searchReset" icon="reload" style="margin-left: 8px">重置</a-button>
+              <a @click="handleToggleSearch" style="margin-left: 8px">
+                {{ toggleSearchStatus ? '收起' : '展开' }}
+                <a-icon :type="toggleSearchStatus ? 'up' : 'down'"/>
+              </a>
+            </span>
+          </a-col>
+
+        </a-row>
+      </a-form>
+    </div>
+
+    <!-- 操作按钮区域 -->
+    <div class="table-operator">
+      <a-button @click="handleAdd" type="primary" icon="plus">新增</a-button>
+      <a-button type="primary" icon="download" @click="handleExportXls('账户日预算')">导出</a-button>
+      <a-upload name="file" :showUploadList="false" :multiple="false" :headers="tokenHeader" :action="importExcelUrl" @change="handleImportExcel">
+        <a-button type="primary" icon="import">导入</a-button>
+      </a-upload>
+      <a-dropdown v-if="selectedRowKeys.length > 0">
+        <a-menu slot="overlay">
+          <a-menu-item key="1" @click="batchDel"><a-icon type="delete"/>删除</a-menu-item>
+        </a-menu>
+        <a-button style="margin-left: 8px"> 批量操作 <a-icon type="down" /></a-button>
+      </a-dropdown>
+    </div>
+
+    <!-- table区域-begin -->
+    <div>
+      <div class="ant-alert ant-alert-info" style="margin-bottom: 16px;">
+        <i class="anticon anticon-info-circle ant-alert-icon"></i> 已选择 <a style="font-weight: 600">{{ selectedRowKeys.length }}</a>项
+        <a style="margin-left: 24px" @click="onClearSelected">清空</a>
+      </div>
+
+      <a-table
+        ref="table"
+        size="middle"
+        bordered
+        rowKey="id"
+        :columns="columns"
+        :dataSource="dataSource"
+        :pagination="ipagination"
+        :loading="loading"
+        :rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}"
+        @change="handleTableChange">
+
+        <span slot="action" slot-scope="text, record">
+          <a @click="handleEdit(record)">编辑</a>
+
+          <a-divider type="vertical" />
+          <a-dropdown>
+            <a class="ant-dropdown-link">更多 <a-icon type="down" /></a>
+            <a-menu slot="overlay">
+              <a-menu-item>
+                <a-popconfirm title="确定删除吗?" @confirm="() => handleDelete(record.id)">
+                  <a>删除</a>
+                </a-popconfirm>
+              </a-menu-item>
+            </a-menu>
+          </a-dropdown>
+        </span>
+
+      </a-table>
+    </div>
+    <!-- table区域-end -->
+
+    <!-- 表单区域 -->
+    <kuaishouAccountBudget-modal ref="modalForm" @ok="modalFormOk"></kuaishouAccountBudget-modal>
+  </a-card>
+</template>
+
+<script>
+  import KuaishouAccountBudgetModal from './modules/KuaishouAccountBudgetModal'
+  import { JeecgListMixin } from '@/mixins/JeecgListMixin'
+
+  export default {
+    name: "KuaishouAccountBudgetList",
+    mixins:[JeecgListMixin],
+    components: {
+      KuaishouAccountBudgetModal
+    },
+    data () {
+      return {
+        description: '账户日预算管理页面',
+        // 表头
+        columns: [
+          {
+            title: '#',
+            dataIndex: '',
+            key:'rowIndex',
+            width:60,
+            align:"center",
+            customRender:function (t,r,index) {
+              return parseInt(index)+1;
+            }
+           },
+		   {
+            title: 'accountId',
+            align:"center",
+            dataIndex: 'accountId'
+           },
+		   {
+            title: 'dayBudget',
+            align:"center",
+            dataIndex: 'dayBudget'
+           },
+		   {
+            title: 'dayBudgetSchedule',
+            align:"center",
+            dataIndex: 'dayBudgetSchedule'
+           },
+          {
+            title: '操作',
+            dataIndex: 'action',
+            align:"center",
+            scopedSlots: { customRender: 'action' },
+          }
+        ],
+		url: {
+          list: "/batch/kuaishouAccountBudget/list",
+          delete: "/batch/kuaishouAccountBudget/delete",
+          deleteBatch: "/batch/kuaishouAccountBudget/deleteBatch",
+          exportXlsUrl: "batch/kuaishouAccountBudget/exportXls",
+          importExcelUrl: "batch/kuaishouAccountBudget/importExcel",
+       },
+    }
+  },
+  computed: {
+    importExcelUrl: function(){
+      return `${window._CONFIG['domianURL']}/${this.url.importExcelUrl}`;
+    }
+  },
+    methods: {
+     
+    }
+  }
+</script>
+<style scoped>
+  @import '~@assets/less/common.less'
+</style>

+ 5 - 7
module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/report/entity/KuaishouAgentAccount.java

@@ -1,21 +1,18 @@
 package cn.com.ctop.kuaishou.modules.report.entity;
 
-import java.io.Serializable;
-import java.util.Date;
 import com.baomidou.mybatisplus.annotation.IdType;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
-import com.baomidou.mybatisplus.annotation.TableField;
 import com.fasterxml.jackson.annotation.JsonProperty;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.experimental.Accessors;
-import com.fasterxml.jackson.annotation.JsonFormat;
-import org.springframework.format.annotation.DateTimeFormat;
 import org.jeecgframework.poi.excel.annotation.Excel;
 
+import java.util.Date;
+
 /**
  * 快手代理商账户表
  * @author jeecg-boot
@@ -28,7 +25,7 @@ import org.jeecgframework.poi.excel.annotation.Excel;
 @Accessors(chain = true)
 @ApiModel(value="ctop_kuaishou_agent_account对象", description="快手代理商账户表")
 public class KuaishouAgentAccount {
-    
+
 	/**id*/
 	@TableId(type = IdType.INPUT)
     @ApiModelProperty(value = "id")
@@ -103,6 +100,7 @@ public class KuaishouAgentAccount {
     @ApiModelProperty(value = "transferAccountStatus")
 	private Boolean transferAccountStatus;
 	/**createTime*/
+    @Excel(name = "transferAccountStatus", width = 15)
     @ApiModelProperty(value = "createTime")
-	private Date createTime;
+    private Date createTime;
 }

+ 96 - 13
module-report/src/main/java/cn/com/ctop/bytedance/controller/BytedanceReportController.java

@@ -1,9 +1,9 @@
 package cn.com.ctop.bytedance.controller;
 
+import cn.com.ctop.bytedance.entity.BytedanceReportMaterialRetry;
 import cn.com.ctop.bytedance.service.IBytedanceReportService;
 import cn.com.ctop.common.module.entity.CtopOauthToken;
 import cn.com.ctop.common.module.service.ICtopOauthTokenService;
-import cn.com.ctop.common.module.utils.CtopAdConstant;
 import com.alibaba.fastjson.JSONObject;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang.StringUtils;
@@ -12,8 +12,9 @@ import org.jeecg.common.util.DateUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
 
-import java.util.Date;
 import java.util.List;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
 
 @Slf4j
 @RestController
@@ -99,26 +100,46 @@ public class BytedanceReportController {
     }
 
     @PostMapping("/bytedance/async")
-    public Result<List<JSONObject>> asyncTaskCreate(@RequestBody JSONObject requestJson) {
+    public Result<List<JSONObject>> asyncTaskCreate(@RequestParam(name = "startDate")String startDate,
+                                                    @RequestParam(name = "endDate")String endDate,
+                                                    @RequestParam(name = "type")Integer type) {
 
         Result<List<JSONObject>> result = new Result<>();
         try {
-            bytedanceReportService.bytedanceAsyncTaskCreate();
+            log.info("头条获取素材报表数据任务执行开始");
+            Long starttime = System.currentTimeMillis();
+            List<CtopOauthToken> tokens = tokenService.selectToutiaoToken();
+            if (null == tokens || tokens.size() <= 0) {
+                log.info("头条获取异步报表数据任务执行失败:未获取到可用的token");
+                return result;
+            }
 
+            for (CtopOauthToken token : tokens) {
+                //if(1629785592929294L == token.getAccountId()){
+                    bytedanceReportService.bytedanceAsyncTaskCreate(startDate, endDate, token, type);
+                //}
+             }
+            Long endtime = System.currentTimeMillis();
+            log.info("头条异步报表数据任务执行结束,执行耗时:{}秒", (endtime - starttime) / 1000);
         } catch (Exception e) {
+            log.error("头条获取异步报表数据任务执行报错");
             e.printStackTrace();
             result.setSuccess(false);
         }
         return result;
-
     }
 
     @PostMapping("/bytedance/async/taskGet")
     public Result<List<JSONObject>> bytedanceAsyncTaskGet(@RequestBody JSONObject requestJson) {
         Result<List<JSONObject>> result = new Result<>();
         try {
+            log.info("头条获取素材报表数据定时任务执行开始");
+            Long starttime = System.currentTimeMillis();
             bytedanceReportService.bytedanceAsyncTaskGet();
+            Long endtime = System.currentTimeMillis();
+            log.info("头条异步报表数据定时任务执行结束,执行耗时:{}秒", (endtime - starttime) / 1000);
         } catch (Exception e) {
+            log.error("头条获取异步报表数据定时任务执行报错");
             e.printStackTrace();
             result.setSuccess(false);
         }
@@ -136,19 +157,38 @@ public class BytedanceReportController {
 
         try {
             log.info("头条获取素材报表数据任务执行开始");
-            Long start = System.currentTimeMillis();
+            Long starttime = System.currentTimeMillis();
             List<CtopOauthToken> tokens = tokenService.selectToutiaoToken();
             if (null == tokens || tokens.size() <= 0) {
                 log.info("头条获取素材报表数据任务执行失败:未获取到可用的token");
                 return result;
             }
-            for (CtopOauthToken token : tokens) {
-                //if(token.getAccountId() == 1647352267707396L){
-                    bytedanceReportService.bytedanceMaterialReport(token,startDate,endDate);
-                //}
-            }
-            Long end = System.currentTimeMillis();
-            log.info("头条获取素材报表数据任务执行结束,执行耗时:{}秒", (end - start) / 1000);
+
+            final ExecutorService executorService = Executors.newFixedThreadPool(8);
+            tokens.forEach(token -> {
+                executorService.submit(new Runnable() {
+                    @Override
+                    public void run() {
+                        try {
+                            Long days = DateUtils.getDiscrepantDays(startDate, endDate); //间隔天数
+                            String start = null;
+                            String end = null;
+                            for(int i=0; i<=days; i++){
+                                start = DateUtils.addDay(startDate,i);
+                                end = start;
+                                //获取头条素材报表数据
+                                bytedanceReportService.bytedanceMaterialReport(token,start,end);
+                            }
+                        } catch (Exception e) {
+                            e.printStackTrace();
+                        } finally {
+                        }
+                    }
+                });
+            });
+            ////
+            Long endtime = System.currentTimeMillis();
+            log.info("头条获取素材报表数据任务执行结束,执行耗时:{}秒", (endtime - starttime) / 1000);
         } catch (Exception e) {
             log.error("头条获取素材报表数据任务执行结失败");
             e.printStackTrace();
@@ -157,4 +197,47 @@ public class BytedanceReportController {
         return result;
     }
 
+    @GetMapping("/bytedance/bytedanceMaterialReporRetry")
+    public Result bytedanceMaterialReportRetry() {
+        log.info("头条获取素材报表失败数据任务重试开始");
+        Result result = new Result<>();
+        try {
+            List<BytedanceReportMaterialRetry> retryList = bytedanceReportService.getRetryList();
+            //for(BytedanceReportMaterialRetry retry:retryList){
+            //    CtopOauthToken token = tokenService.getOauthTokenByAccountId(String.valueOf(retry.getAccountId()));
+            //    log.info("头条素材报表当前accountId为:" + token.getAccountId());
+            //    bytedanceReportService.bytedanceMaterialReportRetry(token,retry.getStartDate(),retry.getEndDate());
+            //}
+
+                //
+                //多线程
+                final ExecutorService executorService = Executors.newFixedThreadPool(8);
+                retryList.forEach(retry -> {
+                    executorService.submit(new Runnable() {
+                        @Override
+                        public void run() {
+                            try {
+                                CtopOauthToken token = tokenService.getOauthTokenByAccountId(String.valueOf(retry.getAccountId()));
+                                log.info("头条素材报表当前accountId为:" + token.getAccountId());
+                                bytedanceReportService.bytedanceMaterialReportRetry(token,retry.getStartDate(),retry.getEndDate());
+                            } catch (Exception e) {
+                                e.printStackTrace();
+                            } finally {
+                            }
+                        }
+                    });
+                });
+                ////
+
+        } catch (Exception e) {
+            log.error("条获取素材报表失败数据任务重试失败");
+            e.printStackTrace();
+            result.setSuccess(false);
+        }
+
+        log.info("头条获取素材报表数据任务重试结束");
+        return result;
+    }
+
+
 }

+ 242 - 0
module-report/src/main/java/cn/com/ctop/bytedance/controller/BytedanceReportMaterialRetryController.java

@@ -0,0 +1,242 @@
+package cn.com.ctop.bytedance.controller;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.common.system.query.QueryGenerator;
+import org.jeecg.common.aspect.annotation.AutoLog;
+import org.jeecg.common.util.oConvertUtils;
+import cn.com.ctop.bytedance.entity.BytedanceReportMaterialRetry;
+import cn.com.ctop.bytedance.service.IBytedanceReportMaterialRetryService;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import lombok.extern.slf4j.Slf4j;
+
+import org.jeecgframework.poi.excel.ExcelImportUtil;
+import org.jeecgframework.poi.excel.def.NormalExcelConstants;
+import org.jeecgframework.poi.excel.entity.ExportParams;
+import org.jeecgframework.poi.excel.entity.ImportParams;
+import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.multipart.MultipartHttpServletRequest;
+import org.springframework.web.servlet.ModelAndView;
+import com.alibaba.fastjson.JSON;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+
+ /**
+ * 头条素材报表连接出错数据记录表
+ * @author jeecg-boot
+ * @date   2020-04-21
+ * @version V1.0
+ */
+@Slf4j
+@Api(tags="头条素材报表连接出错数据记录表")
+@RestController
+@RequestMapping("/bytedance/bytedanceReportMaterialRetry")
+public class BytedanceReportMaterialRetryController {
+	@Autowired
+	private IBytedanceReportMaterialRetryService bytedanceReportMaterialRetryService;
+
+	/**
+	  * 分页列表查询
+	 * @param bytedanceReportMaterialRetry
+	 * @param pageNo
+	 * @param pageSize
+	 * @param req
+	 * @return
+	 */
+	@AutoLog(value = "头条素材报表连接出错数据记录表-分页列表查询")
+	@ApiOperation(value="头条素材报表连接出错数据记录表-分页列表查询", notes="头条素材报表连接出错数据记录表-分页列表查询")
+	@GetMapping(value = "/list")
+	public Result<IPage<BytedanceReportMaterialRetry>> queryPageList(BytedanceReportMaterialRetry bytedanceReportMaterialRetry,
+																	 @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
+																	 @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
+																	 HttpServletRequest req) {
+		Result<IPage<BytedanceReportMaterialRetry>> result = new Result<IPage<BytedanceReportMaterialRetry>>();
+		QueryWrapper<BytedanceReportMaterialRetry> queryWrapper = QueryGenerator.initQueryWrapper(bytedanceReportMaterialRetry, req.getParameterMap());
+		Page<BytedanceReportMaterialRetry> page = new Page<BytedanceReportMaterialRetry>(pageNo, pageSize);
+		IPage<BytedanceReportMaterialRetry> pageList = bytedanceReportMaterialRetryService.page(page, queryWrapper);
+		result.setSuccess(true);
+		result.setResult(pageList);
+		return result;
+	}
+
+	/**
+	  *   添加
+	 * @param bytedanceReportMaterialRetry
+	 * @return
+	 */
+	@AutoLog(value = "头条素材报表连接出错数据记录表-添加")
+	@ApiOperation(value="头条素材报表连接出错数据记录表-添加", notes="头条素材报表连接出错数据记录表-添加")
+	@PostMapping(value = "/add")
+	public Result<BytedanceReportMaterialRetry> add(@RequestBody BytedanceReportMaterialRetry bytedanceReportMaterialRetry) {
+		Result<BytedanceReportMaterialRetry> result = new Result<BytedanceReportMaterialRetry>();
+		try {
+			bytedanceReportMaterialRetryService.save(bytedanceReportMaterialRetry);
+			result.success("添加成功!");
+		} catch (Exception e) {
+			log.error(e.getMessage(),e);
+			result.error500("操作失败");
+		}
+		return result;
+	}
+
+	/**
+	  *  编辑
+	 * @param bytedanceReportMaterialRetry
+	 * @return
+	 */
+	@AutoLog(value = "头条素材报表连接出错数据记录表-编辑")
+	@ApiOperation(value="头条素材报表连接出错数据记录表-编辑", notes="头条素材报表连接出错数据记录表-编辑")
+	@PutMapping(value = "/edit")
+	public Result<BytedanceReportMaterialRetry> edit(@RequestBody BytedanceReportMaterialRetry bytedanceReportMaterialRetry) {
+		Result<BytedanceReportMaterialRetry> result = new Result<BytedanceReportMaterialRetry>();
+		BytedanceReportMaterialRetry bytedanceReportMaterialRetryEntity = bytedanceReportMaterialRetryService.getById(bytedanceReportMaterialRetry.getId());
+		if(bytedanceReportMaterialRetryEntity==null) {
+			result.error500("未找到对应实体");
+		}else {
+			boolean ok = bytedanceReportMaterialRetryService.updateById(bytedanceReportMaterialRetry);
+			if(ok) {
+				result.success("修改成功!");
+			}
+		}
+
+		return result;
+	}
+
+	/**
+	  *   通过id删除
+	 * @param id
+	 * @return
+	 */
+	@AutoLog(value = "头条素材报表连接出错数据记录表-通过id删除")
+	@ApiOperation(value="头条素材报表连接出错数据记录表-通过id删除", notes="头条素材报表连接出错数据记录表-通过id删除")
+	@DeleteMapping(value = "/delete")
+	public Result<?> delete(@RequestParam(name="id",required=true) String id) {
+		try {
+			bytedanceReportMaterialRetryService.removeById(id);
+		} catch (Exception e) {
+			log.error("删除失败",e.getMessage());
+			return Result.error("删除失败!");
+		}
+		return Result.ok("删除成功!");
+	}
+
+	/**
+	  *  批量删除
+	 * @param ids
+	 * @return
+	 */
+	@AutoLog(value = "头条素材报表连接出错数据记录表-批量删除")
+	@ApiOperation(value="头条素材报表连接出错数据记录表-批量删除", notes="头条素材报表连接出错数据记录表-批量删除")
+	@DeleteMapping(value = "/deleteBatch")
+	public Result<BytedanceReportMaterialRetry> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
+		Result<BytedanceReportMaterialRetry> result = new Result<BytedanceReportMaterialRetry>();
+		if(ids==null || "".equals(ids.trim())) {
+			result.error500("参数不识别!");
+		}else {
+			this.bytedanceReportMaterialRetryService.removeByIds(Arrays.asList(ids.split(",")));
+			result.success("删除成功!");
+		}
+		return result;
+	}
+
+	/**
+	  * 通过id查询
+	 * @param id
+	 * @return
+	 */
+	@AutoLog(value = "头条素材报表连接出错数据记录表-通过id查询")
+	@ApiOperation(value="头条素材报表连接出错数据记录表-通过id查询", notes="头条素材报表连接出错数据记录表-通过id查询")
+	@GetMapping(value = "/queryById")
+	public Result<BytedanceReportMaterialRetry> queryById(@RequestParam(name="id",required=true) String id) {
+		Result<BytedanceReportMaterialRetry> result = new Result<BytedanceReportMaterialRetry>();
+		BytedanceReportMaterialRetry bytedanceReportMaterialRetry = bytedanceReportMaterialRetryService.getById(id);
+		if(bytedanceReportMaterialRetry==null) {
+			result.error500("未找到对应实体");
+		}else {
+			result.setResult(bytedanceReportMaterialRetry);
+			result.setSuccess(true);
+		}
+		return result;
+	}
+
+  /**
+      * 导出excel
+   *
+   * @param request
+   * @param response
+   */
+  @RequestMapping(value = "/exportXls")
+  public ModelAndView exportXls(HttpServletRequest request, HttpServletResponse response) {
+      // Step.1 组装查询条件
+      QueryWrapper<BytedanceReportMaterialRetry> queryWrapper = null;
+      try {
+          String paramsStr = request.getParameter("paramsStr");
+          if (oConvertUtils.isNotEmpty(paramsStr)) {
+              String deString = URLDecoder.decode(paramsStr, "UTF-8");
+              BytedanceReportMaterialRetry bytedanceReportMaterialRetry = JSON.parseObject(deString, BytedanceReportMaterialRetry.class);
+              queryWrapper = QueryGenerator.initQueryWrapper(bytedanceReportMaterialRetry, request.getParameterMap());
+          }
+      } catch (UnsupportedEncodingException e) {
+          e.printStackTrace();
+      }
+
+      //Step.2 AutoPoi 导出Excel
+      ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
+      List<BytedanceReportMaterialRetry> pageList = bytedanceReportMaterialRetryService.list(queryWrapper);
+      //导出文件名称
+      mv.addObject(NormalExcelConstants.FILE_NAME, "头条素材报表连接出错数据记录表列表");
+      mv.addObject(NormalExcelConstants.CLASS, BytedanceReportMaterialRetry.class);
+      mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("头条素材报表连接出错数据记录表列表数据", "导出人:Jeecg", "导出信息"));
+      mv.addObject(NormalExcelConstants.DATA_LIST, pageList);
+      return mv;
+  }
+
+  /**
+      * 通过excel导入数据
+   *
+   * @param request
+   * @param response
+   * @return
+   */
+  @RequestMapping(value = "/importExcel", method = RequestMethod.POST)
+  public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
+      MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
+      Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
+      for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
+          MultipartFile file = entity.getValue();
+          ImportParams params = new ImportParams();
+          params.setTitleRows(2);
+          params.setHeadRows(1);
+          params.setNeedSave(true);
+          try {
+              List<BytedanceReportMaterialRetry> listbytedanceReportMaterialRetries = ExcelImportUtil.importExcel(file.getInputStream(), BytedanceReportMaterialRetry.class, params);
+              bytedanceReportMaterialRetryService.saveBatch(listbytedanceReportMaterialRetries);
+              return Result.ok("文件导入成功!数据行数:" + listbytedanceReportMaterialRetries.size());
+          } catch (Exception e) {
+              log.error(e.getMessage(),e);
+              return Result.error("文件导入失败:"+e.getMessage());
+          } finally {
+              try {
+                  file.getInputStream().close();
+              } catch (IOException e) {
+                  e.printStackTrace();
+              }
+          }
+      }
+      return Result.ok("文件导入失败!");
+  }
+
+}

+ 15 - 31
module-report/src/main/java/cn/com/ctop/bytedance/controller/ReportController.java

@@ -4,13 +4,14 @@ import cn.com.ctop.bytedance.service.IReportService;
 import cn.com.ctop.bytedance.vo.ByteDanceAdvertiserReportDTO;
 import cn.com.ctop.common.module.entity.CtopOauthToken;
 import cn.com.ctop.common.module.service.ICtopOauthTokenService;
-import cn.com.ctop.common.module.utils.ResultMapUtils;
-import cn.com.ctop.common.module.utils.StatusCode;
 import cn.com.ctop.kuaishou.modules.batch.service.IKuaishouInterfaceService;
 import com.alibaba.fastjson.JSONObject;
 import org.jeecg.common.util.DateUtils;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.*;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
 
 import javax.servlet.http.HttpServletResponse;
 import java.io.*;
@@ -38,6 +39,17 @@ public class ReportController {
     }
 
     /**
+     * 头条广告计划报表信息
+     * 只支持查询2016-10-26及以后的日期
+     * 单次获取最大条数1000
+     * @return 广告组报表数据
+     */
+    @GetMapping("bytedance/campaign")
+    public Map<String, Object> campaignReport(@RequestBody ByteDanceAdvertiserReportDTO conditions) {
+        return reportService.getCampaignReport(conditions);
+    }
+
+    /**
      * 代理商数据
      * @param conditions
      * @return
@@ -66,34 +78,6 @@ public class ReportController {
     @Autowired
     private IKuaishouInterfaceService kuaishouInterfaceService;
 
-    /**
-     * 360借条报表客户后台数据
-     */
-    @GetMapping("jietiao/customer/insert")
-    public Map<String, Object> jietiaoCustomerInsert() {
-        Map<String, Object> result = new HashMap<>();
-        String csvPath = "D:\\工作文件\\360借条\\测试数据\\客户后台数据.csv";
-        reportService.insertCustomerInfo(csvPath, "utf8");
-        ResultMapUtils.setResultMap(result, StatusCode.COMMON_SUCCESS.getCode());
-        return result;
-    }
-
-    /**
-     * 360借条报表平台数据
-     */
-    @GetMapping("jietiao/plateform/insert")
-    public Map<String, Object> jietiaoPlatformInsert() {
-        Map<String, Object> result = new HashMap<>();
-        String csvPath = "D:\\工作文件\\360借条\\测试数据\\快手后台数据.csv";
-        reportService.insertPlatformInfo(csvPath, "gb2312", 4L);
-        ResultMapUtils.setResultMap(result, StatusCode.COMMON_SUCCESS.getCode());
-        return result;
-    }
-
-    @PostMapping("debitAuto")
-    Map<String, Object> debitAuto(@RequestBody JSONObject data) {
-        return reportService.debitAuto(data);
-    }
 
     @GetMapping("download/file")
     public void downLoadFile(String path, HttpServletResponse response) {

+ 6 - 0
module-report/src/main/java/cn/com/ctop/bytedance/entity/BytedanceDailyReportTask.java

@@ -70,4 +70,10 @@ public class BytedanceDailyReportTask {
 	private Date updateTime;
 
     private String taskStatus;
+
+    private Integer isDownload;
+
+    private Integer type;
+
+    private Integer status;
 }

+ 109 - 6
module-report/src/main/java/cn/com/ctop/bytedance/entity/BytedanceReportMaterialDaily.java

@@ -1,21 +1,19 @@
 package cn.com.ctop.bytedance.entity;
 
-import java.io.Serializable;
-import java.math.BigDecimal;
-import java.util.Date;
+import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.annotation.IdType;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
-import com.baomidou.mybatisplus.annotation.TableField;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.experimental.Accessors;
-import com.fasterxml.jackson.annotation.JsonFormat;
-import org.springframework.format.annotation.DateTimeFormat;
+import org.jeecg.common.util.DateUtils;
 import org.jeecgframework.poi.excel.annotation.Excel;
 
+import java.math.BigDecimal;
+
 /**
  * 素材报表
  * @author jeecg-boot
@@ -445,4 +443,109 @@ public class BytedanceReportMaterialDaily {
 	private java.math.BigDecimal installFinishCost;
 
 	private BigDecimal downloadStartRate;
+
+	public BytedanceReportMaterialDaily() {
+	}
+
+	public BytedanceReportMaterialDaily(JSONObject detailJson, Long accountId) {
+		JSONObject dimensions = detailJson.getJSONObject("dimensions");
+		this.accountId = accountId;
+		this.setImageMode(dimensions.getString("image_mode"));
+		this.setMaterialId(dimensions.getLong("material_id"));
+		this.setInventory(dimensions.getString("inventory"));
+		this.setStatDatetime(dimensions.getDate("stat_datetime") == null ? null : DateUtils.formatDate(dimensions.getDate("stat_datetime"), "yyyy-MM-dd"));
+
+		JSONObject metrics = detailJson.getJSONObject("metrics");
+		this.setActivePayAmount(metrics.getInteger("active_pay_amount"));
+		this.setValidPlayCost(metrics.getBigDecimal("valid_play_cost"));
+		this.setPlay75FeedBreak(metrics.getInteger("play_75_feed_break"));
+		this.setNextDayOpen(metrics.getInteger("next_day_open"));
+		this.setAdvancedCreativeCouponAddition(metrics.getInteger("advanced_creative_coupon_addition"));
+		this.setConvertMaterial(metrics.getInteger("convert"));
+		this.setActivePayCost(metrics.getBigDecimal("active_pay_cost"));
+		this.setInAppCart(metrics.getInteger("in_app_cart"));
+		this.setPlay25FeedBreak(metrics.getInteger("play_25_feed_break"));
+		this.setConsultEffective(metrics.getInteger("consult_effective"));
+		this.setViewMaterial(metrics.getInteger("view"));
+		this.setDownload(metrics.getInteger("download"));
+		this.setCpa(metrics.getBigDecimal("cpa"));
+		this.setCpc(metrics.getBigDecimal("cpc"));
+		this.setLocationClick(metrics.getInteger("location_click"));
+		this.setPhoneConfirm(metrics.getInteger("phone_confirm"));
+		this.setIesMusicClick(metrics.getInteger("ies_music_click"));
+		this.setPlayOverRate(metrics.getBigDecimal("play_over_rate"));
+		this.setWifiPlay(metrics.getInteger("wifi_play"));
+		this.setShopping(metrics.getInteger("shopping"));
+		this.setQq(metrics.getInteger("qq"));
+		this.setCtr(metrics.getBigDecimal("ctr"));
+		this.setCpm(metrics.getBigDecimal("cpm"));
+		this.setWifiPlayRate(metrics.getBigDecimal("wifi_play_rate"));
+		this.setLikeMaterial(metrics.getInteger("like"));
+		this.setPlay50FeedBreak(metrics.getInteger("play_50_feed_break"));
+		this.setActivePayRate(metrics.getBigDecimal("active_pay_rate"));
+		this.setActiveCost(metrics.getBigDecimal("active_cost"));
+		this.setActive(metrics.getInteger("active"));
+		this.setGameAddictionCost(metrics.getBigDecimal("game_addiction_cost"));
+		this.setGameAddiction(metrics.getInteger("game_addiction"));
+		this.setActiveRate(metrics.getBigDecimal("active_rate"));
+		this.setClick(metrics.getInteger("click"));
+		this.setPlayDuration_10s(metrics.getInteger("play_duration_10s"));
+		this.setAdvancedCreativePhoneClick(metrics.getInteger("advanced_creative_phone_click"));
+		this.setDownloadStart(metrics.getInteger("download_start"));
+		this.setHomeVisited(metrics.getInteger("home_visited"));
+		this.setPhone(metrics.getInteger("phone"));
+		this.setPhoneEffective(metrics.getInteger("phone_effective"));
+		this.setInAppPay(metrics.getInteger("in_app_pay"));
+		this.setGameAddictionRate(metrics.getBigDecimal("game_addiction_rate"));
+		this.setNextDayOpenCost(metrics.getBigDecimal("next_day_open_cost"));
+		this.setIesChallengeClick(metrics.getInteger("ies_challenge_click"));
+		this.setTotalPlay(metrics.getInteger("total_play"));
+		this.setActiveRegisterRate(metrics.getBigDecimal("active_register_rate"));
+		this.setAverageVideoPlay(metrics.getBigDecimal("average_video_play"));
+		this.setDownloadFinishCost(metrics.getBigDecimal("download_finish_cost"));
+		this.setPlayDuration_3s(metrics.getInteger("play_duration_3s"));
+		this.setActiveRegisterCost(metrics.getBigDecimal("active_register_cost"));
+		this.setShowMaterial(metrics.getInteger("show"));
+		this.setNextDayOpenRate(metrics.getBigDecimal("next_day_open_rate"));
+		this.setMapSearch(metrics.getInteger("map_search"));
+		this.setButton(metrics.getInteger("button"));
+		this.setPlayDurationSum(metrics.getInteger("play_duration_sum"));
+		this.setPlay100FeedBreak(metrics.getInteger("play_100_feed_break"));
+		this.setAdvancedCreativeCounselClick(metrics.getInteger("advanced_creative_counsel_click"));
+		this.setConvertRate(metrics.getBigDecimal("convert_rate"));
+		this.setDownloadFinishRate(metrics.getBigDecimal("download_finish_rate"));
+		this.setConsult(metrics.getInteger("consult"));
+		this.setShareMaterial(metrics.getInteger("share"));
+		this.setVote(metrics.getInteger("vote"));
+		this.setValidPlay(metrics.getInteger("valid_play"));
+		this.setInstallFinishRate(metrics.getBigDecimal("install_finish_rate"));
+		this.setRedirect(metrics.getInteger("redirect"));
+		this.setPayCount(metrics.getInteger("pay_count"));
+		this.setAdvancedCreativeFormClick(metrics.getInteger("advanced_creative_form_click"));
+		this.setCost(metrics.getBigDecimal("cost"));
+		this.setPhoneConnect(metrics.getInteger("phone_connect"));
+		this.setCoupon(metrics.getInteger("coupon"));
+		this.setDownloadStartRate(metrics.getBigDecimal("download_start_rate"));
+		this.setDownloadFinish(metrics.getInteger("download_finish"));
+		this.setWechat(metrics.getInteger("wechat"));
+		this.setCouponSinglePage(metrics.getInteger("coupon_single_page"));
+		this.setInstallFinish(metrics.getInteger("install_finish"));
+		this.setLottery(metrics.getInteger("lottery"));
+		this.setPlayOver(metrics.getInteger("play_over"));
+		this.setInAppOrder(metrics.getInteger("in_app_order"));
+		this.setDownloadStartCost(metrics.getBigDecimal("download_start_cost"));
+		this.setFollow(metrics.getInteger("follow"));
+		this.setMessage(metrics.getInteger("message"));
+		this.setInAppDetailUv(metrics.getInteger("in_app_detail_uv"));
+		this.setPlayDuration(metrics.getInteger("play_duration"));
+		this.setForm(metrics.getInteger("form"));
+		this.setValidPlayRate(metrics.getBigDecimal("valid_play_rate"));
+		this.setAveragePlayTimePerPlay(metrics.getBigDecimal("average_play_time_per_play"));
+		this.setConvertShowRate(metrics.getBigDecimal("convert_show_rate"));
+		this.setInstallFinishCost(metrics.getBigDecimal("install_finish_cost"));
+		this.setCommentMaterial(metrics.getInteger("comment"));
+		this.setInAppUv(metrics.getInteger("in_app_uv"));
+		this.setRegister(metrics.getInteger("register"));
+		this.setConvertCost(metrics.getBigDecimal("convert_cost"));
+	}
 }

+ 62 - 0
module-report/src/main/java/cn/com/ctop/bytedance/entity/BytedanceReportMaterialRetry.java

@@ -0,0 +1,62 @@
+package cn.com.ctop.bytedance.entity;
+
+import java.io.Serializable;
+import java.util.Date;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.annotation.TableField;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import org.springframework.format.annotation.DateTimeFormat;
+import org.jeecgframework.poi.excel.annotation.Excel;
+
+/**
+ * 头条素材报表连接出错数据记录表
+ * @author jeecg-boot
+ * @date   2020-04-21
+ * @version V1.0
+ */
+@Data
+@TableName("ctop_bytedance_report_material_retry")
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value="ctop_bytedance_report_material_retry对象", description="头条素材报表连接出错数据记录表")
+public class BytedanceReportMaterialRetry {
+
+	/**id*/
+	@TableId(type = IdType.AUTO)
+    @ApiModelProperty(value = "id")
+	private Integer id;
+	/**账户id*/
+	@Excel(name = "账户id", width = 15)
+    @ApiModelProperty(value = "账户id")
+	private Long accountId;
+	/**开始时间*/
+	@Excel(name = "开始时间", width = 15, format = "yyyy-MM-dd")
+	@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
+    @DateTimeFormat(pattern="yyyy-MM-dd")
+    @ApiModelProperty(value = "开始时间")
+	private String startDate;
+	/**结束时间*/
+	@Excel(name = "结束时间", width = 15, format = "yyyy-MM-dd")
+	@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
+    @DateTimeFormat(pattern="yyyy-MM-dd")
+    @ApiModelProperty(value = "结束时间")
+	private String endDate;
+	/**状态 0同步失败 1同步成功*/
+	@Excel(name = "状态 0同步失败 1同步成功", width = 15)
+    @ApiModelProperty(value = "状态 0同步失败 1同步成功")
+	private Integer status;
+	/**createTime*/
+    @ApiModelProperty(value = "createTime")
+	private Date createTime;
+	/**updateTime*/
+    @ApiModelProperty(value = "updateTime")
+	private Date updateTime;
+    private Integer statusCode;
+}

+ 7 - 0
module-report/src/main/java/cn/com/ctop/bytedance/mapper/BytedanceDailyReportTaskMapper.java

@@ -14,4 +14,11 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
  */
 public interface BytedanceDailyReportTaskMapper extends BaseMapper<BytedanceDailyReportTask> {
 
+    void loadBytedanceDailyCreativeFileAsync(@Param("localPath")String localPath);
+
+    void loadBytedanceDailyAccountFileAsync(@Param("localPath")String localPath);
+
+    void loadBytedanceDailyCampaignFileAsync(@Param("localPath")String localPath);
+
+    void loadBytedanceDailyPlanFileAsync(@Param("localPath")String localPath);
 }

+ 5 - 0
module-report/src/main/java/cn/com/ctop/bytedance/mapper/BytedancePlanDailyReportMapper.java

@@ -32,4 +32,9 @@ public interface BytedancePlanDailyReportMapper extends BaseMapper<BytedancePlan
             "set channel_code = substring_index(ad_name, '-', 1) " +
             "where advertiser_id in (select account_id from ctop_user_allocation where project_id = #{projectId}) and stat_datetime =#{date}")
     void cleanChannelCodeData(@Param(value = "projectId") Integer projectId, @Param(value = "date") String date);
+
+    @Update("update ctop_bytedance_report_plan_hourly report left join ctop_user_allocation allocation on report.advertiser_id = allocation.account_id " +
+            "set channel_code = substring_index(ad_name,'-',2) " +
+            "where allocation.project_id = #{projectId} and allocation.system_type = 'ios' and report.stat_datetime = #{date}")
+    void cleanYddHourlyChannelCode(@Param(value = "projectId") Integer projectId, @Param(value = "date") String date);
 }

+ 7 - 0
module-report/src/main/java/cn/com/ctop/bytedance/mapper/BytedanceReportMaterialDailyMapper.java

@@ -2,6 +2,7 @@ package cn.com.ctop.bytedance.mapper;
 
 import java.util.List;
 
+import cn.com.ctop.bytedance.entity.BytedanceReportMaterialRetry;
 import org.apache.ibatis.annotations.Param;
 import cn.com.ctop.bytedance.entity.BytedanceReportMaterialDaily;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
@@ -15,4 +16,10 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 public interface BytedanceReportMaterialDailyMapper extends BaseMapper<BytedanceReportMaterialDaily> {
 
     void replaceIntoBatch(@Param("infos") List<BytedanceReportMaterialDaily> infos);
+
+    void replaceMaterialRetry(@Param("retry")BytedanceReportMaterialRetry retry);
+
+    List<BytedanceReportMaterialRetry> getRetryList();
+
+    void updateRetry(@Param("retry")BytedanceReportMaterialRetry retry);
 }

+ 14 - 0
module-report/src/main/java/cn/com/ctop/bytedance/mapper/BytedanceReportMaterialRetryMapper.java

@@ -0,0 +1,14 @@
+package cn.com.ctop.bytedance.mapper;
+
+import cn.com.ctop.bytedance.entity.BytedanceReportMaterialRetry;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * 头条素材报表连接出错数据记录表
+ * @author: jeecg-boot
+ * @date:   2020-04-21
+ * @cersion: V1.0
+ */
+public interface BytedanceReportMaterialRetryMapper extends BaseMapper<BytedanceReportMaterialRetry> {
+
+}

+ 32 - 5
module-report/src/main/java/cn/com/ctop/bytedance/mapper/xml/AccountReportMapper.xml

@@ -27,7 +27,6 @@
         else 0
         end
         ) eventRegisterCost -- 注册成本
-
         from
         ctop_kuaishou_report_hourly_account
         where stat_date = #{date}
@@ -57,7 +56,14 @@
         (sum(charge) / sum(activation)) activationPrice, -- 激活单价
         ((sum(charge) / sum(activation)) / #{discount}) afterActivationPrice, -- 激活单价
         account_id accountId,
-        (select auth_name from ctop_user_allocation where account_id = accountId limit 1) accountName
+        (select auth_name from ctop_user_allocation where account_id = accountId limit 1) accountName,
+        sum(event_next_day_stay) eventNextDayStay,  -- 次留数
+        (case
+        when sum(activation) != 0
+        then (sum(event_next_day_stay)/sum(activation))
+        else 0
+        end
+        ) eventNextDayStayRatio  -- 次留率=次留数/激活数
         from
         ctop_kuaishou_report_daily_account
         where account_id in
@@ -93,7 +99,14 @@
         end
         ) eventRegisterCost, -- 注册成本
         account_id accountId,
-        (select auth_name from ctop_user_allocation where account_id = accountId limit 1) accountName
+        (select auth_name from ctop_user_allocation where account_id = accountId limit 1) accountName,
+        sum(event_next_day_stay) eventNextDayStay,  -- 次留数
+        (case
+        when sum(activation) != 0
+        then (sum(event_next_day_stay)/sum(activation))
+        else 0
+        end
+        ) eventNextDayStayRatio  -- 次留率=次留数/激活数
         from
         ctop_kuaishou_report_daily_account
         where stat_date &lt;= #{startDate}
@@ -167,7 +180,14 @@
         end
         ) eventRegisterCost, -- 注册成本
         account_id accountId,
-        (select auth_name from ctop_user_allocation where account_id = accountId limit 1) accountName
+        (select auth_name from ctop_user_allocation where account_id = accountId limit 1) accountName,
+        sum(event_next_day_stay) eventNextDayStay,  -- 次留数
+        (case
+        when sum(activation) != 0
+        then ( sum(event_next_day_stay) / sum(activation) )
+        else 0
+        end
+        ) eventNextDayStayRatio  -- 次留率=次留数/激活数
         from
         ctop_kuaishou_report_daily_account
         where stat_date = #{statDate}
@@ -430,7 +450,14 @@
         then (sum(charge) / sum(event_register))
         else 0
         end
-        ) eventRegisterCost -- 注册成本
+        ) eventRegisterCost, -- 注册成本
+        sum(event_next_day_stay) eventNextDayStay,  -- 次留数
+        (case
+        when sum(activation) != 0
+        then (sum(event_next_day_stay)/sum(activation))
+        else 0
+        end
+        ) eventNextDayStayRatio  -- 次留率=次留数/激活数
 
         from
         ctop_kuaishou_report_daily_account

+ 108 - 1
module-report/src/main/java/cn/com/ctop/bytedance/mapper/xml/BytedanceDailyReportTaskMapper.xml

@@ -2,4 +2,111 @@
 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 <mapper namespace="cn.com.ctop.bytedance.mapper.BytedanceDailyReportTaskMapper">
 
-</mapper>
+    <insert id="loadBytedanceDailyCreativeFileAsync">
+		LOAD DATA local INFILE  #{localPath}
+		REPLACE INTO TABLE ctop_bytedance_report_creative_daily_async CHARACTER SET utf8mb4
+		FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n'
+		IGNORE 1 LINES
+		(
+		campaign_id,
+        deep_convert_rate,
+        ad_id,
+        ctr,
+        show_material,
+        avg_show_cost,
+        creative_id,
+        convert_cost,
+        convert_material,
+        deep_convert_cost,
+        account_id,
+        cost,
+        deep_convert,
+        avg_click_cost,
+        ad_name,
+        campaign_name,
+        convert_rate,
+        creative_material_mode,
+        click,
+        stat_datetime
+        )
+    </insert>
+
+    <insert id="loadBytedanceDailyAccountFileAsync">
+        LOAD DATA local INFILE  #{localPath}
+        REPLACE INTO TABLE ctop_bytedance_report_account_daily_async CHARACTER SET utf8mb4
+        FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n'
+        IGNORE 1 LINES
+        (
+            deep_convert_rate,
+            pricing_category,
+            ctr,
+            show_material,
+            avg_show_cost,
+            convert_rate,
+            convert_cost,
+            convert_material,
+            deep_convert_cost,
+            account_id,
+            cost,
+            deep_convert,
+            avg_click_cost,
+            click,
+            stat_datetime
+        )
+    </insert>
+
+    <insert id="loadBytedanceDailyCampaignFileAsync">
+        LOAD DATA local INFILE  #{localPath}
+        REPLACE INTO TABLE ctop_bytedance_report_campaign_daily_async CHARACTER SET utf8mb4
+        FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n'
+        IGNORE 1 LINES
+        (
+            campaign_type,
+            deep_convert_rate,
+            ctr,
+            show_material,
+            avg_show_cost,
+            convert_rate,
+            convert_cost,
+            campaign_id,
+            deep_convert_cost,
+            account_id,
+            cost,
+            deep_convert,
+            avg_click_cost,
+            campaign_name,
+            convert_material,
+            click,
+            stat_datetime
+        )
+    </insert>
+
+    <insert id="loadBytedanceDailyPlanFileAsync">
+        LOAD DATA local INFILE  #{localPath}
+        REPLACE INTO TABLE ctop_bytedance_report_plan_daily_async CHARACTER SET utf8mb4
+        FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n'
+        IGNORE 1 LINES
+        (
+            landing_type,
+            deep_convert_rate,
+            ad_id,
+            ctr,
+            show_material,
+            avg_show_cost,
+            convert_rate,
+            convert_cost,
+            convert_material,
+            deep_convert_cost,
+            account_id,
+            cost,
+            deep_convert,
+            avg_click_cost,
+            ad_name,
+            campaign_name,
+            click,
+            stat_datetime,
+            campaign_id
+        )
+    </insert>
+
+</mapper>

+ 41 - 0
module-report/src/main/java/cn/com/ctop/bytedance/mapper/xml/BytedanceReportMaterialDailyMapper.xml

@@ -205,4 +205,45 @@
         </foreach>
     </insert>
 
+    <insert id="replaceMaterialRetry">
+        REPLACE INTO ctop_bytedance_report_material_retry
+        (
+            account_id,
+            start_date,
+            end_date,
+            status,
+            status_code
+        )
+        VALUES
+        (
+            #{retry.accountId},
+            #{retry.startDate},
+            #{retry.endDate},
+            #{retry.status},
+            #{retry.statusCode}
+        )
+
+    </insert>
+
+    <select id="getRetryList" resultType="cn.com.ctop.bytedance.entity.BytedanceReportMaterialRetry">
+            select
+            account_id,
+            start_date,
+            end_date,
+            status
+        from
+        ctop_bytedance_report_material_retry
+        where status = 0
+    </select>
+
+    <update id="updateRetry">
+        update
+        ctop_bytedance_report_material_retry
+        set
+        status = 1
+        where
+        account_id = #{retry.accountId}
+        and start_date = #{retry.startDate}
+        and end_date = #{retry.endDate}
+    </update>
 </mapper>

+ 5 - 0
module-report/src/main/java/cn/com/ctop/bytedance/mapper/xml/BytedanceReportMaterialRetryMapper.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="cn.com.ctop.bytedance.mapper.BytedanceReportMaterialRetryMapper">
+
+</mapper>

+ 2 - 0
module-report/src/main/java/cn/com/ctop/bytedance/service/IBytedancePlanDailyReportService.java

@@ -21,4 +21,6 @@ public interface IBytedancePlanDailyReportService extends IService<BytedancePlan
     void cleanYzData(Integer projectId);
 
     void cleanChannelCodeData(Integer projectId, Date getDate);
+
+    void cleanYddHourlyChannelCode(Integer projectId, Date getDate);
 }

+ 14 - 0
module-report/src/main/java/cn/com/ctop/bytedance/service/IBytedanceReportMaterialRetryService.java

@@ -0,0 +1,14 @@
+package cn.com.ctop.bytedance.service;
+
+import cn.com.ctop.bytedance.entity.BytedanceReportMaterialRetry;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ * 头条素材报表连接出错数据记录表
+ * @author jeecg-boot
+ * @date   2020-04-21
+ * @version V1.0
+ */
+public interface IBytedanceReportMaterialRetryService extends IService<BytedanceReportMaterialRetry> {
+
+}

+ 7 - 3
module-report/src/main/java/cn/com/ctop/bytedance/service/IBytedanceReportService.java

@@ -1,8 +1,10 @@
 package cn.com.ctop.bytedance.service;
 
+import cn.com.ctop.bytedance.entity.BytedanceReportMaterialRetry;
 import cn.com.ctop.common.module.entity.CtopOauthToken;
 import com.alibaba.fastjson.JSONObject;
 
+import java.text.ParseException;
 import java.util.List;
 
 public interface IBytedanceReportService {
@@ -34,11 +36,13 @@ public interface IBytedanceReportService {
      */
     List<JSONObject> getReportList(JSONObject requestJson);
 
-
-
-    void bytedanceAsyncTaskCreate();
+    void bytedanceAsyncTaskCreate(String startDate, String endDate, CtopOauthToken token, Integer type) throws ParseException;
 
     void bytedanceAsyncTaskGet();
 
     void bytedanceMaterialReport(CtopOauthToken token, String startDate, String endDate);
+
+    void bytedanceMaterialReportRetry(CtopOauthToken token, String startDate, String endDate);
+
+    List<BytedanceReportMaterialRetry> getRetryList();
 }

+ 5 - 7
module-report/src/main/java/cn/com/ctop/bytedance/service/IReportService.java

@@ -10,23 +10,21 @@ import java.util.Map;
 public interface IReportService {
     Map<String, Object> getAdvertiserReport(ByteDanceAdvertiserReportDTO conditions);
 
-    Map<String, Object> getAgentReport(JSONObject conditions);
-
-    void insertCustomerInfo(String csvPath, String charset);
+    void getAdvertiserCampaignReport(CtopOauthToken token, Date startDate, Date endDate, String bytedanceReportTypePl);
 
-    void insertPlatformInfo(String excelPath, String charset, Long accountId);
+    Map<String, Object> getCampaignReport(ByteDanceAdvertiserReportDTO conditions);
 
-    Map<String, Object> debitAuto(JSONObject data);
+    Map<String, Object> getAgentReport(JSONObject conditions);
 
     void getAdvertiserReport(CtopOauthToken token, Date startDate, Date endDate, String bytedanceReportTypePl);
 
-    void getAdvertiserCampaignReport(CtopOauthToken token, Date startDate, Date endDate, String bytedanceReportTypePL);
-
     void getCampaignReportByPage(CtopOauthToken token, Date startDate, Date endDate, String bytedanceReportTypePl, Integer pageNum);
 
     void getAdvertiserPlanReport(CtopOauthToken token, Date startDate, Date endDate, String bytedanceReportTypePL);
 
     void getAdvertiserCreativeReport(CtopOauthToken token, Date startDate, Date endDate, String bytedanceReportTypePL);
 
+    void getMaterialReportByPage(CtopOauthToken token, String startDate, String endDate, Integer pageNum);
+
     void loadBytedanceHistoryData(CtopOauthToken token);
 }

+ 28 - 0
module-report/src/main/java/cn/com/ctop/bytedance/service/impl/AccountReportServiceImpl.java

@@ -523,6 +523,34 @@ public class AccountReportServiceImpl implements IAccountReportService {
                             chainRatioJson.put("eventRegisterProportion", 0);
                         }
 
+                        //次留数
+                        Long nowEventNextDayStay = nowAccountSummary.getLong("activationCount");
+                        Long yesterdayEventNextDayStay = yesterdayAccountSummary.getLong("activationCount");
+                        //表单提交数环比
+                        if (!Check.isNull(nowEventNextDayStay) && !Check.isNull(yesterdayEventNextDayStay)) {
+                            if (yesterdayAClick != 0L) {
+                                double eventNextDayStayProportion = (nowEventNextDayStay.doubleValue() - yesterdayEventNextDayStay.doubleValue()) / yesterdayEventNextDayStay.doubleValue();
+                                chainRatioJson.put("eventNextDayStayProportion", eventNextDayStayProportion);
+                            } else {
+                                chainRatioJson.put("eventNextDayStayProportion", 0);
+                            }
+                        } else {
+                            chainRatioJson.put("eventNextDayStayProportion", 0);
+                        }
+
+
+                        BigDecimal nowEventNextDayStayRatio = nowAccountSummary.getBigDecimal("eventRegister");  // 今日注册数
+                        BigDecimal yesterdayEventNextDayStayRatio = yesterdayAccountSummary.getBigDecimal("eventRegister"); // 昨日注册数
+                        if (!Check.isNull(nowEventNextDayStayRatio) && !Check.isNull(yesterdayEventNextDayStayRatio)) {
+                            if (yesterdayEventNextDayStayRatio.compareTo(new BigDecimal(0)) != 0) {
+                                BigDecimal eventNextDayStayRatioProportion = (nowEventNextDayStayRatio.subtract(yesterdayEventNextDayStayRatio)).divide(yesterdayEventNextDayStayRatio, 4, RoundingMode.HALF_UP);
+                                chainRatioJson.put("eventNextDayStayRatioProportion", eventNextDayStayRatioProportion);
+                            } else {
+                                chainRatioJson.put("eventNextDayStayRatioProportion", 0);
+                            }
+                        } else {
+                            chainRatioJson.put("eventNextDayStayRatioProportion", 0);
+                        }
 
                         returnJson.put("chainRatio", chainRatioJson);
                     }

+ 6 - 0
module-report/src/main/java/cn/com/ctop/bytedance/service/impl/BytedancePlanDailyReportServiceImpl.java

@@ -62,4 +62,10 @@ public class BytedancePlanDailyReportServiceImpl extends ServiceImpl<BytedancePl
         String dateString = DateUtils.formatDate(getDate) + " 00:00:00";
         dailyReportMapper.cleanChannelCodeData(projectId, dateString);
     }
+
+    @Override
+    public void cleanYddHourlyChannelCode(Integer projectId, Date getDate) {
+        String dateString = DateUtils.formatDate(getDate);
+        dailyReportMapper.cleanYddHourlyChannelCode(projectId, dateString);
+    }
 }

+ 19 - 0
module-report/src/main/java/cn/com/ctop/bytedance/service/impl/BytedanceReportMaterialRetryServiceImpl.java

@@ -0,0 +1,19 @@
+package cn.com.ctop.bytedance.service.impl;
+
+import cn.com.ctop.bytedance.entity.BytedanceReportMaterialRetry;
+import cn.com.ctop.bytedance.mapper.BytedanceReportMaterialRetryMapper;
+import cn.com.ctop.bytedance.service.IBytedanceReportMaterialRetryService;
+import org.springframework.stereotype.Service;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+
+/**
+ * 头条素材报表连接出错数据记录表
+ * @author jeecg-boot
+ * @date   2020-04-21
+ * @version V1.0
+ */
+@Service
+public class BytedanceReportMaterialRetryServiceImpl extends ServiceImpl<BytedanceReportMaterialRetryMapper, BytedanceReportMaterialRetry> implements IBytedanceReportMaterialRetryService {
+
+}

+ 143 - 91
module-report/src/main/java/cn/com/ctop/bytedance/service/impl/BytedanceReportServiceImpl.java

@@ -3,6 +3,7 @@ package cn.com.ctop.bytedance.service.impl;
 import cn.com.ctop.bytedance.entity.BytedanceAdvertiserDailyReport;
 import cn.com.ctop.bytedance.entity.BytedanceDailyReportTask;
 import cn.com.ctop.bytedance.entity.BytedanceReportMaterialDaily;
+import cn.com.ctop.bytedance.entity.BytedanceReportMaterialRetry;
 import cn.com.ctop.bytedance.mapper.BytedanceAdvertiserDailyReportMapper;
 import cn.com.ctop.bytedance.mapper.BytedanceDailyReportTaskMapper;
 import cn.com.ctop.bytedance.mapper.BytedanceReportMapper;
@@ -30,6 +31,7 @@ import org.apache.http.entity.ContentType;
 import org.apache.http.entity.StringEntity;
 import org.apache.http.impl.client.CloseableHttpClient;
 import org.apache.http.impl.client.HttpClientBuilder;
+import org.bytedeco.javacpp.freenect2;
 import org.jeecg.common.util.DateUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
@@ -41,6 +43,8 @@ import java.io.InputStreamReader;
 import java.math.BigDecimal;
 import java.math.RoundingMode;
 import java.net.URI;
+import java.sql.Timestamp;
+import java.text.ParseException;
 import java.util.*;
 
 @Service
@@ -673,18 +677,42 @@ public class BytedanceReportServiceImpl implements IBytedanceReportService {
 
     /////////////////////////////////////////////////////////////////////////////////////////////////
     //创建异步任务
-    public void bytedanceAsyncTaskCreate () {
-        String startDate = DateUtils.formatDate(DateUtils.addDay(new Date(), -1));
-        String endDate = DateUtils.formatDate(DateUtils.addDay(new Date(), -31));
-        String type = "BYTEDANCE_LOAD_JOB_TYPE_ASYNC";
-        Long accountId = 1662649623517198L;
+    public void bytedanceAsyncTaskCreate (String startDate, String endDate, CtopOauthToken token, Integer type) throws ParseException {
+        int diffMonths = DateUtils.calDiffMonth(DateUtils.parseDate(startDate,"yyyy-MM-dd"),DateUtils.parseDate(endDate,"yyyy-MM-dd"));
+        if (diffMonths == 0) {
+            bytedanceAsyncTaskCreateByMonth(startDate, endDate, token, type);
+        }else{
+            for(int i=0; i<=diffMonths ; i++){
+                if (i == 0){
+                    Map<String,String> dateMap = DateUtils.getMaxMinDaysOfAddMonth(startDate,"yyyy-MM-dd", i);
+                    String end = dateMap.get("endDate");
+                    //System.out.println(startDate + " ----- " + end);
+                    bytedanceAsyncTaskCreateByMonth(startDate, end, token, type);
+                }else if(i == diffMonths){
+                    Map<String,String> dateMap = DateUtils.getMaxMinDaysOfAddMonth(startDate,"yyyy-MM-dd", i);
+                    String start = dateMap.get("startDate");
+                    //System.out.println(start + " ----- " + endDate);
+                    bytedanceAsyncTaskCreateByMonth(start, endDate, token, type);
+                }else{
+                    Map<String,String> dateMap = DateUtils.getMaxMinDaysOfAddMonth(startDate,"yyyy-MM-dd", i);
+                    String start = dateMap.get("startDate");
+                    String end = dateMap.get("endDate");
+                    //System.out.println(start + " ----- " + end);
+                    bytedanceAsyncTaskCreateByMonth(start, end, token, type);
+                }
+            }
+        }
+    }
 
-        CtopOauthToken token = ctopOauthTokenService.getTokenByAccountId(accountId);
+    /***
+     * 由于异步拉取数据不能跨月,故只能按月循环拉取
+     * @param startDate
+     * @param endDate
+     * @param token
+     */
+    private void bytedanceAsyncTaskCreateByMonth(String startDate, String endDate, CtopOauthToken token, Integer type){
         String access_token = token.getAccessToken();
-        Long advertiser_id = accountId;
-        //final Long[] ad_ids = new Long[]{1L};
-        //List<String> fields_list = FIELDS;
-        //ist<String> fields_list = new ArrayList<>();
+        Long accountId = token.getAccountId();
 
         // 请求地址
         String open_api_domain = "https://ad.toutiao.com";
@@ -694,16 +722,22 @@ public class BytedanceReportServiceImpl implements IBytedanceReportService {
         // 请求参数
         final Map filtering = new HashMap() {
             {
-                //put("start_date", startDate);
-                //put("end_date", endDate);
-                put("start_date", "2020-04-01");
-                put("end_date", "2020-04-15");
-                put("group_by", new String[]{"STAT_GROUP_BY_CREATIVE_ID","STAT_GROUP_BY_TIME_DAY","STAT_GROUP_BY_CREATIVE_MATERIAL_MODE"});   //按照创意分组、天分组、创意类型分组查询
+                put("start_date", startDate);
+                put("end_date", endDate);
+                if(type == 1){//素材
+                    put("group_by", new String[]{"STAT_GROUP_BY_CREATIVE_ID","STAT_GROUP_BY_TIME_DAY","STAT_GROUP_BY_CREATIVE_MATERIAL_MODE"});   //按照创意分组、天分组、创意类型分组查询
+                }else if(type == 2){//广告主
+                    put("group_by", new String[]{"STAT_GROUP_BY_ADVERTISER_ID","STAT_GROUP_BY_TIME_DAY","STAT_GROUP_BY_PRICING_CATEGORY"});   //按照广告主分组、天分组、广告类型类型分组查询
+                }else if(type == 3){//广告组
+                    put("group_by", new String[]{"STAT_GROUP_BY_CAMPAIGN_ID","STAT_GROUP_BY_TIME_DAY","STAT_GROUP_BY_CAMPAIGN_TYPE"});  //按照广告组、天、广告组类型分组
+                }else {//4广告计划
+                    put("group_by", new String[]{"STAT_GROUP_BY_AD_ID","STAT_GROUP_BY_TIME_DAY","STAT_GROUP_BY_LANDING_TYPE"});  //按照广告计划、天、推广类型分组
+                }
             }
         };
-        Map data = new HashMap() {
+        final Map data = new HashMap() {
             {
-                put("advertiser_id", advertiser_id);
+                put("advertiser_id", accountId);
                 put("task_name", taskName);
                 put("task_type", "REPORT");
                 put("task_params", filtering);
@@ -759,6 +793,9 @@ public class BytedanceReportServiceImpl implements IBytedanceReportService {
                     task.setJson(jsonString);
                     task.setTaskStatus(dataJson.getString("task_status"));
                     task.setTaskType(dataJson.getString("task_type"));
+                    task.setType(type);
+                    task.setIsDownload(0);
+                    task.setStatus(1); //状态1正常 0废弃
                     bytedanceDailyReportTaskMapper.insert(task);
                 }
 
@@ -785,7 +822,9 @@ public class BytedanceReportServiceImpl implements IBytedanceReportService {
     public void bytedanceAsyncTaskGet(){
         QueryWrapper<BytedanceDailyReportTask> taskQueryWrapper = new QueryWrapper<>();
         //查询三种状态的信息--任务已创建、任务执行中、任务处理中
-        taskQueryWrapper.in("task_status", "ASYNC_TASK_STATUS_CREATED","ASYNC_TASK_STATUS_EXECUTING","ASYNC_TASK_STATUS_EXECUTING_STAGE2");
+        taskQueryWrapper.eq("is_download",0);
+        //taskQueryWrapper.in("task_status", "ASYNC_TASK_STATUS_CREATED","ASYNC_TASK_STATUS_EXECUTING","ASYNC_TASK_STATUS_EXECUTING_STAGE2");
+        taskQueryWrapper.notIn("task_status", "ASYNC_TASK_STATUS_FAILED");
         taskQueryWrapper.orderByDesc("create_time");
         List<BytedanceDailyReportTask> taskList = bytedanceDailyReportTaskService.list(taskQueryWrapper);
 
@@ -801,7 +840,6 @@ public class BytedanceReportServiceImpl implements IBytedanceReportService {
                     String access_token = token.getAccessToken();
                     Long accountId = task.getAccountId();
                     final Long advertiser_id = accountId;
-                    //Long taskId = 682327L;
 
                     // 请求参数
                     final Map filtering = new HashMap() {
@@ -869,7 +907,8 @@ public class BytedanceReportServiceImpl implements IBytedanceReportService {
                                         String taskStatus = detailJson.getString("task_status");
 
                                         if (taskStatus .equals( "ASYNC_TASK_STATUS_COMPLETED")) {
-                                            bytedanceAsyncTaskDownload(task,token);
+                                            bytedanceAsyncTaskDownload(task,token,task.getType());
+                                            task.setIsDownload(1);
                                         }
                                             task.setTaskStatus(taskStatus);
                                             bytedanceDailyReportTaskMapper.updateById(task);
@@ -901,87 +940,76 @@ public class BytedanceReportServiceImpl implements IBytedanceReportService {
         }
     }
 
-    //下载任务结果
-    private void bytedanceAsyncTaskDownload(BytedanceDailyReportTask task, CtopOauthToken token){
+    //下载任务结果   type 1.creative 2.account 3.campaign 4.plan
+    private void bytedanceAsyncTaskDownload(BytedanceDailyReportTask task, CtopOauthToken token, Integer type){
         // 请求地址
         String open_api_domain = "https://ad.toutiao.com";
         String path = "/open_api/2/async_task/download/";
 
-        Long accountId = task.getAccountId();
-        final Long advertiser_id = accountId;
-        String access_token = token.getAccessToken();
-        Long taskId = task.getTaskId();
-
-        //Map data = new HashMap(){
-        //    {
-        //        put("advertiser_id", advertiser_id);
-        //        put("task_id", taskId);
-        //    }
-        //};
-        //
-        //// 构造请求
-        //HttpEntityEnclosingRequestBase httpEntity = new HttpEntityEnclosingRequestBase() {
-        //    @Override
-        //    public String getMethod() {
-        //        return "GET";
-        //    }
-        //};
-        //
-        //httpEntity.setHeader("Access-Token",access_token);
-        //
-        //CloseableHttpResponse response = null;
-        //CloseableHttpClient client = null;
-
-
-
-        try {
-            //client = HttpClientBuilder.create().build();
-            //httpEntity.setURI(URI.create(open_api_domain + path));
-            //httpEntity.setEntity(new StringEntity(JSONObject.toJSONString(data), ContentType.APPLICATION_JSON));
-            //
-            //response = client.execute(httpEntity);
-            //log.info("response为:" +  response);
-            //if (response != null && response.getStatusLine().getStatusCode() == 200) {
-            //    BufferedReader bufferedReader  = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
-            //    StringBuffer result = new StringBuffer();
-            //    String line = "";
-            //    while((line = bufferedReader.readLine()) != null) {
-            //        result.append(line);
-            //    }
-            //    bufferedReader.close();
-
-            String url = open_api_domain + path;
-            String fileName = task.getAccountId() + "_" +  ".csv";
-            Map<String, Object> requestMap = new HashMap<>();
-            requestMap.put("advertiser_id", task.getAccountId());
-            requestMap.put("task_id", task.getTaskId());
-            String localPath = DownloadUtils.downloadByUrl(requestMap, downloadPath, url, token.getAccessToken(), fileName);
-
-
-
-        } catch (Exception e) {
-            e.printStackTrace();
-            //task.setTaskStatus(5);
+        String url = open_api_domain + path;
+        String fileName = task.getAccountId() + "_" + "type" + type + "_" +System.currentTimeMillis() + ".csv";
+        Map<String, Object> requestMap = new HashMap<>();
+        requestMap.put("advertiser_id", task.getAccountId());
+        requestMap.put("task_id", task.getTaskId());
+        String localPath = DownloadUtils.downloadByUrl(requestMap, downloadPath, url, token.getAccessToken(), fileName);
+        if(type == 1){
+            //素材异步报表
+            bytedanceDailyReportTaskMapper.loadBytedanceDailyCreativeFileAsync(localPath);
+        }else if(type == 2){
+            //账户异步报表
+            bytedanceDailyReportTaskMapper.loadBytedanceDailyAccountFileAsync(localPath);
+        }else if(type == 3){
+            //campaign异步报表
+            bytedanceDailyReportTaskMapper.loadBytedanceDailyCampaignFileAsync(localPath);
+        }else if(type == 4){
+            //plan异步报表
+            bytedanceDailyReportTaskMapper.loadBytedanceDailyPlanFileAsync(localPath);
+        }else{
+            log.error("异步报表类型传入错误,task_id:" + task.getTaskId() + ";类型:" + type);
         }
-
-        return;
     }
 
-
-
-
     /////////////////////////////////////////////////////////\
     //素材报表
+    public void bytedanceMaterialReportRetry(CtopOauthToken token, String startDate, String endDate){
+        Long accountId = token.getAccountId();
+        log.info("头条素材报表当前accountId为:" + accountId);
+        Integer page = 1;
+        Integer pageSize = 100;
+        int code = bytedanceMaterialReportByPage(page, pageSize, token, accountId, startDate, endDate);
+
+        BytedanceReportMaterialRetry retry = new BytedanceReportMaterialRetry();
+        retry.setAccountId(accountId);
+        retry.setStartDate(startDate);
+        retry.setEndDate(endDate);
+        retry.setStatusCode(code);
+        if (code != 200 && code != 1){
+            retry.setStatus(0);
+            bytedanceReportMaterialDailyMapper.replaceMaterialRetry(retry);
+        }else{
+            retry.setStatus(1);
+            bytedanceReportMaterialDailyMapper.replaceMaterialRetry(retry);
+        }
+    }
+
     public void bytedanceMaterialReport(CtopOauthToken token, String startDate, String endDate){
-        //CtopOauthToken token = ctopOauthTokenService.getTokenByAccountId(accountId);
         Long accountId = token.getAccountId();
         log.info("头条素材报表当前accountId为:" + accountId);
         Integer page = 1;
-        Integer pageSize = 500;
-        bytedanceMaterialReportByPage(page, pageSize, token, accountId, startDate, endDate);
+        Integer pageSize = 100;
+        int code = bytedanceMaterialReportByPage(page, pageSize, token, accountId, startDate, endDate);
+        if (code != 200 && code != 1){
+            BytedanceReportMaterialRetry retry = new BytedanceReportMaterialRetry();
+            retry.setAccountId(accountId);
+            retry.setStatus(0);
+            retry.setStartDate(startDate);
+            retry.setEndDate(endDate);
+            retry.setStatusCode(code);
+            bytedanceReportMaterialDailyMapper.replaceMaterialRetry(retry);
+        }
     }
 
-    private void bytedanceMaterialReportByPage(Integer page, Integer pageSize, CtopOauthToken token, Long accountId, String startDate, String endDate){
+    private int bytedanceMaterialReportByPage(Integer page, Integer pageSize, CtopOauthToken token, Long accountId, String startDate, String endDate){
         //log.info("当前页数:"+ page);
         String access_token = token.getAccessToken();
 
@@ -1020,7 +1048,10 @@ public class BytedanceReportServiceImpl implements IBytedanceReportService {
         CloseableHttpResponse response = null;
         CloseableHttpClient client = null;
 
+        int returnCode = 200;
         try {
+            //Long connectStartTime = System.currentTimeMillis();
+
             client = HttpClientBuilder.create().build();
             httpEntity.setURI(URI.create(open_api_domain + path));
             httpEntity.setEntity(new StringEntity(JSONObject.toJSONString(data), ContentType.APPLICATION_JSON));
@@ -1032,6 +1063,8 @@ public class BytedanceReportServiceImpl implements IBytedanceReportService {
             //httpEntity.setConfig(requestConfig);
 
             response = client.execute(httpEntity);
+            //Long connectEndTime = System.currentTimeMillis();
+            //log.info("头条获取素材报表数据任务获取服务器数据结束,执行耗时:{}秒", (connectEndTime - connectStartTime) / 1000);
             //System.out.println(response);
             if (response != null && response.getStatusLine().getStatusCode() == 200) {
                 BufferedReader bufferedReader  = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
@@ -1050,7 +1083,8 @@ public class BytedanceReportServiceImpl implements IBytedanceReportService {
                     Integer code = json.getInteger("code");
                     if(code != 0){
                         log.info("获取任务列表返回信息错误,错误码为:" + code + ",头条accountId:" + accountId + ";返回json为:" + jsonString);
-                        return;
+                        returnCode = -1;
+                        return -1;
                     }
 
                     JSONObject jsonData = json.getJSONObject("data");
@@ -1064,8 +1098,10 @@ public class BytedanceReportServiceImpl implements IBytedanceReportService {
                     JSONArray jsonArrayay = jsonData.getJSONArray("list");
                     if(jsonArrayay.size() == 0){
                         log.info("accountId:" + accountId + ";没有数据。总页数为:" +  totalPage + "当前页数为:" + currentPage);
-                        return;
+                        returnCode = 1;
+                        return 1;
                     }
+
                     List<BytedanceReportMaterialDaily> bytedanceReportMaterialDailyList = new ArrayList<>();
                     for (int i = 0; i < jsonArrayay.size(); i++) {
                         BytedanceReportMaterialDaily daily = new BytedanceReportMaterialDaily();
@@ -1175,22 +1211,33 @@ public class BytedanceReportServiceImpl implements IBytedanceReportService {
                             //bytedanceReportMaterialDailyMapper.insert(daily);
                         }
                     }
-
+                    //Long insertStartTime = System.currentTimeMillis();
                     bytedanceReportMaterialDailyMapper.replaceIntoBatch(bytedanceReportMaterialDailyList);
+                    //Long insertEndTime = System.currentTimeMillis();
+                    //log.info("头条获取素材报表插入数据结束,执行耗时:{}秒", (insertEndTime - insertStartTime) / 1000);
                     if(currentPage >= totalPage){
-                        log.info("accountId:" + accountId + "数据同步完成");
-                        return;
+                        log.info("accountId:" + accountId + "数据同步完成,开始时间:" + startDate + ",结束时间:"+ endDate);
+                        //returnCode = 1;
+                        return 1;
                     }else{
                         bytedanceMaterialReportByPage(page + 1, pageSize, token, accountId, startDate, endDate);
                     }
+                }else{
+                    returnCode = -1;
+                    log.error("服务器返回为空,json:"+jsonString);
+                    return -1;
                 }
             }else{
                 log.error("头条素材报表请求有误:accountId:" + accountId + ",开始时间:" + startDate + "结束时间:" + endDate + "错误返回:" +response);
+                returnCode = 0;  //504等状态0;-2连接服务器报错 ;-1对方服务器返回值为空;200正常;1没有数据(也属于正常)
+                return 0;
             }
         } catch (ClientProtocolException e) {
             e.printStackTrace();
+            returnCode = -2;
         } catch (IOException e) {
             e.printStackTrace();
+            returnCode = -2;
         } finally {
             try {
                 if (response != null) {
@@ -1201,6 +1248,11 @@ public class BytedanceReportServiceImpl implements IBytedanceReportService {
                 e.printStackTrace();
             }
         }
+        return returnCode;
+    }
+
+    public List<BytedanceReportMaterialRetry> getRetryList(){
+        return bytedanceReportMaterialDailyMapper.getRetryList();
     }
 
 }

+ 108 - 489
module-report/src/main/java/cn/com/ctop/bytedance/service/impl/ReportServiceImpl.java

@@ -1,39 +1,33 @@
 package cn.com.ctop.bytedance.service.impl;
 
 import cn.com.ctop.bytedance.entity.*;
+import cn.com.ctop.bytedance.mapper.BytedanceReportMaterialDailyMapper;
 import cn.com.ctop.bytedance.mapper.CustomerPlanStatisticInfoMapper;
 import cn.com.ctop.bytedance.mapper.PlatformCampaignStatisticInfoMapper;
 import cn.com.ctop.bytedance.service.*;
 import cn.com.ctop.bytedance.vo.ByteDanceAdvertiserReportDTO;
-import cn.com.ctop.bytedance.vo.StatisticCampaignVo;
 import cn.com.ctop.common.module.entity.CtopOauthToken;
 import cn.com.ctop.common.module.service.ICtopOauthTokenService;
-import cn.com.ctop.common.module.utils.*;
+import cn.com.ctop.common.module.utils.Check;
+import cn.com.ctop.common.module.utils.CtopAdConstant;
+import cn.com.ctop.common.module.utils.HttpUtils;
+import cn.com.ctop.common.module.utils.PropertiesUtils;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.alibaba.fastjson.PropertyNamingStrategy;
 import com.alibaba.fastjson.serializer.SerializeConfig;
-import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import lombok.extern.slf4j.Slf4j;
 import lombok.var;
-import org.apache.poi.hssf.usermodel.HSSFDataFormat;
-import org.apache.poi.ss.usermodel.Cell;
-import org.apache.poi.ss.usermodel.CellStyle;
-import org.apache.poi.ss.usermodel.Row;
-import org.apache.poi.xssf.usermodel.XSSFSheet;
-import org.apache.poi.xssf.usermodel.XSSFWorkbook;
 import org.jeecg.common.util.DateUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 
-import java.io.*;
-import java.math.BigDecimal;
-import java.net.HttpURLConnection;
-import java.net.URL;
-import java.text.SimpleDateFormat;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
 
 /**
  * @author 宋英豪
@@ -78,6 +72,10 @@ public class ReportServiceImpl implements IReportService {
         getAdvertiserReportByPage(token, conditions, 1);
     }
 
+    @Override
+    public void getCampaignReportByPage(CtopOauthToken token, Date startDate, Date endDate, String bytedanceReportTypePl, Integer pageNum) {
+    }
+
     private void getAdvertiserReportByPage(CtopOauthToken token, ByteDanceAdvertiserReportDTO conditions, Integer page) {
         conditions.setPage(page);
         SerializeConfig config = new SerializeConfig();
@@ -146,10 +144,12 @@ public class ReportServiceImpl implements IReportService {
         getCampaignReportByPage(token, conditions, 1);
     }
 
-    @Override
-    public void getCampaignReportByPage(CtopOauthToken token, Date startDate, Date endDate, String bytedanceReportTypePl, Integer pageNum) {
-        JSONObject getObject = getCampaignStat(token, startDate, endDate, bytedanceReportTypePl, pageNum);
-        System.out.println("返回数据:" + getObject.toJSONString());
+    private void getCampaignReportByPage(CtopOauthToken token, ByteDanceAdvertiserReportDTO conditions, int page) {
+        conditions.setPage(page);
+        SerializeConfig config = new SerializeConfig();
+        config.propertyNamingStrategy = PropertyNamingStrategy.SnakeCase;
+        JSONObject jsonObject = JSONObject.parseObject(JSON.toJSONString(conditions, config));
+        JSONObject getObject = getCampaignStat(token, jsonObject);
         Integer code = getObject.getInteger("code");
         String message = getObject.getString("message");
         if (null == code || code != 0) {
@@ -163,63 +163,51 @@ public class ReportServiceImpl implements IReportService {
         }
         for (var i = 0; i < dataArray.size(); i++) {
             var data = dataArray.getJSONObject(i);
-            if (CtopAdConstant.BYTEDANCE_REPORT_TYPE_HOURLY.equals(bytedanceReportTypePl)) {
+            if (null != conditions.getTimeGranularity() && CtopAdConstant.BYTEDANCE_REPORT_TYPE_HOURLY.equals(conditions.getTimeGranularity())) {
                 var hourlyReport = new BytedanceCampaignHourlyReport(data, token.getAccountId());
                 campaignHourlyReportService.saveOrUpdate(hourlyReport);
             } else {
-                System.out.println(data.toJSONString());
                 var dailyReport = new BytedanceCampaignDailyReport(data, token.getAccountId());
                 campaignDailyReportService.saveOrUpdate(dailyReport);
             }
         }
-        getCampaignReportByPage(token, startDate, endDate, bytedanceReportTypePl, pageNum + 1);
-    }
-
-    private JSONObject getCampaignStat(CtopOauthToken token, Date startDate, Date endDate, String bytedanceReportTypePl, Integer pageNum) {
-        // 请求地址
-        String url = "https://ad.oceanengine.com/open_api/2/report/campaign/get/";
-        // 请求参数
-        JSONObject params = new JSONObject();
-        params.put("page", pageNum);
-        params.put("page_size", 100);
-        params.put("advertiser_id", token.getAccountId());
-        params.put("start_date", DateUtils.formatDate(startDate));
-        params.put("end_date", DateUtils.formatDate(endDate));
-        params.put("time_granularity", bytedanceReportTypePl);
-        params.put("group_by", new String[]{"STAT_GROUP_BY_FIELD_ID", "STAT_GROUP_BY_FIELD_STAT_TIME"});
-        return HttpUtils.bytedanceGetRequest(token.getAccessToken(), url, params);
+        getCampaignReportByPage(token, conditions, page + 1);
     }
 
-    private void getCampaignReportByPage(CtopOauthToken token, ByteDanceAdvertiserReportDTO conditions, int page) {
-        conditions.setPage(page);
+    @Override
+    public Map<String, Object> getCampaignReport(ByteDanceAdvertiserReportDTO conditions) {
+        conditions.setAdvertiserId(111463131228L);
+        conditions.setStartDate("2019-06-01");
+        conditions.setEndDate("2019-06-10");
+        conditions.setPageSize(1000);
+        conditions.setPage(1);
+        conditions.setTimeGranularity(CtopAdConstant.BYTEDANCE_REPORT_TYPE_DAILY);
         SerializeConfig config = new SerializeConfig();
         config.propertyNamingStrategy = PropertyNamingStrategy.SnakeCase;
         JSONObject jsonObject = JSONObject.parseObject(JSON.toJSONString(conditions, config));
-        System.out.println(jsonObject.toJSONString());
-        JSONObject getObject = getCampaignStat(token, jsonObject);
-        System.out.println(getObject.toJSONString());
+        Long accountId = conditions.getAdvertiserId();
+        CtopOauthToken token = tokenService.getOauthTokenByAccountId(accountId + "");
+        JSONObject getObject = getAdStat(token, jsonObject);
         Integer code = getObject.getInteger("code");
         String message = getObject.getString("message");
         if (null == code || code != 0) {
             log.error("广告组报表数据获取异常:{}", message);
-            return;
-        }
-        JSONArray dataArray = getObject.getJSONObject("data").getJSONArray("list");
-        if (null == dataArray || dataArray.size() <= 0) {
-            log.info("广告组报表信息为空=》accountId:{}", token.getAccountId());
-            return;
-        }
-        for (var i = 0; i < dataArray.size(); i++) {
-            var data = dataArray.getJSONObject(i);
-            if (null != conditions.getTimeGranularity() && CtopAdConstant.BYTEDANCE_REPORT_TYPE_HOURLY.equals(conditions.getTimeGranularity())) {
-                var hourlyReport = new BytedanceCampaignHourlyReport(data, token.getAccountId());
-                campaignHourlyReportService.saveOrUpdate(hourlyReport);
-            } else {
-                var dailyReport = new BytedanceCampaignDailyReport(data, token.getAccountId());
-                campaignDailyReportService.saveOrUpdate(dailyReport);
+        } else {
+            JSONArray dataArray = getObject.getJSONObject("data").getJSONArray("list");
+            if (null != dataArray && dataArray.size() > 0) {
+                for (int i = 0; i < dataArray.size(); i++) {
+                    JSONObject data = dataArray.getJSONObject(i);
+                    if (null != conditions.getTimeGranularity() && CtopAdConstant.BYTEDANCE_REPORT_TYPE_HOURLY.equals(conditions.getTimeGranularity())) {
+                        BytedanceCampaignHourlyReport hourlyReport = new BytedanceCampaignHourlyReport(data, token.getAccountId());
+                        campaignHourlyReportService.saveOrUpdate(hourlyReport);
+                    } else {
+                        BytedanceCampaignDailyReport dailyReport = new BytedanceCampaignDailyReport(data, token.getAccountId());
+                        campaignDailyReportService.saveOrUpdate(dailyReport);
+                    }
+                }
             }
         }
-        getCampaignReportByPage(token, conditions, page + 1);
+        return getObject;
     }
 
     @Override
@@ -281,6 +269,68 @@ public class ReportServiceImpl implements IReportService {
         getCreativeReportByPage(token, conditions, 1);
     }
 
+
+    public JSONObject getMaterialReport(CtopOauthToken token, String startDate, String endDate, Integer pageNum) {
+        // 请求地址
+        String url = "https://ad.oceanengine.com/open_api/2/report/integrated/get/";
+        // 请求参数
+        JSONObject params = new JSONObject();
+        params.put("advertiser_id", token.getAccountId());
+        params.put("start_date", startDate);
+        params.put("end_date", endDate);
+        params.put("page", pageNum);
+        params.put("page_size", 100);
+        JSONArray groupBy = new JSONArray();
+        groupBy.add("STAT_GROUP_BY_MATERIAL_ID");
+        groupBy.add("STAT_GROUP_BY_TIME_DAY");
+        groupBy.add("STAT_GROUP_BY_INVENTORY");
+        groupBy.add("STAT_GROUP_BY_IMAGE_MODE");
+        params.put("group_by", groupBy);
+        return HttpUtils.bytedanceGetRequest(token.getAccessToken(), url, params);
+    }
+
+    @Autowired
+    private IBytedanceReportMaterialRetryService retryService;
+
+    @Override
+    public void getMaterialReportByPage(CtopOauthToken token, String startDate, String endDate, Integer pageNum) {
+        JSONObject getObject = getMaterialReport(token, startDate, endDate, pageNum);
+        if (null == getObject) {
+            BytedanceReportMaterialRetry reportMaterialRetry = new BytedanceReportMaterialRetry();
+            reportMaterialRetry.setAccountId(token.getAccountId());
+            reportMaterialRetry.setStartDate(startDate);
+            reportMaterialRetry.setStartDate(endDate);
+            reportMaterialRetry.setStatus(0);
+            retryService.save(reportMaterialRetry);
+            log.error("素材报表请求数据null=>accountId:{};startDate:{};endDate:{}", token.getAccountId(), startDate, endDate);
+            return;
+        }
+        Integer code = getObject.getInteger("code");
+        String message = getObject.getString("message");
+        if (null == code || code != 0) {
+            log.error("素材报表数据获取异常:{}", message);
+            return;
+        }
+        System.out.println(getObject.toJSONString());
+        JSONArray dataArray = getObject.getJSONObject("data").getJSONArray("list");
+        if (null == dataArray || dataArray.size() <= 0) {
+            return;
+        }
+        List<BytedanceReportMaterialDaily> dailyReports = new ArrayList<>();
+        for (var i = 0; i < dataArray.size(); i++) {
+            var data = dataArray.getJSONObject(i);
+            var dailyReport = new BytedanceReportMaterialDaily(data, token.getAccountId());
+            dailyReports.add(dailyReport);
+        }
+        materialDailyMapper.replaceIntoBatch(dailyReports);
+        Integer totalNum = getObject.getJSONObject("data").getJSONObject("page_info").getInteger("total_page");
+        if (null != totalNum && totalNum > pageNum) {
+            getMaterialReportByPage(token, startDate, endDate, pageNum + 1);
+        }
+    }
+
+    @Autowired
+    private BytedanceReportMaterialDailyMapper materialDailyMapper;
     @Override
     public void loadBytedanceHistoryData(CtopOauthToken token) {
         for (int i = 1; i < 180; i++) {
@@ -354,437 +404,6 @@ public class ReportServiceImpl implements IReportService {
         return getObject;
     }
 
-    @Override
-    public void insertCustomerInfo(String csvPath, String charset) {
-        try {
-            List<String[]> data = CsvUtils.readCsv(csvPath, charset);
-            if (null != data && data.size() > 1) {
-                for (int i = 1; i < data.size(); i++) {
-                    String[] record = data.get(i);
-                    CustomerPlanStatisticInfo statisticInfo = new CustomerPlanStatisticInfo(record);
-                    customerPlanStatisticInfoMapper.insert(statisticInfo);
-                }
-            }
-        } catch (IOException e) {
-            e.printStackTrace();
-        }
-    }
-
-    @Override
-    public void insertPlatformInfo(String csvPath, String charset, Long accountId) {
-        try {
-            List<String[]> data = CsvUtils.readCsv(csvPath, charset);
-            if (null != data && data.size() > 1) {
-                for (int i = 1; i < data.size(); i++) {
-                    String[] record = data.get(i);
-                    PlatformCampaignStatisticInfo statisticInfo = new PlatformCampaignStatisticInfo(record, accountId);
-                    platformCampaignStatisticInfoMapper.insert(statisticInfo);
-                }
-            }
-        } catch (IOException e) {
-            e.printStackTrace();
-        }
-    }
-
-    @Override
-    public Map<String, Object> debitAuto(JSONObject data) {
-        Map<String, Object> resultMap = new HashMap<>();
-        String accountOneKsDataUrl = data.getString("accountOneKsDataUrl");
-        String accountFourKsDataUrl = data.getString("accountFourKsDataUrl");
-        String debitDataUrl = data.getString("debitDataUrl");
-        //1:文件下载入库
-        String accountOneKsDataPath = downLoadByUrl(accountOneKsDataUrl);
-        String accountFourKsDataPath = downLoadByUrl(accountFourKsDataUrl);
-        String debitDataPath = downLoadByUrl(debitDataUrl);
-        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/M/dd");
-        //2:文件入库
-        //2.1 清除数据库原始数据
-        QueryWrapper<CustomerPlanStatisticInfo> planWrapper = new QueryWrapper<>();
-        planWrapper.isNotNull("id");
-        customerPlanStatisticInfoService.remove(planWrapper);
-
-        QueryWrapper<PlatformCampaignStatisticInfo> campaignWrapper = new QueryWrapper<>();
-        campaignWrapper.isNotNull("id");
-        platformCampaignStatisticInfoService.remove(campaignWrapper);
-
-        this.insertPlatformInfo(accountOneKsDataPath, "gb2312", 1L);
-        QueryWrapper<PlatformCampaignStatisticInfo> queryWrapper = new QueryWrapper<>();
-        queryWrapper.eq("campaign_code", "biaodan").orderByDesc("id").last("limit 1");
-        PlatformCampaignStatisticInfo statisticInfo = platformCampaignStatisticInfoMapper.selectOne(queryWrapper);
-        if (null != statisticInfo) {
-            PlatformCampaignStatisticInfo updateInfo = new PlatformCampaignStatisticInfo();
-            updateInfo.setCampaignCode("biaodan2");
-            QueryWrapper<PlatformCampaignStatisticInfo> updateWrapper = new QueryWrapper<>();
-            updateWrapper.ne("campaign_info", statisticInfo.getCampaignInfo()).eq("campaign_code", statisticInfo.getCampaignCode());
-            platformCampaignStatisticInfoMapper.update(updateInfo, updateWrapper);
-        }
-        this.insertPlatformInfo(accountFourKsDataPath, "gb2312", 4L);
-        this.insertCustomerInfo(debitDataPath, "utf8");
-        //3:根据模板生成相应的excel模板文件
-        try {
-            String platformReportPath = getExcelDataPath(simpleDateFormat.format(new Date()), 1L, 4L);
-//            //4:同步上传到oss文件服务器
-//            String ossPath = OSSUtils.uploadFile2Oss(new File(platformReportPath));
-//            //5: 返回文件服务器访问链接
-            ResultMapUtils.setResultMap(resultMap, StatusCode.COMMON_SUCCESS.getCode());
-            resultMap.put("path", platformReportPath);
-            return resultMap;
-        } catch (Exception e) {
-            e.printStackTrace();
-            ResultMapUtils.setResultMap(resultMap, StatusCode.COMMON_SERVER_ERROR.getCode());
-            return resultMap;
-        }
-    }
-
-    public String getExcelDataPath(String date, Long accountId1, Long accountId4) throws Exception {
-        List<StatisticCampaignVo> statisticCampaign1Vos = statisticInfoMapper.getVoByParams(accountId1);
-        List<StatisticCampaignVo> statisticCampaign4Vos = statisticInfoMapper.getVoByParams(accountId4);
-        File f = new File(csvUploadPath + "template.xlsx");
-        InputStream inputStream = new FileInputStream(f);
-        XSSFWorkbook xssfWorkbook = new XSSFWorkbook(inputStream);
-//        //获取第一个sheet
-        XSSFSheet xssfSheet = xssfWorkbook.getSheetAt(0);
-        CellStyle numbericCellStyle = xssfWorkbook.createCellStyle();
-        numbericCellStyle.setDataFormat(HSSFDataFormat.getBuiltinFormat("0.00"));
-        int index;
-        for (index = 1; index < statisticCampaign1Vos.size() + 1; index++) {
-            StatisticCampaignVo vo = statisticCampaign1Vos.get(index - 1);
-            String content = vo.getContent();
-            String[] contents = content.split("-");
-            Row row = xssfSheet.getRow(index);
-            setExcelRow(numbericCellStyle, vo, contents, row, "single");
-        }
-        List<StatisticCampaignVo> zero1Vos = statisticInfoMapper.sumZeroVoByParams(accountId1);
-        List<StatisticCampaignVo> zaodianVos = statisticInfoMapper.sumZaodianVoByParams(accountId1);
-        if (null != zero1Vos && zero1Vos.size() > 0) {
-            for (int z = 0; z < zero1Vos.size(); z++) {
-                StatisticCampaignVo vo = zero1Vos.get(z);
-                Row row = xssfSheet.getRow(index);
-                String content = vo.getContent();
-                String[] contents = content.split("-");
-                setExcelRow(numbericCellStyle, vo, contents, row, "single");
-                index++;
-            }
-        }
-        if (null != zaodianVos && zaodianVos.size() > 0) {
-            for (int z = 0; z < zaodianVos.size(); z++) {
-                StatisticCampaignVo vo = zaodianVos.get(z);
-                Row row = xssfSheet.getRow(index);
-                String content = vo.getContent();
-                String[] contents = content.split("-");
-                setExcelRow(numbericCellStyle, vo, contents, row, "single");
-                index++;
-            }
-        }
-        Row totalRow1 = xssfSheet.getRow(index);
-        StatisticCampaignVo total = statisticInfoMapper.getTotalStatisticVoByparams(accountId1);
-        if (null != total) {
-            setExcelRow(numbericCellStyle, total, new String[]{}, totalRow1, "total1");
-        }
-        index++;
-        for (int j = 0; j < statisticCampaign4Vos.size(); j++) {
-            index++;
-            StatisticCampaignVo vo = statisticCampaign4Vos.get(j);
-            String content = vo.getContent();
-            String[] contents = content.split("-");
-            Row row = xssfSheet.getRow(index);
-            setExcelRow(numbericCellStyle, vo, contents, row, "single");
-        }
-        List<StatisticCampaignVo> zero4Vos = statisticInfoMapper.sumZeroVoByParams(accountId4);
-        if (null != zero4Vos && zero4Vos.size() > 0) {
-            for (int z = 0; z < zero4Vos.size(); z++) {
-                index++;
-                StatisticCampaignVo vo = zero4Vos.get(z);
-                Row row = xssfSheet.getRow(index);
-                String content = vo.getContent();
-                String[] contents = content.split("-");
-                setExcelRow(numbericCellStyle, vo, contents, row, "single");
-            }
-        }
-        index++;
-        Row totalRow4 = xssfSheet.getRow(index);
-        StatisticCampaignVo total1 = statisticInfoMapper.getTotalStatisticVoByparams(accountId4);
-        if (null != total1) {
-            setExcelRow(numbericCellStyle, total1, new String[]{}, totalRow4, "total4");
-        }
-        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-m-dd");
-        String path = csvUploadPath + "report_" + dateFormat.format(new Date()) + ".xlsx";
-        FileOutputStream fileOutputStream = new FileOutputStream(path);
-        xssfWorkbook.write(fileOutputStream);
-        fileOutputStream.close();
-        return path;
-
-    }
-
-    private void setExcelRow(CellStyle numbericCellStyle, StatisticCampaignVo vo, String[] contents, Row row, String type) {
-        for (int j = 0; j < 38; j++) {
-            Cell cell = row.createCell(j);
-            if (j == 0) {
-                //日期
-                if (null != type && "single".equals(type)) {
-                    cell.setCellValue(vo.getStatisticDate());
-                } else if (null != type && "total1".equals(type)) {
-                    cell.setCellValue("户一总计");
-                } else {
-                    cell.setCellValue("户四总计");
-                }
-            } else if (j == 1) {
-                //代理
-                cell.setCellValue(vo.getProxy());
-            } else if (j == 2) {
-                //投放系统
-                if (null != contents && contents.length > 3) {
-                    cell.setCellValue(contents[2]);
-                } else {
-                    cell.setCellValue("");
-                }
-            } else if (j == 3) {
-                //渠道号
-                if (null != contents && contents.length > 2) {
-                    cell.setCellValue(contents[1]);
-                } else {
-                    cell.setCellValue("");
-                }
-            } else if (j == 4) {
-                //content
-                if (null != contents && contents.length > 0) {
-                    cell.setCellValue(contents[0]);
-                } else {
-                    cell.setCellValue("");
-                }
-//                cell.setCellValue(vo.getContent());
-            } else if (j == 5) {
-                if (null != contents && contents.length > 5) {
-                    cell.setCellValue(contents[4]);
-                } else {
-                    cell.setCellValue("");
-                }
-            } else if (j == 6) {
-                //出价方式
-                if (null != contents && contents.length > 6) {
-                    cell.setCellValue(contents[5]);
-                } else {
-                    cell.setCellValue("");
-                }
-            } else if (j == 7) {
-                //定向条件
-                if (null != contents && contents.length > 4) {
-                    cell.setCellValue(contents[3]);
-                } else {
-                    cell.setCellValue("");
-                }
-            } else if (j == 8) {
-                //定向条件
-                if (null != contents && contents.length > 7) {
-                    cell.setCellValue(contents[6]);
-                } else {
-                    cell.setCellValue("");
-                }
-            } else if (j == 9) {
-                //花费
-                if (null != vo.getCost() && !"".equals(vo.getCost())) {
-                    cell.setCellValue(Float.parseFloat(vo.getCost()));
-                    cell.setCellStyle(numbericCellStyle);
-                }
-            } else if (j == 10) {
-                //封面曝光数
-                if (null != vo.getCoverViews() && !"".equals(vo.getCoverViews())) {
-                    cell.setCellValue(Integer.parseInt(vo.getCoverViews()));
-                }
-            } else if (j == 11) {
-                //封面点击数
-                if (null != vo.getCoverClick() && !"".equals(vo.getCoverClick())) {
-                    cell.setCellValue(Integer.parseInt(vo.getCoverClick()));
-                }
-            } else if (j == 12) {
-                //素材曝光数
-                if (null != vo.getMaterialViews() && !"".equals(vo.getMaterialViews())) {
-                    cell.setCellValue(Integer.parseInt(vo.getMaterialViews()));
-                }
-            } else if (j == 13) {
-                //行为数
-                if (null != vo.getActions() && !"".equals(vo.getActions())) {
-                    cell.setCellValue(Integer.parseInt(vo.getActions()));
-                }
-            } else if (j == 14) {
-                //点击率
-                if (null != vo.getClickRate() && !"".equals(vo.getClickRate())) {
-                    cell.setCellValue(Float.parseFloat(vo.getClickRate()));
-                    cell.setCellStyle(numbericCellStyle);
-                }
-            } else if (j == 15) {
-                //行为点击率
-                if (null != vo.getActionClickRate() && !"".equals(vo.getActionClickRate())) {
-                    cell.setCellValue(Float.parseFloat(vo.getActionClickRate()));
-                    cell.setCellStyle(numbericCellStyle);
-                }
-            } else if (j == 16) {
-                //ACTR*BCTR
-                if (null != vo.getAbctr() && !"".equals(vo.getAbctr())) {
-                    cell.setCellValue(Float.parseFloat(vo.getAbctr()));
-                    cell.setCellStyle(numbericCellStyle);
-                }
-            } else if (j == 17) {
-                //点击成本
-                if (null != vo.getClickPrice() && !"".equals(vo.getClickPrice())) {
-                    cell.setCellValue(Float.parseFloat(vo.getClickPrice()));
-                    cell.setCellStyle(numbericCellStyle);
-                }
-            } else if (j == 18) {
-                //行为成本
-                if (null != vo.getActionPrice() && !"".equals(vo.getActionPrice())) {
-                    cell.setCellValue(Float.parseFloat(vo.getActionPrice()));
-                    cell.setCellStyle(numbericCellStyle);
-                }
-            } else if (j == 19) {
-                //注册用户
-                if (null != vo.getRegistUserNum() && !"".equals(vo.getRegistUserNum())) {
-                    BigDecimal decimal = new BigDecimal(vo.getRegistUserNum());
-                    cell.setCellValue(decimal.intValue());
-                }
-            } else if (j == 20) {
-                //完件用户
-                if (null != vo.getComplateUserNum() && !"".equals(vo.getComplateUserNum())) {
-                    BigDecimal decimal = new BigDecimal(vo.getComplateUserNum());
-                    cell.setCellValue(decimal.intValue());
-                }
-            } else if (j == 21) {
-                //授信用户
-                if (null != vo.getCreditUserNum() && !"".equals(vo.getCreditUserNum())) {
-                    BigDecimal decimal = new BigDecimal(vo.getCreditUserNum());
-                    cell.setCellValue(decimal.intValue());
-                }
-            } else if (j == 22) {
-                //当日注册且完件数
-                if (null != vo.getRegistCompleteNum() && !"".equals(vo.getRegistCompleteNum())) {
-                    BigDecimal decimal = new BigDecimal(vo.getRegistCompleteNum());
-                    cell.setCellValue(decimal.intValue());
-                }
-            } else if (j == 23) {
-                //当日注册且授信数
-                if (null != vo.getRegistCreditNum() && !"".equals(vo.getRegistCreditNum())) {
-                    BigDecimal decimal = new BigDecimal(vo.getRegistCreditNum());
-                    cell.setCellValue(decimal.intValue());
-                }
-            } else if (j == 24) {
-                //注册成本
-                if (null != vo.getRegistPrice() && !"".equals(vo.getRegistPrice())) {
-                    cell.setCellValue(Float.parseFloat(vo.getRegistPrice()));
-                    cell.setCellStyle(numbericCellStyle);
-                }
-            } else if (j == 25) {
-                //完件成本
-                if (null != vo.getCompletePrice() && !"".equals(vo.getCompletePrice())) {
-                    cell.setCellValue(Float.parseFloat(vo.getCompletePrice()));
-                    cell.setCellStyle(numbericCellStyle);
-                }
-            } else if (j == 26) {
-                //授信成本
-                if (null != vo.getCreditPrice() && !"".equals(vo.getCreditPrice())) {
-                    cell.setCellValue(Float.parseFloat(vo.getCreditPrice()));
-                    cell.setCellStyle(numbericCellStyle);
-                }
-            } else if (j == 27) {
-                //当日注册且完件成本
-                if (null != vo.getRegistCompletePrice() && !"".equals(vo.getRegistCompletePrice())) {
-                    cell.setCellValue(Float.parseFloat(vo.getRegistCompletePrice()));
-                    cell.setCellStyle(numbericCellStyle);
-                }
-            } else if (j == 28) {
-                //当日注册且授信成本
-                if (null != vo.getRegistCreditPrice() && !"".equals(vo.getRegistCreditPrice())) {
-                    cell.setCellValue(Float.parseFloat(vo.getRegistCreditPrice()));
-                    cell.setCellStyle(numbericCellStyle);
-                }
-            } else if (j == 29) {
-                //点击注册率
-                if (null != vo.getClickRegistRate() && !"".equals(vo.getClickRegistRate())) {
-                    cell.setCellValue(Float.parseFloat(vo.getClickRegistRate()));
-                    cell.setCellStyle(numbericCellStyle);
-                }
-            } else if (j == 30) {
-                //行为注册率
-                if (null != vo.getActionRegistRate() && !"".equals(vo.getActionRegistRate())) {
-                    cell.setCellValue(Float.parseFloat(vo.getActionRegistRate()));
-                    cell.setCellStyle(numbericCellStyle);
-                }
-            } else if (j == 31) {
-                //完件率
-                if (null != vo.getCompleteRate() && !"".equals(vo.getCompleteRate())) {
-                    cell.setCellValue(Float.parseFloat(vo.getCompleteRate()));
-                    cell.setCellStyle(numbericCellStyle);
-                }
-            } else if (j == 32) {
-                //授信率
-                if (null != vo.getCreditRate() && !"".equals(vo.getCreditRate())) {
-                    cell.setCellValue(Float.parseFloat(vo.getCreditRate()));
-                    cell.setCellStyle(numbericCellStyle);
-                }
-            } else if (j == 33) {
-                //当日完件率
-                if (null != vo.getRegistCompleteRate() && !"".equals(vo.getRegistCompleteRate())) {
-                    cell.setCellValue(Float.parseFloat(vo.getRegistCompleteRate()));
-                    cell.setCellStyle(numbericCellStyle);
-                }
-            } else if (j == 34) {
-                //当日授信率
-                if (null != vo.getRegistCreditRate() && !"".equals(vo.getRegistCreditRate())) {
-                    cell.setCellValue(Float.parseFloat(vo.getRegistCreditRate()));
-                    cell.setCellStyle(numbericCellStyle);
-                }
-            } else if (j == 35) {
-                //当日完件/完件
-                if (null != vo.getCompleteRateDay() && !"".equals(vo.getCompleteRateDay())) {
-                    cell.setCellValue(Float.parseFloat(vo.getCompleteRateDay()));
-                    cell.setCellStyle(numbericCellStyle);
-                }
-            } else if (j == 36) {
-                //当日授信/授信
-                if (null != vo.getCreditRateDay() && !"".equals(vo.getCreditRateDay())) {
-                    cell.setCellValue(Float.parseFloat(vo.getCreditRateDay()));
-                    cell.setCellStyle(numbericCellStyle);
-                }
-            } else if (j == 37) {
-                //当日授信/注册
-                if (null != vo.getCreditRegistRateDay() && !"".equals(vo.getCreditRegistRateDay())) {
-                    cell.setCellValue(Float.parseFloat(vo.getCreditRegistRateDay()));
-                    cell.setCellStyle(numbericCellStyle);
-                }
-            }
-        }
-    }
-
-    public String downLoadByUrl(String fileUrl) {
-        //获取文件名,文件名实际上在URL中可以找到
-        String fileName = fileUrl.substring(fileUrl.lastIndexOf("/") + 1);
-        //这里服务器上要将此图保存的路径
-        String savePath = this.csvUploadPath + fileName;
-        try {
-            //将网络资源地址传给,即赋值给url
-            URL url = new URL("https:" + fileUrl);
-            //此为联系获得网络资源的固定格式用法,以便后面的in变量获得url截取网络资源的输入流
-            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
-            DataInputStream in = new DataInputStream(connection.getInputStream());
-            //此处也可用BufferedInputStream与BufferedOutputStream
-            DataOutputStream out = new DataOutputStream(new FileOutputStream(savePath));
-            //将参数savePath,即将截取的图片的存储在本地地址赋值给out输出流所指定的地址
-            byte[] buffer = new byte[4096];
-            int count = 0;
-            //将输入流以字节的形式读取并写入buffer中
-            while ((count = in.read(buffer)) > 0) {
-                out.write(buffer, 0, count);
-            }
-            out.close();
-            in.close();
-            connection.disconnect();
-            //返回内容是保存后的完整的URL
-            return savePath;
-
-        } catch (Exception e) {
-            return null;
-        }
-    }
-
     /**
      * 获取广告创意报表信息
      *

+ 7 - 3
performance-appraisal/src/main/java/cn/com/ctop/performanceappraisal/controller/PerformanceOptimizerController.java

@@ -282,7 +282,7 @@ public class PerformanceOptimizerController {
     /**
      * 获取项目经理相关数据
      *
-     * @param req
+     * @param
      * @param mediaType
      * @return
      */
@@ -303,8 +303,12 @@ public class PerformanceOptimizerController {
                                                            @RequestParam(name = "quarter") Integer quarter) {
 
         Map<String,String> map = DateUtils.quarterStartEndDate(year, quarter);
-        performanceOptimizerService.toutiaoYunyingQuarterPerformance(year, quarter, map.get("startDate"), map.get("endDate"));
-        performanceOptimizerService.kuaishouYunyingQuarterPerformance(year, quarter, map.get("startDate"), map.get("endDate"));
+        //performanceOptimizerService.toutiaoYunyingQuarterPerformance(year, quarter, map.get("startDate"), map.get("endDate"));
+        //performanceOptimizerService.kuaishouYunyingQuarterPerformance(year, quarter, map.get("startDate"), map.get("endDate"));
+
+        performanceOptimizerService.toutiaoYunyingQuarterPerformance(year, quarter, "2020-01-01", "2020-03-31");
+        performanceOptimizerService.kuaishouYunyingQuarterPerformance(year, quarter, "2020-01-01", "2020-03-31");
+
     }
 
     /**