فهرست منبع

Merge branch 'zzy' into test

# Conflicts:
#	jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/config/shiro/ShiroConfig.java
zhouzeyu@c-top.com.cn 3 سال پیش
والد
کامیت
ac4afbfa0a
18فایلهای تغییر یافته به همراه4806 افزوده شده و 3 حذف شده
  1. 48 0
      jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/util/DateUtils.java
  2. 14 3
      jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/config/shiro/ShiroConfig.java
  3. 129 0
      jeecg-boot-material-view/pom.xml
  4. 20 0
      jeecg-boot-material-view/src/main/java/org/jeecg/ctop/material/JeecgBootMaterialApplication.java
  5. 529 0
      jeecg-boot-material-view/src/main/java/org/jeecg/ctop/material/controller/MaterialReportOverViewV2Controller.java
  6. 195 0
      jeecg-boot-material-view/src/main/java/org/jeecg/ctop/material/mapper/MaterialReportOverViewV3Mapper.java
  7. 1761 0
      jeecg-boot-material-view/src/main/java/org/jeecg/ctop/material/mapper/xml/MaterialReportOverViewV3Mapper.xml
  8. 80 0
      jeecg-boot-material-view/src/main/java/org/jeecg/ctop/material/service/IMaterialReportOverViewV2Service.java
  9. 914 0
      jeecg-boot-material-view/src/main/java/org/jeecg/ctop/material/service/impl/MaterialReportOverViewV2ServiceImpl.java
  10. 156 0
      jeecg-boot-material-view/src/main/resources/application-dev.yml
  11. 294 0
      jeecg-boot-material-view/src/main/resources/application-prod.yml
  12. 253 0
      jeecg-boot-material-view/src/main/resources/application-test.yml
  13. 12 0
      jeecg-boot-material-view/src/main/resources/application.yml
  14. 382 0
      jeecg-boot-module-system/src/main/java/org/jeecg/common/constant/AccountReportConstants.java
  15. 6 0
      jeecg-cloud-module/jeecg-cloud-gateway/src/main/resources/application-dev.yml
  16. 6 0
      jeecg-cloud-module/jeecg-cloud-gateway/src/main/resources/application-prod.yml
  17. 6 0
      jeecg-cloud-module/jeecg-cloud-gateway/src/main/resources/application-test.yml
  18. 1 0
      pom.xml

+ 48 - 0
jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/util/DateUtils.java

@@ -1068,6 +1068,20 @@ public class DateUtils extends PropertyEditorSupport {
         return sdf.format(calendar.getTime());
     }
 
+    public static String addDayParse(String dateString, int day) {
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
+        Date date = null;
+        try {
+            date = sdf.parse(dateString);
+        } catch (ParseException e) {
+            e.printStackTrace();
+        }
+        Calendar calendar = Calendar.getInstance();
+        calendar.setTime(date);
+        calendar.add(Calendar.DAY_OF_YEAR, day);
+        return sdf.format(calendar.getTime());
+    }
+
     public static Date addDay(Date date, int day) {
         Calendar calendar = Calendar.getInstance();
         calendar.setTime(date);
@@ -1579,6 +1593,24 @@ public class DateUtils extends PropertyEditorSupport {
         return (int) betweenDate;
     }
 
+    public static int dateDiffParse(String start, String end) {
+        //设置转换的日期格式
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
+        //开始时间
+        Date startDate = null;
+        Date endDate = null;
+        try {
+            startDate = sdf.parse(start);
+            endDate = sdf.parse(end);
+        } catch (ParseException e) {
+            e.printStackTrace();
+        }
+
+        //得到相差的天数 betweenDate
+        long betweenDate = (endDate.getTime() - startDate.getTime()) / (60 * 60 * 24 * 1000);
+        return (int) betweenDate;
+    }
+
     /**
      * 判断两个日期间隔是否大于半年
      *
@@ -1595,6 +1627,22 @@ public class DateUtils extends PropertyEditorSupport {
         return day > 180;
     }
 
+    /**
+     * 判断两个日期间隔是否大于半年
+     *
+     * @return
+     */
+    public static boolean isMoreSixMonthParse(String startDate, String endDate) throws ParseException {
+        Calendar c = Calendar.getInstance();
+        c.setTime(Objects.requireNonNull(parseDate(startDate, "yyyyMMdd")));
+        long time1 = c.getTimeInMillis();
+        c.setTime(Objects.requireNonNull(parseDate(endDate, "yyyyMMdd")));
+        long time2 = c.getTimeInMillis();
+        long betweenDays = (time2 - time1) / (1000 * 3600 * 24);
+        int day = Integer.parseInt(String.valueOf(betweenDays));
+        return day > 180;
+    }
+
     public static List<Date> findDates(Date dBegin, Date dEnd) {
         List<Date> lDate = new ArrayList<>();
         lDate.add(dBegin);

+ 14 - 3
jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/config/shiro/ShiroConfig.java

@@ -1,6 +1,7 @@
 package org.jeecg.config.shiro;
 
 import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
 import org.apache.shiro.mgt.DefaultSessionStorageEvaluator;
 import org.apache.shiro.mgt.DefaultSubjectDAO;
 import org.apache.shiro.mgt.SecurityManager;
@@ -8,21 +9,29 @@ import org.apache.shiro.spring.LifecycleBeanPostProcessor;
 import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
 import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
 import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
+import org.crazycake.shiro.IRedisManager;
 import org.crazycake.shiro.RedisCacheManager;
+import org.crazycake.shiro.RedisClusterManager;
 import org.crazycake.shiro.RedisManager;
+import org.jeecg.common.constant.CommonConstant;
 import org.jeecg.common.util.oConvertUtils;
+import org.jeecg.config.shiro.filters.CustomShiroFilterFactoryBean;
 import org.jeecg.config.shiro.filters.JwtFilter;
 import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.context.annotation.DependsOn;
+import org.springframework.core.env.Environment;
+import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
 import org.springframework.util.StringUtils;
+import redis.clients.jedis.HostAndPort;
+import redis.clients.jedis.JedisCluster;
 
+import javax.annotation.Resource;
 import javax.servlet.Filter;
-import java.util.HashMap;
-import java.util.LinkedHashMap;
-import java.util.Map;
+import java.util.*;
 
 /**
  * @author: Scott
@@ -228,6 +237,8 @@ public class ShiroConfig {
         filterChainDefinitionMap.put("/account/bytedance/report/**", "anon");
         filterChainDefinitionMap.put("/material/bytedance/report/**", "anon");
         filterChainDefinitionMap.put("/cwjsSaleAssistantInfo/**", "anon");
+        filterChainDefinitionMap.put("/overView/**", "anon");
+        filterChainDefinitionMap.put("/agent/**", "anon");
         filterChainDefinitionMap.put("/task/kuaishouHostingTask/**", "anon");
 
         // 添加自己的过滤器并且取名为jwt

+ 129 - 0
jeecg-boot-material-view/pom.xml

@@ -0,0 +1,129 @@
+<?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.5</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>jeecg-boot-material-view</artifactId>
+
+    <dependencies>
+        <!--引入微服务启动依赖 starter-->
+        <dependency>
+            <groupId>org.jeecgframework.boot</groupId>
+            <artifactId>jeecg-boot-starter-cloud</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-webflux</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.alibaba.cloud</groupId>
+            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
+        </dependency>
+        <!--健康监控-->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-actuator</artifactId>
+        </dependency>
+
+
+
+        <dependency>
+            <groupId>org.jeecgframework.boot</groupId>
+            <artifactId>jeecg-boot-base-core</artifactId>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.jeecgframework.boot</groupId>
+                    <artifactId>hibernate-re</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
+        <dependency>
+            <groupId>org.jeecgframework.boot</groupId>
+            <artifactId>jeecg-system-cloud-api</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>cn.afterturn</groupId>
+            <artifactId>easypoi-web</artifactId>
+            <version>3.2.0</version>
+        </dependency>
+
+        <dependency>
+            <groupId>cn.afterturn</groupId>
+            <artifactId>easypoi-annotation</artifactId>
+            <version>3.2.0</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.poi</groupId>
+            <artifactId>poi-ooxml</artifactId>
+            <version>3.15</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.jeecgframework.boot</groupId>
+            <artifactId>jeecg-boot-module-system</artifactId>
+        </dependency>
+
+
+
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+            </plugin>
+        </plugins>
+        <resources>
+            <!-- 解决MyBatis配置文件引入问题 -->
+            <resource>
+                <directory>src/main/java</directory>
+                <includes>
+                    <include>**/*.properties</include>
+                    <include>**/*.xml</include>
+                </includes>
+                <!-- 是否替换资源中的属性-->
+                <filtering>true</filtering>
+            </resource>
+            <resource>
+                <directory>src/main/resources</directory>
+                <filtering>true</filtering>
+            </resource>
+        </resources>
+    </build>
+
+    <!-- 环境 -->
+    <profiles>
+        <!-- 开发 -->
+        <profile>
+            <id>dev</id>
+            <properties>
+                <activatedProperties>dev</activatedProperties>
+            </properties>
+        </profile>
+        <!-- 测试 -->
+        <profile>
+            <id>test</id>
+            <properties>
+                <activatedProperties>test</activatedProperties>
+            </properties>
+        </profile>
+        <!-- 生产 -->
+        <profile>
+            <id>prod</id>
+            <properties>
+                <activatedProperties>prod</activatedProperties>
+            </properties>
+        </profile>
+    </profiles>
+</project>

+ 20 - 0
jeecg-boot-material-view/src/main/java/org/jeecg/ctop/material/JeecgBootMaterialApplication.java

@@ -0,0 +1,20 @@
+package org.jeecg.ctop.material;
+
+import com.alibaba.dubbo.config.spring.context.annotation.EnableDubbo;
+import org.apache.shiro.spring.boot.autoconfigure.ShiroAnnotationProcessorAutoConfiguration;
+import org.apache.shiro.spring.boot.autoconfigure.ShiroAutoConfiguration;
+import org.apache.shiro.spring.boot.autoconfigure.ShiroBeanAutoConfiguration;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.transaction.annotation.EnableTransactionManagement;
+
+@SpringBootApplication(exclude = {ShiroAnnotationProcessorAutoConfiguration.class, ShiroAutoConfiguration.class, ShiroBeanAutoConfiguration.class})
+@EnableDubbo
+@ComponentScan(basePackages = {"org.jeecg", "cn.com.ctop"})
+@EnableTransactionManagement
+public class JeecgBootMaterialApplication {
+    public static void main(String[] args) {
+        SpringApplication.run(org.jeecg.ctop.material.JeecgBootMaterialApplication.class, args);
+    }
+}

+ 529 - 0
jeecg-boot-material-view/src/main/java/org/jeecg/ctop/material/controller/MaterialReportOverViewV2Controller.java

@@ -0,0 +1,529 @@
+package org.jeecg.ctop.material.controller;
+
+import cn.com.ctop.common.module.utils.CtopAdConstant;
+import com.alibaba.fastjson.JSONObject;
+import com.github.pagehelper.PageInfo;
+import lombok.extern.slf4j.Slf4j;
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.ctop.material.mapper.MaterialReportOverViewV3Mapper;
+import org.jeecg.ctop.material.service.IMaterialReportOverViewV2Service;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Created by JQ.bi on 2021.03.02
+ */
+@Slf4j
+@RestController
+@RequestMapping("/overView/V2")
+public class MaterialReportOverViewV2Controller {
+
+    @Autowired
+    private IMaterialReportOverViewV2Service materialReportOverViewService;
+
+    @Autowired
+    private MaterialReportOverViewV3Mapper materialReportOverViewV3Mapper;
+
+    /**
+     * 根据userId递归查询下属,默认到最后一级,返回人员参与项目集合
+     */
+    @PostMapping("/getProjects")
+    public Result<Set<JSONObject>> getProjects(@RequestParam String userId, @RequestParam int mediaId) {
+        Result<Set<JSONObject>> result = new Result<>();
+        if (userId.isEmpty()) {
+            result.error500("userId is empty");
+            return result;
+        }
+        //查询所有包含自己的下级
+        Set<String> subordinates = materialReportOverViewService.recursiveQuerySubordinate(userId);
+        //查询并返回所有关联的项目
+        result.setResult(materialReportOverViewService.queryProjectBy(subordinates, mediaId));
+        result.setSuccess(true);
+        return result;
+    }
+
+    /**
+     * 查询快手/头条 设计组信息
+     */
+    @GetMapping("/getDesignTeamList")
+    public Result<List<JSONObject>> getDesignTeamList(@RequestParam("userId") String userId, @RequestParam int mediaId) {
+        Result<List<JSONObject>> result = new Result<>();
+        if (userId.isEmpty()) {
+            result.error500("userId is empty");
+            return result;
+        }
+        //查询所有包含自己的下级
+        List<JSONObject> list = materialReportOverViewService.getDesignTeamList(userId, mediaId);
+        //查询并返回所有关联的项目
+        result.setResult(list);
+        result.setSuccess(true);
+        return result;
+    }
+
+    /**
+     * 根据筛选条件查询总消耗、视频总数、爆款视频、有效视频
+     * mediaId 类型 1-头条 2-快手
+     * projects[] 项目id
+     */
+    @PostMapping("/sumData")
+    public Result<Map<String, Object>> sumData(@RequestBody JSONObject params) {
+        Result<Map<String, Object>> result = new Result<>();
+        Map<String, Object> totalModule = materialReportOverViewService.getTotalModule(
+                params.getInteger("mediaId"),
+                params.getString("startDate"),
+                params.getString("endDate"),
+                params.getJSONArray("projects"),
+                params.getString("dimension"),
+                params.getString("leaderId"),
+                params.getString("designerId"),
+                params.getString("userId"));
+        result.setResult(totalModule);
+        result.setSuccess(true);
+        return result;
+    }
+
+    /**
+     * 根据筛选条件查询视频上新 有效
+     * mediaId 类型 1-头条 2-快手
+     * projects[] 项目id
+     */
+    @PostMapping("/sumDataVideoNewEffective")
+    public Result<Map<String, Object>> sumDataVideoNewEffective(@RequestBody JSONObject params) {
+        Result<Map<String, Object>> result = new Result<>();
+        Map<String, Object> totalModule = materialReportOverViewService.sumDataVideoNewEffective(
+                params.getInteger("mediaId"),
+                params.getString("startDate"),
+                params.getString("endDate"),
+                params.getJSONArray("projects"),
+                params.getString("dimension"),
+                params.getString("leaderId"),
+                params.getString("designerId"),
+                params.getString("userId"));
+        result.setResult(totalModule);
+        result.setSuccess(true);
+        return result;
+    }
+
+    /**
+     * 根据筛选条件查询 爆款视频
+     * mediaId 类型 1-头条 2-快手
+     * projects[] 项目id
+     */
+    @PostMapping("/sumDataVideoHot")
+    public Result<Map<String, Object>> sumDataVideoHot(@RequestBody JSONObject params) {
+        Result<Map<String, Object>> result = new Result<>();
+        Map<String, Object> totalModule = materialReportOverViewService.sumDataVideoHot(
+                params.getInteger("mediaId"),
+                params.getString("startDate"),
+                params.getString("endDate"),
+                params.getJSONArray("projects"),
+                params.getString("dimension"),
+                params.getString("leaderId"),
+                params.getString("designerId"),
+                params.getString("userId"),
+                params.getInteger("type"));
+        result.setResult(totalModule);
+        result.setSuccess(true);
+        return result;
+    }
+
+
+    /**
+     * 设计组维度:组内人均消耗等指标
+     * mediaId 类型 1-头条 2-快手
+     * projects[] 项目id
+     */
+    @PostMapping("/getDesignerAvgData")
+    public Result<Map<String, Object>> getDesignerAvgData(@RequestBody JSONObject params) {
+        Result<Map<String, Object>> result = new Result<>();
+        Map<String, Object> totalModule = materialReportOverViewService.getDesignerAvgData(
+                params.getInteger("mediaId"),
+                params.getString("startDate"),
+                params.getString("endDate"),
+                params.getString("userId"),
+                params.getString("leaderId"));
+        result.setResult(totalModule);
+        result.setSuccess(true);
+        return result;
+    }
+
+    /**
+     * 消耗数据趋势图
+     */
+    @PostMapping("/chartData")
+    public Result<List<JSONObject>> chartData(@RequestBody JSONObject params) {
+        Result<List<JSONObject>> result = new Result<>();
+        List<JSONObject> totalChat = materialReportOverViewService.getTotalChat(params.getInteger("mediaId"),
+                params.getString("startDate"),
+                params.getString("endDate"),
+                params.getJSONArray("projects"),
+                params.getString("dimension"),
+                params.getString("leaderId"),
+                params.getString("designerId"),
+                params.getString("userId"));
+        result.setResult(totalChat);
+        result.setSuccess(true);
+        return result;
+    }
+
+    /**
+     * 标签占比
+     */
+    @PostMapping("/labelRatio")
+    public Result<JSONObject> labelRatio(@RequestBody JSONObject params) {
+        Result<JSONObject> result = new Result<>();
+        JSONObject jsonObject = materialReportOverViewService.labelRatio(params.getInteger("mediaId"),
+                params.getString("startDate"),
+                params.getString("endDate"),
+                params.getJSONArray("projects"),
+                params.getString("dimension"),
+                params.getString("leaderId"),
+                params.getString("designerId"),
+                params.getString("userId"),
+                params.getInteger("type"));
+        result.setResult(jsonObject);
+        result.setSuccess(true);
+        return result;
+    }
+
+    /**
+     * Top素材排行榜
+     */
+    @PostMapping("/materialTop")
+    public Result<List<JSONObject>> materialTop(@RequestBody JSONObject params) {
+        Result<List<JSONObject>> result = new Result<>();
+        List<JSONObject> topMaterialList = materialReportOverViewService.getTopMaterialList(params.getInteger("mediaId"),
+                params.getString("startDate"),
+                params.getString("endDate"),
+                params.getJSONArray("projects"),
+                params.getString("dimension"),
+                params.getString("leaderId"),
+                params.getString("designerId"),
+                params.getString("userId"),
+                params.getInteger("channelType")
+        );
+        result.setResult(topMaterialList);
+        result.setSuccess(true);
+        return result;
+    }
+
+    /**
+     * Top素材排行榜查看更多
+     */
+    @PostMapping("/materialTopViewMore")
+    public Result<PageInfo<JSONObject>> materialTopViewMore(@RequestBody JSONObject params) {
+        Result<PageInfo<JSONObject>> result = new Result<>();
+        PageInfo<JSONObject> pageInfo = materialReportOverViewService.getTopMaterialList(params.getInteger("mediaId"),
+                params.getString("startDate"),
+                params.getString("endDate"),
+                params.getJSONArray("projects"),
+                params.getString("userId"),
+                params.getString("md5"),
+                params.getString("dimension"),
+                params.getString("leaderId"),
+                params.getString("designerId"),
+                params.getInteger("materialQuality"),
+                params.getInteger("materialType"),
+                params.getInteger("innovative"),
+                params.getString("target") == null ? "cost" : params.getString("target"),
+                params.getString("order") == null ? "desc" : params.getString("order"),
+                params.getInteger("pageNo"),
+                params.getInteger("pageSize")
+        );
+        result.setResult(pageInfo);
+        result.setSuccess(true);
+        return result;
+    }
+
+    /**
+     * Top素材排行榜查看更多导出报表
+     */
+    @PostMapping("/excel")
+    public void getExcelReport(@RequestBody JSONObject params,
+                               HttpServletRequest request,
+                               HttpServletResponse response) {
+        if (params.getInteger("mediaId") == CtopAdConstant.PLATFORM_TYPE_BYTEDANCE_INT) {
+            materialReportOverViewService.exportBytedanceExcel(params, request, response);
+        } else if (params.getInteger("mediaId") == CtopAdConstant.PLATFORM_TYPE_KUAISHOU_INT) {
+            materialReportOverViewService.exportKuaishouExcel(params, request, response);
+
+        }
+    }
+
+    /**
+     * Top设计排行榜
+     */
+    @PostMapping("/designTop")
+    public Result<PageInfo> designTop(@RequestBody JSONObject params) {
+        Result<PageInfo> result = new Result<>();
+        PageInfo info = materialReportOverViewService.getTopDesignList(
+                params.getInteger("mediaId"),
+                params.getString("startDate"),
+                params.getString("endDate"),
+                params.getInteger("type"),
+                params.getInteger("pageNumber"),
+                params.getInteger("pageSize"));
+        result.setResult(info);
+        result.setSuccess(true);
+        return result;
+    }
+
+    /**
+     * 标签占比饼状图
+     */
+    //TODO 需等标签库重构完
+    @PostMapping("/tagProportionAnalyse")
+    public Result<JSONObject> tagProportionAnalyse() {
+        return null;
+    }
+
+    /**
+     * 素材详情页
+     */
+    @PostMapping("/materialDetailInfo")
+    public Result<JSONObject> materialDetailInfo(@RequestBody JSONObject params) {
+        Result<JSONObject> result = new Result<>();
+        result.setResult(materialReportOverViewService.getMaterialDetailInfo(params.getInteger("mediaId"),
+                params.getString("md5")));
+        result.setSuccess(true);
+        return result;
+
+    }
+
+    @PostMapping("/getProjectIdByMd5")
+    public Result<Long> getProjectIdByMd5(@RequestBody JSONObject params) {
+        Result<Long> result = new Result<>();
+        if (params.getInteger("mediaId") == CtopAdConstant.PLATFORM_TYPE_BYTEDANCE_INT) {
+            result.setResult(materialReportOverViewV3Mapper.queryBytedanceProjectIdByMd5(params.getString("md5")));
+        } else if (params.getInteger("mediaId") == CtopAdConstant.PLATFORM_TYPE_KUAISHOU_INT) {
+            result.setResult(materialReportOverViewV3Mapper.queryKuaishouProjectIdByMd5(params.getString("md5")));
+        }
+        result.setSuccess(true);
+        return result;
+    }
+
+    @PostMapping("/materialDetailCost")
+    public Result<Map<String, Object>> materialDetailCost(@RequestBody JSONObject params) {
+        Result<Map<String, Object>> result = new Result<>();
+        Map<String, Object> map = new HashMap<>();
+        map.put("cost", materialReportOverViewV3Mapper.queryBytedanceCostByMd5(params.getString("md5"), params.getLong("projectId")));
+        result.setResult(map);
+        result.setSuccess(true);
+        return result;
+    }
+
+    @PostMapping("/materialDetailClick")
+    public Result<Map<String, Object>> materialDetailClick(@RequestBody JSONObject params) {
+        Result<Map<String, Object>> result = new Result<>();
+        Map<String, Object> map = new HashMap<>();
+        map.put("click", materialReportOverViewV3Mapper.queryBytedanceClickByMd5(params.getString("md5"), params.getLong("projectId")));
+        result.setResult(map);
+        result.setSuccess(true);
+        return result;
+    }
+
+    @PostMapping("/materialDetailMaterialShow")
+    public Result<Map<String, Object>> materialDetailMaterialShow(@RequestBody JSONObject params) {
+        Result<Map<String, Object>> result = new Result<>();
+        Map<String, Object> map = new HashMap<>();
+        map.put("materialShow", materialReportOverViewV3Mapper.queryBytedanceMaterialShowByMd5(params.getString("md5"), params.getLong("projectId")));
+        result.setResult(map);
+        result.setSuccess(true);
+        return result;
+    }
+
+    @PostMapping("/materialDetailPlay100Rate")
+    public Result<Map<String, Object>> materialDetailPlay100Rate(@RequestBody JSONObject params) {
+        Result<Map<String, Object>> result = new Result<>();
+        Map<String, Object> map = new HashMap<>();
+        map.put("play100Rate", materialReportOverViewV3Mapper.queryBytedancePlay100RateByMd5(params.getString("md5"), params.getLong("projectId")));
+        result.setResult(map);
+        result.setSuccess(true);
+        return result;
+    }
+
+    @PostMapping("/materialDetailLikeMaterial")
+    public Result<Map<String, Object>> materialDetailLikeMaterial(@RequestBody JSONObject params) {
+        Result<Map<String, Object>> result = new Result<>();
+        Map<String, Object> map = new HashMap<>();
+        map.put("likeMaterial", materialReportOverViewV3Mapper.queryBytedanceLikeMaterialByMd5(params.getString("md5"), params.getLong("projectId")));
+        result.setResult(map);
+        result.setSuccess(true);
+        return result;
+    }
+
+    @PostMapping("/materialDetailCommentMaterial")
+    public Result<Map<String, Object>> materialDetailCommentMaterial(@RequestBody JSONObject params) {
+        Result<Map<String, Object>> result = new Result<>();
+        Map<String, Object> map = new HashMap<>();
+        map.put("commentMaterial", materialReportOverViewV3Mapper.queryBytedanceCommentMaterialByMd5(params.getString("md5"), params.getLong("projectId")));
+        result.setResult(map);
+        result.setSuccess(true);
+        return result;
+    }
+
+    @PostMapping("/materialDetailShareMaterial")
+    public Result<Map<String, Object>> materialDetailShareMaterial(@RequestBody JSONObject params) {
+        Result<Map<String, Object>> result = new Result<>();
+        Map<String, Object> map = new HashMap<>();
+        map.put("shareMaterial", materialReportOverViewV3Mapper.queryBytedanceShareMaterialByMd5(params.getString("md5"), params.getLong("projectId")));
+        result.setResult(map);
+        result.setSuccess(true);
+        return result;
+    }
+
+    @PostMapping("/materialDetailFollow")
+    public Result<Map<String, Object>> materialDetailFollow(@RequestBody JSONObject params) {
+        Result<Map<String, Object>> result = new Result<>();
+        Map<String, Object> map = new HashMap<>();
+        map.put("follow", materialReportOverViewV3Mapper.queryBytedanceFollowByMd5(params.getString("md5"), params.getLong("projectId")));
+        result.setResult(map);
+        result.setSuccess(true);
+        return result;
+    }
+
+    @PostMapping("/materialDetailCharge")
+    public Result<Map<String, Object>> materialDetailCharge(@RequestBody JSONObject params) {
+        Result<Map<String, Object>> result = new Result<>();
+        Map<String, Object> map = new HashMap<>();
+        map.put("charge", materialReportOverViewV3Mapper.queryKuaishouChargeByMd5(params.getString("md5"), params.getLong("projectId")));
+        result.setResult(map);
+        result.setSuccess(true);
+        return result;
+    }
+
+    /* @PostMapping("/materialDetailPhotoShow")
+     public Result<Map<String,Object>> materialDetailPhotoShow(@RequestBody JSONObject params){
+         Result<Map<String,Object>> result= new Result<>();
+         Map<String,Object> map = new HashMap<>();
+         map.put("photoShow",materialReportOverViewV3Mapper.queryKuaishouPhotoShowByMd5(params.getString("md5"),params.getLong("projectId")));
+         result.setResult(map);
+         result.setSuccess(true);
+         return result;
+     }*/
+  /*  @PostMapping("/materialDetailPhotoClick")
+    public Result<Map<String,Object>> materialDetailPhotoClick(@RequestBody JSONObject params){
+        Result<Map<String,Object>> result= new Result<>();
+        Map<String,Object> map = new HashMap<>();
+        map.put("photoClick",materialReportOverViewV3Mapper.queryKuaishouPhotoClickByMd5(params.getString("md5"),params.getLong("projectId")));
+        result.setResult(map);
+        result.setSuccess(true);
+        return result;
+    }*/
+    @PostMapping("/materialDetailAClick")
+    public Result<Map<String, Object>> materialDetailAClick(@RequestBody JSONObject params) {
+        Result<Map<String, Object>> result = new Result<>();
+        Map<String, Object> map = new HashMap<>();
+        map.put("aclick", materialReportOverViewV3Mapper.queryKuaishouAClickByMd5(params.getString("md5"), params.getLong("projectId")));
+        result.setResult(map);
+        result.setSuccess(true);
+        return result;
+    }
+
+    /* @PostMapping("/materialDetailBClick")
+     public Result<Map<String,Object>> materialDetailBClick(@RequestBody JSONObject params){
+         Result<Map<String,Object>> result= new Result<>();
+         Map<String,Object> map = new HashMap<>();
+         map.put("bclick",materialReportOverViewV3Mapper.queryKuaishouBClickByMd5(params.getString("md5"),params.getLong("projectId")));
+         result.setResult(map);
+         result.setSuccess(true);
+         return result;
+     }*/
+    @PostMapping("/materialDetailActivation")
+    public Result<Map<String, Object>> materialDetailActivation(@RequestBody JSONObject params) {
+        Result<Map<String, Object>> result = new Result<>();
+        Map<String, Object> map = new HashMap<>();
+        map.put("activation", materialReportOverViewV3Mapper.queryKuaishouActivationByMd5(params.getString("md5"), params.getLong("projectId")));
+        result.setResult(map);
+        result.setSuccess(true);
+        return result;
+    }
+
+    @PostMapping("/materialDetailPlay3sRate")
+    public Result<Map<String, Object>> materialDetailPlay3sRate(@RequestBody JSONObject params) {
+        Result<Map<String, Object>> result = new Result<>();
+        Map<String, Object> map = new HashMap<>();
+        map.put("play3sRate", materialReportOverViewV3Mapper.queryKuaishouPlay3sRateByMd5(params.getString("md5"), params.getLong("projectId")));
+        result.setResult(map);
+        result.setSuccess(true);
+        return result;
+    }
+
+    @PostMapping("/materialDetailChat")
+    public Result<List<JSONObject>> materialDetailChat(@RequestBody JSONObject params) {
+        Result<List<JSONObject>> result = new Result<>();
+        result.setResult(materialReportOverViewService.getMaterialDetailChat(params.getInteger("mediaId"),
+                params.getString("md5")));
+        result.setSuccess(true);
+        return result;
+    }
+
+    /**
+     * 查询人群分析数据列表
+     *
+     * @param
+     * @return
+     */
+    @GetMapping("/populationAnalysisList")
+    public Result populationAnalysisList(@RequestParam String signature) {
+        return materialReportOverViewService.populationAnalysisList(signature);
+
+    }
+
+    /**
+     * 查询人群分析数据图
+     *
+     * @param
+     * @return
+     */
+    @GetMapping("/populationAnalysisChart")
+    public Result populationAnalysisChart(@RequestParam("signature") String signature) {
+        return materialReportOverViewService.populationAnalysisChart(signature);
+
+    }
+
+    /**
+     * 最优定向组合
+     *
+     * @param
+     * @return
+     */
+    @GetMapping("/optimalCombination")
+    public Result optimalCombination(@RequestParam("signature") String signature) {
+        return materialReportOverViewService.optimalCombination(signature);
+
+    }
+
+    /**
+     * 相似素材
+     *
+     * @param
+     * @return
+     */
+    @GetMapping("/similarMaterial")
+    public Result similarMaterial(@RequestParam("signature") String signature) {
+        return materialReportOverViewService.similarMaterial(signature);
+
+    }
+
+
+    /**
+     * 判断是否有设计组权限
+     *
+     * @param
+     * @return
+     */
+    @GetMapping("/getRole")
+    public Result getRole(@RequestParam("userId") String userId) {
+        return materialReportOverViewService.getRole(userId);
+
+    }
+}

+ 195 - 0
jeecg-boot-material-view/src/main/java/org/jeecg/ctop/material/mapper/MaterialReportOverViewV3Mapper.java

@@ -0,0 +1,195 @@
+package org.jeecg.ctop.material.mapper;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.math.BigDecimal;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+@Mapper
+public interface MaterialReportOverViewV3Mapper {
+
+    Set<String> recursiveQuerySubordinateByLeader(@Param("leaderId") String leaderId);
+
+    List<JSONObject> getDesignTeamList(@Param("mediaId") int mediaId);
+
+    Set<String> recursiveQuerySubordinateByLeaders(@Param("leaderIds") Set<String> leaderIds);
+
+    Set<String> recursiveQuerySubordinateByUserId(@Param("userId") String userId);
+
+    //查询用户参与的项目
+    Set<JSONObject> queryProjectBy(@Param("userIds") Set<String> userIds, @Param("mediaIds") JSONArray mediaIds);
+
+    JSONArray queryProjectIdBy(@Param("userIds") Set<String> userIds, @Param("mediaIds") JSONArray mediaIds);
+
+    //查询头条总消耗
+    BigDecimal queryBytedanceCost(@Param("startDate") Long startDate, @Param("endDate") Long endDate, @Param("projects") JSONArray projects, @Param("dimension") String dimension, @Param("leaderId") String leaderId, @Param("designerId") String designerId, @Param("companyId") String companyId);
+
+    //查询快手总消耗
+    BigDecimal queryKuaishouCost(@Param("startDate") Long startDate, @Param("endDate") Long endDate, @Param("projects") JSONArray projects, @Param("dimension") String dimension, @Param("leaderId") String leaderId, @Param("designerId") String designerId, @Param("companyId") String companyId);
+
+    //查询素材总数
+    Long queryMaterialCount(@Param("startDate") String startDate, @Param("endDate") String endDate, @Param("projects") JSONArray projects);
+
+    //查询素材 上新 数据 头条
+    List<Map<String, String>> queryMaterialCountList(@Param("startDate") String startDate, @Param("endDate") String endDate, @Param("projects") JSONArray projects, @Param("dimension") String dimension, @Param("leaderId") String leaderId, @Param("designerId") String designerId, @Param("companyId") String companyId);
+
+    //上新 快手
+    List<Map<String, String>> queryMaterialCountListKs(@Param("startDate") String startDate, @Param("endDate") String endDate, @Param("projects") JSONArray projects, @Param("dimension") String dimension, @Param("leaderId") String leaderId, @Param("designerId") String designerId, @Param("companyId") String companyId);
+
+    //查询有消耗的素材 - 头条
+    Long queryMaterialCostList(@Param("startDate") String startDate, @Param("endDate") String endDate, @Param("projects") JSONArray projects, @Param("dimension") String dimension, @Param("leaderId") String leaderId, @Param("designerId") String designerId, @Param("companyId") String companyId);
+
+    //查询有消耗的素材 - 快手
+    Long queryMaterialCostListKs(@Param("startDate") String startDate, @Param("endDate") String endDate, @Param("projects") JSONArray projects, @Param("dimension") String dimension, @Param("leaderId") String leaderId, @Param("designerId") String designerId, @Param("companyId") String companyId);
+
+    //查询有效视频-头条
+    List<Map<String, String>> selectEffectiveMaterialVideoBytedance(@Param("startDate") Long startDate, @Param("endDate") Long endDate, @Param("projects") JSONArray projects, @Param("dimension") String dimension, @Param("leaderId") String leaderId, @Param("designerId") String designerId, @Param("companyId") String companyId);
+
+    //有效视频-快手
+    List<Map<String, String>> selectEffectiveMaterialVideoKs(@Param("startDate") Long startDate, @Param("endDate") Long endDate, @Param("projects") JSONArray projects, @Param("dimension") String dimension, @Param("leaderId") String leaderId, @Param("designerId") String designerId, @Param("companyId") String companyId);
+
+    //查询爆款视频-头条
+    List<Map<String, String>> selectHotMaterialVideoBytedance(@Param("startDate") Long startDate, @Param("endDate") Long endDate, @Param("projects") JSONArray projects, @Param("dimension") String dimension, @Param("leaderId") String leaderId, @Param("designerId") String designerId, @Param("companyId") String companyId, @Param("type") int type);
+
+    //爆款视频 -快手
+    List<Map<String, String>> selectHotMaterialVideoKs(@Param("startDate") Long startDate, @Param("endDate") Long endDate, @Param("projects") JSONArray projects, @Param("dimension") String dimension, @Param("leaderId") String leaderId, @Param("designerId") String designerId, @Param("companyId") String companyId, @Param("type") int type);
+
+    //查询今日上新素材数
+    Long queryNewMaterialCount(@Param("statDate") String statDate, @Param("projects") JSONArray projects);
+
+    //查询头条消耗数据趋势
+    List<JSONObject> queryBytedanceChat(@Param("startDate") Long startDate, @Param("endDate") Long endDate, @Param("projects") JSONArray projects, @Param("dimension") String dimension, @Param("leaderId") String leaderId, @Param("designerId") String designerId, @Param("companyId") String companyId);
+
+    List<JSONObject> queryBytedanceChatGroupMonth(@Param("startDate") Long startDate, @Param("endDate") Long endDate, @Param("projects") JSONArray projects, @Param("dimension") String dimension, @Param("leaderId") String leaderId, @Param("designerId") String designerId, @Param("companyId") String companyId);
+
+    //查询快手消耗数据趋势
+    List<JSONObject> queryKuaishouChat(@Param("startDate") Long startDate, @Param("endDate") Long endDate, @Param("projects") JSONArray projects, @Param("dimension") String dimension, @Param("leaderId") String leaderId, @Param("designerId") String designerId, @Param("companyId") String companyId);
+
+    List<JSONObject> queryKuaishouChatGroupMonth(@Param("startDate") Long startDate, @Param("endDate") Long endDate, @Param("projects") JSONArray projects, @Param("dimension") String dimension, @Param("leaderId") String leaderId, @Param("designerId") String designerId, @Param("companyId") String companyId);
+
+    //头条素材排行榜
+    List<JSONObject> queryBytedanceTopMaterial(@Param("startDate") Long startDate, @Param("endDate") Long endDate, @Param("projects") JSONArray projects, @Param("dimension") String dimension, @Param("leaderId") String leaderId, @Param("designerId") String designerId, @Param("companyId") String companyId);
+
+    //头条素材排行榜New
+    List<JSONObject> queryBytedanceTopMaterialNew(@Param("startDate") String startDate, @Param("endDate") String endDate, @Param("projects") JSONArray projects, @Param("channelType") Integer channelType);
+
+    //查看更多
+    List<JSONObject> queryBytedanceMaterialReport(@Param("filed") String filed, @Param("startDate") Long startDate, @Param("endDate") Long endDate, @Param("projects") JSONArray projects,
+                                                  @Param("md5") String md5, @Param("dimension") String dimension, @Param("leaderId") String leaderId,
+                                                  @Param("designerId") String designerId, @Param("materialQuality") Integer materialQuality, @Param("materialType") Integer materialType,
+                                                  @Param("innovative") Integer innovative,
+                                                  @Param("target") String target, @Param("order") String order, @Param("companyId") String companyId);
+
+    Long queryBytedanceMaterialReportCount(@Param("startDate") String startDate, @Param("endDate") String endDate, @Param("projects") JSONArray projects,
+                                           @Param("md5") String md5);
+
+    //快手素材排行榜
+    List<JSONObject> queryKuaishouTopMaterial(@Param("startDate") Long startDate, @Param("endDate") Long endDate, @Param("projects") JSONArray projects, @Param("dimension") String dimension, @Param("leaderId") String leaderId, @Param("designerId") String designerId, @Param("companyId") String companyId, @Param("channelType") Integer channelType);
+
+    //查看更多
+    List<JSONObject> queryKuaishouMaterialReport(@Param("filed") String filed, @Param("startDate") Long startDate, @Param("endDate") Long endDate, @Param("projects") JSONArray projects,
+                                                 @Param("md5") String md5, @Param("dimension") String dimension, @Param("leaderId") String leaderId,
+                                                 @Param("designerId") String designerId, @Param("materialQuality") Integer materialQuality, @Param("materialType") Integer materialType,
+                                                 @Param("innovative") Integer innovative,
+                                                 @Param("target") String target, @Param("order") String order, @Param("companyId") String companyId);
+
+    Long queryKuaishouMaterialReportCount(@Param("startDate") String startDate, @Param("endDate") String endDate, @Param("projects") JSONArray projects,
+                                          @Param("channelType") String channelType, @Param("md5") String md5);
+
+    //设计排行榜
+    List<JSONObject> queryTopDesign(String startDate, String endDate, Set<String> userIds, String target, String order, String roleName);
+
+    Long queryTopDesignCount(String startDate, String endDate, Set<String> userIds);
+
+    //设计排行榜新版本
+    List<JSONObject> queryKuaishouTopDesign(@Param("startDate") Long startDate, @Param("endDate") Long endDate, @Param("type") Integer type);
+
+    List<JSONObject> queryBytedanceTopDesign(@Param("startDate") Long startDate, @Param("endDate") Long endDate, @Param("type") Integer type);
+
+    //素材详情页
+    JSONObject queryBytedanceVideoDetail(String md5);
+
+    JSONObject queryKuaishouVideoDetail(String md5);
+
+    //数据概览
+    Long queryBytedanceProjectIdByMd5(String md5);
+
+    Long queryKuaishouProjectIdByMd5(String md5);
+
+    List<JSONObject> queryBytedanceCostByMd5(String md5, Long project);
+
+    List<JSONObject> queryBytedanceClickByMd5(String md5, Long project);
+
+    List<JSONObject> queryBytedanceMaterialShowByMd5(String md5, Long project);
+
+    List<JSONObject> queryBytedancePlay100RateByMd5(String md5, Long project);
+
+    List<JSONObject> queryBytedanceLikeMaterialByMd5(String md5, Long project);
+
+    List<JSONObject> queryBytedanceCommentMaterialByMd5(String md5, Long project);
+
+    List<JSONObject> queryBytedanceShareMaterialByMd5(String md5, Long project);
+
+    List<JSONObject> queryBytedanceFollowByMd5(String md5, Long project);
+
+    List<JSONObject> queryKuaishouChargeByMd5(String md5, Long project);
+
+    List<JSONObject> queryKuaishouPhotoShowByMd5(String md5, Long project);
+
+    List<JSONObject> queryKuaishouPhotoClickByMd5(String md5, Long project);
+
+    List<JSONObject> queryKuaishouAClickByMd5(String md5, Long project);
+
+    List<JSONObject> queryKuaishouBClickByMd5(String md5, Long project);
+
+    List<JSONObject> queryKuaishouActivationByMd5(String md5, Long project);
+
+    List<JSONObject> queryKuaishouPlay3sRateByMd5(String md5, Long project);
+
+    //数据趋势
+    List<JSONObject> queryBytedanceVideoChat(String md5);
+
+    List<JSONObject> queryKuaishouVideoChat(String md5);
+
+    List<Map> populationAnalysisList(@Param("signature") String signature);
+
+    String getActualProb(@Param("signature") String signature, @Param("targetType") String targetType);
+
+    List<Map> populationAnalysisChart(@Param("signature") String signature);
+
+    Map<String, String> optimalCombination(@Param("signature") String signature, @Param("targetType") String targetType);
+
+    Map similarMaterialInfo(@Param("signature") String signature);
+
+    Map<String, String> getSimilarMaterialList(@Param("signature") String signature);
+
+    String getCompanyId(@Param("userId") String userId);
+
+    BigDecimal getBytedanceDesignTeamAvgCost(@Param("startDate") Long startDate, @Param("endDate") Long endDate, @Param("leaderId") String leaderId, @Param("companyId") String companyId);
+
+    BigDecimal getKuaishouDesignTeamAvgCost(@Param("startDate") Long startDate, @Param("endDate") Long endDate, @Param("leaderId") String leaderId, @Param("companyId") String companyId);
+
+    BigDecimal getBytedanceDesignTeamGroupWork(@Param("startDate") String startDate, @Param("endDate") String endDate, @Param("leaderId") String leaderId);
+
+    BigDecimal getKuaishouDesignTeamGroupWork(@Param("startDate") String startDate, @Param("endDate") String endDate, @Param("leaderId") String leaderId);
+
+    int getBytedanceDesignTeaminnovativeVideoCount(@Param("startDate") Long startDate, @Param("endDate") Long endDate, @Param("leaderId") String leaderId);
+
+    int getKuaishouDesignTeaminnovativeVideoCount(@Param("startDate") Long startDate, @Param("endDate") Long endDate, @Param("leaderId") String leaderId);
+
+    BigDecimal getBytedanceMaterialCost(@Param("startDate") Long startDate, @Param("endDate") Long endDate, @Param("leaderId") String leaderId, @Param("companyId") String companyId);
+
+    BigDecimal getKuaishouDesignTeaminnovativeVideoCost(@Param("startDate") Long startDate, @Param("endDate") Long endDate, @Param("leaderId") String leaderId, @Param("companyId") String companyId);
+
+    JSONObject getBytedanceMaterialCountByLable(@Param("startDate") String startDate, @Param("endDate") String endDate, @Param("projects") JSONArray projects, @Param("dimension") String dimension, @Param("leaderId") String leaderId, @Param("designerId") String designerId, @Param("companyId") String companyId);
+
+    JSONObject getBytedanceMaterialCountByCost(@Param("startDate") String startDate, @Param("endDate") String endDate, @Param("projects") JSONArray projects, @Param("dimension") String dimension, @Param("leaderId") String leaderId, @Param("designerId") String designerId, @Param("companyId") String companyId);
+
+    JSONObject getKuaishouMaterialCountByLable(@Param("startDate") String startDate, @Param("endDate") String endDate, @Param("projects") JSONArray projects, @Param("dimension") String dimension, @Param("leaderId") String leaderId, @Param("designerId") String designerId, @Param("companyId") String companyId);
+
+    JSONObject getKuaishouMaterialCountByCost(@Param("startDate") String startDate, @Param("endDate") String endDate, @Param("projects") JSONArray projects, @Param("dimension") String dimension, @Param("leaderId") String leaderId, @Param("designerId") String designerId, @Param("companyId") String companyId);
+}

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 1761 - 0
jeecg-boot-material-view/src/main/java/org/jeecg/ctop/material/mapper/xml/MaterialReportOverViewV3Mapper.xml


+ 80 - 0
jeecg-boot-material-view/src/main/java/org/jeecg/ctop/material/service/IMaterialReportOverViewV2Service.java

@@ -0,0 +1,80 @@
+package org.jeecg.ctop.material.service;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.github.pagehelper.PageInfo;
+import org.jeecg.common.api.vo.Result;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+public interface IMaterialReportOverViewV2Service {
+
+    //递归查询下级
+    Set<String> recursiveQuerySubordinate(String userId);
+    List<JSONObject> getDesignTeamList(String userId, int mediaId);
+
+    //查询用户参与的项目
+    Set<JSONObject> queryProjectBy(Set<String> userIds, int mediaId);
+
+    JSONArray queryProjectIdBy(Set<String> userIds, int mediaId);
+
+    //查询总消耗、视频总数、爆款视频数、有效是视频数
+    Map<String,Object> getTotalModule(int mediaId, String startDate, String endDate, JSONArray projects, String dimension, String leaderId, String designerId, String userId);
+    //查询 视频上新 和 有效
+    Map<String,Object> sumDataVideoNewEffective(int mediaId, String startDate, String endDate, JSONArray projects, String dimension, String leaderId, String designerId, String userId);
+    //查询 爆款
+    Map<String,Object> sumDataVideoHot(int mediaId, String startDate, String endDate, JSONArray projects, String dimension, String leaderId, String designerId, String userId, int type);
+
+    //查询消耗趋势图
+    List<JSONObject> getTotalChat(int mediaId, String startDate, String endDate, JSONArray projects, String dimension, String leaderId, String designerId, String userId);
+
+    //查询标签占比图
+    JSONObject getTagProportion(int mediaId, String startDate, String endDate, int tagId);
+
+    //查询Top素材排行榜
+    List<JSONObject> getTopMaterialList(int mediaId, String startDate, String endDate, JSONArray projects, String dimension, String leaderId, String designerId, String userId, Integer channelType);
+
+    //素材查看更多
+   PageInfo<JSONObject> getTopMaterialList(Integer mediaId, String startDate, String endDate, JSONArray projects, String userId, String md5, String dimension, String leaderId, String designerId, Integer materialQuality, Integer materialType, Integer innovative, String target, String order, Integer pageNo, Integer pageSize);
+
+    //导出
+    void exportBytedanceExcel(JSONObject requestBody, HttpServletRequest request, HttpServletResponse response);
+
+    void exportKuaishouExcel(JSONObject requestBody, HttpServletRequest request, HttpServletResponse response);
+
+    //查询设计人员排行榜
+    PageInfo getTopDesignList(Integer mediaId, String startDate, String endDate, Integer type, int pageNUmber, int pageSize);
+
+    // 视频详情页
+    JSONObject getMaterialDetailInfo(int mediaId, String md5);
+
+    Map<String,Object> materialDetailAnalyse(int mediaId, String md5);
+
+    List<JSONObject> getMaterialDetailChat(int mediaId, String md5);
+    //查询人群分析数据列表
+    Result populationAnalysisList(String signature);
+    //查询人群分析数据图
+    Result populationAnalysisChart(String signature);
+    /**  最优定向组合
+     * @param
+     * @return
+     */
+    Result optimalCombination(String signature);
+    /**  相似素材
+     * @param
+     * @return
+     */
+    Result similarMaterial(String signature);
+
+    Map<String, Object> getDesignerAvgData(Integer mediaId, String startDate, String endDate, String userId, String leaderId);
+    /**
+     * 标签占比
+     */
+    JSONObject labelRatio(Integer mediaId, String startDate, String endDate, JSONArray projects, String dimension, String leaderId, String designerId, String userId, int type);
+
+    Result getRole(String userId);
+}

+ 914 - 0
jeecg-boot-material-view/src/main/java/org/jeecg/ctop/material/service/impl/MaterialReportOverViewV2ServiceImpl.java

@@ -0,0 +1,914 @@
+package org.jeecg.ctop.material.service.impl;
+
+import cn.com.ctop.common.module.utils.Check;
+import cn.com.ctop.common.module.utils.CtopAdConstant;
+import cn.com.ctop.common.module.utils.ExportExcelUtils;
+import cn.com.ctop.common.module.utils.HttpUtils;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.github.pagehelper.PageHelper;
+import com.github.pagehelper.PageInfo;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.common.constant.AccountReportConstants;
+import org.jeecg.common.util.DateUtils;
+import org.jeecg.common.utils.JsonResourceUtil;
+import org.jeecg.ctop.material.mapper.MaterialReportOverViewV3Mapper;
+import org.jeecg.ctop.material.service.IMaterialReportOverViewV2Service;
+import org.jeecg.modules.system.service.ISysRoleService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.*;
+import java.util.stream.Collectors;
+
+@Slf4j
+@Service
+public class MaterialReportOverViewV2ServiceImpl implements IMaterialReportOverViewV2Service {
+
+    @Autowired
+    private MaterialReportOverViewV3Mapper materialReportOverViewV3Mapper;
+
+    @Autowired
+    private ISysRoleService roleService;
+
+    @Override
+    public Set<String> recursiveQuerySubordinate(String userId) {
+        Set<String> result;
+        //查询当前用户是否存在下级
+        Set<String> subordinate = materialReportOverViewV3Mapper.recursiveQuerySubordinateByLeader(userId);
+        if (subordinate.isEmpty()) {
+            subordinate.add(userId);
+            return subordinate;
+        } else {
+            result = querySubordinate(subordinate, subordinate);
+            result.add(userId);
+        }
+        return result;
+    }
+
+    /**
+     * 查询快手/头条 设计组信息
+     */
+    @Override
+    public List<JSONObject> getDesignTeamList(String userId, int mediaId) {
+
+        List<JSONObject> designTeamList = materialReportOverViewV3Mapper.getDesignTeamList(mediaId);
+        if (designTeamList != null && !designTeamList.isEmpty()) {
+            //判断是否默认选中
+            for (JSONObject jsonObject : designTeamList) {
+                String leaderId = jsonObject.getString("leaderId");
+                if (leaderId != null && leaderId.equals(userId)) {
+                    jsonObject.put("default", true);
+                } else {
+                    jsonObject.put("default", false);
+                }
+            }
+        }
+        return designTeamList;
+    }
+
+    @Override
+    public Set<JSONObject> queryProjectBy(Set<String> userIds, int mediaId) {
+        JSONArray mediaIds = new JSONArray();
+        if (mediaId == CtopAdConstant.PLATFORM_TYPE_BYTEDANCE_INT) {
+            mediaIds.add(1);
+            mediaIds.add(3);
+        } else if (mediaId == CtopAdConstant.PLATFORM_TYPE_KUAISHOU_INT) {
+            mediaIds.add(2);
+            mediaIds.add(4);
+        }
+        return materialReportOverViewV3Mapper.queryProjectBy(userIds, mediaIds);
+    }
+
+    @Override
+    public JSONArray queryProjectIdBy(Set<String> userIds, int mediaId) {
+        JSONArray mediaIds = new JSONArray();
+        if (mediaId == CtopAdConstant.PLATFORM_TYPE_BYTEDANCE_INT) {
+            mediaIds.add(1);
+            mediaIds.add(3);
+        } else if (mediaId == CtopAdConstant.PLATFORM_TYPE_KUAISHOU_INT) {
+            mediaIds.add(2);
+            mediaIds.add(4);
+        }
+        return materialReportOverViewV3Mapper.queryProjectIdBy(userIds, mediaIds);
+    }
+
+    @Override
+    public Map<String, Object> getTotalModule(int mediaId, String startDate, String endDate, JSONArray projects, String dimension, String leaderId, String designerId, String userId) {
+
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
+        String nowData = sdf.format(new Date());
+        startDate = startDate.replace("-", "");
+        endDate = endDate.replace("-", "");
+        Map<String, Object> result = new HashMap<>();
+        if (projects != null && projects.isEmpty()) {
+            projects = getProjectsByCurrentUser(mediaId);
+        }
+        //根据userID查询公司id
+        String companyId = materialReportOverViewV3Mapper.getCompanyId(userId);
+        if (mediaId == CtopAdConstant.PLATFORM_TYPE_BYTEDANCE_INT) {
+            //总消耗
+            BigDecimal cost = materialReportOverViewV3Mapper.queryBytedanceCost(Long.parseLong(startDate), Long.parseLong(endDate), projects, dimension, leaderId, designerId, companyId);
+            //上阶段消耗
+            BigDecimal lastCost = materialReportOverViewV3Mapper.queryBytedanceCost(Long.parseLong(DateUtils.addDayParse(startDate, -DateUtils.dateDiffParse(startDate, endDate) - 1)), Long.parseLong(DateUtils.addDayParse(startDate, -1)), projects, dimension, leaderId, designerId, companyId);
+            result.put("costTotal", cost);
+            //同比 (本阶段截止昨天消耗-上一个阶段截止和昨天对应日期的消耗)/上一个阶段截止和昨天对应日期的消耗 X 100%
+            result.put("yearOnYearCompare", countLink(cost, lastCost));
+            //昨日消耗
+            BigDecimal yesterdayCost = materialReportOverViewV3Mapper.queryBytedanceCost(Long.parseLong(DateUtils.addDayParse(nowData, -1)), Long.parseLong(DateUtils.addDayParse(nowData, -1)), projects, dimension, leaderId, designerId, companyId);
+            //前天消耗
+            BigDecimal beforeYesterdayCost = materialReportOverViewV3Mapper.queryBytedanceCost(Long.parseLong(DateUtils.addDayParse(nowData, -2)), Long.parseLong(DateUtils.addDayParse(nowData, -2)), projects, dimension, leaderId, designerId, companyId);
+            result.put("yesterdayCost", yesterdayCost);
+            //环比 (昨日消耗-前日消耗)/前日消耗 X 100%
+            result.put("chainCompare", countLink(yesterdayCost, beforeYesterdayCost));
+
+        } else if (mediaId == CtopAdConstant.PLATFORM_TYPE_KUAISHOU_INT) {
+            //总消耗
+            BigDecimal cost = materialReportOverViewV3Mapper.queryKuaishouCost(Long.parseLong(startDate), Long.parseLong(endDate), projects, dimension, leaderId, designerId, companyId);
+            //上阶段
+            BigDecimal lastCost = materialReportOverViewV3Mapper.queryKuaishouCost(Long.parseLong(DateUtils.addDayParse(startDate, -DateUtils.dateDiffParse(startDate, endDate) - 1)), Long.parseLong(DateUtils.addDayParse(startDate, -1)), projects, dimension, leaderId, designerId, companyId);
+            result.put("costTotal", cost);
+            //同比 (本阶段截止昨天消耗-上一个阶段截止和昨天对应日期的消耗)/上一个阶段截止和昨天对应日期的消耗 X 100%
+            result.put("yearOnYearCompare", countLink(cost, lastCost));
+            //昨日消耗
+            BigDecimal yesterdayCost = materialReportOverViewV3Mapper.queryKuaishouCost(Long.parseLong(DateUtils.addDayParse(nowData, -1)), Long.parseLong(DateUtils.addDayParse(nowData, -1)), projects, dimension, leaderId, designerId, companyId);
+            //前天消耗
+            BigDecimal beforeYesterdayCost = materialReportOverViewV3Mapper.queryKuaishouCost(Long.parseLong(DateUtils.addDayParse(nowData, -2)), Long.parseLong(DateUtils.addDayParse(nowData, -2)), projects, dimension, leaderId, designerId, companyId);
+            result.put("yesterdayCost", yesterdayCost);
+            //日环比 (昨日消耗-前日消耗)/前日消耗 X 100%
+            result.put("chainCompare", countLink(yesterdayCost, beforeYesterdayCost));
+        }
+        return result;
+    }
+
+
+    @Override
+    public Map<String, Object> sumDataVideoNewEffective(int mediaId, String startDate, String endDate, JSONArray projects, String dimension, String leaderId, String designerId, String userId) {
+        Map<String, Object> result = new HashMap<>();
+        if (projects != null && projects.isEmpty()) {
+            projects = getProjectsByCurrentUser(mediaId);
+        }
+        //根据userID查询公司id
+        String companyId = materialReportOverViewV3Mapper.getCompanyId(userId);
+
+        if (mediaId == CtopAdConstant.PLATFORM_TYPE_BYTEDANCE_INT) {
+            //视频上新
+            List<Map<String, String>> videoList = materialReportOverViewV3Mapper.queryMaterialCountList(startDate + " 00:00:00", endDate + " 23:59:59", projects, dimension, leaderId, designerId, companyId);
+            //总数
+            long videoTotal = videoList.stream().collect(Collectors.summarizingInt(s -> Integer.valueOf(String.valueOf(s.get("count"))))).getSum();
+            result.put("videoList", videoList);
+            result.put("videoTotal", videoTotal);
+            //素材使用率 = 有消耗的素材 / 总数 * 100%
+            long videoCost = materialReportOverViewV3Mapper.queryMaterialCostList(startDate + " 00:00:00", endDate + " 23:59:59", projects, dimension, leaderId, designerId, companyId);
+            result.put("useCompare", Check.isNull(videoCost) ? 0 : new BigDecimal(videoCost).divide(new BigDecimal(videoTotal), 4, RoundingMode.HALF_UP));
+            //有效视频
+            List<Map<String, String>> effectiveList = materialReportOverViewV3Mapper.selectEffectiveMaterialVideoBytedance(Long.parseLong(startDate.replace("-", "")), Long.parseLong(endDate.replace("-", "")), projects, dimension, leaderId, designerId, companyId);
+            //总数
+            long effectiveTotal = effectiveList.stream().collect(Collectors.summarizingInt(s -> Integer.valueOf(String.valueOf(s.get("count"))))).getSum();
+            result.put("effectiveList", effectiveList);
+            result.put("effectiveTotal", effectiveTotal);
+            //素材有效率 = 有效视频数量 / 视频总数 X 100%
+            result.put("effectiveCompare", Check.isNull(videoCost) ? 0 : new BigDecimal(effectiveTotal).divide(new BigDecimal(videoTotal), 4, RoundingMode.HALF_UP));
+
+        } else if (mediaId == CtopAdConstant.PLATFORM_TYPE_KUAISHOU_INT) {
+
+            //视频上新
+            List<Map<String, String>> videoList = materialReportOverViewV3Mapper.queryMaterialCountListKs(startDate + " 00:00:00", endDate + " 23:59:59", projects, dimension, leaderId, designerId, companyId);
+            //总数
+            long videoTotal = videoList.stream().collect(Collectors.summarizingInt(s -> Integer.valueOf(String.valueOf(s.get("count"))))).getSum();
+            result.put("videoList", videoList);
+            result.put("videoTotal", videoTotal);
+            //素材使用率 = 有消耗的素材 / 总数 * 100%
+            long videoCost = materialReportOverViewV3Mapper.queryMaterialCostListKs(startDate + " 00:00:00", endDate + " 23:59:59", projects, dimension, leaderId, designerId, companyId);
+            result.put("useCompare", Check.isNull(videoCost) ? 0 : new BigDecimal(videoCost).divide(new BigDecimal(videoTotal), 4, RoundingMode.HALF_UP));
+            //有效视频
+            List<Map<String, String>> effectiveList = materialReportOverViewV3Mapper.selectEffectiveMaterialVideoKs(Long.parseLong(startDate.replace("-", "")), Long.parseLong(endDate.replace("-", "")), projects, dimension, leaderId, designerId, companyId);
+            //总数
+            long effectiveTotal = effectiveList.stream().collect(Collectors.summarizingInt(s -> Integer.valueOf(String.valueOf(s.get("count"))))).getSum();
+            result.put("effectiveList", effectiveList);
+            result.put("effectiveTotal", effectiveTotal);
+            //素材有效率 = 有效视频数量 / 视频总数 X 100%
+            result.put("effectiveCompare", Check.isNull(videoTotal) ? 0 : new BigDecimal(effectiveTotal).divide(new BigDecimal(videoTotal), 4, RoundingMode.HALF_UP));
+
+        }
+        return result;
+    }
+
+    //爆款视频
+    @Override
+    public Map<String, Object> sumDataVideoHot(int mediaId, String startDate, String endDate, JSONArray projects, String dimension, String leaderId, String designerId, String userId, int type) {
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
+        String nowData = sdf.format(new Date());
+        Map<String, Object> result = new HashMap<>();
+        if (projects != null && projects.isEmpty()) {
+            projects = getProjectsByCurrentUser(mediaId);
+        }
+        //根据userID查询公司id
+        String companyId = materialReportOverViewV3Mapper.getCompanyId(userId);
+        startDate = startDate.replace("-", "");
+        endDate = endDate.replace("-", "");
+        if (mediaId == CtopAdConstant.PLATFORM_TYPE_BYTEDANCE_INT) {
+            //爆款视频
+            List<Map<String, String>> hotList = materialReportOverViewV3Mapper.selectHotMaterialVideoBytedance(Long.parseLong(startDate), Long.parseLong(endDate), projects, dimension, leaderId, designerId, companyId, type);
+            //总数
+            long hotTotal = hotList.stream().collect(Collectors.summarizingInt(s -> Integer.valueOf(String.valueOf(s.get("count"))))).getSum();
+            result.put("hotList", hotList);
+            result.put("hotTotal", hotTotal);
+            //上阶段
+            List<Map<String, String>> lastHostList = materialReportOverViewV3Mapper.selectHotMaterialVideoBytedance(Long.parseLong(DateUtils.addDayParse(startDate, -DateUtils.dateDiffParse(startDate, endDate) - 1)), Long.parseLong(DateUtils.addDayParse(startDate, -1)), projects, dimension, leaderId, designerId, companyId, type);
+            long lastHotTotal = lastHostList.stream().collect(Collectors.summarizingInt(s -> Integer.valueOf(String.valueOf(s.get("count"))))).getSum();
+            //同比 (本阶段截止昨天的爆款视频数量-上一个阶段截止和昨天对应日期的爆款视频数量)/上一个阶段截止和昨天对应日期的爆款视频数量X 100%
+            result.put("hotYearOnYearCompare", countLink(new BigDecimal(hotTotal), new BigDecimal(lastHotTotal)));
+            //昨日消耗
+            List<Map<String, String>> yesterdayHost = materialReportOverViewV3Mapper.selectHotMaterialVideoBytedance(Long.parseLong(DateUtils.addDayParse(nowData, -1)), Long.parseLong(DateUtils.addDayParse(nowData, -1)), projects, dimension, leaderId, designerId, companyId, type);
+            //前天消耗
+            List<Map<String, String>> beforeYesterdayHost = materialReportOverViewV3Mapper.selectHotMaterialVideoBytedance(Long.parseLong(DateUtils.addDayParse(nowData, -2)), Long.parseLong(DateUtils.addDayParse(nowData, -2)), projects, dimension, leaderId, designerId, companyId, type);
+            long yesterday = yesterdayHost.stream().collect(Collectors.summarizingInt(s -> Integer.valueOf(String.valueOf(s.get("count"))))).getSum();
+            long before = beforeYesterdayHost.stream().collect(Collectors.summarizingInt(s -> Integer.valueOf(String.valueOf(s.get("count"))))).getSum();
+            //日环比 (昨日-前日)/前日消耗 X 100%
+            result.put("hostCompare", countLink(new BigDecimal(yesterday), new BigDecimal(before)));
+
+        } else if (mediaId == CtopAdConstant.PLATFORM_TYPE_KUAISHOU_INT) {
+            //爆款视频
+            List<Map<String, String>> hotList = materialReportOverViewV3Mapper.selectHotMaterialVideoKs(Long.parseLong(startDate), Long.parseLong(endDate), projects, dimension, leaderId, designerId, companyId, type);
+            //总数
+            long hotTotal = hotList.stream().collect(Collectors.summarizingInt(s -> Integer.valueOf(String.valueOf(s.get("count"))))).getSum();
+            result.put("hotList", hotList);
+            result.put("hotTotal", hotTotal);
+            //上阶段
+            List<Map<String, String>> lastHostList = materialReportOverViewV3Mapper.selectHotMaterialVideoKs(Long.parseLong(DateUtils.addDayParse(startDate, -DateUtils.dateDiffParse(startDate, endDate) - 1)), Long.parseLong(DateUtils.addDayParse(startDate, -1)), projects, dimension, leaderId, designerId, companyId, type);
+            long lastHotTotal = lastHostList.stream().collect(Collectors.summarizingInt(s -> Integer.valueOf(String.valueOf(s.get("count"))))).getSum();
+            //同比 (本阶段截止昨天的爆款视频数量-上一个阶段截止和昨天对应日期的爆款视频数量)/上一个阶段截止和昨天对应日期的爆款视频数量X 100%
+            result.put("hotYearOnYearCompare", countLink(new BigDecimal(hotTotal), new BigDecimal(lastHotTotal)));
+            //昨日消耗
+            List<Map<String, String>> yesterdayHost = materialReportOverViewV3Mapper.selectHotMaterialVideoKs(Long.parseLong(DateUtils.addDayParse(nowData, -1)), Long.parseLong(DateUtils.addDayParse(nowData, -1)), projects, dimension, leaderId, designerId, companyId, type);
+            //前天消耗
+            List<Map<String, String>> beforeYesterdayHost = materialReportOverViewV3Mapper.selectHotMaterialVideoKs(Long.parseLong(DateUtils.addDayParse(nowData, -2)), Long.parseLong(DateUtils.addDayParse(nowData, -2)), projects, dimension, leaderId, designerId, companyId, type);
+            long yesterday = yesterdayHost.stream().collect(Collectors.summarizingInt(s -> Integer.valueOf(String.valueOf(s.get("count"))))).getSum();
+            long before = beforeYesterdayHost.stream().collect(Collectors.summarizingInt(s -> Integer.valueOf(String.valueOf(s.get("count"))))).getSum();
+            //日环比 (昨日-前日)/前日消耗 X 100%
+            result.put("hostCompare", countLink(new BigDecimal(yesterday), new BigDecimal(before)));
+        }
+        return result;
+    }
+
+
+    @Override
+    public List<JSONObject> getTotalChat(int mediaId, String startDate, String endDate, JSONArray projects, String dimension, String leaderId, String designerId, String userId) {
+        List<JSONObject> result = new ArrayList<>();
+        if (projects != null && projects.isEmpty()) {
+            projects = getProjectsByCurrentUser(mediaId);
+        }
+        //根据userID查询公司id
+        String companyId = materialReportOverViewV3Mapper.getCompanyId(userId);
+        startDate = startDate.replace("-", "");
+        endDate = endDate.replace("-", "");
+        try {
+            if (mediaId == CtopAdConstant.PLATFORM_TYPE_BYTEDANCE_INT) {
+                if (DateUtils.isMoreSixMonthParse(startDate, endDate)) {
+                    result = materialReportOverViewV3Mapper.queryBytedanceChatGroupMonth(Long.parseLong(startDate), Long.parseLong(endDate), projects, dimension, leaderId, designerId, companyId);
+                } else {
+                    result = materialReportOverViewV3Mapper.queryBytedanceChat(Long.parseLong(startDate), Long.parseLong(endDate), projects, dimension, leaderId, designerId, companyId);
+                }
+            } else if (mediaId == CtopAdConstant.PLATFORM_TYPE_KUAISHOU_INT) {
+                if (DateUtils.isMoreSixMonthParse(startDate, endDate)) {
+                    result = materialReportOverViewV3Mapper.queryKuaishouChatGroupMonth(Long.parseLong(startDate), Long.parseLong(endDate), projects, dimension, leaderId, designerId, companyId);
+                } else {
+                    result = materialReportOverViewV3Mapper.queryKuaishouChat(Long.parseLong(startDate), Long.parseLong(endDate), projects, dimension, leaderId, designerId, companyId);
+                }
+            }
+        } catch (ParseException e) {
+            e.printStackTrace();
+        }
+        return result;
+    }
+
+    @Override
+    public JSONObject getTagProportion(int mediaId, String startDate, String endDate, int tagId) {
+        return null;
+    }
+
+    @Override
+    public List<JSONObject> getTopMaterialList(int mediaId, String startDate, String endDate, JSONArray projects, String dimension, String leaderId, String designerId, String userId, Integer channelType) {
+        List<JSONObject> result = new ArrayList<>();
+        //根据userID查询公司id
+        String companyId = materialReportOverViewV3Mapper.getCompanyId(userId);
+        startDate = startDate.replace("-", "");
+        endDate = endDate.replace("-", "");
+        if (projects != null && projects.isEmpty()) {
+            projects = getProjectsByCurrentUser(mediaId);
+        }
+
+        if (mediaId == CtopAdConstant.PLATFORM_TYPE_BYTEDANCE_INT) {
+            result = materialReportOverViewV3Mapper.queryBytedanceTopMaterial(Long.parseLong(startDate), Long.parseLong(endDate), projects, dimension, leaderId, designerId, companyId);
+
+        } else if (mediaId == CtopAdConstant.PLATFORM_TYPE_KUAISHOU_INT) {
+            result = materialReportOverViewV3Mapper.queryKuaishouTopMaterial(Long.parseLong(startDate), Long.parseLong(endDate), projects, dimension, leaderId, designerId, companyId, channelType);
+        }
+        return result;
+    }
+
+    @Override
+    public PageInfo<JSONObject> getTopMaterialList(Integer mediaId, String startDate, String endDate, JSONArray projects, String userId, String md5, String dimension, String leaderId, String designerId, Integer materialQuality, Integer materialType, Integer innovative, String target, String order, Integer pageNo, Integer pageSize) {
+        PageInfo<JSONObject> result = new PageInfo<>();
+        if (projects != null && projects.isEmpty()) {
+            projects = getProjectsByCurrentUser(mediaId);
+        }
+        //根据userID查询公司id
+        String companyId = materialReportOverViewV3Mapper.getCompanyId(userId);
+        startDate = startDate.replace("-", "");
+        endDate = endDate.replace("-", "");
+        if (mediaId == CtopAdConstant.PLATFORM_TYPE_BYTEDANCE_INT) {
+            String filedAll = JsonResourceUtil.joinAllFiled(AccountReportConstants.getDicMapByVideoNew());
+            PageHelper.startPage(pageNo, pageSize);
+            List<JSONObject> list = materialReportOverViewV3Mapper.queryBytedanceMaterialReport(filedAll, Long.parseLong(startDate), Long.parseLong(endDate), projects, md5, dimension, leaderId, designerId, materialQuality, materialType, innovative, target, order, companyId);
+            result = new PageInfo(list);
+        } else if (mediaId == CtopAdConstant.PLATFORM_TYPE_KUAISHOU_INT) {
+            String filedAll = JsonResourceUtil.joinAllFiled(AccountReportConstants.getKuaishouVideoReportMapNew());
+            PageHelper.startPage(pageNo, pageSize);
+            List<JSONObject> list = materialReportOverViewV3Mapper.queryKuaishouMaterialReport(filedAll, Long.parseLong(startDate), Long.parseLong(endDate), projects, md5, dimension, leaderId, designerId, materialQuality, materialType, innovative, target, order, companyId);
+            result = new PageInfo(list);
+        }
+        return result;
+    }
+
+    @Override
+    public void exportBytedanceExcel(JSONObject requestBody, HttpServletRequest request, HttpServletResponse response) {
+        JSONArray projects = requestBody.getJSONArray("projects");
+        if (projects.isEmpty()) {
+            projects = getProjectsByCurrentUser(requestBody.getInteger("mediaId"));
+        }
+        JSONArray columns = requestBody.getJSONArray("columns");
+        if (columns.isEmpty()) {
+            //默认消耗必查
+            columns.add("cost");
+        }
+        String filed = JsonResourceUtil.joinFiled(AccountReportConstants.getDicMapByVideo(), columns);
+        List<String> titles = new ArrayList<>(JsonResourceUtil.joinTitle(AccountReportConstants.getDicMapByVideo(), columns));
+
+        titles.add(0, "唯一标识");
+        titles.add(1, "视频");
+        titles.add(2, "视频名称");
+        titles.add(3, "项目名称");
+        columns.add(0, "signature");
+        columns.add(1, "url");
+        columns.add(2, "materialName");
+        columns.add(3, "projectName");
+        String companyId = materialReportOverViewV3Mapper.getCompanyId(requestBody.getString("userId"));
+        List<JSONObject> excelData = materialReportOverViewV3Mapper.queryBytedanceMaterialReport(filed,
+                Long.parseLong(requestBody.getString("startDate").replace("-", "")),
+                Long.parseLong(requestBody.getString("endDate").replace("-", "")),
+                requestBody.getJSONArray("projects"),
+                requestBody.getString("md5"),
+                requestBody.getString("dimension"),
+                requestBody.getString("leaderId"),
+                requestBody.getString("designerId"),
+                requestBody.getInteger("materialQuality"),
+                requestBody.getInteger("materialType"),
+                requestBody.getInteger("innovative"),
+                requestBody.getString("target") == null ? "cost" : requestBody.getString("target"),
+                requestBody.getString("order") == null ? "desc" : requestBody.getString("order"), companyId);
+
+        if (null != excelData && excelData.isEmpty()) {
+            return;
+        }
+        List<List<Object>> excelList = new ArrayList<>();
+        excelData.forEach(data -> {
+            List<Object> temp = new ArrayList<>();
+            columns.forEach(k -> {
+                temp.add(data.get(k.toString()));
+            });
+            excelList.add(temp);
+        });
+        try {
+            String[] headers = titles.toArray(new String[titles.size()]);
+            OutputStream os = response.getOutputStream();
+            ExportExcelUtils eeu = new ExportExcelUtils();
+            XSSFWorkbook workbook = new XSSFWorkbook();
+            eeu.exportExcel(workbook, 0, "头条视频报表", headers, excelList);
+            HttpUtils.setResponseHeader(response, "头条视频报表.xlsx");
+            workbook.write(os);
+            os.flush();
+            os.close();
+        } catch (IOException e) {
+            log.error(e.getMessage());
+        }
+    }
+
+    @Override
+    public void exportKuaishouExcel(JSONObject requestBody, HttpServletRequest request, HttpServletResponse response) {
+        JSONArray projects = requestBody.getJSONArray("projects");
+        if (projects.isEmpty()) {
+            projects = getProjectsByCurrentUser(requestBody.getInteger("mediaId"));
+        }
+        JSONArray columns2 = new JSONArray();
+        columns2.add(0, "signature");
+        columns2.add(1, "url");
+        columns2.add(2, "projectName");
+        columns2.add(3, "materialName");
+        JSONArray columns = requestBody.getJSONArray("columns");
+        for (int i = 0; i < columns.size(); i++) {
+            columns2.add(columns2.size(), columns.getString(i));
+        }
+        List<String> titles = getfileIds(AccountReportConstants.getKuaishouVideoReportDict(), columns2);
+        String filedAll = JsonResourceUtil.joinAllFiled(AccountReportConstants.getKuaishouVideoReportMap());
+        String companyId = materialReportOverViewV3Mapper.getCompanyId(requestBody.getString("userId"));
+        List<JSONObject> excelData = materialReportOverViewV3Mapper.queryKuaishouMaterialReport(filedAll,
+                Long.parseLong(requestBody.getString("startDate").replace("-", "")),
+                Long.parseLong(requestBody.getString("endDate").replace("-", "")),
+                requestBody.getJSONArray("projects"),
+                requestBody.getString("md5"),
+                requestBody.getString("dimension"),
+                requestBody.getString("leaderId"),
+                requestBody.getString("designerId"),
+                requestBody.getInteger("materialQuality"),
+                requestBody.getInteger("materialType"),
+                requestBody.getInteger("innovative"),
+                requestBody.getString("target") == null ? "cost" : requestBody.getString("target"),
+                requestBody.getString("order") == null ? "desc" : requestBody.getString("order"), companyId);
+        if (null != excelData && excelData.isEmpty()) {
+            return;
+        }
+        List<List<Object>> excelList = new ArrayList<>();
+        for (int i = 0; i < excelData.size(); i++) {
+            List<Object> temp = new ArrayList<>();
+            JSONObject jsonObject = excelData.get(i);
+            for (int j = 0; j < columns2.size(); j++) {
+                String key = columns2.getString(j);
+                String value = jsonObject.getString(key);
+                temp.add(value);
+            }
+            excelList.add(temp);
+        }
+
+        try {
+            String[] strings = titles.toArray(new String[]{});
+            OutputStream os = response.getOutputStream();
+            ExportExcelUtils eeu = new ExportExcelUtils();
+            XSSFWorkbook workbook = new XSSFWorkbook();
+            eeu.exportExcel(workbook, 0, "快手素材报表", strings, excelList);
+            HttpUtils.setResponseHeader(response, "快手素材.xlsx");
+            workbook.write(os);
+            os.flush();
+            os.close();
+        } catch (IOException e) {
+            log.error(e.getMessage());
+        }
+    }
+
+    @Override
+    public PageInfo getTopDesignList(Integer mediaId, String startDate, String endDate, Integer type, int pageNumber, int pageSize) {
+
+        startDate = startDate.replace("-", "");
+        endDate = endDate.replace("-", "");
+        List<JSONObject> result = new ArrayList<>();
+        int total=0;
+        int page=pageNumber;
+        if (mediaId == CtopAdConstant.PLATFORM_TYPE_BYTEDANCE_INT) {
+            total=materialReportOverViewV3Mapper.queryBytedanceTopDesign(Long.parseLong(startDate), Long.parseLong(endDate), type).size();
+            PageHelper.startPage(pageNumber, pageSize,false);
+            result = materialReportOverViewV3Mapper.queryBytedanceTopDesign(Long.parseLong(startDate), Long.parseLong(endDate), type);
+
+        } else if (mediaId == CtopAdConstant.PLATFORM_TYPE_KUAISHOU_INT) {
+            total= materialReportOverViewV3Mapper.queryKuaishouTopDesign(Long.parseLong(startDate), Long.parseLong(endDate), type).size();
+            PageHelper.startPage(pageNumber, pageSize,false);
+            result = materialReportOverViewV3Mapper.queryKuaishouTopDesign(Long.parseLong(startDate), Long.parseLong(endDate), type);
+        }
+        int number=(page-1)*10+1;
+        for (JSONObject jsonObject : result) {
+            jsonObject.put("number",number);
+            number++;
+        }
+        PageInfo info = new PageInfo(result);
+        info.setTotal(total);
+        return info;
+    }
+
+    @Override
+    public JSONObject getMaterialDetailInfo(int mediaId, String md5) {
+        JSONObject result = new JSONObject();
+        if (mediaId == CtopAdConstant.PLATFORM_TYPE_BYTEDANCE_INT) {
+            result = materialReportOverViewV3Mapper.queryBytedanceVideoDetail(md5);
+        } else if (mediaId == CtopAdConstant.PLATFORM_TYPE_KUAISHOU_INT) {
+            result = materialReportOverViewV3Mapper.queryKuaishouVideoDetail(md5);
+
+        }
+        return result;
+    }
+
+    @Override
+    public Map<String, Object> materialDetailAnalyse(int mediaId, String md5) {
+        Map<String, Object> result = new HashMap<>();
+        if (mediaId == CtopAdConstant.PLATFORM_TYPE_BYTEDANCE_INT) {
+            Long projectId = materialReportOverViewV3Mapper.queryBytedanceProjectIdByMd5(md5);
+            result.put("cost", materialReportOverViewV3Mapper.queryBytedanceCostByMd5(md5, projectId));
+            result.put("click", materialReportOverViewV3Mapper.queryBytedanceClickByMd5(md5, projectId));
+            result.put("materialShow", materialReportOverViewV3Mapper.queryBytedanceMaterialShowByMd5(md5, projectId));
+            result.put("play100Rate", materialReportOverViewV3Mapper.queryBytedancePlay100RateByMd5(md5, projectId));
+            result.put("likeMaterial", materialReportOverViewV3Mapper.queryBytedanceLikeMaterialByMd5(md5, projectId));
+            result.put("commentMaterial", materialReportOverViewV3Mapper.queryBytedanceCommentMaterialByMd5(md5, projectId));
+            result.put("shareMaterial", materialReportOverViewV3Mapper.queryBytedanceShareMaterialByMd5(md5, projectId));
+            result.put("follow", materialReportOverViewV3Mapper.queryBytedanceFollowByMd5(md5, projectId));
+        } else if (mediaId == CtopAdConstant.PLATFORM_TYPE_KUAISHOU_INT) {
+            Long projectId = materialReportOverViewV3Mapper.queryKuaishouProjectIdByMd5(md5);
+            result.put("charge", materialReportOverViewV3Mapper.queryKuaishouChargeByMd5(md5, projectId));
+            result.put("photoShow", materialReportOverViewV3Mapper.queryKuaishouPhotoShowByMd5(md5, projectId));
+            result.put("photoClick", materialReportOverViewV3Mapper.queryKuaishouPhotoClickByMd5(md5, projectId));
+            result.put("aclick", materialReportOverViewV3Mapper.queryKuaishouAClickByMd5(md5, projectId));
+            result.put("bclick", materialReportOverViewV3Mapper.queryKuaishouBClickByMd5(md5, projectId));
+            result.put("activation", materialReportOverViewV3Mapper.queryKuaishouActivationByMd5(md5, projectId));
+            result.put("play3sRate", materialReportOverViewV3Mapper.queryKuaishouPlay3sRateByMd5(md5, projectId));
+        }
+        return result;
+    }
+
+    @Override
+    public List<JSONObject> getMaterialDetailChat(int mediaId, String md5) {
+        List<JSONObject> result = new ArrayList<>();
+        List<JSONObject> data = new ArrayList<>();
+        List<String> monthBetween = new ArrayList<>();
+        Map<String, JSONObject> map = new HashMap<>();
+        try {
+            if (mediaId == CtopAdConstant.PLATFORM_TYPE_BYTEDANCE_INT) {
+                result = materialReportOverViewV3Mapper.queryBytedanceVideoChat(md5);
+            } else if (mediaId == CtopAdConstant.PLATFORM_TYPE_KUAISHOU_INT) {
+                result = materialReportOverViewV3Mapper.queryKuaishouVideoChat(md5);
+            }
+            //获取最小日期和最大日期 计算中间无数据日期 填充0
+            if (result != null && result.size() > 0) {
+                JSONObject first = result.get(0);
+                JSONObject last = result.get(result.size() - 1);
+                String startDate = first.get("statDate") == null ? null : (String) first.get("statDate");
+                String endDate = last.get("statDate") == null ? null : (String) last.get("statDate");
+                if (startDate != null && endDate != null) {
+                    monthBetween = getMonthBetween(startDate, endDate);
+                    log.info(":{}", monthBetween.size());
+                }
+                for (JSONObject jsonObject : result) {
+                    String date = jsonObject.get("statDate") == null ? null : (String) jsonObject.get("statDate");
+                    if (date != null) {
+                        map.put(date, jsonObject);
+                    }
+                }
+                for (String date : monthBetween) {
+                    if (map.get(date) != null) {
+                        data.add(map.get(date));
+                    } else {
+                        JSONObject dataMap = new JSONObject();
+                        dataMap.put("statDate", date);
+                        dataMap.put("cost", 0);
+                        dataMap.put("aclick", 0);
+                        dataMap.put("activation", 0);
+                        data.add(dataMap);
+                    }
+                }
+            }
+
+
+        } catch (Exception e) {
+            log.info("查询数据错误:{}", e.toString());
+        }
+        return data;
+    }
+
+    private static List<String> getMonthBetween(String minDate, String maxDate) throws ParseException {
+        ArrayList<String> result = new ArrayList<String>();
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");//格式化为年月
+
+        Calendar min = Calendar.getInstance();
+        Calendar max = Calendar.getInstance();
+
+        min.setTime(sdf.parse(minDate));
+        min.set(min.get(Calendar.YEAR), min.get(Calendar.MONTH), 1);
+
+        max.setTime(sdf.parse(maxDate));
+        max.set(max.get(Calendar.YEAR), max.get(Calendar.MONTH), 2);
+
+        Calendar curr = min;
+        while (curr.before(max)) {
+            result.add(sdf.format(curr.getTime()));
+            curr.add(Calendar.MONTH, 1);
+        }
+
+        return result;
+    }
+
+    /**
+     * 查询人群分析数据列表
+     *
+     * @param
+     * @return
+     */
+    @Override
+    public Result populationAnalysisList(String signature) {
+        Result result = new Result<>();
+        Map resultMap = new HashMap();
+        try {
+            List<Map> list = materialReportOverViewV3Mapper.populationAnalysisList(signature);
+            //查询点击率
+            String actionRatio = materialReportOverViewV3Mapper.getActualProb(signature, "action_ratio");
+            //查询转化率
+            String convertRatio = materialReportOverViewV3Mapper.getActualProb(signature, "convert_ratio");
+            resultMap.put("dataList", list);
+            resultMap.put("actionRatio", actionRatio);
+            resultMap.put("convertRatio", convertRatio);
+            result.setSuccess(true);
+            result.setResult(resultMap);
+        } catch (Exception e) {
+            log.info("查询错误:{}", e.toString());
+            result.error500("查询错误");
+        }
+        return result;
+    }
+
+    /**
+     * 查询人群分析数据图
+     *
+     * @param
+     * @return
+     */
+    @Override
+    public Result populationAnalysisChart(String signature) {
+        Result result = new Result<>();
+        try {
+            List<Map> list = materialReportOverViewV3Mapper.populationAnalysisChart(signature);
+            result.setResult(list);
+        } catch (Exception e) {
+            log.info("查询错误:{}", e.toString());
+            result.error500("查询错误");
+        }
+        return result;
+    }
+
+    /**
+     * 最优定向组合
+     *
+     * @param
+     * @return
+     */
+    @Override
+    public Result optimalCombination(String signature) {
+        Result result = new Result<>();
+        Map<String, String> map = new HashMap();
+        try {
+            //最优转化率组合
+            Map<String, String> convertRatio = materialReportOverViewV3Mapper.optimalCombination(signature, "convert_ratio");
+            //最优点击率组合
+            Map<String, String> actionRatio = materialReportOverViewV3Mapper.optimalCombination(signature, "action_ratio");
+            if (convertRatio != null) {
+                map.put("convertRatio", convertRatio.get("gender") + "/" + convertRatio.get("age"));
+            } else {
+                map.put("convertRatio", null);
+            }
+            if (actionRatio != null) {
+                map.put("actionRatio", actionRatio.get("gender") + "/" + actionRatio.get("age"));
+            } else {
+                map.put("actionRatio", null);
+            }
+
+            result.setResult(map);
+        } catch (Exception e) {
+            log.info("查询错误:{}", e.toString());
+            result.error500("查询错误");
+        }
+        return result;
+    }
+
+    /**
+     * 相似素材
+     *
+     * @param
+     * @return
+     */
+    @Override
+    public Result similarMaterial(String signature) {
+        Result result = new Result<>();
+        List<Map> resultMap = new ArrayList<>();
+        Map<String, String> map = materialReportOverViewV3Mapper.getSimilarMaterialList(signature);
+        if (map != null) {
+            String signature1 = map.get("s1");
+            String signature2 = map.get("s2");
+            String signature3 = map.get("s3");
+            String signature4 = map.get("s4");
+            String signature5 = map.get("s5");
+            if (signature1 != null && !signature1.equals("")) {
+                Map info = materialReportOverViewV3Mapper.similarMaterialInfo(signature1);
+                if (info.get("signature") != null && !info.get("signature").equals("")) {
+                    resultMap.add(info);
+                }
+            }
+            if (signature2 != null && !signature2.equals("")) {
+                Map info = materialReportOverViewV3Mapper.similarMaterialInfo(signature2);
+                if (info.get("signature") != null && !info.get("signature").equals("")) {
+                    resultMap.add(info);
+                }
+            }
+            if (signature3 != null && !signature3.equals("")) {
+                Map info = materialReportOverViewV3Mapper.similarMaterialInfo(signature3);
+                if (info.get("signature") != null && !info.get("signature").equals("")) {
+                    resultMap.add(info);
+                }
+            }
+            if (signature4 != null && !signature4.equals("")) {
+                Map info = materialReportOverViewV3Mapper.similarMaterialInfo(signature4);
+                if (info.get("signature") != null && !info.get("signature").equals("")) {
+                    resultMap.add(info);
+                }
+            }
+            if (signature5 != null && !signature5.equals("")) {
+                Map info = materialReportOverViewV3Mapper.similarMaterialInfo(signature5);
+                if (info.get("signature") != null && !info.get("signature").equals("")) {
+                    resultMap.add(info);
+                }
+            }
+        }
+        result.setResult(resultMap);
+        return result;
+    }
+
+    /**
+     * 设计组维度:组内人均消耗等指标
+     * mediaId 类型 1-头条 2-快手
+     */
+    @Override
+    public Map<String, Object> getDesignerAvgData(Integer mediaId, String startDate, String endDate, String userId, String leaderId) {
+        //根据userID查询公司id
+        String companyId = materialReportOverViewV3Mapper.getCompanyId(userId);
+        Map<String, Object> result = new HashMap<>();
+        if (mediaId == CtopAdConstant.PLATFORM_TYPE_BYTEDANCE_INT) {
+            //头条
+            //组内人均消耗
+            BigDecimal sumCost = materialReportOverViewV3Mapper.getBytedanceDesignTeamAvgCost(Long.parseLong(startDate.replace("-", "")), Long.parseLong(endDate.replace("-", "")), leaderId, companyId);
+            //组人效
+            BigDecimal groupWork = materialReportOverViewV3Mapper.getBytedanceDesignTeamGroupWork(startDate, endDate, leaderId);
+            //创新视频数
+            int innovativeVideoCount = materialReportOverViewV3Mapper.getBytedanceDesignTeaminnovativeVideoCount(Long.parseLong(startDate.replace("-", "")), Long.parseLong(endDate.replace("-", "")), leaderId);
+            //素材平均消耗
+            BigDecimal avgCost = materialReportOverViewV3Mapper.getBytedanceMaterialCost(Long.parseLong(startDate.replace("-", "")), Long.parseLong(endDate.replace("-", "")), leaderId, companyId);
+
+            result.put("avgCost", sumCost);
+            result.put("peopleWork", groupWork);
+            result.put("innovativeVideoCount", innovativeVideoCount);
+            result.put("avgMaterialCost", avgCost);
+        } else if (mediaId == CtopAdConstant.PLATFORM_TYPE_KUAISHOU_INT) {
+            //快手
+            //组内人均消耗
+            BigDecimal sumCost = materialReportOverViewV3Mapper.getKuaishouDesignTeamAvgCost(Long.parseLong(startDate.replace("-", "")), Long.parseLong(endDate.replace("-", "")), leaderId, companyId);
+            //组人效
+            BigDecimal groupWork = materialReportOverViewV3Mapper.getKuaishouDesignTeamGroupWork(startDate, endDate, leaderId);
+            //创新视频数
+            int innovativeVideoCount = materialReportOverViewV3Mapper.getKuaishouDesignTeaminnovativeVideoCount(Long.parseLong(startDate.replace("-", "")), Long.parseLong(endDate.replace("-", "")), leaderId);
+            //创新视频消耗
+            BigDecimal innovativeVideoCost = materialReportOverViewV3Mapper.getKuaishouDesignTeaminnovativeVideoCost(Long.parseLong(startDate.replace("-", "")), Long.parseLong(endDate.replace("-", "")), leaderId, companyId);
+            result.put("avgCost", sumCost);
+            result.put("peopleWork", groupWork);
+            result.put("innovativeVideoCount", innovativeVideoCount);
+            result.put("innovativeVideoCost", innovativeVideoCost);
+        }
+        return result;
+    }
+
+    /**
+     * 标签占比
+     */
+    @Override
+    public JSONObject labelRatio(Integer mediaId, String startDate, String endDate, JSONArray projects, String dimension, String leaderId, String designerId, String userId, int type) {
+        //根据userID查询公司id
+        String companyId = materialReportOverViewV3Mapper.getCompanyId(userId);
+        Map<String, Object> result = new HashMap<>();
+        JSONObject object = new JSONObject();
+        if (projects != null && projects.isEmpty()) {
+            projects = getProjectsByCurrentUser(mediaId);
+        }
+        if (mediaId == CtopAdConstant.PLATFORM_TYPE_BYTEDANCE_INT) {
+            //头条
+            if (type == 0) {
+                //素材数
+                //获取真人 制作 其他 数量
+                object = materialReportOverViewV3Mapper.getBytedanceMaterialCountByLable(startDate, endDate, projects, dimension, leaderId, designerId, companyId);
+
+            } else if (type == 1) {
+                //消耗
+                //获取真人 制作 其他 数量
+                object = materialReportOverViewV3Mapper.getBytedanceMaterialCountByCost(startDate, endDate, projects, dimension, leaderId, designerId, companyId);
+            }
+
+        } else if (mediaId == CtopAdConstant.PLATFORM_TYPE_KUAISHOU_INT) {
+            //快手
+            if (type == 0) {
+                //素材数
+                //获取真人 制作 其他 数量
+                object = materialReportOverViewV3Mapper.getKuaishouMaterialCountByLable(startDate, endDate, projects, dimension, leaderId, designerId, companyId);
+            } else if (type == 1) {
+                //消耗
+                //获取真人 制作 其他 数量
+                object = materialReportOverViewV3Mapper.getKuaishouMaterialCountByCost(startDate, endDate, projects, dimension, leaderId, designerId, companyId);
+            }
+        }
+
+        return object;
+    }
+
+    /**
+     * 判断是否有设计组权限
+     *
+     * @param
+     * @return
+     */
+    @Override
+    public Result getRole(String userId) {
+        Map map = new HashMap();
+        Result result = new Result<>();
+        String roleCode = roleService.getRoleCodeByUserId(userId);
+        map.put("role", roleCode);
+        if ("admin".equals(roleCode) || "designTeamLeader".equals(roleCode)) {
+            map.put("permissions", true);
+        } else {
+            map.put("permissions", false);
+        }
+        result.setResult(map);
+        return result;
+    }
+
+
+    //递归查询
+    private Set<String> querySubordinate(Set<String> leaderIds, Set<String> result) {
+        if (leaderIds.isEmpty()) {
+            return result;
+        }
+        Set<String> temp = materialReportOverViewV3Mapper.recursiveQuerySubordinateByLeaders(leaderIds);
+        result.addAll(temp);
+        querySubordinate(temp, result);
+        return result;
+    }
+
+    //当项目为空的时候,根据当前登录人查询可查看的所有项目集合
+    private JSONArray getProjectsByCurrentUser(int mediaId) {
+        //String currentUser = ((LoginUser) SecurityUtils.getSubject().getPrincipal()).getId();
+        String currentUser = "e9ca23d68d884d4ebb19d07889727dae";
+        //TODO 为了解决管理员等角色初始化查全部项目查询效率慢的问题判断角色,待优化
+        String roleCode = roleService.getRoleCodeByUserId(currentUser);
+        if ("admin".equals(roleCode)) {
+            return null;
+        }
+        return Check.isNull(queryProjectIdBy(recursiveQuerySubordinate(currentUser), mediaId)) ? null : queryProjectIdBy(recursiveQuerySubordinate(currentUser), mediaId);
+    }
+
+    private List<String> getfileIds(Map<String, Map<String, Object>> kuaishouVideoReportMap, JSONArray columns) {
+        List<String> titles = new ArrayList<>();
+        for (int i = 0; i < columns.size(); i++) {
+            String string = columns.getString(i);
+            Map<String, Object> stringObjectMap = kuaishouVideoReportMap.get(string);
+            if (Check.isNull(stringObjectMap)) {
+                titles.add("-");
+                continue;
+            }
+            Object comment = stringObjectMap.get("comment");
+            titles.add(String.valueOf(comment));
+
+        }
+        return titles;
+    }
+
+    //环比计算
+    private BigDecimal countLink(BigDecimal numA, BigDecimal numB) {
+        BigDecimal link = new BigDecimal("0");
+        if (Check.isNull(numA) || Check.isNull(numB)) {
+            return link;
+        }
+        if (numB.compareTo(BigDecimal.ZERO) != 0) {
+            link = (numA.subtract(numB)).divide(numB, 4, RoundingMode.HALF_UP);
+        }
+        return link;
+    }
+
+
+    /**
+     * 同比 (当前 - 上阶段 ) / 上阶段
+     *
+     * @param current 当前阶段数值
+     * @param last    上阶段数值
+     * @return
+     */
+    private BigDecimal yearOnYearCompare(BigDecimal current, BigDecimal last) {
+        BigDecimal yearOnYear = new BigDecimal("0");
+        if (last.compareTo(BigDecimal.ZERO) != 0) {
+            // (当前 - 上阶段 ) / 上阶段
+            yearOnYear = (current.subtract(last)).divide(last, 20, BigDecimal.ROUND_HALF_UP);
+        }
+        return yearOnYear;
+    }
+
+
+}

+ 156 - 0
jeecg-boot-material-view/src/main/resources/application-dev.yml

@@ -0,0 +1,156 @@
+server:
+  tomcat:
+    max-swallow-size: -1
+  error:
+    include-exception: true
+    include-stacktrace: ALWAYS
+    include-message: ALWAYS
+
+  compression:
+    enabled: true
+    min-response-size: 1024
+    mime-types: application/javascript,application/json,application/xml,text/html,text/xml,text/plain,text/css,image/*
+management:
+ endpoints:
+  web:
+   exposure:
+    include: metrics,httptrace
+spring:
+  cloud:
+    nacos:
+      discovery:
+        server-addr: 127.0.0.1:8848
+        service: jeecg-cloud-material
+  servlet:
+     multipart:
+        max-file-size: 10MB
+        max-request-size: 10MB
+  mail:
+    host: smtp.163.com
+    username: jeecgos@163.com
+    password: ??
+    properties:
+      mail:
+        smtp:
+          auth: true
+          starttls:
+            enable: true
+            required: true
+  #json 时间戳统一转换
+  jackson:
+    date-format:   yyyy-MM-dd HH:mm:ss
+    time-zone:   GMT+8
+  jpa:
+    open-in-view: false
+  activiti:
+    check-process-definitions: false
+    #启用作业执行器
+    async-executor-activate: false
+    #启用异步执行器
+    job-executor-activate: false
+  aop:
+    proxy-target-class: true
+  #配置freemarker
+  freemarker:
+    # 设置模板后缀名
+    suffix: .ftl
+    # 设置文档类型
+    content-type: text/html
+    # 设置页面编码格式
+    charset: UTF-8
+    # 设置页面缓存
+    cache: false
+    prefer-file-system-access: false
+    # 设置ftl文件路径
+    template-loader-path:
+      - classpath:/templates
+  # 设置静态文件路径,js,css等
+  mvc:
+    static-path-pattern: /**
+  resource:
+    static-locations: classpath:/static/,classpath:/public/
+  autoconfigure:
+    exclude: com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure
+  datasource:
+    druid:
+      stat-view-servlet:
+        enabled: true
+        loginUsername: admin
+        loginPassword: 123456
+        allow:
+      web-stat-filter:
+        enabled: true
+    dynamic:
+      druid: # 全局druid参数,绝大部分值和默认保持一致。(现已支持的参数如下,不清楚含义不要乱设置)
+        # 连接池的配置信息
+        # 初始化大小,最小,最大
+        initial-size: 5
+        min-idle: 5
+        maxActive: 20
+        # 配置获取连接等待超时的时间
+        maxWait: 60000
+        # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
+        timeBetweenEvictionRunsMillis: 60000
+        # 配置一个连接在池中最小生存的时间,单位是毫秒
+        minEvictableIdleTimeMillis: 300000
+        validationQuery: SELECT 1 FROM DUAL
+        testWhileIdle: true
+        testOnBorrow: false
+        testOnReturn: false
+        # 打开PSCache,并且指定每个连接上PSCache的大小
+        poolPreparedStatements: true
+        maxPoolPreparedStatementPerConnectionSize: 20
+        # 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
+        filters: stat,wall,slf4j
+        # 通过connectProperties属性来打开mergeSql功能;慢SQL记录
+        connectionProperties: druid.stat.mergeSql\=true;druid.stat.slowSqlMillis\=5000
+      datasource:
+        master:
+          url: jdbc:mysql://192.168.0.184:3390/jeecg-boot?characterEncoding=UTF-8&useUnicode=true&allowMultiQueries=true&serverTimezone=GMT%2B8
+          username: hcst
+          password: hcst@2021
+          driver-class-name: com.mysql.jdbc.Driver
+          # 多数据源配置
+          #multi-datasource1:
+          #url: jdbc:mysql://localhost:3306/jeecg-boot2?useUnicode=true&characterEncoding=utf8&autoReconnect=true&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai
+          #username: root
+          #password: root
+          #driver-class-name: com.mysql.cj.jdbc.Driver
+  #redis 配置
+  redis:
+    database: 0
+    host: 127.0.0.1
+    lettuce:
+      pool:
+        max-active: 8   #最大连接数据库连接数,设 0 为没有限制
+        max-idle: 8     #最大等待连接中的数量,设 0 为没有限制
+        max-wait: -1ms  #最大建立连接等待时间。如果超过此时间将接到异常。设为-1表示无限制。
+        min-idle: 0     #最小等待连接中的数量,设 0 为没有限制
+      shutdown-timeout: 100ms
+    password: ''
+    port: 6379
+#mybatis plus 设置
+mybatis-plus:
+  mapper-locations: classpath*:org/jeecg/modules/**/xml/*Mapper.xml,classpath*:org/jeecg/**/xml/*Mapper.xml,classpath*:cn/com/ctop/**/xml/*Mapper.xml
+  global-config:
+    # 关闭MP3.0自带的banner
+    banner: false
+    db-config:
+      #主键类型  0:"数据库ID自增",1:"该类型为未设置主键类型", 2:"用户输入ID",3:"全局唯一ID (数字类型唯一ID)", 4:"全局唯一ID UUID",5:"字符串全局唯一ID (idWorker 的字符串表示)";
+      id-type: ASSIGN_ID
+      # 默认数据库表下划线命名
+      table-underline: true
+  configuration:
+    # 这个配置会将执行的sql打印出来,在开发或测试的时候可以用
+    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
+    # 返回类型为Map,显示null对应的字段
+    call-setters-on-nulls: true
+#jeecg专用配置
+jeecg :
+  elasticsearch:
+    cluster-name: jeecg-ES
+    cluster-nodes: 127.0.0.1:9200
+    check-enabled: false
+
+
+

+ 294 - 0
jeecg-boot-material-view/src/main/resources/application-prod.yml

@@ -0,0 +1,294 @@
+server:
+  tomcat:
+    max-swallow-size: -1
+  error:
+    include-exception: true
+    include-stacktrace: ALWAYS
+    include-message: ALWAYS
+
+  compression:
+    enabled: true
+    min-response-size: 1024
+    mime-types: application/javascript,application/json,application/xml,text/html,text/xml,text/plain,text/css,image/*
+management:
+ endpoints:
+  web:
+   exposure:
+    include: metrics,httptrace
+spring:
+  cloud:
+    nacos:
+      discovery:
+        server-addr: 172.30.0.7:8848
+        service: jeecg-cloud-material
+  servlet:
+     multipart:
+        max-file-size: 10MB
+        max-request-size: 10MB
+  mail:
+    host: smtp.163.com
+    username: jeecgos@163.com
+    password: ??
+    properties:
+      mail:
+        smtp:
+          auth: true
+          starttls:
+            enable: true
+            required: true
+  #json 时间戳统一转换
+  jackson:
+    date-format:   yyyy-MM-dd HH:mm:ss
+    time-zone:   GMT+8
+  jpa:
+    open-in-view: false
+  activiti:
+    check-process-definitions: false
+    #启用作业执行器
+    async-executor-activate: false
+    #启用异步执行器
+    job-executor-activate: false
+  aop:
+    proxy-target-class: true
+  #配置freemarker
+  freemarker:
+    # 设置模板后缀名
+    suffix: .ftl
+    # 设置文档类型
+    content-type: text/html
+    # 设置页面编码格式
+    charset: UTF-8
+    # 设置页面缓存
+    cache: false
+    prefer-file-system-access: false
+    # 设置ftl文件路径
+    template-loader-path:
+      - classpath:/templates
+  # 设置静态文件路径,js,css等
+  mvc:
+    static-path-pattern: /**
+  resource:
+    static-locations: classpath:/static/,classpath:/public/
+  autoconfigure:
+    exclude: com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure
+  datasource:
+    druid:
+      stat-view-servlet:
+        enabled: true
+        loginUsername: admin
+        loginPassword: 123456
+        allow:
+      web-stat-filter:
+        enabled: true
+    dynamic:
+      druid: # 全局druid参数,绝大部分值和默认保持一致。(现已支持的参数如下,不清楚含义不要乱设置)
+        # 连接池的配置信息
+        # 初始化大小,最小,最大
+        initial-size: 5
+        min-idle: 5
+        maxActive: 20
+        # 配置获取连接等待超时的时间
+        maxWait: 60000
+        # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
+        timeBetweenEvictionRunsMillis: 60000
+        # 配置一个连接在池中最小生存的时间,单位是毫秒
+        minEvictableIdleTimeMillis: 300000
+        validationQuery: SELECT 1 FROM DUAL
+        testWhileIdle: true
+        testOnBorrow: false
+        testOnReturn: false
+        # 打开PSCache,并且指定每个连接上PSCache的大小
+        poolPreparedStatements: true
+        maxPoolPreparedStatementPerConnectionSize: 20
+        # 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
+        filters: stat,wall,slf4j
+        # 通过connectProperties属性来打开mergeSql功能;慢SQL记录
+        connectionProperties: druid.stat.mergeSql\=true;druid.stat.slowSqlMillis\=5000
+      datasource:
+        master:
+          url: jdbc:mysql://111.206.86.186:3390/jeecg-boot?characterEncoding=UTF-8&useUnicode=true&characterEncoding=utf8&autoReconnect=true&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai
+          username: data
+          password: hcst@2021
+          driver-class-name: com.mysql.jdbc.Driver
+  #redis 配置
+  redis:
+    database: 0
+    host: 172.30.0.17
+    lettuce:
+      pool:
+        max-active: 8   #最大连接数据库连接数,设 0 为没有限制
+        max-idle: 8     #最大等待连接中的数量,设 0 为没有限制
+        max-wait: -1ms  #最大建立连接等待时间。如果超过此时间将接到异常。设为-1表示无限制。
+        min-idle: 0     #最小等待连接中的数量,设 0 为没有限制
+      shutdown-timeout: 100ms
+    password: hcst@2021..
+    port: 6379
+#mybatis plus 设置
+mybatis-plus:
+  mapper-locations: classpath*:org/jeecg/**/xml/*Mapper.xml,classpath*:cn/com/ctop/**/xml/*Mapper.xml
+  global-config:
+    # 关闭MP3.0自带的banner
+    banner: false
+    db-config:
+      #主键类型  0:"数据库ID自增",1:"该类型为未设置主键类型", 2:"用户输入ID",3:"全局唯一ID (数字类型唯一ID)", 4:"全局唯一ID UUID",5:"字符串全局唯一ID (idWorker 的字符串表示)";
+      id-type: ASSIGN_ID
+      # 默认数据库表下划线命名
+      table-underline: true
+  configuration:
+    # 这个配置会将执行的sql打印出来,在开发或测试的时候可以用
+    #log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
+    # 返回类型为Map,显示null对应的字段
+    call-setters-on-nulls: true
+#minidao 设置
+minidao :
+  base-package: org.jeecg.modules.jmreport.*
+  db-type: mysql
+#jeecg专用配置
+jeecg :
+  # 本地:local\Minio:minio\阿里云:alioss
+  uploadType: local
+  path :
+    #文件上传根目录 设置
+    upload: D://opt//upFiles
+    #webapp文件路径
+    webapp: D://opt//webapp
+  shiro:
+    excludeUrls: /test/jeecgDemo/demo3,/test/jeecgDemo/redisDemo/**,/category/**,/visual/**,/map/**,/jmreport/bigscreen2/**
+  #阿里云oss存储配置
+  oss:
+    endpoint: oss-cn-beijing.aliyuncs.com
+    accessKey: ??
+    secretKey: ??
+    bucketName: jeecgos
+    staticDomain: ??
+  # ElasticSearch 6设置
+  elasticsearch:
+    cluster-name: jeecg-ES
+    cluster-nodes: 127.0.0.1:9200
+    check-enabled: false
+  # 表单设计器配置
+  desform:
+    # 主题颜色(仅支持 16进制颜色代码)
+    theme-color: "#1890ff"
+    # 文件、图片上传方式,可选项:qiniu(七牛云)、system(跟随系统配置)
+    upload-type: system
+  # 在线预览文件服务器地址配置
+  file-view-domain: 127.0.0.1:8012
+  # minio文件上传
+  minio:
+    minio_url: http://minio.jeecg.com
+    minio_name: ??
+    minio_pass: ??
+    bucketName: otatest
+  #大屏报表参数设置
+  jmreport:
+    mode: dev
+    #数据字典是否进行saas数据隔离,自己看自己的字典
+    saas: false
+    #是否需要校验token
+    is_verify_token: false
+    #必须校验方法
+    verify_methods: remove,delete,save,add,update
+  #Wps在线文档
+  wps:
+    domain: https://wwo.wps.cn/office/
+    appid: ??
+    appsecret: ??
+  #xxl-job配置
+  xxljob:
+    enabled: false
+    adminAddresses: http://127.0.0.1:9080/xxl-job-admin
+    appname: ${spring.application.name}
+    accessToken: ''
+    address: 127.0.0.1:30007
+    ip: 127.0.0.1
+    port: 30007
+    logPath: logs/jeecg/job/jobhandler/
+    logRetentionDays: 30
+   #自定义路由配置 yml nacos database
+  route:
+    config:
+      data-id: jeecg-gateway-router
+      group: DEFAULT_GROUP
+      data-type: yml
+  #分布式锁配置
+  redisson:
+    address: 127.0.0.1:6379
+    password:
+    type: STANDALONE
+    enabled: true
+#cas单点登录
+cas:
+  prefixUrl: http://cas.example.org:8443/cas
+#Mybatis输出sql日志
+logging:
+  level:
+    org.jeecg.modules.system.mapper : info
+#swagger
+knife4j:
+  production: false
+  basic:
+    enable: false
+    username: jeecg
+    password: jeecg1314
+#第三方登录
+justauth:
+  enabled: true
+  type:
+    GITHUB:
+      client-id: ??
+      client-secret: ??
+      redirect-uri: http://sso.test.com:8080/jeecg-boot/sys/thirdLogin/github/callback
+    WECHAT_ENTERPRISE:
+      client-id: ??
+      client-secret: ??
+      redirect-uri: http://sso.test.com:8080/jeecg-boot/sys/thirdLogin/wechat_enterprise/callback
+      agent-id: 1000002
+    DINGTALK:
+      client-id: ??
+      client-secret: ??
+      redirect-uri: http://sso.test.com:8080/jeecg-boot/sys/thirdLogin/dingtalk/callback
+    WECHAT_OPEN:
+      client-id: ??
+      client-secret: ??
+      redirect-uri: http://sso.test.com:8080/jeecg-boot/sys/thirdLogin/wechat_open/callback
+  cache:
+    type: default
+    prefix: 'demo::'
+    timeout: 1h
+
+bytedance:
+  appId: 1635316529903624
+  secret: 0c51523e90d6166418fc8421a4896808e90e26f4
+  url:
+    auth-prefix: https://ad.oceanengine.com/openapi
+    api-prefix: https://ad.oceanengine.com/open_api
+    callback-url: http://adsp.c-top.com.cn:8080/jeecg-boot/bytedance
+    refresh-token: /oauth2/refresh_token
+    advertiser-info: /2/advertiser/public_info/
+    ad-get: /2/ad/get/
+    ad-create: /2/ad/create/
+    ad-update: /2/ad/update/
+    ad-update-status: /2/ad/update/status/
+    ad-update-bid: /2/ad/update/bid/
+    ad-update-budget: /2/ad/update/budget/
+    ad-update-reject-reason: 2/ad/reject_reason/
+    campaign-get: /2/campaign/get/
+    campaign-create: /2/campaign/create/
+    campaign-update-status: /2/campaign/update/status/
+    campaign-update: /2/campaign/update/
+    dmp-custom-audience-select: /2/dmp/custom_audience/select/
+    file-video-ad: /2/file/video/ad/
+    file-image-ad: /2/file/image/ad/
+    creative-update-status: /2/creative/update/status/
+    creative-material-get: /2/creative/material/read/
+    creative-create-v2: /2/creative/create_v2/
+    creative-get: /2/creative/get/
+    creative-read: /2/creative/read_v2/
+    creative-update: /2/creative/update_v2/
+    creative-reject-reason: /2/creative/reject_reason/
+    advertiser-report-get: /2/report/advertiser/get/
+    campaign-report-get: /2/report/campaign/get/
+    ad-report-get: /2/report/ad/get/
+    ad-creative-get: /2/report/creative/get/
+    advertiser-fund-daily-stat: /2/advertiser/fund/daily_stat/

+ 253 - 0
jeecg-boot-material-view/src/main/resources/application-test.yml

@@ -0,0 +1,253 @@
+
+#swagger
+knife4j:
+  production: false
+  basic:
+    enable: false
+    username: jeecg
+    password: jeecg1314
+management:
+  endpoints:
+    web:
+      exposure:
+        include: metrics,httptrace
+spring:
+  cloud:
+    nacos:
+      discovery:
+        server-addr: 139.186.134.115:8848
+        service: jeecg-cloud-material
+  servlet:
+    multipart:
+      max-file-size: -1
+      max-request-size: -1
+  mail:
+    host: smtp.163.com
+    username: jeecgos@163.com
+    password: ??
+    properties:
+      mail:
+        smtp:
+          auth: true
+          starttls:
+            enable: true
+            required: true
+  ## quartz定时任务,采用数据库方式
+  #json 时间戳统一转换
+  jackson:
+    date-format:   yyyy-MM-dd HH:mm:ss
+    time-zone:   GMT+8
+  aop:
+    proxy-target-class: true
+  #配置freemarker
+  freemarker:
+    # 设置模板后缀名
+    suffix: .ftl
+    # 设置文档类型
+    content-type: text/html
+    # 设置页面编码格式
+    charset: UTF-8
+    # 设置页面缓存
+    cache: false
+    prefer-file-system-access: false
+    # 设置ftl文件路径
+    template-loader-path:
+      - classpath:/templates
+  # 设置静态文件路径,js,css等
+  mvc:
+    static-path-pattern: /**
+  resource:
+    static-locations: classpath:/static/,classpath:/public/
+  autoconfigure:
+    exclude: com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure
+  datasource:
+    url: jdbc:mysql://192.168.0.184:3390/jeecg-boot?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=GMT%2B8
+    username: hcst
+    password: hcst@2020
+    driver-class-name: com.mysql.jdbc.Driver
+    druid:
+      stat-view-servlet:
+        loginUsername: admin
+        loginPassword: hcst2016
+        enabled: true
+      web-stat-filter:
+        enabled: true
+    #      remove-abandoned: false
+    dynamic:
+      druid:
+        # 全局druid参数,绝大部分值和默认保持一致。(现已支持的参数如下,不清楚含义不要乱设置)
+        # 连接池的配置信息
+        # 初始化大小,最小,最大
+        connection-init-sql: set names utf8mb4
+        initial-size: 5
+        min-idle: 5
+        maxActive: 20
+        # 配置获取连接等待超时的时间
+        maxWait: 60000
+        # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
+        timeBetweenEvictionRunsMillis: 60000
+        # 配置一个连接在池中最小生存的时间,单位是毫秒
+        minEvictableIdleTimeMillis: 300000
+        validationQuery: SELECT 1 FROM DUAL
+        testWhileIdle: true
+        testOnBorrow: false
+        testOnReturn: false
+        # 打开PSCache,并且指定每个连接上PSCache的大小
+        poolPreparedStatements: true
+        maxPoolPreparedStatementPerConnectionSize: 20
+        # 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
+        filters: stat,slf4j
+        # 通过connectProperties属性来打开mergeSql功能;慢SQL记录
+        connectionProperties: druid.stat.mergeSql\=true;druid.stat.slowSqlMillis\=5000
+      datasource:
+        master:
+          url: jdbc:mysql://139.186.165.84:3306/jeecg-boot?characterEncoding=UTF-8&useUnicode=true&useSSL=false
+          username: hcst
+          password: hcst@2020
+          driver-class-name: com.mysql.jdbc.Driver
+  #redis 配置
+  redis:
+    database: 0
+    #    host: 172.30.0.17
+    host: 127.0.0.1
+    password:
+    port: 6379
+    lettuce:
+      pool:
+        max-active: 8   #最大连接数据库连接数,设 0 为没有限制
+        max-idle: 8     #最大等待连接中的数量,设 0 为没有限制
+        max-wait: -1ms  #最大建立连接等待时间。如果超过此时间将接到异常。设为-1表示无限制。
+        min-idle: 0     #最小等待连接中的数量,设 0 为没有限制
+      shutdown-timeout: 100ms
+#mybatis plus 设置
+mybatis-plus:
+  mapper-locations: classpath*:org/jeecg/**/xml/*Mapper.xml,classpath*:cn/com/ctop/**/xml/*Mapper.xml
+  global-config:
+    # 关闭MP3.0自带的banner
+    banner: false
+    db-config:
+      #主键类型  0:"数据库ID自增",1:"该类型为未设置主键类型", 2:"用户输入ID",3:"全局唯一ID (数字类型唯一ID)", 4:"全局唯一ID UUID",5:"字符串全局唯一ID (idWorker 的字符串表示)";
+      id-type: 4
+      # 默认数据库表下划线命名
+      table-underline: true
+#  configuration:
+#    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
+#jeecg专用配置
+jeecg:
+  elasticsearch:
+    address: 127.0.0.1:9200
+    connect-timeout: 1000
+    socket-timeout: 30000
+    connection-request-timeout: 500
+    max-connect-num: 500
+    max-connect-per-route: 100
+    cluster-nodes:
+    check-enabled: false
+  uploadType:
+  oss:
+    endpoint:
+    accessKey:
+    secretKey:
+    bucketName:
+    staticDomain:
+  sms:
+    accessKeyId:
+    accessKeySecret:
+  minio:
+    minio_url:
+    minio_name:
+    minio_pass:
+    bucketName:
+  ffmpeg:
+    bin: ffmpeg
+  path:
+    #文件上传根目录 设置
+    upload: /mnt/upload
+    #webapp文件路径
+    webapp: /mnt/webapp
+    video-upload: /mnt/upload/video/
+    image-upload: D://data//image//
+    kuaishou-agent-image: D://temp.png
+    kuaishou-account-captcha-image: D://captcha.png
+    chrome-driver: D://chromedriver.exe
+    csv-upload: /mnt/upload/csv/
+    bak-database-file: /mnt/data/bak/
+    report-history: D://mnt//reportKs//
+    report-daily: D://mnt//reportKs//
+kuaishou:
+  api-url: https://ad.e.kuaishou.com
+  auth-url: https://ad.e.kuaishou.com
+  appid: 27
+  third-appid: 328
+  oauth-type: agent
+  secret: QovprB1tNhXptgDc
+  third-secret: 1iFTBiMdohkyEQQs
+  callback-url: http://adsp.c-top.com.cn:8080/jeecg-boot/kuaishou
+  third-callback-url: http://callback.shyouteng.com.cn/kuaishou
+  apk-sava-path: /mnt/file/apk
+  image-sava-path: /mnt/file/image
+  video-sava-path: /mnt/file/video
+  model-video-src-path: /mnt/data/src/
+  model-video-fill-path: /mnt/data/fill/
+  model-video-final-path: /mnt/data/final/
+  group-control:
+    path: http://39.106.184.70
+    port: 4723
+logging:
+  level:
+    root: info
+  config: classpath:logback-prod.xml
+chrome:
+  script:
+    clean: sh /mnt/webapp/cleanProcess.sh
+cas:
+  prefixUrl:
+oss:
+  replace:
+    replace-value: oss-cn-beijing-internal
+    replace-old-value: oss-cn-beijing
+    download: D://mnt//image//
+zip:
+  local:
+    download-path: D://mnt//data//
+bytedance:
+  appId: 1635316529903624
+  secret: 0c51523e90d6166418fc8421a4896808e90e26f4
+  url:
+    auth-prefix: https://ad.oceanengine.com/openapi
+    api-prefix: https://ad.oceanengine.com/open_api
+    callback-url: http://adsp.c-top.com.cn:8080/jeecg-boot/bytedance
+    refresh-token: /oauth2/refresh_token
+    advertiser-info: /2/advertiser/public_info/
+    ad-get: /2/ad/get/
+    ad-create: /2/ad/create/
+    ad-update: /2/ad/update/
+    ad-update-status: /2/ad/update/status/
+    ad-update-bid: /2/ad/update/bid/
+    ad-update-budget: /2/ad/update/budget/
+    ad-update-reject-reason: 2/ad/reject_reason/
+    campaign-get: /2/campaign/get/
+    campaign-create: /2/campaign/create/
+    campaign-update-status: /2/campaign/update/status/
+    campaign-update: /2/campaign/update/
+    dmp-custom-audience-select: /2/dmp/custom_audience/select/
+    file-video-ad: /2/file/video/ad/
+    file-image-ad: /2/file/image/ad/
+    creative-update-status: /2/creative/update/status/
+    creative-material-get: /2/creative/material/read/
+    creative-create-v2: /2/creative/create_v2/
+    creative-get: /2/creative/get/
+    creative-read: /2/creative/read_v2/
+    creative-update: /2/creative/update_v2/
+    creative-reject-reason: /2/creative/reject_reason/
+    advertiser-report-get: /2/report/advertiser/get/
+    campaign-report-get: /2/report/campaign/get/
+    ad-report-get: /2/report/ad/get/
+    ad-creative-get: /2/report/creative/get/
+    advertiser-fund-daily-stat: /2/advertiser/fund/daily_stat/
+ai:
+  callback:
+    callback-unit-url: http://139.186.165.84::31012/ai_callback_add_group
+    callback-creative-url: http://139.186.165.84::31012/ai_callback_add_creative
+xxl-job:
+  requestUrl: http://jiaoyangapi.shyouteng.com.cn

+ 12 - 0
jeecg-boot-material-view/src/main/resources/application.yml

@@ -0,0 +1,12 @@
+server:
+  port: 7006
+  servlet:
+    context-path: /material
+
+spring:
+  application:
+    name: jeecg-cloud-material
+  profiles:
+    active: @activatedProperties@
+  main:
+    allow-bean-definition-overriding: true

+ 382 - 0
jeecg-boot-module-system/src/main/java/org/jeecg/common/constant/AccountReportConstants.java

@@ -569,6 +569,221 @@ public class AccountReportConstants {
             "    \"comment\": \"3s播放率\"\n" +
             "  }\n" +
             "}";
+
+    public static final String KUAISHOU_VIDEO_REPORT_FILED_MAPPING_JSON_NEW = "{\n" +
+            "  \"signature\": {\n" +
+            "    \"filed\": \"t1.signature as signature \",\n" +
+            "    \"comment\": \"素材标识\"\n" +
+            "  },\n" +
+            "  \"projectName\": {\n" +
+            "    \"filed\": \"t1.project_name as projectName \",\n" +
+            "    \"comment\": \"项目名称\"\n" +
+            "  },\n" +
+            "  \"cost\": {\n" +
+            "    \"filed\": \"IFNULL(sum(t1.charge),0) as cost \",\n" +
+            "    \"comment\": \"消耗\"\n" +
+            "  },\n" +
+            "  \"photoShow\": {\n" +
+            "    \"filed\": \"IFNULL(sum(t1.`show`),0) as photoShow \",\n" +
+            "    \"comment\": \"封面曝光数\"\n" +
+            "  },\n" +
+            "  \"photoClick\": {\n" +
+            "    \"filed\": \"IFNULL(sum(t1.photo_click),0) as photoClick \",\n" +
+            "    \"comment\": \"封面点击数\"\n" +
+            "  },\n" +
+            "  \"aClick\": {\n" +
+            "    \"filed\": \"IFNULL(sum(t1.aclick),0) as aClick \",\n" +
+            "    \"comment\": \"素材曝光数\"\n" +
+            "  },\n" +
+            "  \"bClick\": {\n" +
+            "    \"filed\": \"IFNULL(sum(t1.bclick),0) as bClick \",\n" +
+            "    \"comment\": \"行为数\"\n" +
+            "  },\n" +
+            "  \"clickRate\": {\n" +
+            "    \"filed\": \"CASE WHEN sum(t1.`show`) != 0    THEN CONCAT( CAST(ROUND((sum(t1.photo_click) / sum(t1.`show`)) * 100,2) AS CHAR) ,'%') else '0%' END AS clickRate \",\n" +
+            "    \"comment\": \"封面点击率\"\n" +
+            "  },\n" +
+            "  \"bClickRate\": {\n" +
+            "    \"filed\": \"CASE WHEN  sum(t1.aclick) != 0 THEN CONCAT( CAST(ROUND((sum(t1.bclick) / sum(t1.aclick)) * 100,2) AS CHAR) ,'%') ELSE '0%' END AS bClickRate \",\n" +
+            "    \"comment\": \"行为率\"\n" +
+            "  },\n" +
+            "  \"cpm\": {\n" +
+            "    \"filed\": \"CASE WHEN sum(t1.charge) / sum(t1.`show`) IS NULL THEN 0 ELSE ROUND((sum(t1.charge) / sum(t1.`show`)) * 1000, 2 ) END AS cpm \",\n" +
+            "    \"comment\": \"平均千次封面曝光花费\"\n" +
+            "  },\n" +
+            "  \"cpc\": {\n" +
+            "    \"filed\": \"CASE WHEN sum(t1.charge) / sum(t1.photo_click) IS NULL THEN 0 ELSE ROUND((sum(t1.charge) / sum(t1.photo_click)), 2) END AS cpc \",\n" +
+            "    \"comment\": \"平均封面点击单价\"\n" +
+            "  },\n" +
+            "  \"cpb\": {\n" +
+            "    \"filed\": \"CASE WHEN sum(t1.charge) / sum(t1.bclick) IS NULL THEN 0 ELSE ROUND((sum(t1.charge) / sum(t1.bclick)), 2) END AS cpb \",\n" +
+            "    \"comment\": \"平均行为单价\"\n" +
+            "  },\n" +
+            "  \"downloadStart\": {\n" +
+            "    \"filed\": \"IFNULL(sum(download_started),0) as downloadStart \",\n" +
+            "    \"comment\": \"安卓开始下载数\"\n" +
+            "  },\n" +
+            "  \"downloadStartCost\": {\n" +
+            "    \"filed\": \"CASE WHEN sum(t1.charge) / (t1.download_started) IS NULL THEN 0 ELSE sum(t1.charge) / sum(t1.download_started) end AS downloadStartCost \",\n" +
+            "    \"comment\": \"安卓开始下载单价\"\n" +
+            "  },\n" +
+            "  \"downloadStartRate\": {\n" +
+            "    \"filed\": \"CASE WHEN  sum(t1.bclick) != 0 THEN concat(CAST(round(sum(t1.download_started) / sum(t1.bclick)*100,2) AS CHAR) ,'%') else '0%' end AS downloadStartRate\",\n" +
+            "    \"comment\": \"安卓开始下载率\"\n" +
+            "  },\n" +
+            "  \"downloadFinish\": {\n" +
+            "    \"filed\": \"IFNULL(sum(download_completed),0) as downloadFinish \",\n" +
+            "    \"comment\": \"安卓下载完成数\"\n" +
+            "  },\n" +
+            "  \"downloadFinishCost\": {\n" +
+            "    \"filed\": \"CASE WHEN sum(t1.charge) / sum(t1.download_completed) IS NULL THEN 0 ELSE  sum(t1.charge) / sum(t1.download_completed) end AS downloadFinishCost \",\n" +
+            "    \"comment\": \"安卓下载完成单价\"\n" +
+            "  },\n" +
+            "  \"downloadFinishRate\": {\n" +
+            "    \"filed\": \"CASE WHEN  sum(t1.download_started) != 0 then  concat(CAST(round(sum(t1.download_completed) / sum(t1.download_started)*100,2) AS CHAR) ,'%') else '0%' end AS downloadFinishRate  \",\n" +
+            "    \"comment\": \"安卓下载完成率\"\n" +
+            "  },\n" +
+            "  \"active\": {\n" +
+            "    \"filed\": \"IFNULL(sum(activation),0) as active \",\n" +
+            "    \"comment\": \"激活数\"\n" +
+            "  },\n" +
+            "  \"activeCost\": {\n" +
+            "    \"filed\": \"CASE WHEN sum(t1.charge) / sum(t1.activation) IS NULL THEN 0 ELSE sum(t1.charge) / sum(t1.activation) end AS activeCost \",\n" +
+            "    \"comment\": \"激活单价\"\n" +
+            "  },\n" +
+            "  \"firstDayPay\": {\n" +
+            "    \"filed\": \"CASE WHEN sum(t1.event_pay_first_day) != 0 THEN sum(t1.event_pay_first_day) ELSE 0  end as firstDayPay \",\n" +
+            "    \"comment\": \"首日付费次数\"\n" +
+            "  },\n" +
+            "  \"firstDayPayAmount\": {\n" +
+            "    \"filed\": \"IFNULL(sum(t1.event_pay_purchase_amount_first_day),0) as firstDayPayAmount  \",\n" +
+            "    \"comment\": \"首日付费金额\"\n" +
+            "  },\n" +
+            "  \"firstDayPayCost\": {\n" +
+            "    \"filed\": \"CASE WHEN sum(t1.charge) / sum(t1.event_pay_first_day) IS NULL THEN 0 ELSE sum(t1.charge) / sum(t1.event_pay_first_day) end AS firstDayPayCost \",\n" +
+            "    \"comment\": \"首日付费成本\"\n" +
+            "  },\n" +
+            "  \"firstDayPayROI\": {\n" +
+            "    \"filed\": \"CASE WHEN sum(t1.event_pay_purchase_amount_first_day) / sum(t1.charge) IS NULL THEN 0 ELSE sum(t1.event_pay_purchase_amount_first_day) / sum(t1.charge) end AS firstDayPayROI \",\n" +
+            "    \"comment\": \"首日ROI\"\n" +
+            "  },\n" +
+            "  \"eventPay\": {\n" +
+            "    \"filed\": \"IFNULL(sum(t1.event_pay),0) as eventPay  \",\n" +
+            "    \"comment\": \"付费次数\"\n" +
+            "  },\n" +
+            "  \"eventPayPurchaseAmount\": {\n" +
+            "    \"filed\": \"IFNULL(sum(t1.event_pay_purchase_amount),0) as eventPayPurchaseAmount  \",\n" +
+            "    \"comment\": \"付费金额\"\n" +
+            "  },\n" +
+            "  \"eventPayCost\": {\n" +
+            "    \"filed\": \"CASE WHEN sum(t1.charge) / sum(t1.event_pay) IS NULL THEN 0 ELSE sum(t1.charge) / sum(t1.event_pay) end AS eventPayCost \",\n" +
+            "    \"comment\": \"付费次数成本\"\n" +
+            "  },\n" +
+            "  \"ROI\": {\n" +
+            "    \"filed\": \"CASE WHEN sum(t1.event_pay_purchase_amount) / sum(t1.charge) IS NULL THEN 0 ELSE sum(t1.event_pay_purchase_amount) / sum(t1.charge) end AS ROI \",\n" +
+            "    \"comment\": \"ROI\"\n" +
+            "  },\n" +
+            "  \"register\": {\n" +
+            "    \"filed\": \"IFNULL(sum(t1.event_register),0) as register \",\n" +
+            "    \"comment\": \"注册数\"\n" +
+            "  },\n" +
+            "  \"activeRegisterCost\": {\n" +
+            "    \"filed\": \"CASE WHEN sum(t1.charge) / sum(t1.event_register) IS NULL THEN 0 ELSE round(sum(t1.charge)/sum(t1.event_register),3) end as activeRegisterCost \",\n" +
+            "    \"comment\": \"注册成本\"\n" +
+            "  },\n" +
+            "  \"activeRegisterRate\": {\n" +
+            "    \"filed\": \"CASE WHEN  sum(t1.activation) !=0  THEN concat(CAST(round(sum(t1.event_register) / sum(t1.activation)*100,2) AS CHAR) ,'%') else '0%' end as activeRegisterRate \",\n" +
+            "    \"comment\": \"注册率\"\n" +
+            "  },\n" +
+            "  \"eventJinJianApp\": {\n" +
+            "    \"filed\": \"IFNULL(sum(event_jin_jian_app),0) as eventJinJianApp \",\n" +
+            "    \"comment\": \"完件数\"\n" +
+            "  },\n" +
+            "  \"eventJinJianAppCost\": {\n" +
+            "    \"filed\": \"CASE WHEN sum(t1.charge) / sum(t1.event_jin_jian_app) IS NULL THEN 0 ELSE round(sum(t1.charge)/sum(t1.event_jin_jian_app),3) end as eventJinJianAppCost \",\n" +
+            "    \"comment\": \"完件成本\"\n" +
+            "  },\n" +
+            "  \"eventCreditGrantApp\": {\n" +
+            "    \"filed\": \"IFNULL(sum(event_credit_grant_app),0) as eventCreditGrantApp \",\n" +
+            "    \"comment\": \"授信数\"\n" +
+            "  },\n" +
+            "  \"eventCreditGrantAppCost\": {\n" +
+            "    \"filed\": \"CASE WHEN sum(t1.charge) / sum(t1.event_credit_grant_app) IS NULL THEN 0 ELSE round(sum(t1.charge)/sum(t1.event_credit_grant_app),3) end as eventCreditGrantAppCost \",\n" +
+            "    \"comment\": \"授信成本\"\n" +
+            "  },\n" +
+            "  \"eventCreditGrantAppRate\": {\n" +
+            "    \"filed\": \"CASE WHEN  sum(t1.event_jin_jian_app) !=0 THEN concat(CAST(round(sum(t1.event_credit_grant_app) / sum(t1.event_jin_jian_app)*100,2) AS CHAR) ,'%') ELSE '0' end as eventCreditGrantAppRate\",\n" +
+            "    \"comment\": \"授信率\"\n" +
+            "  },\n" +
+            "  \"formCount\": {\n" +
+            "    \"filed\": \"IFNULL(sum(t1.form_count),0) as formCount \",\n" +
+            "    \"comment\": \"表单提交数\"\n" +
+            "  },\n" +
+            "  \"formCountRate\": {\n" +
+            "    \"filed\": \"CASE WHEN sum(t1.activation) != 0  THEN  concat(CAST(round(sum(t1.form_count) / sum(t1.activation)*100,2) AS CHAR) ,'%') else '0%' end as formCountRate \",\n" +
+            "    \"comment\": \"表单提交率\"\n" +
+            "  },\n" +
+            "  \"formCountCost\": {\n" +
+            "    \"filed\": \"CASE WHEN sum(t1.charge) / sum(t1.form_count) IS NULL THEN 0 ELSE round(sum(t1.charge)/sum(t1.form_count),3) end as formCountCost \",\n" +
+            "    \"comment\": \"表单提交成本\"\n" +
+            "  },\n" +
+            "  \"nextDayOpen\": {\n" +
+            "    \"filed\": \"IFNULL(sum(t1.event_next_day_stay),0) as nextDayOpen \",\n" +
+            "    \"comment\": \"次留数\"\n" +
+            "  },\n" +
+            "  \"nextDayOpenCost\": {\n" +
+            "    \"filed\": \"CASE WHEN sum(t1.charge) / sum(t1.event_next_day_stay) IS NULL THEN 0 ELSE round(sum(t1.charge)/sum(t1.event_next_day_stay),3) end as nextDayOpenCost \",\n" +
+            "    \"comment\": \"次留成本\"\n" +
+            "  },\n" +
+            "  \"nextDayOpenRate\": {\n" +
+            "    \"filed\": \"CASE WHEN  sum(t1.activation) != 0 THEN  concat(CAST(round(sum(t1.event_next_day_stay) / sum(t1.activation)*100,2) AS CHAR) ,'%') ELSE '0%' end as nextDayOpenRate\",\n" +
+            "    \"comment\": \"次留率\"\n" +
+            "  },\n" +
+            "  \"eventJinJianLandingPage\": {\n" +
+            "    \"filed\": \"IFNULL(sum(t1.event_jin_jian_landing_page),0) as eventJinJianLandingPage \",\n" +
+            "    \"comment\": \"落地页完件数\"\n" +
+            "  },\n" +
+            "  \"eventJinJianLandingPageCost\": {\n" +
+            "    \"filed\": \"CASE WHEN sum(t1.charge) / sum(t1.event_jin_jian_landing_page) IS NULL THEN 0 ELSE round(sum(t1.charge)/sum(t1.event_jin_jian_landing_page),3) end as eventJinJianLandingPageCost \",\n" +
+            "    \"comment\": \"落地页完件成本\"\n" +
+            "  },\n" +
+            "  \"eventCreditGrantLandingPage\": {\n" +
+            "    \"filed\": \"IFNULL(sum(t1.event_credit_grant_landing_page),0) as eventCreditGrantLandingPage \",\n" +
+            "    \"comment\": \"落地页授信数\"\n" +
+            "  },\n" +
+            "  \"eventCreditGrantLandingPageCost\": {\n" +
+            "    \"filed\": \"CASE WHEN sum(t1.charge) / sum(t1.event_credit_grant_landing_page) IS NULL THEN 0 ELSE round(sum(t1.charge)/sum(t1.event_credit_grant_landing_page),3) end as eventCreditGrantLandingPageCost \",\n" +
+            "    \"comment\": \"落地页授信成本\"\n" +
+            "  },\n" +
+            "  \"eventCreditGrantLandingPageRate\": {\n" +
+            "    \"filed\": \"CASE WHEN  sum(t1.event_jin_jian_landing_page)  != 0 THEN  concat( CAST(round(sum(t1.event_credit_grant_landing_page) / sum(t1.event_jin_jian_landing_page)*100,2) AS CHAR),'%') ELSE '0%' end as eventCreditGrantLandingPageRate \",\n" +
+            "    \"comment\": \"落地页授信率\"\n" +
+            "  },\n" +
+            "  \"submit\": {\n" +
+            "    \"filed\": \"IFNULL(sum(t1.event_button_click),0) as submit \",\n" +
+            "    \"comment\": \"按钮点击数\"\n" +
+            "  },\n" +
+            "  \"submitCost\": {\n" +
+            "    \"filed\": \"CASE WHEN sum(t1.charge) / sum(t1.event_button_click) IS NULL THEN 0 ELSE round(sum(t1.charge)/sum(t1.event_button_click),3) end as submitCost \",\n" +
+            "    \"comment\": \"按钮点击成本\"\n" +
+            "  },\n" +
+            "  \"submitRate\": {\n" +
+            "    \"filed\": \"CASE WHEN  sum(t1.bclick) != 0 THEN concat(CAST(round(sum(t1.event_button_click) / sum(t1.bclick)*100,2) AS CHAR) ,'%') else '0%' end as submitRate \",\n" +
+            "    \"comment\": \"按钮点击率\"\n" +
+            "  },\n" +
+            "  \"activeRate\": {\n" +
+            "    \"filed\": \"CASE WHEN  sum(t1.download_completed) != 0 THEN concat(CAST(round(sum(t1.activation) / sum(t1.download_completed)*100,2) AS CHAR) ,'%') else '0%' end as activeRate \",\n" +
+            "    \"comment\": \"下载完成激活率\"\n" +
+            "  },\n" +
+            "  \"play3sCount\": {\n" +
+            "    \"filed\": \"sum(t1.play_3s_count) as play3sCount\",\n" +
+            "    \"comment\": \"3s播放数\"\n" +
+            "  },\n" +
+            "  \"play3sRate\": {\n" +
+            "    \"filed\": \"CASE WHEN sum(aclick) != 0 THEN CONCAT(CAST(ROUND( sum(t1.play_3s_count) / sum(t1.aclick),2 )  * 100 AS CHAR),'%') ELSE '-' END AS play3sRate\",\n" +
+            "    \"comment\": \"3s播放率\"\n" +
+            "  }\n" +
+            "}";
     public static final String KUAISHOU_VIDEO_REPORT_FILED_DICT_JSON = "{\n" +
             "  \"clip\": {\n" +
             "    \"comment\": \"剪辑\"\n" +
@@ -918,6 +1133,163 @@ public class AccountReportConstants {
             "    \"comment\": \"展示数\"\n" +
             "  }\n" +
             "}";
+
+
+
+    public static final String BYTEDANCE_VIDEO_REPORT_MAPPING_JSON_NEW = "{\n" +
+            "  \"cost\": {\n" +
+            "    \"filed\": \"IFNULL(sum(t1.cost),0) as cost \",\n" +
+            "    \"comment\": \"消耗\"\n" +
+            "  },\n" +
+            "  \"cpm\": {\n" +
+            "    \"filed\": \"CASE WHEN sum(t1.cost) / sum(t1.`show`) IS NULL THEN 0 ELSE ROUND((sum(t1.cost) / sum(t1.`show`)) * 1000, 2 ) END AS cpm \",\n" +
+            "    \"comment\": \"平均千次展现费用\"\n" +
+            "  },\n" +
+            "  \"clickMaterial\": {\n" +
+            "    \"filed\": \"IFNULL(sum(t1.click),0) as clickMaterial \",\n" +
+            "    \"comment\": \"点击数\"\n" +
+            "  },\n" +
+            "  \"ctr\": {\n" +
+            "    \"filed\": \"CASE WHEN sum(t1.`show`) != 0 THEN CONCAT(CAST(ROUND((sum(t1.click) / sum(t1.`show`)) * 100,2) AS CHAR) ,'%') ELSE '0%' end  AS ctr\",\n" +
+            "    \"comment\": \"点击率\"\n" +
+            "  },\n" +
+            "  \"cpc\": {\n" +
+            "    \"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 \",\n" +
+            "    \"comment\": \"平均点击单价\"\n" +
+            "  },\n" +
+            "  \"convertMaterial\": {\n" +
+            "    \"filed\": \"IFNULL(sum(t1.`convert`),0) as convertMaterial \",\n" +
+            "    \"comment\": \"转化数\"\n" +
+            "  },\n" +
+            "  \"convertCost\": {\n" +
+            "    \"filed\": \"CASE WHEN sum(t1.cost) / sum(t1.`convert`) IS NULL THEN 0 ELSE ROUND((sum(t1.cost) / sum(t1.`convert`)), 2 ) END AS convertCost \",\n" +
+            "    \"comment\": \"转化成本\"\n" +
+            "  },\n" +
+            "  \"convertRate\": {\n" +
+            "    \"filed\": \"CASE WHEN sum(t1.`show`)!= 0 THEN concat(CAST(round(sum(t1.`convert`) / sum(t1.`show`)*100,2) AS CHAR) ,'%') ELSE '0%' end  AS convertRate \",\n" +
+            "    \"comment\": \"转化率\"\n" +
+            "  },\n" +
+            "  \"downloadStart\": {\n" +
+            "    \"filed\": \"IFNULL(sum(download_start),0) as downloadStart \",\n" +
+            "    \"comment\": \"安卓开始下载数\"\n" +
+            "  },\n" +
+            "  \"downloadStartCost\": {\n" +
+            "    \"filed\": \"CASE WHEN sum(t1.cost) / (t1.download_start) IS NULL THEN 0 ELSE sum(t1.cost) / sum(t1.download_start) end AS downloadStartCost \",\n" +
+            "    \"comment\": \"安卓开始下载成本\"\n" +
+            "  },\n" +
+            "  \"downloadStartRate\": {\n" +
+            "    \"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 \",\n" +
+            "    \"comment\": \"安卓开始下载率\"\n" +
+            "  },\n" +
+            "  \"downloadFinish\": {\n" +
+            "    \"filed\": \"IFNULL(sum(t1.download_finish),0) as downloadFinish \",\n" +
+            "    \"comment\": \"安卓下载完成数\"\n" +
+            "  },\n" +
+            "  \"downloadFinishCost\": {\n" +
+            "    \"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 \",\n" +
+            "    \"comment\": \"安卓下载完成成本\"\n" +
+            "  },\n" +
+            "  \"downloadFinishRate\": {\n" +
+            "    \"filed\": \"CASE WHEN sum(t1.download_start) != 0 THEN concat(CAST(round(sum(t1.download_finish) / sum(t1.download_start)*100,2) AS CHAR),'%') ELSE '0%' end  AS downloadFinishRate \",\n" +
+            "    \"comment\": \"安卓下载完成率\"\n" +
+            "  },\n" +
+            "  \"active\": {\n" +
+            "    \"filed\": \"IFNULL(sum(t1.active),0) as active \",\n" +
+            "    \"comment\": \"激活数\"\n" +
+            "  },\n" +
+            "  \"activeCost\": {\n" +
+            "    \"filed\": \"CASE WHEN sum(t1.cost) / sum(t1.active) IS NULL THEN 0 ELSE sum(t1.cost) / sum(t1.active) end AS activeCost \",\n" +
+            "    \"comment\": \"激活成本\"\n" +
+            "  },\n" +
+            "  \"activeRate\": {\n" +
+            "    \"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\",\n" +
+            "    \"comment\": \"激活率\"\n" +
+            "  },\n" +
+            "  \"register\": {\n" +
+            "    \"filed\": \"IFNULL(sum(t1.register),0) as register  \",\n" +
+            "    \"comment\": \"注册数\"\n" +
+            "  },\n" +
+            "  \"activeRegisterCost\": {\n" +
+            "    \"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 \",\n" +
+            "    \"comment\": \"注册成本\"\n" +
+            "  },\n" +
+            "  \"activeRegisterRate\": {\n" +
+            "    \"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 \",\n" +
+            "    \"comment\": \"注册率\"\n" +
+            "  },\n" +
+            "  \"gameAddiction\": {\n" +
+            "    \"filed\": \"IFNULL(sum(t1.game_addiction),0) as gameAddiction  \",\n" +
+            "    \"comment\": \"关键行为数\"\n" +
+            "  },\n" +
+            "  \"gameAddictionCost\": {\n" +
+            "    \"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 \",\n" +
+            "    \"comment\": \"关键行为成本\"\n" +
+            "  },\n" +
+            "  \"gameAddictionRate\": {\n" +
+            "    \"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\",\n" +
+            "    \"comment\": \"关键行为率\"\n" +
+            "  },\n" +
+            "  \"nextDayOpen\": {\n" +
+            "    \"filed\": \"IFNULL(sum(t1.next_day_open),0) as nextDayOpen \",\n" +
+            "    \"comment\": \"次留数\"\n" +
+            "  },\n" +
+            "  \"nextDayOpenCost\": {\n" +
+            "    \"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 \",\n" +
+            "    \"comment\": \"次留成本\"\n" +
+            "  },\n" +
+            "  \"nextDayOpenRate\": {\n" +
+            "    \"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 \",\n" +
+            "    \"comment\": \"次留率\"\n" +
+            "  },\n" +
+            "  \"activePayAmount\": {\n" +
+            "    \"filed\": \"IFNULL(sum(game_pay_count),0) as activePayAmount \",\n" +
+            "    \"comment\": \"付费数\"\n" +
+            "  },\n" +
+            "  \"activePayCost\": {\n" +
+            "    \"filed\": \"CASE WHEN sum(t1.cost) / sum(t1.game_pay_count) IS NULL THEN 0 ELSE round(sum(t1.cost)/sum(t1.game_pay_count),3) end as activePayCost \",\n" +
+            "    \"comment\": \"付费成本\"\n" +
+            "  },\n" +
+            "  \"form\": {\n" +
+            "    \"filed\": \"IFNULL(sum(t1.form),0) as form \",\n" +
+            "    \"comment\": \"表单提交\"\n" +
+            "  },\n" +
+            "  \"validPlayCost\": {\n" +
+            "    \"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 \",\n" +
+            "    \"comment\": \"有效播放成本\"\n" +
+            "  },\n" +
+            "  \"play25FeedBreak\": {\n" +
+            "    \"filed\": \"IFNULL(sum(t1.play_25_feed_break),0) as play25FeedBreak \",\n" +
+            "    \"comment\": \"25%进度播放数\"\n" +
+            "  },\n" +
+            "  \"play50FeedBreak\": {\n" +
+            "    \"filed\": \"IFNULL(sum(t1.play_50_feed_break),0) as play50FeedBreak\",\n" +
+            "    \"comment\": \"50%进度播放数\"\n" +
+            "  },\n" +
+            "  \"play75FeedBreak\": {\n" +
+            "    \"filed\": \"IFNULL(sum(t1.play_75_feed_break),0) as play75FeedBreak\",\n" +
+            "    \"comment\": \"75%进度播放数\"\n" +
+            "  },\n" +
+            "  \"play100FeedBreak\": {\n" +
+            "    \"filed\": \"IFNULL(sum(t1.play_100_feed_break),0) as play100FeedBreak\",\n" +
+            "    \"comment\": \"100%进度播放数\"\n" +
+            "  },\n" +
+            "  \"follow\": {\n" +
+            "    \"filed\": \"IFNULL(sum(t1.follow),0) as follow \",\n" +
+            "    \"comment\": \"新增关注数\"\n" +
+            "  },\n" +
+            "  \"likeMaterial\": {\n" +
+            "    \"filed\": \"IFNULL(sum(t1.`like`),0) as likeMaterial \",\n" +
+            "    \"comment\": \"点赞数\"\n" +
+            "  },\n" +
+            "  \"shareMaterial\": {\n" +
+            "    \"filed\": \"IFNULL(sum(t1.`share`),0) as shareMaterial \",\n" +
+            "    \"comment\": \"分享数\"\n" +
+            "  },\n" +
+            "  \"showMaterial\": {\n" +
+            "    \"filed\": \"IFNULL(t1.`show`, 0 ) AS material_show \",\n" +
+            "    \"comment\": \"展示数\"\n" +
+            "  }\n" +
+            "}";
     public static Map<String, Map<String, Object>> getDictMapBy(){
         JSONObject jsonBy = JSON.parseObject(BYTEDANCE_FILED_MAPPING_JSON);
         return JsonResourceUtil.jsonToMap(jsonBy);
@@ -930,10 +1302,20 @@ public class AccountReportConstants {
         Object jsonByVideo = JSON.parseObject(BYTEDANCE_VIDEO_REPORT_MAPPING_JSON);
         return JsonResourceUtil.jsonToMap(jsonByVideo);
     }
+    public static Map<String, Map<String, Object>> getDicMapByVideoNew(){
+        Object jsonByVideo = JSON.parseObject(BYTEDANCE_VIDEO_REPORT_MAPPING_JSON_NEW);
+        return JsonResourceUtil.jsonToMap(jsonByVideo);
+    }
     public static Map<String, Map<String, Object>> getKuaishouVideoReportMap(){
         Object kuaiShouVideoJson = JSON.parseObject(KUAISHOU_VIDEO_REPORT_FILED_MAPPING_JSON);
         return JsonResourceUtil.jsonToMap(kuaiShouVideoJson);
     }
+    public static Map<String, Map<String, Object>> getKuaishouVideoReportMapNew(){
+        Object kuaiShouVideoJson = JSON.parseObject(KUAISHOU_VIDEO_REPORT_FILED_MAPPING_JSON_NEW);
+        return JsonResourceUtil.jsonToMap(kuaiShouVideoJson);
+    }
+
+
     public static Map<String, Map<String, Object>> getKuaishouVideoReportDict(){
         Object kuaiShouVideoDictJson = JSON.parseObject(KUAISHOU_VIDEO_REPORT_FILED_DICT_JSON);
         return JsonResourceUtil.jsonToMap(kuaiShouVideoDictJson);

+ 6 - 0
jeecg-cloud-module/jeecg-cloud-gateway/src/main/resources/application-dev.yml

@@ -44,6 +44,12 @@ spring:
           - Path=/reportModule/**
         filters:
           - DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin
+      - id: jeecg-cloud-material
+        uri: lb://jeecg-cloud-material
+        predicates:
+          - Path=/material/**
+        filters:
+          - DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin
 # hystrix 信号量隔离,3秒后自动超时
 hystrix:
   enabled: true

+ 6 - 0
jeecg-cloud-module/jeecg-cloud-gateway/src/main/resources/application-prod.yml

@@ -56,6 +56,12 @@ spring:
           - Path=/reportModule/**
         filters:
           - DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin
+      - id: jeecg-cloud-material
+        uri: lb://jeecg-cloud-material
+        predicates:
+          - Path=/material/**
+        filters:
+          - DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin
 # hystrix 信号量隔离,3秒后自动超时
 hystrix:
   enabled: true

+ 6 - 0
jeecg-cloud-module/jeecg-cloud-gateway/src/main/resources/application-test.yml

@@ -50,6 +50,12 @@ spring:
           - DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin
         predicates:
           - Path=/finance/**
+      - id: jeecg-cloud-material
+        uri: lb://jeecg-cloud-material
+        predicates:
+          - Path=/material/**
+        filters:
+          - DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin
 # hystrix 信号量隔离,3秒后自动超时
 hystrix:
   enabled: true

+ 1 - 0
pom.xml

@@ -56,6 +56,7 @@
         <module>jeecg-cloud-module</module>
         <module>jeecg-boot-finance</module>
 		<module>jeecg-boot-report</module>
+        <module>jeecg-boot-material-view</module>
     </modules>
 
 	<distributionManagement>