浏览代码

init code

syh 4 年之前
父节点
当前提交
f4f28f3f78
共有 18 个文件被更改,包括 2186 次插入2 次删除
  1. 28 0
      jeecg-boot-bytedance/pom.xml
  2. 532 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/entity/ByteDanceAdvertisePlan.java
  3. 249 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/entity/ByteDanceAdvertiser.java
  4. 147 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/entity/ByteDanceAudiencePackage.java
  5. 151 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/entity/ByteDanceCampaign.java
  6. 161 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/entity/ByteDanceCreative.java
  7. 107 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/entity/ByteDanceCreativeMaterial.java
  8. 113 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/entity/ByteDanceVideoInfo.java
  9. 72 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/entity/BytedanceAreaInfo.java
  10. 81 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/entity/BytedanceImageInfo.java
  11. 42 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/entity/BytedanceIndustryInfo.java
  12. 62 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/entity/BytedanceInterestCategory.java
  13. 90 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/utils/CtopAdConstant.java
  14. 34 0
      jeecg-boot-bytedance/src/main/resources/bytedance_config.properties
  15. 142 0
      jeecg-boot-bytedance/src/main/resources/json_template/bytedance_filed_mapping.json
  16. 154 0
      jeecg-boot-bytedance/src/main/resources/json_template/bytedance_video_report_mapping.json
  17. 20 0
      jeecg-boot-bytedance/src/test/java/cn/com/ctop/AppTest.java
  18. 1 2
      pom.xml

+ 28 - 0
jeecg-boot-bytedance/pom.xml

@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>jeecg-boot-parent</artifactId>
+        <groupId>org.jeecgframework.boot</groupId>
+        <version>2.4.3</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>jeecg-boot-bytedance</artifactId>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.jeecgframework.boot</groupId>
+            <artifactId>jeecg-boot-base-core</artifactId>
+        </dependency>
+        <!--引入微服务启动依赖 starter
+      <dependency>
+          <groupId>org.jeecgframework.boot</groupId>
+          <artifactId>jeecg-boot-starter-cloud</artifactId>
+      </dependency>
+        <dependency>
+            <groupId>org.jeecgframework.boot</groupId>
+            <artifactId>jeecg-boot-starter-job</artifactId>
+        </dependency>-->
+    </dependencies>
+</project>

+ 532 - 0
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/entity/ByteDanceAdvertisePlan.java

@@ -0,0 +1,532 @@
+package org.jeecg.modules.bytedance.advertise.entity;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModel;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+import org.jeecg.common.aspect.annotation.Dict;
+import org.jeecg.modules.bytedance.advertise.utils.CtopAdConstant;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * 今日头条广告计划信息
+ *
+ * @author jeecg-boot
+ * @version V1.0
+ * @date 2019-07-22
+ */
+@Data
+@TableName("ctop_bytedance_advertise_plan")
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value = "ctop_bytedance_advertise_plan对象", description = "今日头条广告计划信息")
+public class ByteDanceAdvertisePlan {
+    @TableId
+    private Long id;
+
+    @Dict(dicCode = "account_id",dictTable="ctop_user_allocation",dicText="auth_name")
+    private String accountId;
+
+    // 计划名称
+    private String name;
+
+    @TableField(exist=false)
+    private String names;
+
+    @TableField(exist=false)
+    private String landingType;
+
+    @Dict(dicCode = "id",dictTable="ctop_bytedance_campaign",dicText="name")
+    private Long campaignId;
+
+    private String operation;
+
+    private String unionVideoType;
+
+    // 上次修改时间戳(用于更新时提交,服务端判断是否基于最新信息修改)
+    private String planModifyTime;
+
+    // 投放范围
+    private String deliveryRange;
+
+    // 计划上次修改时间
+    private String adModifyTime;
+
+    // 计划创建时间
+    private String adCreateTime;
+
+    // 广告预算类型
+    private String budgetMode;
+
+    // 广告预算
+    private BigDecimal budget;
+
+    // 广告计划投放状态
+    private String toutiaoStatus;
+
+    //true:投放中 false:暂停
+    private Boolean planStatus;
+
+    // 广告计划操作状态
+    private String optStatus;
+
+    // 广告投放起始时间
+    private String startTime;
+
+    // 广告投放结束时间
+    private String endTime;
+
+    // 广告出价
+    private BigDecimal bid;
+
+    // 广告出价类型
+    private String pricing;
+
+    // 广告投放时间类型
+    private String scheduleType;
+
+    // 广告投放时段
+    private String scheduleTime;
+
+    // 广告投放速度类型
+    private String flowControlMode;
+
+    // 应用直达链接
+    private String openUrl;
+
+    // 应用下载方式
+    private String downloadType;
+
+    // 应用下载方式
+    private String downloadUrl;
+
+    // 广告落地页链接
+    private String externalUrl;
+
+    // 广告应用下载包名
+    private String toutiaoPackage;
+
+    // 广告应用下载类型
+    private String appType;
+
+    // 广告计划审核不通过原因
+    private String auditRejectReason;
+
+    // ocpc广告转化出价
+    private BigDecimal cpaBid;
+
+    // 深度优化出价
+    private BigDecimal deepCpaBid;
+
+    private String deepBidType;
+
+    private Integer cpaSkipFirstPhrase;
+
+    // 转化类型广告的转化工具id
+    private Long convertId;
+
+    // 过滤已转化用户类型字段
+    private String hideIfConverted;
+
+    // 过滤已安装,当推广目标为安卓应用下载时可填
+    private Integer hideIfExists;
+
+    private String convertedTimeDuration;
+
+
+    // audience
+    private String audience;
+
+    private String modifyTime;
+
+    private Date createTime;
+
+    private Date updateTime;
+
+    private BigDecimal lubanRoiGoal;
+
+    private BigDecimal roiGoal;
+    /**
+     *  受众公共参数
+     */
+    // 受众性别
+    private String gender;
+    // 受众平台
+    @TableField(exist=false)
+    private Object platform;
+    @TableField(exist=false)
+    private Object retargetingTags;
+    @TableField(exist=false)
+    private Object retargetingTagsExclude;
+    @TableField(exist=false)
+    private Object age;
+    @TableField(exist=false)
+    private Object carrier;
+    @TableField(exist=false)
+    private Object ac;
+    @TableField(exist=false)
+    private Object deviceBrand;
+    @TableField(exist=false)
+    private Object articleCategory;
+    @TableField(exist=false)
+    private Object activateType;
+    @TableField(exist=false)
+    private Object city;
+    @TableField(exist=false)
+    private Object businessIds;
+    @TableField(exist=false)
+    private String locationType;
+    @TableField(exist=false)
+    private Object superiorPopularityType;
+    @TableField(exist=false)
+    private Object flowPackage;
+    @TableField(exist=false)
+    private Object excludeFlowPackage;
+    @TableField(exist=false)
+    private Object deviceType;
+    @TableField(exist=false)
+    private Object autoExtendEnabled;
+    @TableField(exist=false)
+    private Object launchPrice;
+    @TableField(exist=false)
+    private Object interestActionMode;
+    @TableField(exist=false)
+    private Object actionScene;
+    @TableField(exist=false)
+    private Object actionDays;
+    @TableField(exist=false)
+    private Object actionCategories;
+    @TableField(exist=false)
+    private Object actionWords;
+    @TableField(exist=false)
+    private Object interestCategories;
+    @TableField(exist=false)
+    private Object interestWords;
+    @TableField(exist=false)
+    private Object geolocation;
+    @TableField(exist=false)
+    private String externalAction;
+    @TableField(exist=false)
+    private String useOpenUrl;
+
+    public ByteDanceAdvertisePlan(JSONObject dataObject, String accountId) {
+        this.id = dataObject.getLong("id");
+        this.accountId = accountId;
+        String name = dataObject.getString("name");
+        if (null != name && !"".equals(name.trim())) {
+            this.name = name;
+        }
+        JSONObject audience = dataObject.getJSONObject("audience");
+        if (null != audience) {
+            this.audience = audience.toJSONString();
+            JSONArray platform = audience.getJSONArray("platform");
+            if (null != platform && platform.size() > 0) {
+                String plat = "";
+                for (int i = 0; i < platform.size(); i++) {
+                    String platformStr = platform.getString(i);
+                    if ("IOS".equals(platformStr)) {
+                        plat += "ios,";
+                    } else {
+                        plat += "安卓,";
+                    }
+                }
+                this.platform = plat.substring(0, plat.length() - 1);
+            }
+            String gender = audience.getString("gender");
+            if (null != gender) {
+                if (CtopAdConstant.BYTEDANCE_GENDER_TYPE_NONE.equals(gender)) {
+                    this.gender = "不限";
+                } else if (CtopAdConstant.BYTEDANCE_GENDER_TYPE_GENDER_MALE.equals(gender)) {
+                    this.gender = "男";
+                } else {
+                    this.gender = "女";
+                }
+            }
+        }
+        this.createTime = new Date();
+        this.updateTime = new Date();
+        Long advertiserId = dataObject.getLong("advertiser_id");
+
+        if (null != advertiserId) {
+            this.accountId = advertiserId+"";
+        }
+        Long campaignId = dataObject.getLong("campaign_id");
+        if (null != campaignId) {
+            this.campaignId = campaignId;
+        }
+
+        String budgetMode = dataObject.getString("budget_mode");
+        if (null != budgetMode && !"".equals(budgetMode.trim())) {
+            this.budgetMode = budgetMode;
+        }
+        String modifyTime = dataObject.getString("modify_time");
+        if (null != modifyTime && !"".equals(modifyTime.trim())) {
+            this.modifyTime = modifyTime;
+        }
+        String openUrl = dataObject.getString("open_url");
+        if (null != openUrl && !"".equals(openUrl.trim())) {
+            this.openUrl = openUrl;
+        }
+
+        String adCreateTime = dataObject.getString("ad_create_time");
+        if (null != adCreateTime && !"".equals(adCreateTime.trim())) {
+            this.adCreateTime = adCreateTime;
+        }
+
+        String adModifyTime = dataObject.getString("ad_modify_time");
+        if (null != adModifyTime && !"".equals(adModifyTime.trim())) {
+            this.adModifyTime = adModifyTime;
+        }
+
+        String auditRejectReason = dataObject.getString("audit_reject_reason");
+        if (null != auditRejectReason && !"".equals(auditRejectReason.trim())) {
+            this.auditRejectReason = auditRejectReason;
+        }
+
+        String pricing = dataObject.getString("pricing");
+        if (null != pricing && !"".equals(pricing.trim())) {
+            this.pricing = pricing;
+        }
+
+
+        Integer hideIfExists = dataObject.getInteger("hide_if_exists");
+        if (null != hideIfExists) {
+            this.hideIfExists = hideIfExists;
+        }
+
+        String appType = dataObject.getString("app_type");
+        if (null != appType && !"".equals(appType.trim())) {
+            this.appType = appType;
+        }
+
+        String flowControlMode = dataObject.getString("flow_control_mode");
+        if (null != flowControlMode && !"".equals(flowControlMode.trim())) {
+            this.flowControlMode = flowControlMode;
+        }
+
+
+        BigDecimal cpaBid = dataObject.getBigDecimal("cpa_bid");
+        if (null != cpaBid) {
+            this.cpaBid = cpaBid;
+        }
+
+        String startTime = dataObject.getString("start_time");
+        if (null != startTime && !"".equals(startTime.trim())) {
+            this.startTime = startTime;
+        }
+
+        String optStatus = dataObject.getString("opt_status");
+        if (null != optStatus && !"".equals(optStatus.trim())) {
+            this.optStatus = optStatus;
+        }
+
+        String endTime = dataObject.getString("end_time");
+        if (null != endTime && !"".equals(endTime.trim())) {
+            this.endTime = endTime;
+        }
+
+        String status = dataObject.getString("status");
+        if (null != status && !"".equals(status.trim())) {
+            this.toutiaoStatus = status;
+        }
+
+        Long convertId = dataObject.getLong("convert_id");
+        if (null != convertId) {
+            this.convertId = convertId;
+        }
+
+        BigDecimal bid = dataObject.getBigDecimal("bid");
+        if (null != bid) {
+            this.bid = bid;
+        }
+
+        String hideIfConverted = dataObject.getString("hide_if_converted");
+        if (null != hideIfConverted && !"".equals(hideIfConverted.trim())) {
+            this.hideIfConverted = hideIfConverted;
+        }
+
+        String toutiaoPackage = dataObject.getString("package");
+        if (null != toutiaoPackage && !"".equals(toutiaoPackage.trim())) {
+            this.toutiaoPackage = toutiaoPackage;
+        }
+
+        String deliveryRange = dataObject.getString("delivery_range");
+        if (null != deliveryRange && !"".equals(deliveryRange.trim())) {
+            this.deliveryRange = deliveryRange;
+        }
+
+        BigDecimal budget = dataObject.getBigDecimal("budget");
+        if (null != budget) {
+            this.budget = budget;
+        }
+
+        String scheduleType = dataObject.getString("schedule_type");
+        if (null != scheduleType && !"".equals(scheduleType.trim())) {
+            this.scheduleType = scheduleType;
+        }
+
+        String scheduleTime = dataObject.getString("schedule_time");
+        if (null != scheduleTime && !"".equals(scheduleTime.trim())) {
+            this.scheduleTime = scheduleTime;
+        }
+
+        String downloadType = dataObject.getString("download_type");
+        if (null != downloadType && !"".equals(downloadType.trim())) {
+            this.downloadType = downloadType;
+        }
+
+        String downloadUrl = dataObject.getString("download_url");
+        if (null != downloadUrl && !"".equals(downloadUrl.trim())) {
+            this.downloadUrl = downloadUrl;
+        }
+
+        String externalUrl = dataObject.getString("external_url");
+        if (null != externalUrl && !"".equals(externalUrl.trim())) {
+            this.externalUrl = externalUrl;
+        }
+    }
+
+    public ByteDanceAdvertisePlan(String advertiserId, Long adId, JSONObject params) {
+        this.id = adId;
+        this.accountId = advertiserId;
+        String name = params.getString("name");
+        if (null != name && !"".equals(name.trim())) {
+            this.name = name;
+        }
+
+        Long campaignId = params.getLong("campaign_id");
+        if (null != campaignId) {
+            this.campaignId = campaignId;
+        }
+
+        String budgetMode = params.getString("budget_mode");
+        if (null != budgetMode && !"".equals(budgetMode.trim())) {
+            this.budgetMode = budgetMode;
+        }
+
+        String openUrl = params.getString("open_url");
+        if (null != openUrl && !"".equals(openUrl.trim())) {
+            this.openUrl = openUrl;
+        }
+
+        String adCreateTime = params.getString("ad_create_time");
+        if (null != adCreateTime && !"".equals(adCreateTime.trim())) {
+            this.adCreateTime = adCreateTime;
+        }
+
+        String adModifyTime = params.getString("ad_modify_time");
+        if (null != adModifyTime && !"".equals(adModifyTime.trim())) {
+            this.adModifyTime = adModifyTime;
+        }
+
+        String auditRejectReason = params.getString("audit_reject_reason");
+        if (null != auditRejectReason && !"".equals(auditRejectReason.trim())) {
+            this.auditRejectReason = auditRejectReason;
+        }
+
+        String pricing = params.getString("pricing");
+        if (null != pricing && !"".equals(pricing.trim())) {
+            this.pricing = pricing;
+        }
+
+        Integer hideIfExists = params.getInteger("hide_if_exists");
+        if (null != hideIfExists) {
+            this.hideIfExists = hideIfExists;
+        }
+
+        String appType = params.getString("app_type");
+        if (null != appType && !"".equals(appType.trim())) {
+            this.appType = appType;
+        }
+
+        String flowControlMode = params.getString("flow_control_mode");
+        if (null != flowControlMode && !"".equals(flowControlMode.trim())) {
+            this.flowControlMode = flowControlMode;
+        }
+
+        BigDecimal cpaBid = params.getBigDecimal("cpa_bid");
+        if (null != cpaBid) {
+            this.cpaBid = cpaBid;
+        }
+
+        String startTime = params.getString("start_time");
+        if (null != startTime && !"".equals(startTime.trim())) {
+            this.startTime = startTime;
+        }
+
+        String optStatus = params.getString("opt_status");
+        if (null != optStatus && !"".equals(optStatus.trim())) {
+            this.optStatus = optStatus;
+        }
+
+        String endTime = params.getString("end_time");
+        if (null != endTime && !"".equals(endTime.trim())) {
+            this.endTime = endTime;
+        }
+
+        String status = params.getString("status");
+        if (null != status && !"".equals(status.trim())) {
+            this.toutiaoStatus = status;
+        }
+
+        Long convertId = params.getLong("convert_id");
+        if (null != convertId) {
+            this.convertId = convertId;
+        }
+
+        BigDecimal bid = params.getBigDecimal("bid");
+        if (null != bid) {
+            this.bid = bid;
+        }
+
+        String hideIfConverted = params.getString("hide_if_converted");
+        if (null != hideIfConverted && !"".equals(hideIfConverted.trim())) {
+            this.hideIfConverted = hideIfConverted;
+        }
+
+        String toutiaoPackage = params.getString("package");
+        if (null != toutiaoPackage && !"".equals(toutiaoPackage.trim())) {
+            this.toutiaoPackage = toutiaoPackage;
+        }
+
+        String deliveryRange = params.getString("delivery_range");
+        if (null != deliveryRange && !"".equals(deliveryRange.trim())) {
+            this.deliveryRange = deliveryRange;
+        }
+
+        BigDecimal budget = params.getBigDecimal("budget");
+        if (null != budget) {
+            this.budget = budget;
+        }
+
+        String scheduleType = params.getString("schedule_type");
+        if (null != scheduleType && !"".equals(scheduleType.trim())) {
+            this.scheduleType = scheduleType;
+        }
+
+        String scheduleTime = params.getString("schedule_time");
+        if (null != scheduleTime && !"".equals(scheduleTime.trim())) {
+            this.scheduleTime = scheduleTime;
+        }
+
+        String downloadType = params.getString("download_type");
+        if (null != downloadType && !"".equals(downloadType.trim())) {
+            this.downloadType = downloadType;
+        }
+
+        String externalUrl = params.getString("external_url");
+        if (null != externalUrl && !"".equals(externalUrl.trim())) {
+            this.externalUrl = externalUrl;
+        }
+    }
+
+    public ByteDanceAdvertisePlan() {
+    }
+}

+ 249 - 0
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/entity/ByteDanceAdvertiser.java

@@ -0,0 +1,249 @@
+package org.jeecg.modules.bytedance.advertise.entity;
+
+import com.alibaba.fastjson.JSONObject;
+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 java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * 今日头条广告主信息
+ *
+ * @author jeecg-boot
+ * @version V1.0
+ * @date 2019-07-22
+ */
+@Data
+@TableName("ctop_bytedance_advertiser")
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value = "ctop_bytedance_advertiser对象", description = "今日头条广告主信息")
+public class ByteDanceAdvertiser {
+
+    /**
+     * 外部平台头条id
+     */
+    @TableId
+    private Long id;
+    /**
+     * 本平台id
+     */
+    private String advertiserId;
+    /**
+     * 头条账户名
+     */
+    private String name;
+    /**
+     * 品牌描述,即推广内容
+     */
+    private String description;
+    /**
+     * 邮箱
+     */
+    private String email;
+    /**
+     * 联系人
+     */
+    private String contacter;
+    /**
+     * 手机号
+     */
+    private String phonenumber;
+    /**
+     *  角色
+     */
+    private String role;
+    /**
+     *  头条广告主状态
+     */
+    private String toutiaoStatus;
+    /**
+     * 固定电话
+     */
+    private String telephone;
+    /**
+     * 地址
+     */
+    private String address;
+    /**
+     * 执照预览地址(链接默认1小时内有效)
+     */
+    private String licenseUrl;
+    /**
+     * 执照编号
+     */
+    private String licenseNo;
+    /**
+     * 执照省份
+     */
+    private String licenseProvince;
+    /**
+     * 执照城市
+     */
+    private String licenseCity;
+    /**
+     * 公司名称
+     */
+    private String company;
+    /**
+     * 经营类别
+     */
+    private String brand;
+    /**
+     * 运营区域
+     */
+    private String promotionArea;
+    /**
+     * 运营省份
+     */
+    private String promotionCenterProvince;
+    /**
+     * 运营城市
+     */
+    private String promotionCenterCity;
+    /**
+     * 一级行业名称
+     */
+    private String firstIndustryName;
+    /**
+     * 二级行业名称
+     */
+    private String secondIndustryName;
+    /**
+     * 审核拒绝原因
+     */
+    private String reason;
+    /**
+     * 账户总余额,单位元
+     */
+    private BigDecimal balance;
+    /**
+     * 头条平台中广告主创建时间
+     */
+    private String toutiaoCreateTime;
+    /**
+     * 数据状态
+     */
+    private Integer status;
+    /**
+     * createTime
+     */
+    @ApiModelProperty(value = "createTime")
+    private Date createTime;
+    /**
+     * updateTime
+     */
+    @ApiModelProperty(value = "updateTime")
+    private Date updateTime;
+
+    public ByteDanceAdvertiser(JSONObject dataObject, String accountId) {
+        Long id = dataObject.getLong("id");
+        this.id = id;
+        this.advertiserId = accountId;
+        String name = dataObject.getString("name");
+        if (null != name && !"".equals(name.trim())) {
+            this.name = name;
+        }
+        String description = dataObject.getString("description");
+        if (null != description && !"".equals(description.trim())) {
+            this.description = description;
+        }
+        String email = dataObject.getString("email");
+        if (null != email && !"".equals(email.trim())) {
+            this.email = email;
+        }
+        String contacter = dataObject.getString("contacter");
+        if (null != contacter && !"".equals(contacter.trim())) {
+            this.contacter = contacter;
+        }
+        String phonenumber = dataObject.getString("phonenumber");
+        if (null != phonenumber && !"".equals(phonenumber.trim())) {
+            this.phonenumber = phonenumber;
+        }
+        String role = dataObject.getString("role");
+        if (null != role && !"".equals(role.trim())) {
+            this.role = role;
+        }
+        String status = dataObject.getString("status");
+        if (null != status && !"".equals(status.trim())) {
+            this.toutiaoStatus = status;
+        }
+        String telephone = dataObject.getString("telephone");
+        if (null != telephone && !"".equals(telephone.trim())) {
+            this.telephone = telephone;
+        }
+        String address = dataObject.getString("address");
+        if (null != address && !"".equals(address.trim())) {
+            this.address = address;
+        }
+        String licenseUrl = dataObject.getString("license_url");
+        if (null != licenseUrl && !"".equals(licenseUrl.trim())) {
+            this.licenseUrl = licenseUrl;
+        }
+        String licenseNo = dataObject.getString("license_no");
+        if (null != licenseNo && !"".equals(licenseNo.trim())) {
+            this.licenseNo = licenseNo;
+        }
+        String licenseProvince = dataObject.getString("license_province");
+        if (null != licenseProvince && !"".equals(licenseProvince.trim())) {
+            this.licenseProvince = licenseProvince;
+        }
+        String licenseCity = dataObject.getString("license_city ");
+        if (null != licenseCity && !"".equals(licenseCity.trim())) {
+            this.licenseCity = licenseCity;
+        }
+        String company = dataObject.getString("company");
+        if (null != company && !"".equals(company.trim())) {
+            this.company = company;
+        }
+        String brand = dataObject.getString("brand");
+        if (null != brand && !"".equals(brand.trim())) {
+            this.brand = brand;
+        }
+        String promotionArea = dataObject.getString("promotion_area");
+        if (null != promotionArea && !"".equals(promotionArea.trim())) {
+            this.promotionArea = promotionArea;
+        }
+        String promotionCenterProvince = dataObject.getString("promotion_center_province ");
+        if (null != promotionCenterProvince && !"".equals(promotionCenterProvince.trim())) {
+            this.promotionCenterProvince = promotionCenterProvince;
+        }
+        String promotionCenterCity = dataObject.getString("promotion_center_city");
+        if (null != promotionCenterCity && !"".equals(promotionCenterCity.trim())) {
+            this.promotionCenterCity = promotionCenterCity;
+        }
+        String firstIndustryName = dataObject.getString("first_industry_name ");
+        if (null != firstIndustryName && !"".equals(firstIndustryName.trim())) {
+            this.firstIndustryName = firstIndustryName;
+        }
+        String secondIndustryName = dataObject.getString("second_industry_name");
+        if (null != secondIndustryName && !"".equals(secondIndustryName.trim())) {
+            this.secondIndustryName = secondIndustryName;
+        }
+        String reason = dataObject.getString("reason");
+        if (null != reason && !"".equals(reason.trim())) {
+            this.reason = reason;
+        }
+        BigDecimal balance = dataObject.getBigDecimal("balance");
+        if (null != balance) {
+            this.balance = balance;
+        }
+        String createTime = dataObject.getString("create_time ");
+        if (null != createTime && !"".equals(createTime.trim())) {
+            this.toutiaoCreateTime = createTime;
+        }
+        Date now = new Date();
+        this.createTime = now;
+        this.updateTime = now;
+    }
+
+    public ByteDanceAdvertiser() {
+
+    }
+}

+ 147 - 0
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/entity/ByteDanceAudiencePackage.java

@@ -0,0 +1,147 @@
+package org.jeecg.modules.bytedance.advertise.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModel;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+/**
+ * 头条定向包
+ * @author jeecg-boot
+ * @date   2020-07-22
+ * @version V1.0
+ */
+@Data
+@TableName("ctop_bytedance_audience_package")
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+public class ByteDanceAudiencePackage {
+
+	/**汇创主键id*/
+	@TableId(type = IdType.AUTO)
+	private Long id;
+
+	/**账户Id*/
+	private String userId;
+
+
+	/**定向包名称*/
+	private String name;
+
+	/**定向包描述*/
+	private String description;
+
+	/**定向包类型*/
+	private String landingType;
+
+	/**投放范围*/
+	private String deliveryRange;
+
+	/**精选流量包*/
+	private String trafficPackage;
+
+	/**定向人群包列表,内容为人群包id*/
+	private Object retargetingTags;
+
+	/**排除人群包列表,内容为人群包id*/
+	private Object retargetingTagsExclude;
+
+	/**受众性别,允许值: GENDER_FEMALE,GENDER_MALE , NONE*/
+	private String gender;
+
+	/**	受众年龄区间,允许值: AGE_BETWEEN_18_23,AGE_BETWEEN_24_30,AGE_BETWEEN_31_40, AGE_BETWEEN_41_49,AGE_ABOVE_50*/
+	private Object age;
+
+	/**受众最低android版本*/
+	private String androidOsv;
+
+	/**受众最低ios版本*/
+	private String iosOsv;
+
+	/**受众运营商*/
+	private Object carrier;
+
+	/**受众网络类型*/
+	private Object ac;
+
+	/**受众手机品牌*/
+	private Object deviceBrand;
+
+	/**受众文章分类*/
+	private Object articleCategory;
+
+	/**用户首次激活时间*/
+	private Object activateType;
+
+	/**受众平台*/
+	private Object platform;
+
+	/**是否启动智能放量*/
+	private Integer autoExtendEnabled;
+
+	/**智能放量定向*/
+	private Object autoExtendTargets;
+
+	/**手机价格定向,传入价格区间,最高传入11000(表示1w以上)传值示例 "launch_price": [2000, 11000]*/
+	private Object launchPrice;
+
+	/**行为兴趣选择*/
+	private String interestActionMode;
+
+	/**行为场景*/
+	private Object actionScene;
+
+	/**行为天数,允许值:7, 15, 30, 60, 90, 180, 365*/
+	private Integer actionDays;
+
+	/**行为类目*/
+	private Object actionCategories;
+
+	/**行为关键词*/
+	private Object actionWords;
+
+	/**兴趣分类,如果传空数组 [] 表示不限,如果只传[0]表示系统推荐*/
+	private Object interestCategories;
+
+	/**兴趣关键词*/
+	private Object interestWords;
+
+	/**地域定向城市或者区县列表(当传递省份ID时,旗下市县ID可省略不传)*/
+	private Object city;
+
+	/**商圈ID数组	*/
+	private Object businessIds;
+
+	/**地域类型,前者为省市,后者为区县。当city有数据时,必填。*/
+	private String district;
+
+	/**受众位置类型,当city和district有值时,该字段必填*/
+	private String locationType;
+
+	/**需要传json对象!地图位置,district为BUSINESS_DISTRICT才有效*/
+	private Object geolocation;
+
+	private String filterConvertedUsers;
+
+	/**(抖音推广特有)账号粉丝相似人群(添加抖音账号,会将广告投放给对应账号的相似人群粉丝)	*/
+	private Object awemeFansNumbers;
+
+	/**(抖音推广特有)过滤高活跃用户*/
+	private Integer filterAwemeAbnormalActive;
+
+	/**(抖音推广特有)过滤自己的粉丝,允许值:0表示不过滤,1表示过滤	*/
+	private Integer filterAwemeFansCount;
+
+	/**抖音号id,与aweme_fan_behaviors同时设置才会生效(抖音达人定向)	*/
+	private Object awemeFanAccounts;
+
+	private Object awemeFanCategories;
+
+	private Object awemeFanBehaviors;
+
+	/**过滤已安装,当推广目标为安卓应用下载时可填,0表示不过滤,1表示过滤,默认为不过滤*/
+	private Integer hideIfExists;
+}

+ 151 - 0
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/entity/ByteDanceCampaign.java

@@ -0,0 +1,151 @@
+package org.jeecg.modules.bytedance.advertise.entity;
+
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModel;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+import org.jeecg.common.aspect.annotation.Dict;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * 今日头条广告组信息
+ *
+ * @author jeecg-boot
+ * @version V1.0
+ * @date 2019-07-22
+ */
+@Data
+@TableName("ctop_bytedance_campaign")
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value = "ctop_bytedance_campaign对象", description = "今日头条广告组信息")
+public class ByteDanceCampaign {
+
+    /**
+     * 今日头条广告组id
+     */
+    @TableId
+    private Long id;
+    private Long accountId;
+    /**
+     * 广告组名称
+     */
+    private String name;
+    /**
+     * 广告组预算
+     */
+    private BigDecimal budget;
+    /**
+     * 广告组预算类型
+     */
+    @Dict(dicCode = "item_value", dictTable = "sys_dict_item", dicText = "item_text",extendsKey = "dict_id",extendsValue = "6512a5e70b99f6499dc3164b95e06395")
+    private String budgetMode;
+    /**
+     * 广告组推广目的
+     * extendsValue在此处为固定值,切忌胡乱修改
+     */
+    @Dict(dicCode = "item_value", dictTable = "sys_dict_item", dicText = "item_text",extendsKey = "dict_id",extendsValue = "181afbae847dd3bc7e27795d89538c9c")
+    private String landingType;
+    /**
+     * 广告组时间戳,用于更新时提交,服务端判断是否基于最新信息修改
+     */
+    private String modifyTime;
+
+    @Dict(dicCode = "item_value", dictTable = "sys_dict_item", dicText = "item_text",extendsKey = "dict_id",extendsValue = "fbc3e2fc9e6f5cfa5f6aeddd4c3bf818")
+    private String status;
+    /**
+     * 广告组创建时间
+     */
+    private String campaignCreateTime;
+    /**
+     * 广告组修改时间
+     */
+    private String campaignModifyTime;
+    /**
+     * createTime
+     */
+    private Date createTime;
+    /**
+     * updateTime
+     */
+    private Date updateTime;
+
+    @TableField(exist = false)
+    private Boolean campaignStatus;
+
+    public ByteDanceCampaign() {
+    }
+
+    public ByteDanceCampaign(Long id, String advertiserId, Long toutiaoId, String name, BigDecimal budget, String budgetMode, String landingType, String modifyTime, String status, String optStatus, String campaignCreateTime, String campaignModifyTime, Date createTime, Date updateTime) {
+        this.id = id;
+        this.name = name;
+        this.budget = budget;
+        this.budgetMode = budgetMode;
+        this.landingType = landingType;
+        this.modifyTime = modifyTime;
+        this.status = status;
+        this.campaignCreateTime = campaignCreateTime;
+        this.campaignModifyTime = campaignModifyTime;
+        this.createTime = createTime;
+        this.updateTime = updateTime;
+    }
+
+    public ByteDanceCampaign(JSONObject dataObject, Long accountId) {
+        Long id = dataObject.getLong("id");
+        this.id = id;
+        this.accountId = accountId;
+        String name = dataObject.getString("name");
+        if (null != name && !"".equals(name.trim())) {
+            this.name = name;
+        }
+        BigDecimal budget = dataObject.getBigDecimal("budget");
+        if (null != budget) {
+            this.budget = budget;
+        }
+        String budgetMode = dataObject.getString("budget_mode");
+        if (null != budgetMode && !"".equals(budgetMode.trim())) {
+            this.budgetMode = budgetMode;
+        }
+        String landingType = dataObject.getString("landing_type");
+        if (null != landingType && !"".equals(landingType.trim())) {
+            this.landingType = landingType;
+        }
+        String modifyTime = dataObject.getString("modify_time");
+        if (null != modifyTime && !"".equals(modifyTime.trim())) {
+            this.modifyTime = modifyTime;
+        }
+        String status = dataObject.getString("status");
+        if (null != status && !"".equals(status.trim())) {
+            this.status = status;
+        }
+        String campaignCreateTime = dataObject.getString("campaign_create_time");
+        if (null != campaignCreateTime && !"".equals(campaignCreateTime.trim())) {
+            this.campaignCreateTime = campaignCreateTime;
+        }
+        String campaignModifyTime = dataObject.getString("campaign_modify_time");
+        if (null != campaignModifyTime && !"".equals(campaignModifyTime.trim())) {
+            this.campaignModifyTime = campaignModifyTime;
+        }
+        Date now = new Date();
+        this.createTime = now;
+        this.updateTime = now;
+    }
+
+    public ByteDanceCampaign(Long id, CtopOauthToken oauthToken, String campaignName, String budgetMode, Integer budget, String landingType) {
+        this.id = id;
+        this.accountId = oauthToken.getAccountId();
+        this.name = campaignName;
+        this.budgetMode = budgetMode;
+        this.budget = BigDecimal.valueOf(budget);
+        this.landingType = landingType;
+        Date now = new Date();
+        this.createTime = now;
+        this.updateTime = now;
+    }
+}

+ 161 - 0
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/entity/ByteDanceCreative.java

@@ -0,0 +1,161 @@
+package org.jeecg.modules.bytedance.advertise.entity;
+
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModel;
+import lombok.Data;
+import lombok.experimental.Accessors;
+import org.jeecg.common.aspect.annotation.Dict;
+
+import java.util.Date;
+
+/**
+ * @Description: 今日头条创意信息
+ * @Author: jeecg-boot
+ * @Date: 2019-07-22
+ * @Version: V1.0
+ */
+@Data
+@TableName("ctop_bytedance_creative")
+@Accessors(chain = true)
+@ApiModel(value = "ctop_bytedance_creative对象", description = "今日头条创意信息")
+public class ByteDanceCreative {
+
+    /**
+     * 创意id
+     */
+    @TableId
+    private Long id;
+    /**
+     * 广告计划id
+     */
+    @Dict(dicCode = "id",dictTable="ctop_bytedance_advertise_plan",dicText="name")
+    private Long planId;
+    /**
+     * 本平台广告主id
+     */
+    @Dict(dicCode = "account_id",dictTable="ctop_user_allocation",dicText="auth_name")
+    private String accountId;
+    /**
+     * 创意素材标题
+     */
+    private String title;
+    /**
+     * 动态词包列表
+     */
+    private String creativeWordIds;
+    /**
+     * 创意素材状态
+     */
+    @Dict(dicCode = "item_value", dictTable = "sys_dict_item", dicText = "item_text",extendsKey = "dict_id",extendsValue = "57b60cec65bbc7cd3d6da4fbda589594")
+    private String status;
+    private String optStatus;
+    /**
+     * 创意素材类型
+     */
+    private String imageMode;
+    /**
+     * 图片素材id列表
+     */
+    private String imageIds;
+    /**
+     * 视频素材封面
+     */
+    @Dict(dicCode = "id",dictTable="ctop_bytedance_image_info",dicText="image_url")
+    private String imageId;
+    /**
+     * 视频id
+     */
+    @Dict(dicCode = "id",dictTable="ctop_bytedance_video_info",dicText="video_url")
+    private String videoId;
+    /**
+     * 创意审核信息
+     */
+    private String auditRejectReason;
+    /**
+     * 第三方id
+     */
+    private String thirdPartyId;
+    /**
+     * 广告创意创建时间
+     */
+    private String creativeCreateTime;
+    /**
+     * 广告创意更新时间
+     */
+    private String creativeModifyTime;
+    /**
+     * createTime
+     */
+    private Date createTime;
+    /**
+     * updateTime
+     */
+    private Date updateTime;
+    @TableField(exist = false)
+    private Boolean createStatus;
+
+    public ByteDanceCreative(){
+
+    }
+
+    public ByteDanceCreative(JSONObject dataObject, CtopOauthToken token) {
+        this.id = dataObject.getLong("creative_id");
+        this.planId = dataObject.getLong("ad_id");
+        this.accountId = token.getAccountId()+"";
+        String title = dataObject.getString("title");
+        if (null != title && !"".equals(title.trim())) {
+            this.title = title;
+        }
+        String creativeWordIds = dataObject.getString("creative_word_ids");
+        if (null != creativeWordIds && !"".equals(creativeWordIds.trim())) {
+            this.creativeWordIds = creativeWordIds;
+        }
+        String status = dataObject.getString("status");
+        if (null != status && !"".equals(status.trim())) {
+            this.status = status;
+        }
+        String optStatus = dataObject.getString("opt_status");
+        if(null!=optStatus&&!"".equals(optStatus.trim())){
+            this.optStatus = optStatus;
+        }
+        String imageMode = dataObject.getString("image_mode");
+        if (null != imageMode && !"".equals(imageMode.trim())) {
+            this.imageMode = imageMode;
+        }
+        String imageIds = dataObject.getString("image_ids");
+        if (null != imageIds && !"".equals(imageIds.trim())) {
+            this.imageIds = imageIds;
+        }
+        String imageId = dataObject.getString("image_id");
+        if (null != imageId && !"".equals(imageId.trim())) {
+            this.imageId = imageId;
+        }
+        String videoId = dataObject.getString("video_id");
+        if (null != videoId && !"".equals(videoId.trim())) {
+            this.videoId = videoId;
+        }
+        String thirdPartyId = dataObject.getString("third_party_id");
+        if (null != thirdPartyId && !"".equals(thirdPartyId.trim())) {
+            this.thirdPartyId = thirdPartyId;
+        }
+        String auditRejectReason = dataObject.getString("audit_reject_reason");
+        if (null != auditRejectReason && !"".equals(auditRejectReason.trim())) {
+            this.auditRejectReason = auditRejectReason;
+        }
+        String creativeCreateTime = dataObject.getString("creative_create_time");
+        if (null != creativeCreateTime && !"".equals(creativeCreateTime.trim())) {
+            this.creativeCreateTime = creativeCreateTime;
+        }
+        String creativeModifyTime = dataObject.getString("creative_modify_time");
+        if (null != creativeModifyTime && !"".equals(creativeModifyTime.trim())) {
+            this.creativeModifyTime = creativeModifyTime;
+        }
+        Date now = new Date();
+        this.createTime = now;
+        this.updateTime = now;
+    }
+
+}

+ 107 - 0
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/entity/ByteDanceCreativeMaterial.java

@@ -0,0 +1,107 @@
+package org.jeecg.modules.bytedance.advertise.entity;
+
+import com.alibaba.fastjson.JSONObject;
+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;
+
+/**
+ * @Description: 今日头条创意素材信息
+ * @Author: jeecg-boot
+ * @Date: 2019-07-22
+ * @Version: V1.0
+ */
+@Data
+@TableName("ctop_bytedance_creative_material")
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value = "ctop_bytedance_creative_material对象", description = "今日头条创意素材信息")
+public class ByteDanceCreativeMaterial {
+
+    /**
+     * 素材id
+     */
+    @TableId
+    private Long id;
+    /**
+     * 广告主id
+     */
+    private Long accountId;
+    /**
+     * 广告id
+     */
+    private Long adId;
+    /**
+     * 创意标题
+     */
+    private String title;
+    /**
+     * 创意状态
+     */
+    private String status;
+    /**
+     * 创意状态
+     */
+    private String optStatus;
+    /**
+     * 创意类型
+     */
+    private String imageMode;
+    /**
+     * 图片素材信息
+     */
+    private String imageInfo;
+    /**
+     * createTime
+     */
+    private Date createTime;
+    /**
+     * updateTime
+     */
+    private Date updateTime;
+
+    public ByteDanceCreativeMaterial() {
+    }
+
+    public ByteDanceCreativeMaterial(JSONObject dataObject, String accountId) {
+        this.id = dataObject.getLong("id");
+        this.accountId = dataObject.getLong("advertiser_id");
+
+        String status = dataObject.getString("status");
+        if (null != status && !"".equals(status.trim())) {
+            this.status = status;
+        }
+
+        Long adId = dataObject.getLong("ad_id");
+        if (null != adId) {
+            this.adId = adId;
+        }
+
+        String title = dataObject.getString("title");
+        if (null != title && !"".equals(title.trim())) {
+            this.title = title;
+        }
+
+        String imageMode = dataObject.getString("image_mode");
+        if (null != imageMode && !"".equals(imageMode.trim())) {
+            this.imageMode = imageMode;
+        }
+
+        String imageInfo = dataObject.getString("image_info");
+        if (null != imageInfo && !"".equals(imageInfo.trim())) {
+            this.imageInfo = imageInfo;
+        }
+
+        String optStatus = dataObject.getString("opt_status");
+        if (null != optStatus && !"".equals(optStatus.trim())) {
+            this.optStatus = optStatus;
+        }
+    }
+}

+ 113 - 0
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/entity/ByteDanceVideoInfo.java

@@ -0,0 +1,113 @@
+package org.jeecg.modules.bytedance.advertise.entity;
+
+import cn.com.ctop.common.module.entity.CtopOauthToken;
+import com.alibaba.fastjson.JSONObject;
+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;
+
+/**
+ * @Description: 今日头条视频素材信息
+ * @Author: jeecg-boot
+ * @Date: 2019-07-29
+ * @Version: V1.0
+ */
+@Data
+@TableName("ctop_bytedance_video_info")
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value = "ctop_bytedance_video_info对象", description = "今日头条视频素材信息")
+public class ByteDanceVideoInfo {
+
+    /**
+     * id
+     */
+    @TableId
+    private String id;
+    /**
+     * 视频vid
+     */
+    private String vid;
+    /**
+     * 对应本文件id
+     */
+    private String fileId;
+    /**
+     * 平台账号id 已经废弃
+     */
+    @Deprecated
+    private String advertiserId;
+    /**
+     * 对应本文件id
+     */
+    private Long accountId;
+    /**
+     * 视频宽度
+     */
+    private Integer width;
+    /**
+     * 视频高度
+     */
+    private Integer height;
+    /**
+     * 视频时长
+     */
+    private Double duration;
+    /**
+     * 视频大小
+     */
+    private Long size;
+    /**
+     * 视频地址
+     */
+    private String videoUrl;
+    private String signature;
+    private Integer status;
+    private Date createTime;
+    private Date updateTime;
+    private String url;
+    private String format;
+    private String posterUrl;
+    private Long bitRate;
+    private Long materialId;
+    private String source;
+    private Date materialUploadTime;
+    private String filename;
+    private Integer type;
+
+    public ByteDanceVideoInfo(JSONObject data, CtopOauthToken token) {
+        this.id = data.getString("id")+token.getAccountId();
+        this.vid = data.getString("id");
+        this.fileId = data.getString("video_id");
+        this.accountId = token.getAccountId();
+        this.advertiserId = token.getAdvertiserId();
+        this.width = data.getInteger("width");
+        this.height = data.getInteger("height");
+        this.size = data.getLong("size");
+        this.duration = data.getDouble("duration");
+        this.videoUrl = "https://aweme.snssdk.com/aweme/v1/playwm/?video_id="+data.getString("id")+"&line=0";
+        this.signature = data.getString("signature");
+        this.status = 1;
+        this.source = data.getString("source");
+        this.materialId = data.getLong("material_id");
+        this.bitRate = data.getLong("bit_rate");
+        this.posterUrl = data.getString("poster_url");
+        this.format = data.getString("format");
+        this.url = data.getString("url");
+        Date now = new Date();
+        this.createTime = now;
+        this.updateTime = now;
+        this.materialUploadTime = data.getDate("create_time");
+        this.filename = data.getString("filename");
+    }
+
+    public ByteDanceVideoInfo() {
+    }
+}

+ 72 - 0
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/entity/BytedanceAreaInfo.java

@@ -0,0 +1,72 @@
+package org.jeecg.modules.bytedance.advertise.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+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 2019-09-17
+ */
+@Data
+@TableName("ctop_bytedance_area_info")
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value = "ctop_bytedance_area_info对象", description = "省市县信息")
+public class BytedanceAreaInfo {
+    /**
+     * id
+     */
+    @TableId(type = IdType.UUID)
+    @ApiModelProperty(value = "id")
+    private Integer id;
+    /**
+     * name
+     */
+    @Excel(name = "name", width = 15)
+    @ApiModelProperty(value = "name")
+    private String name;
+    /**
+     * code
+     */
+    @Excel(name = "code", width = 15)
+    @ApiModelProperty(value = "code")
+    private String code;
+    /**
+     * parentCode
+     */
+    @Excel(name = "parentCode", width = 15)
+    @ApiModelProperty(value = "parentCode")
+    private String parentCode;
+    /**
+     * level
+     */
+    @Excel(name = "level", width = 15)
+    @ApiModelProperty(value = "level")
+    private Integer level;
+    /**
+     * createTime
+     */
+    @ApiModelProperty(value = "createTime")
+    private Date createTime;
+    /**
+     * updateTime
+     */
+    @ApiModelProperty(value = "updateTime")
+    private Date updateTime;
+
+    @TableField(exist = false)
+    private Boolean hasChild;
+}

+ 81 - 0
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/entity/BytedanceImageInfo.java

@@ -0,0 +1,81 @@
+package org.jeecg.modules.bytedance.advertise.entity;
+
+import cn.com.ctop.common.module.entity.CtopOauthToken;
+import com.alibaba.fastjson.JSONObject;
+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
+ * @date   2020-08-01
+ * @version V1.0
+ */
+@Data
+@TableName("ctop_bytedance_image_info")
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value="ctop_bytedance_image_info对象", description="头条图片素材")
+public class BytedanceImageInfo {
+
+	/**id*/
+	@TableId()
+	private String id;
+	/**头条平台账号id*/
+	private Long accountId;
+	/**advertiserId*/
+	private Long materialId;
+	/**图片大小*/
+	private Long size;
+	/**图片宽度*/
+	private Long width;
+	/**图片高度*/
+	private Long height;
+	/**预览地址*/
+	private String url;
+	private String imageUrl;
+	/**图片格式*/
+	private String format;
+	/**图片Md5*/
+	private String signature;
+	private String imageCreateTime;
+	private String fileName;
+	/**createTime*/
+	private Date createTime;
+	/**updateTime*/
+	private Date updateTime;
+    private Integer type;
+
+	public BytedanceImageInfo(JSONObject dataObject, CtopOauthToken token) {
+		String id = dataObject.getString("id");
+		if(null!=id&&id.contains("web")){
+			this.imageUrl = "https://sf6-ttcdn-tos.pstatp.com/obj/"+id;
+		}else{
+			this.imageUrl = "https://sf6-ttcdn-tos.pstatp.com/obj/mosaic-legacy/"+id;
+		}
+		this.id = dataObject.getString("id");
+		this.accountId = token.getAccountId();
+		this.materialId = dataObject.getLong("material_id");
+		this.size = dataObject.getLong("size");
+		this.width = dataObject.getLong("width");
+		this.height = dataObject.getLong("height");
+		this.url = dataObject.getString("url");
+		this.format = dataObject.getString("format");
+		this.signature = dataObject.getString("signature");
+		this.imageCreateTime = dataObject.getString("create_time");
+		this.fileName = dataObject.getString("filename");
+		this.createTime = new Date();
+		this.updateTime = new Date();
+	}
+
+	public BytedanceImageInfo() {
+	}
+}

+ 42 - 0
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/entity/BytedanceIndustryInfo.java

@@ -0,0 +1,42 @@
+package org.jeecg.modules.bytedance.advertise.entity;
+
+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
+ * @date   2020-07-30
+ * @version V1.0
+ */
+@Data
+@TableName("ctop_bytedance_industry_info")
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value="ctop_bytedance_industry_info对象", description="头条行业类别")
+public class BytedanceIndustryInfo {
+
+	/**id*/
+	@TableId
+	private Long id;
+	/**name*/
+	private String name;
+	/**code*/
+	private String code;
+	/**parentCode*/
+	private String parentCode;
+	/**level*/
+	private Integer level;
+	/**createTime*/
+	private Date createTime;
+	/**updateTime*/
+	private Date updateTime;
+}

+ 62 - 0
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/entity/BytedanceInterestCategory.java

@@ -0,0 +1,62 @@
+package org.jeecg.modules.bytedance.advertise.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+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 2019-09-18
+ */
+@Data
+@TableName("ctop_bytedance_interest_category")
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value = "ctop_bytedance_interest_category对象", description = "兴趣分类信息")
+public class BytedanceInterestCategory {
+
+    /**
+     * id
+     */
+    @TableId(type = IdType.AUTO)
+    private Long id;
+    /**
+     * 名称
+     */
+    private String name;
+    /**
+     * code
+     */
+    private String code;
+    /**
+     * parentCode
+     */
+    private String parentCode;
+    /**
+     * level
+     */
+    private Integer level;
+    /**
+     * createTime
+     */
+    private Date createTime;
+    /**
+     * updateTime
+     */
+    private Date updateTime;
+
+    @TableField(exist = false)
+    private Boolean hasChild;
+}

+ 90 - 0
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/utils/CtopAdConstant.java

@@ -0,0 +1,90 @@
+package org.jeecg.modules.bytedance.advertise.utils;
+
+import java.math.BigDecimal;
+
+/**
+ * 广告相关常量数据
+ */
+public class CtopAdConstant {
+    //头条
+    public static final String PLATFORM_TYPE_BYTEDANCE = "1";
+    public static final  int PLATFORM_TYPE_BYTEDANCE_INT = 1;
+    //快手
+    public static final String PLATFORM_TYPE_KUAISHOU = "2";
+    public static final  int   PLATFORM_TYPE_KUAISHOU_INT = 2;
+    //头条内广
+    public static final String PLATFORM_TYPE_BYTEDANCE_INSIDE = "3";
+    public static final  int PLATFORM_TYPE_BYTEDANCE_INSIDE_INT = 3;
+    //头条内广
+    public static final String PLATFORM_TYPE_KUAISHOU_INSIDE = "4";
+    public static final  int PLATFORM_TYPE_KUAISHOU_INSIDE_INT = 4;
+
+    public static final String PLATFORM_TYPE_PANGOLIN = "5";
+
+    public static final String PLATFORM_TYPE_BYTEDANCE_PY = "bytedance";
+    public static final String PLATFORM_TYPE_KUAISHOU_PY = "kuaishou";
+    public static final String PLATFORM_TYPE_PANGOLIN_PY = "pangolin";
+
+    public static final String BYTEDANCE_REPORT_TYPE_DAILY = "STAT_TIME_GRANULARITY_DAILY";
+    public static final String BYTEDANCE_REPORT_TYPE_HOURLY = "STAT_TIME_GRANULARITY_HOURLY";
+
+    public static final String UREPORT_PREVIEW_URL_PREFIX = "/jeecg-boot/ureport/designer?_u=mysql:";
+
+
+    public static final String CTOP_ORGCODE_NORTH_CHINA_PREFIX = "A01";
+    public static final String CTOP_ORGCODE_EAST_CHINA_PREFIX = "A02";
+
+    public static final String KUAISHOU_LOAD_JOB_TYPE_HISTORY = "history";
+    public static final String KUAISHOU_LOAD_JOB_TYPE_DAILY = "daily";
+
+    public static final String BYTEDANCE_LOAD_JOB_TYPE_ASYNC = "async";
+    public static final String BYTEDANCE_LOAD_JOB_TYPE_DAILY = "daily";
+
+    /**
+     * 销售角色Id
+     */
+    public static final String SYSTEM_SALE_CODE = "75ee837e6f3de29c0e3ed75d4629438e";
+
+    /**
+     * 销售AM角色Id
+     */
+    public static final String SYSTEM_SALE_AM_CODE = "f5a68aa2acf86e842100f0fa4b050d28";
+
+    /**
+     * 头条销售媒体季度任务
+     */
+    public static final BigDecimal BYTEDANCE_MEDIA_TASK_COST = new BigDecimal("150000000");
+    /**
+     * 快手销售媒体季度任务
+     */
+    public static final BigDecimal KUAISHOU_MEDIA_TASK_COST = new BigDecimal("147000000");
+    /**
+     * 头条销售季度个人任务
+     */
+    public static final BigDecimal BYTEDANCE_PERSONAL_TASK_COST = new BigDecimal("2400000");
+    /**
+     * 快手销售季度个人任务
+     */
+    public static final BigDecimal KUAISHOU_PERSONAL_TASK_COST = new BigDecimal("2400000");
+
+    /**
+     * 华北快手销售机构号
+     */
+    public static final String HB_KUAISHOU_SALE_ORG_CODE = "A01A11A01";
+    /**
+     * 华北头条销售机构号
+     */
+    public static final String HB_BYTEDANCE_SALE_ORG_CODE = "A01A11A02";
+
+    public static final String BYTEDANCE_GENDER_TYPE_NONE = "NONE";
+    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;
+
+    public static final String COMMON_ORDER_TYPE_ASC = "asc";
+    public static final String COMMON_ORDER_TYPE_DESC = "desc";
+}

+ 34 - 0
jeecg-boot-bytedance/src/main/resources/bytedance_config.properties

@@ -0,0 +1,34 @@
+#release
+bytedance_appid=1635316529903624
+# bytedance_appid=1634953881401358
+bytedance_secret=0c51523e90d6166418fc8421a4896808e90e26f4
+# bytedance_secret=34bc59f53955c66871ce111a1f15a6051cfa3f12
+#release
+bytedance_api_url=https://ad.oceanengine.com/open_api
+bytedance_auth_url=https://ad.oceanengine.com/openapi
+#sandbox
+#bytedance_api_url=https://test-ad.toutiao.com/open_api
+#bytedance_auth_url=https://test-ad.toutiao.com/open_api
+#bytedance_callback_url=http://callback.c-top.com.cn/bytedance
+bytedance_callback_url=http://adsp.c-top.com.cn:8080/jeecg-boot/bytedance
+bytedance_v2_advertiser_info=/2/advertiser/public_info/
+bytedance_v2_ad_get=/2/ad/get/
+bytedance_v2_ad_create=/2/ad/create/
+bytedance_v2_ad_update_status=/2/ad/update/status/
+bytedance_v2_ad_update_bid=/2/ad/update/bid/
+bytedance_v2_ad_update_budget=/2/ad/update/budget/
+bytedance_v2_campaign_get=/2/campaign/get/
+bytedance_v2_campaign_create=/2/campaign/create/
+bytedance_v2_campaign_update_status=/2/campaign/update/status/
+bytedance_v2_campaign_update=/2/campaign/update/
+bytedance_v2_dmp_custom_audience_select=/2/dmp/custom_audience/select/
+bytedance_v2_file_video_ad=/2/file/video/ad/
+bytedance_v2_file_image_ad=/2/file/image/ad/
+bytedance_v2_creative_update_status=/2/creative/update/status/
+bytedance_v2_creative_material_get=/2/creative/material/read/
+bytedance_v2_creative_create_v2=/2/creative/create_v2/
+bytedance_v2_creative_get=/2/creative/get/
+bytedance_v2_advertiser_report_get=/2/report/advertiser/get/
+bytedance_v2_campaign_report_get=/2/report/campaign/get/
+bytedance_v2_ad_report_get=/2/report/ad/get/
+bytedance_v2_ad_creative_get=/2/report/creative/get/

+ 142 - 0
jeecg-boot-bytedance/src/main/resources/json_template/bytedance_filed_mapping.json

@@ -0,0 +1,142 @@
+{
+  "cost": {
+    "filed": "IFNULL(sum(t1.cost),0) as cost ",
+    "comment": "消耗"
+  },
+  "showMaterial": {
+    "filed": "IFNULL(sum(t1.show_num),0) as showMaterial ",
+    "comment": "展示数"
+  },
+  "cpm": {
+    "filed": "CASE WHEN sum(t1.cost) / sum(t1.show_num) IS NULL THEN 0 ELSE ROUND((sum(t1.cost) / sum(t1.show_num)) * 1000, 2 ) END AS cpm ",
+    "comment": "平均千次展现费用"
+  },
+  "clickMaterial": {
+    "filed": "IFNULL(sum(t1.click),0) as clickMaterial ",
+    "comment": "点击数"
+  },
+  "ctr": {
+    "filed": "CASE WHEN sum(t1.show_num) != 0 THEN concat(CAST(round( sum(t1.click) /sum(t1.show_num)*100,2) AS CHAR),'%') ELSE '0%' end as ctr ",
+    "comment": "点击率"
+  },
+  "cpc": {
+    "filed": "CASE WHEN sum(t1.click) / sum(t1.cost) IS NULL THEN 0 ELSE ROUND((sum(t1.cost) / sum(t1.click)), 2) END AS cpc ",
+    "comment": "平均点击单价"
+  },
+  "convertMaterial": {
+    "filed": "IFNULL(sum(t1.convert_num),0) as convertMaterial ",
+    "comment": "转化数"
+  },
+  "convertCost": {
+    "filed": "CASE WHEN sum(t1.cost) / sum(t1.convert_num) IS NULL THEN 0 ELSE ROUND((sum(t1.cost) / sum(t1.convert_num)), 2 ) END AS convertCost ",
+    "comment": "转化成本"
+  },
+  "convertRate": {
+    "filed": "CASE WHEN sum(t1.cost) != 0 THEN concat(CAST(round(sum(t1.convert_num) / sum(t1.cost)*100,2) AS CHAR) ,'%') ELSE '0%' end AS convertRate",
+    "comment": "转化率"
+  },
+  "downloadStart": {
+    "filed": "IFNULL(sum(download_start),0) as downloadStart ",
+    "comment": "安卓开始下载数"
+  },
+  "downloadStartCost": {
+    "filed": "CASE WHEN sum(t1.cost) / (t1.download_start) IS NULL THEN 0 ELSE sum(t1.cost) / sum(t1.download_start) end AS downloadStartCost ",
+    "comment": "安卓开始下载成本"
+  },
+  "downloadStartRate": {
+    "filed": "CASE WHEN sum(t1.click) != 0 THEN concat(CAST(round(sum(t1.download_start) / sum(t1.click)*100,2) AS CHAR),'%') ELSE '0%' end AS downloadStartRate ",
+    "comment": "安卓开始下载率"
+  },
+  "downloadFinish": {
+    "filed": "IFNULL(sum(download_finish),0) as downloadFinish ",
+    "comment": "安卓下载完成数"
+  },
+  "downloadFinishCost": {
+    "filed": "CASE WHEN sum(t1.cost) / sum(t1.download_finish) IS NULL THEN 0 ELSE  sum(t1.cost) / sum(t1.download_finish) end AS downloadFinishCost ",
+    "comment": "安卓下载完成成本"
+  },
+  "downloadFinishRate": {
+    "filed": "CASE WHEN sum(t1.download_finish) != 0 THEN  concat(CAST(round(sum(t1.install_finish) / sum(t1.download_finish)*100,2) AS CHAR) ,'%') ELSE '0%' end  AS downloadFinishRate ",
+    "comment": "安卓下载完成率"
+  },
+  "active": {
+    "filed": "IFNULL(sum(active),0) as active ",
+    "comment": "激活数"
+  },
+  "activeCost": {
+    "filed": "CASE WHEN sum(t1.cost) / sum(t1.active) IS NULL THEN 0 ELSE sum(t1.cost) / sum(t1.active) end AS activeCost ",
+    "comment": "激活成本"
+  },
+  "activeRate": {
+    "filed": "CASE WHEN sum(t1.click) != 0 THEN concat(CAST(round(sum(t1.active) / sum(t1.click)*100,2) AS CHAR) ,'%') ELSE '0%' end as activeRate ",
+    "comment": "激活率"
+  },
+  "register": {
+    "filed": "IFNULL(sum(t1.register),0) as register",
+    "comment": "注册数"
+  },
+  "activeRegisterCost": {
+    "filed": "CASE WHEN sum(t1.cost) / sum(t1.register) IS NULL THEN 0 ELSE round(sum(t1.cost)/sum(t1.register),3) end as activeRegisterCost ",
+    "comment": "注册成本"
+  },
+  "activeRegisterRate": {
+    "filed": " CASE WHEN sum(t1.active) != 0 THEN concat(CAST(round(sum(t1.register) / sum(t1.active)*100,2) AS CHAR) ,'%') ELSE '0%' end as activeRegisterRate ",
+    "comment": "注册率"
+  },
+  "nextDayOpen": {
+    "filed": "IFNULL(sum(t1.next_day_open),0) as nextDayOpen ",
+    "comment": "次留数"
+  },
+  "nextDayOpenCost": {
+    "filed": "CASE WHEN sum(t1.cost) / sum(t1.next_day_open) IS NULL THEN 0 ELSE round(sum(t1.cost)/sum(t1.next_day_open),3) end as nextDayOpenCost ",
+    "comment": "次留成本"
+  },
+  "nextDayOpenRate": {
+    "filed": "CASE WHEN sum(t1.active) != 0 THEN concat(CAST(round(sum(t1.next_day_open) / sum(t1.active)*100,2) AS CHAR) ,'%') ELSE '0%' end as nextDayOpenRate ",
+    "comment": "次留率"
+  },
+  "activePayAmount": {
+    "filed": "IFNULL(sum(pay_count),0) as activePayAmount ",
+    "comment": "付费数"
+  },
+  "activePayCost": {
+    "filed": "CASE WHEN sum(t1.cost) / sum(t1.pay_count) IS NULL THEN 0 ELSE round(sum(t1.cost)/sum(t1.pay_count),3) end as activePayCost ",
+    "comment": "付费成本"
+  },
+  "form": {
+    "filed": "IFNULL(sum(t1.form),0) as form ",
+    "comment": "表单提交"
+  },
+  "validPlayCost": {
+    "filed": "CASE WHEN sum(t1.cost) / sum(t1.valid_play) IS NULL THEN 0 ELSE round(sum(t1.cost)/sum(t1.valid_play),3) end as validPlayCost ",
+    "comment": "有效播放成本"
+  },
+  "play25FeedBreak": {
+    "filed": "IFNULL(sum(t1.play25_feed_break),0) as play25FeedBreak ",
+    "comment": "25%进度播放数"
+  },
+  "play50FeedBreak": {
+    "filed": "IFNULL(sum(t1.play50_feed_break),0) as play50FeedBreak",
+    "comment": "50%进度播放数"
+  },
+  "play75FeedBreak": {
+    "filed": "IFNULL(sum(t1.play75_feed_break),0) as play75FeedBreak",
+    "comment": "75%进度播放数"
+  },
+  "play100FeedBreak": {
+    "filed": "IFNULL(sum(t1.play100_feed_break),0) as play100FeedBreak",
+    "comment": "100%进度播放数"
+  },
+  "follow": {
+    "filed": "IFNULL(sum(t1.follow),0) as follow ",
+    "comment": "新增关注数"
+  },
+  "likeMaterial": {
+    "filed": "IFNULL(sum(t1.like_num),0) as likeMaterial ",
+    "comment": "点赞数"
+  },
+  "shareMaterial": {
+    "filed": "IFNULL(sum(t1.share),0) as shareMaterial ",
+    "comment": "分享数"
+  }
+}

+ 154 - 0
jeecg-boot-bytedance/src/main/resources/json_template/bytedance_video_report_mapping.json

@@ -0,0 +1,154 @@
+{
+  "cost": {
+    "filed": "IFNULL(sum(t1.cost),0) as cost ",
+    "comment": "消耗"
+  },
+  "showMaterial": {
+    "filed": "IFNULL(sum(t1.material_show),0) as showMaterial ",
+    "comment": "展示数"
+  },
+  "cpm": {
+    "filed": "CASE WHEN sum(t1.cost) / sum(t1.material_show) IS NULL THEN 0 ELSE ROUND((sum(t1.cost) / sum(t1.material_show)) * 1000, 2 ) END AS cpm ",
+    "comment": "平均千次展现费用"
+  },
+  "clickMaterial": {
+    "filed": "IFNULL(sum(t1.click),0) as clickMaterial ",
+    "comment": "点击数"
+  },
+  "ctr": {
+    "filed": "CASE WHEN sum(t1.material_show) != 0 THEN CONCAT(CAST(ROUND((sum(t1.click) / sum(t1.material_show)) * 100,2) AS CHAR) ,'%') ELSE '0%' end  AS ctr",
+    "comment": "点击率"
+  },
+  "cpc": {
+    "filed": "CASE WHEN sum(t1.click) / sum(t1.cost) IS NULL THEN 0 ELSE ROUND((sum(t1.cost) / sum(t1.click)), 2) END AS cpc ",
+    "comment": "平均点击单价"
+  },
+  "convertMaterial": {
+    "filed": "IFNULL(sum(t1.convert_material),0) as convertMaterial ",
+    "comment": "转化数"
+  },
+  "convertCost": {
+    "filed": "CASE WHEN sum(t1.cost) / sum(t1.convert_material) IS NULL THEN 0 ELSE ROUND((sum(t1.cost) / sum(t1.convert_material)), 2 ) END AS convertCost ",
+    "comment": "转化成本"
+  },
+  "convertRate": {
+    "filed": "CASE WHEN sum(t1.material_show)!= 0 THEN concat(CAST(round(sum(t1.convert_material) / sum(t1.material_show)*100,2) AS CHAR) ,'%') ELSE '0%' end  AS convertRate ",
+    "comment": "转化率"
+  },
+  "downloadStart": {
+    "filed": "IFNULL(sum(download_start),0) as downloadStart ",
+    "comment": "安卓开始下载数"
+  },
+  "downloadStartCost": {
+    "filed": "CASE WHEN sum(t1.cost) / (t1.download_start) IS NULL THEN 0 ELSE sum(t1.cost) / sum(t1.download_start) end AS downloadStartCost ",
+    "comment": "安卓开始下载成本"
+  },
+  "downloadStartRate": {
+    "filed": "CASE WHEN sum(t1.click) != 0 THEN concat(CAST(round(sum(t1.download_start) / sum(t1.click)*100,2) AS CHAR) ,'%') ELSE '0%' end  AS downloadStartRate ",
+    "comment": "安卓开始下载率"
+  },
+  "downloadFinish": {
+    "filed": "IFNULL(sum(t1.download_finish),0) as downloadFinish ",
+    "comment": "安卓下载完成数"
+  },
+  "downloadFinishCost": {
+    "filed": "CASE WHEN sum(t1.cost) / sum(t1.download_finish) IS NULL THEN 0 ELSE  sum(t1.cost) / sum(t1.download_finish) end AS downloadFinishCost ",
+    "comment": "安卓下载完成成本"
+  },
+  "downloadFinishRate": {
+    "filed": "CASE WHEN sum(t1.download_finish) != 0 THEN concat(CAST(round(sum(t1.install_finish) / sum(t1.download_finish)*100,2) AS CHAR),'%') ELSE '0%' end  AS downloadFinishRate ",
+    "comment": "安卓下载完成率"
+  },
+  "active": {
+    "filed": "IFNULL(sum(t1.active),0) as active ",
+    "comment": "激活数"
+  },
+  "activeCost": {
+    "filed": "CASE WHEN sum(t1.cost) / sum(t1.active) IS NULL THEN 0 ELSE sum(t1.cost) / sum(t1.active) end AS activeCost ",
+    "comment": "激活成本"
+  },
+  "activeRate": {
+    "filed": "CASE WHEN sum(t1.click)!= 0 THEN concat( CAST(round(sum(t1.active) / sum(t1.click)*100,2) AS CHAR),'%') ELSE '0%' end  as activeRate",
+    "comment": "激活率"
+  },
+  "register": {
+    "filed": "IFNULL(sum(t1.register),0) as register  ",
+    "comment": "注册数"
+  },
+  "activeRegisterCost": {
+    "filed": "CASE WHEN sum(t1.cost) / sum(t1.register) IS NULL THEN 0 ELSE round(sum(t1.cost)/sum(t1.register),3) end as activeRegisterCost ",
+    "comment": "注册成本"
+  },
+  "activeRegisterRate": {
+    "filed": " CASE WHEN sum(t1.active) != 0 THEN concat(CAST(round(sum(t1.register) / sum(t1.active)*100,2) AS CHAR) ,'%') ELSE '0%' end  as activeRegisterRate ",
+    "comment": "注册率"
+  },
+  "gameAddiction": {
+    "filed": "IFNULL(sum(t1.game_addiction),0) as gameAddiction  ",
+    "comment": "关键行为数"
+  },
+  "gameAddictionCost": {
+    "filed": "CASE WHEN sum(t1.cost) / sum(t1.game_addiction) IS NULL THEN 0 ELSE round(sum(t1.cost)/sum(t1.game_addiction),3) end as gameAddictionCost ",
+    "comment": "关键行为成本"
+  },
+  "gameAddictionRate": {
+    "filed": "CASE WHEN sum(t1.active)!= 0 THEN concat(CAST(round(sum(t1.game_addiction) / sum(t1.active)*100,2) AS CHAR),'%') ELSE '0%' end  as gameAddictionRate",
+    "comment": "关键行为率"
+  },
+  "nextDayOpen": {
+    "filed": "IFNULL(sum(t1.next_day_open),0) as nextDayOpen ",
+    "comment": "次留数"
+  },
+  "nextDayOpenCost": {
+    "filed": "CASE WHEN sum(t1.cost) / sum(t1.next_day_open) IS NULL THEN 0 ELSE round(sum(t1.cost)/sum(t1.next_day_open),3) end as nextDayOpenCost ",
+    "comment": "次留成本"
+  },
+  "nextDayOpenRate": {
+    "filed": "CASE WHEN  sum(t1.active)!= 0 THEN concat(CAST(round(sum(t1.next_day_open) / sum(t1.active)*100,2) AS CHAR) ,'%') ELSE '0%' end  as nextDayOpenRate ",
+    "comment": "次留率"
+  },
+  "activePayAmount": {
+    "filed": "IFNULL(sum(pay_count),0) as activePayAmount ",
+    "comment": "付费数"
+  },
+  "activePayCost": {
+    "filed": "CASE WHEN sum(t1.cost) / sum(t1.pay_count) IS NULL THEN 0 ELSE round(sum(t1.cost)/sum(t1.pay_count),3) end as activePayCost ",
+    "comment": "付费成本"
+  },
+  "form": {
+    "filed": "IFNULL(sum(t1.form),0) as form ",
+    "comment": "表单提交"
+  },
+  "validPlayCost": {
+    "filed": "CASE WHEN sum(t1.cost) / sum(t1.valid_play) IS NULL THEN 0 ELSE round(sum(t1.cost)/sum(t1.valid_play),3) end as validPlayCost ",
+    "comment": "有效播放成本"
+  },
+  "play25FeedBreak": {
+    "filed": "IFNULL(sum(t1.play25_feed_break),0) as play25FeedBreak ",
+    "comment": "25%进度播放数"
+  },
+  "play50FeedBreak": {
+    "filed": "IFNULL(sum(t1.play50_feed_break),0) as play50FeedBreak",
+    "comment": "50%进度播放数"
+  },
+  "play75FeedBreak": {
+    "filed": "IFNULL(sum(t1.play75_feed_break),0) as play75FeedBreak",
+    "comment": "75%进度播放数"
+  },
+  "play100FeedBreak": {
+    "filed": "IFNULL(sum(t1.play100_feed_break),0) as play100FeedBreak",
+    "comment": "100%进度播放数"
+  },
+  "follow": {
+    "filed": "IFNULL(sum(t1.follow),0) as follow ",
+    "comment": "新增关注数"
+  },
+  "likeMaterial": {
+    "filed": "IFNULL(sum(t1.like_material),0) as likeMaterial ",
+    "comment": "点赞数"
+  },
+  "shareMaterial": {
+    "filed": "IFNULL(sum(t1.share_material),0) as shareMaterial ",
+    "comment": "分享数"
+  }
+}

+ 20 - 0
jeecg-boot-bytedance/src/test/java/cn/com/ctop/AppTest.java

@@ -0,0 +1,20 @@
+package cn.com.ctop;
+
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+/**
+ * Unit test for simple App.
+ */
+public class AppTest 
+{
+    /**
+     * Rigorous Test :-)
+     */
+    @Test
+    public void shouldAnswerWithTrue()
+    {
+        assertTrue( true );
+    }
+}

+ 1 - 2
pom.xml

@@ -50,11 +50,10 @@
 	<modules>
         <module>jeecg-boot-base</module>
         <module>jeecg-boot-module-demo</module>
+		<module>jeecg-boot-bytedance</module>
         <module>jeecg-boot-module-system</module>
 
        <!-- 需要微服务,请打开注释-->
-       	<module>jeecg-boot-starter</module>
-		<module>jeecg-cloud-module</module>
 	</modules>
 
 	<distributionManagement>