yangzian 4 gadi atpakaļ
vecāks
revīzija
064102e7dc
18 mainītis faili ar 1277 papildinājumiem un 1 dzēšanām
  1. 10 0
      jeecg-boot-bytedance/pom.xml
  2. 64 1
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/dockapi/marketing.java
  3. 3 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/common/constant/BytedanceConstant.java
  4. 134 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/common/entity/FileInfo.java
  5. 142 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/common/entity/MaterialImageInfo.java
  6. 14 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/common/mapper/FileInfoMapper.java
  7. 25 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/common/mapper/MaterialImageInfoMapper.java
  8. 5 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/common/mapper/xml/FileInfoMapper.xml
  9. 134 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/common/mapper/xml/MaterialImageInfoMapper.xml
  10. 24 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/common/service/IFileInfoService.java
  11. 35 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/common/service/IMaterialImageInfoService.java
  12. 70 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/common/service/impl/FileInfoServiceImpl.java
  13. 165 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/common/service/impl/MaterialImageInfoServiceImpl.java
  14. 120 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/common/utils/AesEncryptUtil.java
  15. 189 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/common/utils/LoadFileUtil.java
  16. 92 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/common/utils/MD5Util.java
  17. 3 0
      jeecg-boot-bytedance/src/main/resources/bytedance_config.properties
  18. 48 0
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/bytedance/common/FileController.java

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

@@ -15,6 +15,16 @@
             <groupId>org.jeecgframework.boot</groupId>
             <artifactId>jeecg-boot-base-core</artifactId>
         </dependency>
+        <dependency>
+            <groupId>com.aliyun</groupId>
+            <artifactId>aliyun-java-sdk-mts</artifactId>
+            <version>2.5.2</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpmime</artifactId>
+            <version>4.5.10</version>
+        </dependency>
         <!--引入微服务启动依赖 starter
       <dependency>
           <groupId>org.jeecgframework.boot</groupId>

+ 64 - 1
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/dockapi/marketing.java

@@ -3,6 +3,11 @@ package org.jeecg.modules.bytedance.advertise.dockapi;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.http.HttpEntity;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClientBuilder;
 import org.jeecg.common.api.vo.Result;
 import org.jeecg.modules.bytedance.advertise.entity.AiBytedanceAdvertiserStrategy;
 import org.jeecg.modules.bytedance.advertise.entity.ByteDanceAdvertisePlan;
@@ -15,7 +20,11 @@ import org.jeecg.modules.bytedance.common.entity.CtopOauthToken;
 import org.jeecg.modules.bytedance.common.utils.Check;
 import org.jeecg.modules.bytedance.common.utils.HttpUtils;
 import org.jeecg.modules.bytedance.common.utils.PropertiesUtils;
-
+import org.apache.http.entity.mime.MultipartEntityBuilder;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.URI;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -1055,6 +1064,60 @@ public class marketing {
     }
 
 
+    /**
+     *  上传平台 图片
+     * @param token
+     * @param advertiserId 广告主id
+     * @param imageUrl 图片url
+     * @return
+     */
+    public static JSONObject imageUpload(CtopOauthToken token, String advertiserId, String imageUrl) {
+        // 请求地址
+        String url = urlPath + PropertiesUtils.getValue("bytedance_config", "bytedance_v2_file_image_ad");
+        // 构造请求
+        HttpPost httpPost = new HttpPost(url);
+        httpPost.setHeader("Access-Token", token.getAccessToken());
+        MultipartEntityBuilder entityBuilder = MultipartEntityBuilder.create();
+        // 其他参数
+        entityBuilder.addTextBody("advertiser_id", advertiserId);
+        entityBuilder.addTextBody("upload_type", BytedanceConstant.UPLOAD_TYPE_BY_URL);
+        entityBuilder.addTextBody("image_url", imageUrl);
+
+        HttpEntity entity = entityBuilder.build();
+        CloseableHttpResponse response = null;
+        CloseableHttpClient client = null;
+        try {
+            client = HttpClientBuilder.create().build();
+            httpPost.setURI(URI.create(url));
+            httpPost.setEntity(entity);
+            response = client.execute(httpPost);
+            if (response != null && response.getStatusLine().getStatusCode() == 200) {
+                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
+                StringBuilder buffer = new StringBuilder();
+                String line = "";
+                while ((line = bufferedReader.readLine()) != null) {
+                    buffer.append(line);
+                }
+                bufferedReader.close();
+                return JSONObject.parseObject(buffer.toString());
+            }
+        } catch (IOException e) {
+            log.error(e.getMessage(), e);
+        } finally {
+            try {
+                if (response != null) {
+                    response.close();
+                }
+                if (null != client) {
+                    client.close();
+                }
+            } catch (IOException e) {
+                log.error(e.getMessage(), e);
+            }
+        }
+        return null;
+    }
+
 
 
 

+ 3 - 0
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/common/constant/BytedanceConstant.java

@@ -54,4 +54,7 @@ public class BytedanceConstant {
 
     //为代理商行业获取,代理商行业level都为1
     public static final String LEVEL_AGENT = "AGENT";
+
+
+    public static final String UPLOAD_TYPE_BY_URL = "UPLOAD_BY_URL";
 }

+ 134 - 0
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/common/entity/FileInfo.java

@@ -0,0 +1,134 @@
+package org.jeecg.modules.bytedance.common.entity;
+
+import com.alibaba.fastjson.JSONObject;
+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;
+
+/**
+ * @Description: 文件信息
+ * @Author: jeecg-boot
+ * @Date: 2019-07-28
+ * @Version: V1.0
+ */
+@Data
+@TableName("ctop_file_info")
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value = "ctop_file_info对象", description = "文件信息")
+public class FileInfo {
+
+    /**
+     * id
+     */
+    @TableId(type = IdType.AUTO)
+    @ApiModelProperty(value = "id")
+    private Long id;
+    /**
+     * 文件名称
+     */
+    @Excel(name = "文件名称", width = 15)
+    @ApiModelProperty(value = "文件名称")
+    private String fileName;
+
+    /**
+     * md5
+     */
+    @Excel(name = "md5", width = 15)
+    @ApiModelProperty(value = "文件MD5值")
+    private String md5;
+
+    /**
+     * 平台文件id
+     */
+    @Excel(name = "平台文件id")
+    @ApiModelProperty(value = "平台文件id")
+    private String fileId;
+
+    /**
+     * 文件类型
+     */
+    @Excel(name = "文件类型", width = 15)
+    @ApiModelProperty(value = "文件类型")
+    private String type;
+
+    /**
+     * 文件类型
+     */
+    @Excel(name = "所属平台类型", width = 15)
+    @ApiModelProperty(value = "所属平台类型")
+    private String platformType;
+
+    /**
+     * 文件访问路径
+     */
+    @Excel(name = "文件地址", width = 15)
+    @ApiModelProperty(value = "文件地址")
+    private String path;
+
+    @Excel(name = "头条账号id", width = 15)
+    @ApiModelProperty(value = "头条账号id")
+    private Long accountId;
+
+    @Excel(name = "广告主id", width = 15)
+    @ApiModelProperty(value = "广告主id")
+    private String advertiserId;
+
+    @Excel(name = "文件访问路径", width = 15)
+    @ApiModelProperty(value = "文件访问路径")
+    private String fileUrl;
+    /**
+     * createTime
+     */
+    @ApiModelProperty(value = "createTime")
+    private Date createTime;
+    /**
+     * updateTime
+     */
+    @ApiModelProperty(value = "updateTime")
+    private Date updateTime;
+
+    public FileInfo(String md5Hex, JSONObject data, String advertiserId, CtopOauthToken token, String imageUrl, String imagePath, String fileType, String platformType) {
+        this.type = fileType;
+        if ("IMAGE".equals(type)) {
+            this.fileId = data.getString("id");
+        } else {
+            this.fileId = data.getString("video_id");
+        }
+        this.fileName = imagePath.substring(imagePath.lastIndexOf("/") + 1);
+        Date now = new Date();
+        this.createTime = now;
+        this.updateTime = now;
+        this.accountId = token.getAccountId();
+        this.advertiserId = token.getAdvertiserId();
+        this.fileUrl = imageUrl;
+        this.path = imagePath;
+        this.platformType = platformType;
+        this.md5 = md5Hex;
+    }
+
+    public FileInfo() {
+    }
+
+    @Override
+    public String toString() {
+        return "FileInfo{" +
+                "id=" + id +
+                ", fileName='" + fileName + '\'' +
+                ", type='" + type + '\'' +
+                ", platformType='" + platformType + '\'' +
+                ", path='" + path + '\'' +
+                ", fileUrl='" + fileUrl + '\'' +
+                ", createTime=" + createTime +
+                ", updateTime=" + updateTime +
+                '}';
+    }
+}

+ 142 - 0
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/common/entity/MaterialImageInfo.java

@@ -0,0 +1,142 @@
+package org.jeecg.modules.bytedance.common.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 2020-03-16
+ */
+@Data
+@TableName("ctop_material_image_info")
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value = "ctop_material_image_info对象", description = "素材")
+public class MaterialImageInfo {
+
+    /**
+     * id
+     */
+    @TableId(type = IdType.AUTO)
+    @ApiModelProperty(value = "id")
+    private Long id;
+    /**
+     * code
+     */
+    @Excel(name = "code", width = 15)
+    @ApiModelProperty(value = "code")
+    private String code;
+    /**
+     * url
+     */
+    @Excel(name = "url", width = 15)
+    @ApiModelProperty(value = "url")
+    private String url;
+    /**
+     * 素材名称
+     */
+    @Excel(name = "素材名称", width = 15)
+    @ApiModelProperty(value = "素材名称")
+    private String videoId;
+    /**
+     * 素材名称
+     */
+    @Excel(name = "素材名称", width = 15)
+    @ApiModelProperty(value = "素材名称")
+    private String materialName;
+    /**
+     * 创建人id
+     */
+    @Excel(name = "创建人id", width = 15)
+    @ApiModelProperty(value = "创建人id")
+    private String userId;
+    /**
+     * 审核人
+     */
+    @Excel(name = "审核人", width = 15)
+    @ApiModelProperty(value = "审核人")
+    private String auditorId;
+    /**
+     * 0-待审核 1-审核通过 2-审核拒绝
+     */
+    @Excel(name = "0-待审核 1-审核通过 2-审核拒绝", width = 15)
+    @ApiModelProperty(value = "0-待审核 1-审核通过 2-审核拒绝")
+    private Integer status;
+    /**
+     * 素材描述
+     */
+    @Excel(name = "素材描述", width = 15)
+    @ApiModelProperty(value = "素材描述")
+    private Object materialDescribe;
+    /**
+     * 拒绝原因
+     */
+    @Excel(name = "拒绝原因", width = 15)
+    @ApiModelProperty(value = "拒绝原因")
+    private Object refuseReason;
+    /**
+     * 拒绝截图
+     */
+    @Excel(name = "拒绝截图", width = 15)
+    @ApiModelProperty(value = "拒绝截图")
+    private Object refuseFile;
+    /**
+     * width
+     */
+    @Excel(name = "width", width = 15)
+    @ApiModelProperty(value = "width")
+    private String width;
+    /**
+     * 素材类型
+     */
+    @Excel(name = "素材类型", width = 15)
+    @ApiModelProperty(value = "素材类型")
+    private String type;
+    /**
+     * height
+     */
+    @Excel(name = "height", width = 15)
+    @ApiModelProperty(value = "height")
+    private String height;
+    /**
+     * size
+     */
+    @Excel(name = "size", width = 15)
+    @ApiModelProperty(value = "size")
+    private String size;
+
+    private Integer excellent;
+    /**
+     * createTime
+     */
+    @ApiModelProperty(value = "createTime")
+    private Date createTime;
+    /**
+     * updateTime
+     */
+    @ApiModelProperty(value = "updateTime")
+    private Date updateTime;
+
+    @TableField(exist = false)
+    private String videoUrl;
+
+    @TableField(exist = false)
+    private String auditorName;
+
+    @TableField(exist = false)
+    private String userName;
+
+}

+ 14 - 0
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/common/mapper/FileInfoMapper.java

@@ -0,0 +1,14 @@
+package org.jeecg.modules.bytedance.common.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.jeecg.modules.bytedance.common.entity.FileInfo;
+
+/**
+ * @Description: 文件信息
+ * @Author: jeecg-boot
+ * @Date: 2019-07-28
+ * @Version: V1.0
+ */
+public interface FileInfoMapper extends BaseMapper<FileInfo> {
+
+}

+ 25 - 0
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/common/mapper/MaterialImageInfoMapper.java

@@ -0,0 +1,25 @@
+package org.jeecg.modules.bytedance.common.mapper;
+
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Param;
+import org.jeecg.modules.bytedance.common.entity.MaterialImageInfo;
+
+import java.util.List;
+
+/**
+ * 素材
+ *
+ * @author: jeecg-boot
+ * @date: 2020-03-16
+ * @cersion: V1.0
+ */
+public interface MaterialImageInfoMapper extends BaseMapper<MaterialImageInfo> {
+
+    void insertSelective(MaterialImageInfo materialImageInfo);
+
+    List<String> getCodeList();
+
+    List<JSONObject> getUrlList(@Param("videoId") String videoId);
+
+}

+ 5 - 0
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/common/mapper/xml/FileInfoMapper.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.bytedance.common.mapper.FileInfoMapper">
+
+</mapper>

+ 134 - 0
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/common/mapper/xml/MaterialImageInfoMapper.xml

@@ -0,0 +1,134 @@
+<?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.bytedance.common.mapper.MaterialImageInfoMapper">
+
+    <insert id="insertSelective" parameterType="org.jeecg.modules.bytedance.common.entity.MaterialImageInfo">
+        replace into ctop_material_image_info
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="id != null">
+                id,
+            </if>
+            <if test="code != null">
+                code,
+            </if>
+            <if test="videoId != null">
+                video_id,
+            </if>
+            <if test="materialName != null">
+                material_name,
+            </if>
+            <if test="userId != null">
+                user_id,
+            </if>
+            <if test="auditorId != null">
+                auditor_id,
+            </if>
+            <if test="status != null">
+                status,
+            </if>
+
+            <if test="width != null">
+                width,
+            </if>
+            <if test="type != null">
+                type,
+            </if>
+            <if test="height != null">
+                height,
+            </if>
+            <if test="size != null">
+                size,
+            </if>
+            <if test="createTime != null">
+                create_time,
+            </if>
+            <if test="updateTime != null">
+                update_time,
+            </if>
+            <if test="url != null">
+                url,
+            </if>
+            <if test="materialDescribe != null">
+                material_describe,
+            </if>
+            <if test="refuseReason != null">
+                refuse_reason,
+            </if>
+            <if test="refuseFile != null">
+                refuse_file,
+            </if>
+        </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="id != null">
+                #{id,jdbcType=VARCHAR},
+            </if>
+            <if test="code != null">
+                #{code,jdbcType=VARCHAR},
+            </if>
+            <if test="videoId != null">
+                #{videoId,jdbcType=VARCHAR},
+            </if>
+            <if test="materialName != null">
+                #{materialName,jdbcType=VARCHAR},
+            </if>
+            <if test="userId != null">
+                #{userId,jdbcType=VARCHAR},
+            </if>
+            <if test="auditorId != null">
+                #{auditorId,jdbcType=VARCHAR},
+            </if>
+            <if test="status != null">
+                #{status,jdbcType=INTEGER},
+            </if>
+
+            <if test="width != null">
+                #{width,jdbcType=VARCHAR},
+            </if>
+            <if test="type != null">
+                #{type,jdbcType=VARCHAR},
+            </if>
+            <if test="height != null">
+                #{height,jdbcType=VARCHAR},
+            </if>
+            <if test="size != null">
+                #{size,jdbcType=VARCHAR},
+            </if>
+            <if test="createTime != null">
+                #{createTime,jdbcType=TIMESTAMP},
+            </if>
+            <if test="updateTime != null">
+                #{updateTime,jdbcType=TIMESTAMP},
+            </if>
+            <if test="url != null">
+                #{url},
+            </if>
+            <if test="materialDescribe != null">
+                #{materialDescribe},
+            </if>
+            <if test="refuseReason != null">
+                #{refuseReason},
+            </if>
+            <if test="refuseFile != null">
+                #{refuseFile},
+            </if>
+        </trim>
+    </insert>
+
+
+    <select id="getCodeList" resultType="java.lang.String">
+
+     SELECT DISTINCT(code)  from  ctop_material_image_info
+    </select>
+
+    <select id="getUrlList" resultType="com.alibaba.fastjson.JSONObject">
+
+        SELECT t.url as 'imageUrl',t.`code` as 'signature'  from (
+        SELECT url,`code` from ctop_material_image_info
+        WHERE video_id = #{videoId}
+        UNION ALL
+        SELECT url,signature  from ctop_material_cut_frame WHERE video_signature = #{videoId}
+        ) t
+
+    </select>
+
+</mapper>

+ 24 - 0
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/common/service/IFileInfoService.java

@@ -0,0 +1,24 @@
+package org.jeecg.modules.bytedance.common.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.jeecg.modules.bytedance.common.entity.FileInfo;
+
+import java.util.Map;
+
+/**
+ * @Description: 文件
+ * @Author: jeecg-boot
+ * @Date: 2019-07-09
+ * @Version: V1.0
+ */
+public interface IFileInfoService extends IService<FileInfo> {
+
+
+    /**
+     * 平台 上传图片
+     * @param accountId
+     * @param imageFileId
+     * @return
+     */
+    Map<String, Object> uploadImageToBytedance(String accountId, String imageFileId);
+}

+ 35 - 0
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/common/service/IMaterialImageInfoService.java

@@ -0,0 +1,35 @@
+package org.jeecg.modules.bytedance.common.service;
+
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.jeecg.modules.bytedance.common.entity.MaterialImageInfo;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 素材
+ *
+ * @author jeecg-boot
+ * @version V1.0
+ * @date 2020-03-16
+ */
+public interface IMaterialImageInfoService extends IService<MaterialImageInfo> {
+    /**
+     * 根据视频id  关联封面
+     */
+    void insertImage(JSONObject imageJson);
+
+    Map<String, Object> checkMaterialInfo(String code, String videoId);
+
+    List<String> getCodeList();
+
+    List<JSONObject> getUrlList(String videoId);
+
+    void initImageCode(MaterialImageInfo image);
+
+    MaterialImageInfo getByCode(String signature);
+
+
+    List<MaterialImageInfo> getListByVideoSignature(String signature);
+}

+ 70 - 0
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/common/service/impl/FileInfoServiceImpl.java

@@ -0,0 +1,70 @@
+package org.jeecg.modules.bytedance.common.service.impl;
+
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.http.HttpEntity;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.entity.mime.MultipartEntityBuilder;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClientBuilder;
+import org.jeecg.modules.bytedance.advertise.dockapi.marketing;
+import org.jeecg.modules.bytedance.common.constant.BytedanceConstant;
+import org.jeecg.modules.bytedance.common.entity.CtopOauthToken;
+import org.jeecg.modules.bytedance.common.entity.FileInfo;
+import org.jeecg.modules.bytedance.common.mapper.FileInfoMapper;
+import org.jeecg.modules.bytedance.common.service.ICtopOauthTokenService;
+import org.jeecg.modules.bytedance.common.service.IFileInfoService;
+import org.jeecg.modules.bytedance.common.utils.PropertiesUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Primary;
+import org.springframework.stereotype.Service;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.URI;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @Description:
+ * @Author: jeecg-boot
+ * @Date: 2019-07-09
+ * @Version: V1.0
+ */
+@Slf4j
+@Service
+@Primary
+public class FileInfoServiceImpl extends ServiceImpl<FileInfoMapper, FileInfo> implements IFileInfoService {
+
+
+    @Autowired
+    private ICtopOauthTokenService ctopOauthTokenService;
+
+
+    /**
+     * 平台 上传图片
+     * @param accountId
+     * @param imageUrl
+     * @return
+     */
+    @Override
+    public Map<String, Object> uploadImageToBytedance(String accountId, String imageUrl) {
+        Map<String, Object> resultMap = new HashMap<>();
+        try {
+            CtopOauthToken token = ctopOauthTokenService.getOauthTokenByAccountId(accountId);
+            JSONObject jsonObject = marketing.imageUpload(token, String.valueOf(token.getAccountId()), imageUrl);
+            log.info("头条上传图片素材返回信息:{},accountId:{}", jsonObject, accountId);
+        } catch (Exception e) {
+            log.error("头条上传图片文件失败,accountId:{}", accountId);
+            log.error(e.getMessage(), e);
+        }
+
+        return resultMap;
+    }
+
+
+
+}

+ 165 - 0
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/common/service/impl/MaterialImageInfoServiceImpl.java

@@ -0,0 +1,165 @@
+package org.jeecg.modules.bytedance.common.service.impl;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import lombok.extern.slf4j.Slf4j;
+import org.jeecg.modules.bytedance.common.entity.MaterialImageInfo;
+import org.jeecg.modules.bytedance.common.mapper.MaterialImageInfoMapper;
+import org.jeecg.modules.bytedance.common.service.IMaterialImageInfoService;
+import org.jeecg.modules.bytedance.common.utils.*;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+import javax.imageio.ImageIO;
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 素材
+ *
+ * @author jeecg-boot
+ * @version V1.0
+ * @date 2020-03-16
+ */
+@Slf4j
+@Service
+public class MaterialImageInfoServiceImpl extends ServiceImpl<MaterialImageInfoMapper, MaterialImageInfo> implements IMaterialImageInfoService {
+
+    @Value("${oss.replace.download}")
+    private String downloadUrl;
+
+    @Autowired
+    private MaterialImageInfoMapper materialImageInfoMapper;
+
+
+    @Override
+    public void insertImage(JSONObject imageJson) {
+        try {
+
+            String videoId = imageJson.getString("videoId");
+            if (Check.isNull(videoId)) {
+                log.error("视频id不能为空");
+
+            }
+            String userId = imageJson.getString("userId");
+            JSONArray imageArr = imageJson.getJSONArray("imageArr");
+            for (int i = 0; i < imageArr.size(); i++) {
+                JSONObject json = imageArr.getJSONObject(i);
+                if (!Check.isNull(json)) {
+                    MaterialImageInfo materialImageInfo = new MaterialImageInfo();
+                    materialImageInfo.setVideoId(videoId);
+                    materialImageInfo.setMaterialDescribe(json.getString("materialDescribe"));
+                    materialImageInfo.setType("IMAGE");
+                    String url = "https:" + json.getString("url");
+                    materialImageInfo.setUrl(url);
+                    materialImageInfo.setMaterialName(json.getString("materialName"));
+                    materialImageInfo.setStatus(0);
+                    materialImageInfo.setUserId(userId);
+                    String localUrl = LoadFileUtil.downLoadFromUrl(url, downloadUrl);
+                    String md5Code = MD5Util.getFileMd5(localUrl);
+                    materialImageInfo.setCode(md5Code);
+                    File picture = new File(localUrl);
+                    BufferedImage sourceImg = null;
+                    try {
+                        sourceImg = ImageIO.read(new FileInputStream(picture));
+                    } catch (IOException e) {
+                        e.printStackTrace();
+                    }
+                    String size = String.format("%.1f", picture.length() / 1024.0);
+                    Integer width = sourceImg.getWidth();
+                    Integer height = sourceImg.getHeight();
+                    materialImageInfo.setSize(size);
+                    materialImageInfo.setHeight(String.valueOf(height));
+                    materialImageInfo.setWidth(String.valueOf(width));
+                    materialImageInfoMapper.insertSelective(materialImageInfo);
+                    LoadFileUtil.delFile(localUrl);
+                }
+
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+    }
+
+    /**
+     * 检查自己数据库 ctop_material_image_info 是否有图片素材
+     * @param code
+     * @param videoId
+     * @return
+     */
+    @Override
+    public Map<String, Object> checkMaterialInfo(String code, String videoId) {
+        Map<String, Object> result = new HashMap<>();
+        QueryWrapper<MaterialImageInfo> queryWrapper = new QueryWrapper<>();
+        queryWrapper.eq("code", code);
+        queryWrapper.eq("video_id", videoId);
+        queryWrapper.last("limit 1");
+        MaterialImageInfo info = this.getOne(queryWrapper);
+        if (null != info) {
+            //文件已存在
+            ResultMapUtils.setResultMap(result, StatusCode.FILE_HAS_UPLOAD.getCode());
+            result.put("url", info.getUrl());
+            return result;
+        } else {
+            //文件尚未上传
+            ResultMapUtils.setResultMap(result, StatusCode.FILE_HAS_NOT_UPLOAD.getCode());
+            return result;
+        }
+
+    }
+
+
+    @Override
+    public List<String> getCodeList() {
+        return materialImageInfoMapper.getCodeList();
+    }
+
+    @Override
+    public List<JSONObject> getUrlList(String videoId) {
+        return materialImageInfoMapper.getUrlList(videoId);
+    }
+
+    @Override
+    public void initImageCode(MaterialImageInfo image) {
+        String localUrl = LoadFileUtil.downLoadFromUrl(image.getUrl(), downloadUrl);
+        String md5Code = null;
+        try {
+            md5Code = MD5Util.getFileMd5(localUrl);
+            image.setCode(md5Code);
+            image.setUpdateTime(new Date());
+            this.saveOrUpdate(image);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    @Override
+    public MaterialImageInfo getByCode(String signature) {
+        QueryWrapper<MaterialImageInfo> queryWrapper = new QueryWrapper<>();
+        queryWrapper.eq("code",signature);
+        queryWrapper.last("limit 1");
+        return this.getOne(queryWrapper);
+    }
+
+
+    @Override
+    public List<MaterialImageInfo> getListByVideoSignature(String signature) {
+        QueryWrapper<MaterialImageInfo>queryWrapper =new QueryWrapper<>();
+        if(null!=signature&&!signature.trim().equals("")){
+            queryWrapper.eq("video_id",signature);
+        }
+        return this.list(queryWrapper);
+    }
+
+
+}

+ 120 - 0
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/common/utils/AesEncryptUtil.java

@@ -0,0 +1,120 @@
+package org.jeecg.modules.bytedance.common.utils;
+
+import lombok.extern.slf4j.Slf4j;
+import org.apache.shiro.codec.Base64;
+import org.jeecg.common.util.encryption.EncryptedString;
+
+import javax.crypto.Cipher;
+import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+import java.io.UnsupportedEncodingException;
+
+/**
+ * AES 加密
+ * @author jeecg-boot
+ */
+@Slf4j
+public class AesEncryptUtil {
+
+    private AesEncryptUtil() {
+    }
+    /**
+     * 加密方法
+     *
+     * @param data 要加密的数据
+     * @param key  加密key
+     * @param iv   加密iv
+     * @return 加密的结果
+     */
+    public static String encrypt(String data, String key, String iv) {
+        try {
+            //"算法/模式/补码方式"NoPadding PkcsPadding
+            Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
+            int blockSize = cipher.getBlockSize();
+
+            byte[] dataBytes = data.getBytes();
+            int plaintextLength = dataBytes.length;
+            if (plaintextLength % blockSize != 0) {
+                plaintextLength = plaintextLength + (blockSize - (plaintextLength % blockSize));
+            }
+
+            byte[] plaintext = new byte[plaintextLength];
+            System.arraycopy(dataBytes, 0, plaintext, 0, dataBytes.length);
+
+            SecretKeySpec keyspec = new SecretKeySpec(key.getBytes(), "AES");
+            IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes());
+
+            cipher.init(Cipher.ENCRYPT_MODE, keyspec, ivspec);
+            byte[] encrypted = cipher.doFinal(plaintext);
+
+            return Base64.encodeToString(encrypted);
+
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+            return null;
+        }
+    }
+
+    /**
+     * 解密方法
+     *
+     * @param data 要解密的数据
+     * @param key  解密key
+     * @param iv   解密iv
+     * @return 解密的结果
+     * @throws Exception
+     */
+    public static String desEncrypt(String data, String key, String iv) {
+        try {
+            byte[] encrypted1 = Base64.decode(data);
+
+            Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
+            SecretKeySpec keyspec = new SecretKeySpec(key.getBytes(), "AES");
+            IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes());
+
+            cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec);
+
+            byte[] original = cipher.doFinal(encrypted1);
+            return new String(original);
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+            return null;
+        }
+    }
+
+    /**
+     * 使用默认的key和iv加密
+     *
+     * @param data
+     * @return
+     * @throws Exception
+     */
+    public static String encrypt(String data) {
+        return encrypt(data, EncryptedString.key, EncryptedString.iv);
+    }
+
+    /**
+     * 使用默认的key和iv解密
+     *
+     * @param data
+     * @return
+     */
+    public static String desEncrypt(String data) {
+        return desEncrypt(data, EncryptedString.key, EncryptedString.iv);
+    }
+
+
+    public static String getUrlDecoderString(String str) {
+        String result = "";
+        if (null == str) {
+            return "";
+        }
+        try {
+            result = java.net.URLDecoder.decode(str, "UTF-8");
+        } catch (UnsupportedEncodingException e) {
+            log.error(e.getMessage(), e);
+        }
+        return result;
+
+    }
+}

+ 189 - 0
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/common/utils/LoadFileUtil.java

@@ -0,0 +1,189 @@
+package org.jeecg.modules.bytedance.common.utils;
+
+import org.apache.commons.codec.digest.DigestUtils;
+
+import java.io.*;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.net.URLEncoder;
+import java.util.Map;
+
+public class LoadFileUtil {
+    /**
+     * 上传文件
+     *
+     * @param urlStr
+     * @param savePath
+     * @return
+     * @throws IOException
+     */
+    public static String downLoadFromUrl(String urlStr, String savePath) {
+        try {
+            String fileName = AesEncryptUtil.getUrlDecoderString(urlStr.substring(urlStr.lastIndexOf("/") + 1));
+            URL url = new URL(urlStr);
+
+            System.setProperty("https.protocols", "TLSv1,TLSv1.1,TLSv1.2,SSLv3");
+            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
+            //设置超时间为3秒
+            conn.setConnectTimeout(60 * 1000);
+            //防止屏蔽程序抓取而返回403错误
+            conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
+            //得到输入流
+            InputStream inputStream = conn.getInputStream();
+            //获取自己数组
+            byte[] getData = readInputStream(inputStream);
+
+            //文件保存位置
+            File saveDir = new File(savePath);
+            if (!saveDir.exists()) {
+                saveDir.mkdirs();
+            }
+            String localPath = saveDir + File.separator + fileName;
+            File file = new File(localPath);
+            if (!file.exists()) {
+                file.getParentFile().mkdirs();
+            }
+            FileOutputStream fos = new FileOutputStream(file);
+            fos.write(getData);
+            if (fos != null) {
+                fos.close();
+            }
+            if (inputStream != null) {
+                inputStream.close();
+            }
+            return localPath;
+        } catch (Exception e) {
+            return null;
+        }
+
+
+    }
+
+    public static byte[] readInputStream(InputStream inputStream) throws IOException {
+        byte[] buffer = new byte[1024];
+        int len = 0;
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        while ((len = inputStream.read(buffer)) != -1) {
+            bos.write(buffer, 0, len);
+        }
+        bos.close();
+        return bos.toByteArray();
+    }
+
+
+    /**
+     * 删除文件
+     *
+     * @param path
+     * @return
+     */
+    public static boolean delFile(String path) {
+        boolean flag = false;
+        File file = new File(path);
+        if (!file.exists()) {
+            return false;
+        }
+        try {
+            flag = file.delete();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return flag;
+    }
+
+    /**
+     * 获取文件md5
+     *
+     * @param path
+     * @return
+     * @throws IOException
+     */
+    public static String getMD5(String path) throws IOException {
+        return DigestUtils.md5Hex(new FileInputStream(path));
+    }
+
+    public static String getMD5ByFile(FileInputStream inputStream) throws IOException {
+        return DigestUtils.md5Hex(inputStream);
+    }
+
+    public static void checkFile(String filePackageName) {
+        File file = new File(filePackageName);
+        if (!file.exists()) {
+            file.mkdir();
+        }
+    }
+
+    public static String downloadByUrl(Map<String, Object> requestMap, String downloadPath, String urlStr, String token, String fileName) {
+
+        try {
+            StringBuilder postBody = null;
+            if (!Check.isNull(requestMap)) {
+                postBody = new StringBuilder();
+                for (Map.Entry<String, Object> entry : requestMap.entrySet()) {
+                    if (entry.getValue() == null) {
+                        continue;
+                    }
+                    postBody.append(entry.getKey()).append("=").append(URLEncoder.encode(entry.getValue().toString(),
+                            "utf-8")).append("&");
+                }
+                if (!requestMap.isEmpty()) {
+                    postBody.deleteCharAt(postBody.length() - 1);
+                }
+            }
+
+            URL url = new URL(urlStr + "?" + postBody);
+            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
+            //设置超时间为3秒
+            conn.setConnectTimeout(120 * 1000);
+            //防止屏蔽程序抓取而返回403错误
+            conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
+            conn.setRequestProperty("Access-Token", token);
+            //得到输入流
+            InputStream inputStream = null;
+
+            inputStream = conn.getInputStream();
+
+            //获取自己数组
+            byte[] getData = readInputStream(inputStream);
+
+            //文件保存位置
+            File saveDir = new File(downloadPath);
+            if (!saveDir.exists()) {
+                saveDir.mkdirs();
+            }
+            String filePath = downloadPath + fileName;
+
+            File file = new File(saveDir + File.separator + fileName);
+            FileOutputStream fos = new FileOutputStream(file);
+            fos.write(getData);
+            fos.close();
+            inputStream.close();
+            return filePath;
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+
+
+        return null;
+
+    }
+
+
+    public static InputStream getFileStream(String url) {
+        try {
+            HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
+            connection.setReadTimeout(60000);
+            connection.setConnectTimeout(60000);
+            connection.setRequestMethod("GET");
+            if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
+                InputStream inputStream = connection.getInputStream();
+                return inputStream;
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+
+}

+ 92 - 0
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/common/utils/MD5Util.java

@@ -0,0 +1,92 @@
+package org.jeecg.modules.bytedance.common.utils;
+
+import org.apache.commons.codec.digest.DigestUtils;
+
+import java.io.FileInputStream;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+public class MD5Util {
+	private static ThreadLocal<MessageDigest> MD5 = new ThreadLocal<MessageDigest>() {
+		@Override
+		protected MessageDigest initialValue() {
+			try {
+				return MessageDigest.getInstance("MD5");
+			} catch (NoSuchAlgorithmException e) {
+				throw new IllegalStateException("No md5 algorithm found");
+			}
+		}
+	};
+	public static String toHexStr(byte[] bytes) {
+		int j = bytes.length;
+		char[] str = new char[j * 2];
+		int k = 0;
+		for (int i = 0; i < j; i++) {
+			byte byte0 = bytes[i];
+			str[k++] = HEX_DIGITS_CHAR[byte0 >>> 4 & 0xf];
+			str[k++] = HEX_DIGITS_CHAR[byte0 & 0xf];
+		}
+		return String.valueOf(str);
+	}
+	public static String getMd5(String url) {
+		MessageDigest md5 = MD5.get();
+		md5.reset();
+		return toHexStr(md5.digest(url.getBytes()));
+	}
+
+	public static String byteArrayToHexString(byte[] b) {
+		StringBuffer resultSb = new StringBuffer();
+		for (int i = 0; i < b.length; i++){
+			resultSb.append(byteToHexString(b[i]));
+		}
+		return resultSb.toString();
+	}
+
+	private static String byteToHexString(byte b) {
+		int n = b;
+		if (n < 0) {
+			n += 256;
+		}
+		int d1 = n / 16;
+		int d2 = n % 16;
+		return hexDigits[d1] + hexDigits[d2];
+	}
+
+	public static String MD5Encode(String origin, String charsetname) {
+		String resultString = null;
+		try {
+			resultString = new String(origin);
+			MessageDigest md = MessageDigest.getInstance("MD5");
+			if (charsetname == null || "".equals(charsetname)) {
+				resultString = byteArrayToHexString(md.digest(resultString.getBytes()));
+			} else {
+				resultString = byteArrayToHexString(md.digest(resultString.getBytes(charsetname)));
+			}
+		} catch (Exception exception) {
+		}
+		return resultString;
+	}
+	public static String md5Encode(String origin, String charsetname) {
+		String resultString = null;
+		try {
+			resultString = new String(origin);
+			MessageDigest md = MessageDigest.getInstance("MD5");
+			if (charsetname == null || "".equals(charsetname)) {
+				resultString = byteArrayToHexString(md.digest(resultString.getBytes()));
+			} else {
+				resultString = byteArrayToHexString(md.digest(resultString.getBytes(charsetname)));
+			}
+		} catch (Exception exception) {
+		}
+		return resultString;
+	}
+	private static final String[] hexDigits = { "0", "1", "2", "3", "4", "5",
+			"6", "7", "8", "9", "a", "b", "c", "d", "e", "f" };
+	private static final String[] HEX_DIGITS = {"0", "1", "2", "3", "4", "5",
+			"6", "7", "8", "9", "a", "b", "c", "d", "e", "f" };
+	private static final char[] HEX_DIGITS_CHAR = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
+
+	public static String getFileMd5(String path) throws Exception {
+		return DigestUtils.md5Hex(new FileInputStream(path));
+	}
+}

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

@@ -49,6 +49,9 @@ bytedance_v2_campaign_update_status=/2/campaign/update/status/
 bytedance_v2_campaign_update=/2/campaign/update/
 
 bytedance_v2_file_video_ad=/2/file/video/ad/
+
+
+#图片上传平台
 bytedance_v2_file_image_ad=/2/file/image/ad/
 
 #更改创意状态

+ 48 - 0
jeecg-boot-module-system/src/main/java/org/jeecg/modules/bytedance/common/FileController.java

@@ -0,0 +1,48 @@
+package org.jeecg.modules.bytedance.common;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import org.apache.shiro.SecurityUtils;
+import org.jeecg.common.system.vo.LoginUser;
+import org.jeecg.modules.bytedance.common.service.IFileInfoService;
+import org.jeecg.modules.bytedance.common.service.IMaterialImageInfoService;
+import org.jeecg.modules.bytedance.common.utils.Check;
+import org.jeecg.modules.bytedance.common.utils.ResultMapUtils;
+import org.jeecg.modules.bytedance.common.utils.StatusCode;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Administrator
+ * 2021/4/26
+ **/
+
+@RestController
+public class FileController {
+
+
+    @Autowired
+    private IMaterialImageInfoService materialImageInfoService;
+
+
+    /**
+     * 检查自己数据库 ctop_material_image_info 是否有图片素材
+     * @param code
+     * @param videoId
+     * @return
+     */
+    @RequestMapping("file/imageCheck")
+    public Map<String, Object> imageCheck(String code, String videoId) {
+        return materialImageInfoService.checkMaterialInfo(code, videoId);
+    }
+
+
+
+
+}