Jelajahi Sumber

项目自动化功能

zhaoxian 4 tahun lalu
induk
melakukan
dff052801a

+ 154 - 0
module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/ai/controller/AiKuaishouProjectCreateCreativeController.java

@@ -0,0 +1,154 @@
+package cn.com.ctop.kuaishou.modules.ai.controller;
+
+import cn.com.ctop.common.module.service.IUserAllocationService;
+import cn.com.ctop.common.module.utils.Check;
+import cn.com.ctop.kuaishou.modules.ai.entity.AiKuaishouAdvertiserStrategy;
+import cn.com.ctop.kuaishou.modules.ai.entity.KuaishouProjectStrategy;
+import cn.com.ctop.kuaishou.modules.ai.service.IAiKuaishouAdvertiserStrategyService;
+import cn.com.ctop.kuaishou.modules.ai.service.IAiKuaishouProjectCreateCreativeService;
+import cn.com.ctop.kuaishou.modules.ai.service.IKuaishouProjectStrategyService;
+import com.alibaba.fastjson.JSONObject;
+import io.swagger.annotations.Api;
+import lombok.extern.slf4j.Slf4j;
+import org.jeecg.common.api.vo.Result;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.text.ParseException;
+import java.util.List;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+@Slf4j
+@Api(tags = "快手-自动投放")
+@RestController
+@RequestMapping("/ai/projectCreate")
+public class AiKuaishouProjectCreateCreativeController {
+    @Autowired
+    private IAiKuaishouProjectCreateCreativeService projectCreateCreativeService;
+    @Autowired
+    private IAiKuaishouAdvertiserStrategyService strategyService;
+    @Autowired
+    private IKuaishouProjectStrategyService kuaishouProjectStrategyService;
+    @Autowired
+    private IUserAllocationService userAllocationService;
+
+
+    static ExecutorService executorService = Executors.newFixedThreadPool(2);
+    static ExecutorService kuaishouCustomCreativeSupplementExecutorService = Executors.newFixedThreadPool(2);
+    static ExecutorService kuaishouProgramCreativeAutoService = Executors.newFixedThreadPool(2);
+    static ExecutorService kuaishouProgramTopCreativeAutoService = Executors.newFixedThreadPool(2);
+
+    /**
+     * 项目自动创建
+     *
+     * @param id
+     * @return
+     */
+    @GetMapping(value = "/projectAutomaticCreates")
+    public Result<Object> projectAutomaticCreates(String id) {
+        try {
+            if (Check.isNull(id)) {
+                throw new Exception("主键id不能为空");
+            }
+            KuaishouProjectStrategy strategy = kuaishouProjectStrategyService.getById(id);
+            if (Check.isNull(strategy)) {
+                throw new Exception("根据id获取详细信息为空");
+            }
+            Long projectId = strategy.getProjectId();
+            List<Long> list = userAllocationService.queryAutomaticAccounts(projectId);
+            if (Check.isNull(list)) {
+                return Result.ok("项目:" + projectId + "中未配置自动投放账户!");
+            }
+            list.forEach(accountId -> executorService.submit(() -> {
+                Boolean unitOverrun = projectCreateCreativeService.getUnitOverrun(projectId.toString().concat(accountId.toString()));
+                if (!unitOverrun) {
+                    strategy.setAccountId(accountId);
+                    projectCreateCreativeService.projectAutomaticCreates(strategy);
+                }
+            }));
+            return Result.ok("异步创建中...");
+        } catch (Exception e) {
+            log.error("项目自动创建异常", e.fillInStackTrace());
+            return Result.error(e.getMessage());
+        }
+    }
+
+
+    /**
+     * 自动上新
+     *
+     * @param id
+     * @return
+     */
+    @GetMapping(value = "/customCreativeLimit")
+    public JSONObject customCreativeLimit(String id) {
+        JSONObject returnJson = new JSONObject();
+        try {
+            if (Check.isNull(id)) {
+                throw new Exception("主键id不能为空");
+            }
+            KuaishouProjectStrategy strategy = kuaishouProjectStrategyService.getById(id);
+            if (Check.isNull(strategy)) {
+                throw new Exception("根据id获取详细信息为空");
+            }
+            Boolean unitOverrun = projectCreateCreativeService.getUnitOverrun(strategy.getAccountId().toString());
+            if (unitOverrun) {
+                log.error("组创建超限,accountId:{}", strategy.getAccountId());
+                throw new Exception("今日组创建已超限");
+            }
+
+            executorService.submit(() ->
+                    projectCreateCreativeService.customCreativeLimit(strategy)
+            );
+            returnJson.put("code", 0);
+            returnJson.put("message", "异步创建中");
+        } catch (Exception e) {
+            returnJson.put("code", -1);
+            returnJson.put("message", e.getMessage());
+        }
+        return returnJson;
+
+    }
+
+    /**
+     * 自定义创意补充
+     * @param id
+     * @param hour
+     * @return
+     */
+    @GetMapping(value = "/kuaishouCustomCreativeSupplement")
+    public JSONObject kuaishouCustomCreativeSupplement(String id, Integer hour) {
+        JSONObject returnJson = new JSONObject();
+        try {
+            if (Check.isNull(id)) {
+                throw new Exception("主键id不能为空");
+            }
+            KuaishouProjectStrategy strategy = kuaishouProjectStrategyService.getById(id);
+            if (Check.isNull(strategy)) {
+                throw new Exception("根据id获取详细信息为空");
+            }
+            Boolean unitOverrun = projectCreateCreativeService.getUnitOverrun(strategy.getAccountId().toString());
+            if (unitOverrun) {
+                log.error("组创建超限,accountId:{}", strategy.getAccountId());
+                throw new Exception("今日组创建已超限");
+            }
+            if (Check.isNull(hour)) {
+                throw new Exception("小时数据为空");
+            }
+            kuaishouCustomCreativeSupplementExecutorService.submit(() -> {
+                projectCreateCreativeService.customCreativeSupplement(strategy, hour);
+            });
+            returnJson.put("code", 0);
+            returnJson.put("message", "异步创建中");
+        } catch (Exception e) {
+            returnJson.put("code", -1);
+            returnJson.put("message", e.getMessage());
+        }
+        return returnJson;
+
+    }
+
+}

+ 304 - 0
module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/ai/controller/KuaishouProjectStrategyController.java

@@ -0,0 +1,304 @@
+package cn.com.ctop.kuaishou.modules.ai.controller;
+
+import cn.com.ctop.common.module.service.IUserAllocationService;
+import cn.com.ctop.common.module.utils.Check;
+import cn.com.ctop.common.module.utils.QueryGenerator;
+import cn.com.ctop.kuaishou.modules.ai.entity.KuaishouProjectStrategy;
+import cn.com.ctop.kuaishou.modules.ai.service.IKuaishouProjectStrategyService;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.common.util.DateUtils;
+import org.jeecg.common.util.oConvertUtils;
+import org.jeecgframework.poi.excel.ExcelImportUtil;
+import org.jeecgframework.poi.excel.def.NormalExcelConstants;
+import org.jeecgframework.poi.excel.entity.ExportParams;
+import org.jeecgframework.poi.excel.entity.ImportParams;
+import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.multipart.MultipartHttpServletRequest;
+import org.springframework.web.servlet.ModelAndView;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 自动投放-项目策略表
+ *
+ * @author jeecg-boot
+ * @version V1.0
+ * @date 2021-06-24
+ */
+@Slf4j
+@Api(tags = "自动投放-项目策略表")
+@RestController
+@RequestMapping("/kuaishouProjectStrategy")
+public class KuaishouProjectStrategyController {
+    @Autowired
+    private IKuaishouProjectStrategyService kuaishouProjectStrategyService;
+    @Autowired
+    private IUserAllocationService userAllocationService;
+
+    /**
+     * 项目配置列表
+     */
+    @PostMapping(value = "/queryProjectList")
+    public Result<Object> queryProjectList(@RequestBody JSONObject data, @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo, @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize) {
+        try {
+            if (Check.isNull(data.getString("startTime")) || Check.isNull(data.getString("endTime"))) {
+                return Result.error("请选择查询时间");
+            }
+            return kuaishouProjectStrategyService.queryProjectList(data, pageNo, pageSize);
+        } catch (Exception e) {
+            log.error("查询异常,", e.getMessage());
+            e.printStackTrace();
+        }
+        return Result.error("查询失败");
+    }
+
+    /**
+     * 项目策略中账户列表
+     */
+    @PostMapping(value = "/queryAccountList")
+    public Result<Object> queryAccountList(@RequestBody JSONObject data) {
+        try {
+            if (Check.isNull(data.getString("startTime")) || Check.isNull(data.getString("endTime"))) {
+                return Result.error("请选择查询时间");
+            }
+            return kuaishouProjectStrategyService.queryAccountList(data);
+        } catch (Exception e) {
+            log.error("查询异常,", e.getMessage());
+            e.printStackTrace();
+        }
+        return Result.error("查询失败");
+    }
+
+    /**
+     * 修改项目策略状态
+     */
+    @PostMapping(value = "/updateProjectStrategy")
+    public Result<Object> updateProjectStrategy(@RequestBody KuaishouProjectStrategy kuaishouProjectStrategy) {
+        KuaishouProjectStrategy kuaishouProjectStrategyEntity = kuaishouProjectStrategyService.getById(kuaishouProjectStrategy.getId());
+        if (kuaishouProjectStrategyEntity == null) {
+            return Result.error("未找到对应实体");
+        } else {
+            boolean ok = kuaishouProjectStrategyService.updateById(kuaishouProjectStrategy);
+            if (ok) {
+                return Result.ok("修改成功!");
+            }
+        }
+        return Result.ok("修改失败!");
+    }
+
+    /**
+     * 修改项目策略状态
+     */
+    @GetMapping(value = "/updateAccountStatus")
+    public Result<Object> updateAccountStatus(Long accountId, Integer projectStrategy) {
+        try {
+            if (Check.isNull(accountId) || Check.isNull(projectStrategy)) {
+                return Result.error("缺失参数");
+            }
+            boolean ok = userAllocationService.updateProjectStrategyStatus(accountId, projectStrategy);
+            if (ok) {
+                return Result.ok("修改成功!");
+            }
+        } catch (Exception e) {
+            log.error("修改异常,", e.getMessage());
+            e.printStackTrace();
+        }
+        return Result.error("修改失败");
+    }
+
+    /**
+     * 出价反显展示
+     */
+    @GetMapping(value = "/queryBidInfo")
+    public Result<Object> queryBidInfo(@RequestParam(name = "id", required = true) String id) {
+        Result<KuaishouProjectStrategy> result = new Result<>();
+        KuaishouProjectStrategy kuaishouProjectStrategy = kuaishouProjectStrategyService.getById(id);
+        if (kuaishouProjectStrategy == null) {
+            return Result.error("未找到对应实体");
+        } else {
+            return Result.ok(kuaishouProjectStrategy);
+        }
+    }
+
+    /**
+     * 查询项目策略匹配结果
+     */
+    @GetMapping(value = "/queryMatchResult")
+    public Result<Object> queryMatchResult(@RequestParam(name = "id", required = true) String id) {
+        Result<KuaishouProjectStrategy> result = new Result<>();
+        try {
+            return kuaishouProjectStrategyService.queryMatchResult(id);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return Result.error("查询失败");
+    }
+
+
+    /**
+     * 创建项目策略
+     */
+    @PostMapping(value = "/createProjectStrategy")
+    public Result<KuaishouProjectStrategy> createProjectStrategy(@RequestBody JSONObject data) {
+        Result<KuaishouProjectStrategy> result = new Result<>();
+        try {
+            KuaishouProjectStrategy kuaishouProjectStrategy = JSONObject.parseObject(data.toJSONString(),KuaishouProjectStrategy.class);
+            kuaishouProjectStrategy.setStatDate(DateUtils.getNowDate("yyyy-MM-dd"));
+            kuaishouProjectStrategyService.saveOrUpdate(kuaishouProjectStrategy);
+            result.success("操作成功!");
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+            result.error500("操作失败");
+        }
+        return result;
+    }
+
+
+    /**
+     * 通过id删除
+     *
+     * @param id
+     * @return
+     */
+    @ApiOperation(value = "自动投放-项目策略表-通过id删除", notes = "自动投放-项目策略表-通过id删除")
+    @DeleteMapping(value = "/delete")
+    public Result<?> delete(@RequestParam(name = "id") String id) {
+        try {
+            kuaishouProjectStrategyService.removeById(id);
+        } catch (Exception e) {
+            log.error("删除失败", e.getMessage());
+            return Result.error("删除失败!");
+        }
+        return Result.ok("删除成功!");
+    }
+
+    /**
+     * 批量删除
+     *
+     * @param ids
+     * @return
+     */
+    @ApiOperation(value = "自动投放-项目策略表-批量删除", notes = "自动投放-项目策略表-批量删除")
+    @DeleteMapping(value = "/deleteBatch")
+    public Result<KuaishouProjectStrategy> deleteBatch(@RequestParam(name = "ids") String ids) {
+        Result<KuaishouProjectStrategy> result = new Result<>();
+        if (ids == null || "".equals(ids.trim())) {
+            result.error500("参数不识别!");
+        } else {
+            this.kuaishouProjectStrategyService.removeByIds(Arrays.asList(ids.split(",")));
+            result.success("删除成功!");
+        }
+        return result;
+    }
+
+    /**
+     * 通过id查询
+     *
+     * @param id
+     * @return
+     */
+    @ApiOperation(value = "自动投放-项目策略表-通过id查询", notes = "自动投放-项目策略表-通过id查询")
+    @GetMapping(value = "/queryById")
+    public Result<KuaishouProjectStrategy> queryById(@RequestParam(name = "id", required = true) String id) {
+        Result<KuaishouProjectStrategy> result = new Result<>();
+        KuaishouProjectStrategy kuaishouProjectStrategy = kuaishouProjectStrategyService.getById(id);
+        if (kuaishouProjectStrategy == null) {
+            result.error500("未找到对应实体");
+        } else {
+            result.setResult(kuaishouProjectStrategy);
+            result.setSuccess(true);
+        }
+        return result;
+    }
+
+    /**
+     * 导出excel
+     *
+     * @param request
+     * @param response
+     */
+    @RequestMapping(value = "/exportXls")
+    public ModelAndView exportXls(HttpServletRequest request, HttpServletResponse response) {
+        // Step.1 组装查询条件
+        QueryWrapper<KuaishouProjectStrategy> queryWrapper = null;
+        try {
+            String paramsStr = request.getParameter("paramsStr");
+            if (oConvertUtils.isNotEmpty(paramsStr)) {
+                String deString = URLDecoder.decode(paramsStr, "UTF-8");
+                KuaishouProjectStrategy kuaishouProjectStrategy = JSON.parseObject(deString, KuaishouProjectStrategy.class);
+                queryWrapper = QueryGenerator.initQueryWrapper(kuaishouProjectStrategy, request.getParameterMap());
+            }
+        } catch (UnsupportedEncodingException e) {
+            e.printStackTrace();
+        }
+
+        //Step.2 AutoPoi 导出Excel
+        ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
+        List<KuaishouProjectStrategy> pageList = kuaishouProjectStrategyService.list(queryWrapper);
+        //导出文件名称
+        mv.addObject(NormalExcelConstants.FILE_NAME, "自动投放-项目策略表列表");
+        mv.addObject(NormalExcelConstants.CLASS, KuaishouProjectStrategy.class);
+        mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("自动投放-项目策略表列表数据", "导出人:Jeecg", "导出信息"));
+        mv.addObject(NormalExcelConstants.DATA_LIST, pageList);
+        return mv;
+    }
+
+    /**
+     * 通过excel导入数据
+     *
+     * @param request
+     * @param response
+     * @return
+     */
+    @RequestMapping(value = "/importExcel", method = RequestMethod.POST)
+    public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
+        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
+        Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
+        for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
+            MultipartFile file = entity.getValue();
+            ImportParams params = new ImportParams();
+            params.setTitleRows(2);
+            params.setHeadRows(1);
+            params.setNeedSave(true);
+            try {
+                List<KuaishouProjectStrategy> listKuaishouProjectStrategys = ExcelImportUtil.importExcel(file.getInputStream(), KuaishouProjectStrategy.class, params);
+                kuaishouProjectStrategyService.saveBatch(listKuaishouProjectStrategys);
+                return Result.ok("文件导入成功!数据行数:" + listKuaishouProjectStrategys.size());
+            } catch (Exception e) {
+                log.error(e.getMessage(), e);
+                return Result.error("文件导入失败:" + e.getMessage());
+            } finally {
+                try {
+                    file.getInputStream().close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+        return Result.ok("文件导入失败!");
+    }
+
+}

+ 365 - 0
module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/ai/entity/KuaishouProjectStrategy.java

@@ -0,0 +1,365 @@
+package cn.com.ctop.kuaishou.modules.ai.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+import org.jeecgframework.poi.excel.annotation.Excel;
+
+import java.util.Date;
+
+/**
+ * 自动投放-项目策略表
+ *
+ * @author jeecg-boot
+ * @version V1.0
+ * @date 2021-06-24
+ */
+@Data
+@TableName("ctop_ai_kuaishou_project_strategy")
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value = "ctop_ai_kuaishou_project_strategy对象", description = "自动投放-项目策略表")
+public class KuaishouProjectStrategy {
+
+    /**
+     * 客户策略ID
+     */
+    @TableId(type = IdType.AUTO)
+    @ApiModelProperty(value = "客户策略ID")
+    private Long id;
+    /**
+     * 项目ID
+     */
+    @Excel(name = "项目ID", width = 15)
+    @ApiModelProperty(value = "项目ID")
+    private Long projectId;
+    /**
+     * userId
+     */
+    @Excel(name = "userId", width = 15)
+    @ApiModelProperty(value = "userId")
+    private String userId;
+    /**
+     * 策略状态 0-停用 1-使用
+     */
+    @Excel(name = "策略状态 0-停用 1-使用", width = 15)
+    @ApiModelProperty(value = "策略状态 0-停用 1-使用")
+    private Integer dataStatus;
+    /**
+     * 计划类型 2-提升应用安装 3-获取电商下单 4-推广品牌活动 5-收集销售线索 7-提高应用活跃
+     */
+    @Excel(name = "计划类型 2-提升应用安装 3-获取电商下单 4-推广品牌活动 5-收集销售线索 7-提高应用活跃", width = 15)
+    @ApiModelProperty(value = "计划类型 2-提升应用安装 3-获取电商下单 4-推广品牌活动 5-收集销售线索 7-提高应用活跃")
+    private Integer campaignType;
+    /**
+     * 计划命名规范
+     */
+    @Excel(name = "计划命名规范", width = 15)
+    @ApiModelProperty(value = "计划命名规范")
+    private String campaignName;
+
+    private Integer campaignStatus;
+
+    private String statDate;
+    /**
+     * 广告组命名规范
+     */
+    @Excel(name = "广告组命名规范", width = 15)
+    @ApiModelProperty(value = "广告组命名规范")
+    private String groupName;
+    /**
+     * -1:投放 2 暂停
+     */
+    private Integer groupStatus;
+    /**
+     * 计划单日预算
+     */
+    @Excel(name = "计划单日预算", width = 15)
+    @ApiModelProperty(value = "计划单日预算")
+    private Long campaignDayBudget;
+    /**
+     * 组单日预算
+     */
+    @Excel(name = "组单日预算", width = 15)
+    @ApiModelProperty(value = "组单日预算")
+    private Long unitDayBudget;
+    /**
+     * 单/多应用,1单应用,2多应用
+     */
+    @Excel(name = "单/多应用,1单应用,2多应用", width = 15)
+    @ApiModelProperty(value = "单/多应用,1单应用,2多应用")
+    private Integer singleAppid;
+    /**
+     * 应用ID
+     */
+    @Excel(name = "应用ID", width = 15)
+    @ApiModelProperty(value = "应用ID")
+    private Long appId;
+    /**
+     * 应用ID列表
+     */
+    @Excel(name = "应用ID列表", width = 15)
+    @ApiModelProperty(value = "应用ID列表")
+    private String appIdArray;
+    /**
+     * 定向模板id列表
+     */
+    @Excel(name = "定向模板id列表", width = 15)
+    @ApiModelProperty(value = "定向模板id列表")
+    private String templateIdArray;
+    /**
+     * 组-优先从系统应用商店下载
+     */
+    @Excel(name = "组-优先从系统应用商店下载", width = 15)
+    @ApiModelProperty(value = "组-优先从系统应用商店下载")
+    private Integer useAppMarket;
+    /**
+     * 组-应用商店列表
+     */
+    @Excel(name = "组-应用商店列表", width = 15)
+    @ApiModelProperty(value = "组-应用商店列表")
+    private String appStore;
+    /**
+     * 组-调起应用链接
+     */
+    @Excel(name = "组-调起应用链接", width = 15)
+    @ApiModelProperty(value = "组-调起应用链接")
+    private String schemaUri;
+    /**
+     * 组-优化目标 2:行为数,180:激活数;53:表单数;190: 付费;191:首日ROI;324:唤起应用...
+     */
+    @Excel(name = "组-优化目标 2:行为数,180:激活数;53:表单数;190: 付费;191:首日ROI;324:唤起应用...", width = 15)
+    @ApiModelProperty(value = "组-优化目标 2:行为数,180:激活数;53:表单数;190: 付费;191:首日ROI;324:唤起应用...")
+    private Integer ocpxActionType;
+    /**
+     * 组-转化目标ID
+     */
+    @Excel(name = "组-转化目标ID", width = 15)
+    @ApiModelProperty(value = "组-转化目标ID")
+    private Integer convertId;
+    /**
+     * 组-优化目标出价类型
+     */
+    @Excel(name = "组-优化目标出价类型", width = 15)
+    @ApiModelProperty(value = "组-优化目标出价类型")
+    private Integer bidType;
+    /**
+     * 出价
+     */
+    @Excel(name = "出价", width = 15)
+    @ApiModelProperty(value = "出价")
+    private String bid;
+    /**
+     * OCPC出价
+     */
+    @Excel(name = "OCPC出价", width = 15)
+    @ApiModelProperty(value = "OCPC出价")
+    private String cpaBid;
+    /**
+     * 组-深度转化出价
+     */
+    @Excel(name = "组-深度转化出价", width = 15)
+    @ApiModelProperty(value = "组-深度转化出价")
+    private String deepConversionBid;
+    /**
+     * 组-深度转化目标
+     */
+    @Excel(name = "组-深度转化目标", width = 15)
+    @ApiModelProperty(value = "组-深度转化目标")
+    private Long deepConversionType;
+    /**
+     * 组-优先低成本出价
+     */
+    @Excel(name = "组-优先低成本出价", width = 15)
+    @ApiModelProperty(value = "组-优先低成本出价")
+    private Long smartBid;
+    /**
+     * 组-付费ROI系数
+     */
+    @Excel(name = "组-付费ROI系数", width = 15)
+    @ApiModelProperty(value = "组-付费ROI系数")
+    private Float roiRatio;
+    /**
+     * 组-投放开始时间
+     */
+    @Excel(name = "组-投放开始时间", width = 15)
+    @ApiModelProperty(value = "组-投放开始时间")
+    private String beginTime;
+    /**
+     * 组-投放结束时间
+     */
+    @Excel(name = "组-投放结束时间", width = 15)
+    @ApiModelProperty(value = "组-投放结束时间")
+    private String endTime;
+    /**
+     * 组-投放时间段
+     */
+    @Excel(name = "组-投放时间段", width = 15)
+    @ApiModelProperty(value = "组-投放时间段")
+    private String scheduleTime;
+    /**
+     * url类型 当计划类型为:3(获取电商下单)时必填:1 - 淘宝商品短链;2 - 淘宝商品itemID;4 - 金牛电商
+     */
+    @Excel(name = "url类型 当计划类型为:3(获取电商下单)时必填:1 - 淘宝商品短链;2 - 淘宝商品itemID;4 - 金牛电商", width = 15)
+    @ApiModelProperty(value = "url类型 当计划类型为:3(获取电商下单)时必填:1 - 淘宝商品短链;2 - 淘宝商品itemID;4 - 金牛电商")
+    private Integer urlType;
+    /**
+     * 当计划类型为5(收集销售线索)&使用建站时必填:需使用魔力建站;不传默认1,2:落地页
+     */
+    @Excel(name = "当计划类型为5(收集销售线索)&使用建站时必填:需使用魔力建站;不传默认1,2:落地页", width = 15)
+    @ApiModelProperty(value = "当计划类型为5(收集销售线索)&使用建站时必填:需使用魔力建站;不传默认1,2:落地页")
+    private Integer webUriType;
+    /**
+     * 投放链接
+     */
+    @Excel(name = "投放链接", width = 15)
+    @ApiModelProperty(value = "投放链接")
+    private String url;
+    /**
+     * 组-创意展现方式 1-轮播  2-优选
+     */
+    @Excel(name = "组-创意展现方式 1-轮播  2-优选", width = 15)
+    @ApiModelProperty(value = "组-创意展现方式 1-轮播  2-优选")
+    private Integer showMode;
+    /**
+     * 组-投放方式 1-加速投放  2-平滑投放 3-优先低成本
+     */
+    @Excel(name = "组-投放方式 1-加速投放  2-平滑投放 3-优先低成本", width = 15)
+    @ApiModelProperty(value = "组-投放方式 1-加速投放  2-平滑投放 3-优先低成本")
+    private Integer speed;
+    /**
+     * 创意制作方式,0-不限,4-自定义,7-程序化创意2.0
+     */
+    @Excel(name = " 创意制作方式,0-不限,4-自定义,7-程序化创意2.0", width = 15)
+    @ApiModelProperty(value = " 创意制作方式,0-不限,4-自定义,7-程序化创意2.0")
+    private Integer unitType;
+    /**
+     * 广告位;1:优选,3:视频播放页,5:联盟,6:上下滑
+     */
+    @Excel(name = "广告位;1:优选,3:视频播放页,5:联盟,6:上下滑", width = 15)
+    @ApiModelProperty(value = "广告位;1:优选,3:视频播放页,5:联盟,6:上下滑")
+    private String sceneId;
+    /**
+     * 关联封面数
+     */
+    @Excel(name = "关联封面数", width = 15)
+    @ApiModelProperty(value = "关联封面数")
+    private Integer imageCnt;
+    /**
+     * 自定义组数,最多400
+     */
+    @Excel(name = "自定义组数,最多400", width = 15)
+    @ApiModelProperty(value = "自定义组数,最多400")
+    private Integer customUnitCnt;
+    /**
+     * 程序化组数,最多60
+     */
+    @Excel(name = "程序化组数,最多60", width = 15)
+    @ApiModelProperty(value = "程序化组数,最多60")
+    private Integer programUnitCnt;
+    /**
+     * 素材类型 2-不限,0-内部,1-素造
+     */
+    @Excel(name = "素材类型 2-不限,0-内部,1-素造", width = 15)
+    @ApiModelProperty(value = "素材类型 2-不限,0-内部,1-素造")
+    private Integer channelType;
+    /**
+     * 智能抽帧
+     */
+    @Excel(name = "智能抽帧", width = 15)
+    @ApiModelProperty(value = "智能抽帧")
+    private Integer smartCover;
+    /**
+     * 行动号召
+     */
+    @Excel(name = "行动号召", width = 15)
+    @ApiModelProperty(value = "行动号召")
+    private String actionBarText;
+    /**
+     * 广告语
+     */
+    @Excel(name = "广告语", width = 15)
+    @ApiModelProperty(value = "广告语")
+    private String description;
+
+    private String stickerTitle;
+
+    private String overlayType;
+
+    private String exposeTag;
+
+    private String newExposeTag;
+    /**
+     * 创意分类
+     */
+    @Excel(name = "创意分类", width = 15)
+    @ApiModelProperty(value = "创意分类")
+    private Integer creativeCategory;
+    //安卓下载中间页ID
+    private Integer siteId;
+    /**
+     * 创意标签
+     */
+    @Excel(name = "创意标签", width = 15)
+    @ApiModelProperty(value = "创意标签")
+    private String creativeTag;
+    /**
+     * 创意-第三方点击检测链接
+     */
+    @Excel(name = "创意-第三方点击检测链接", width = 15)
+    @ApiModelProperty(value = "创意-第三方点击检测链接")
+    private String clickTrackUrl;
+    /**
+     * 创意-第三方开始播放监测链接
+     */
+    @Excel(name = "创意-第三方开始播放监测链接", width = 15)
+    @ApiModelProperty(value = "创意-第三方开始播放监测链接")
+    private String impressionUrl;
+    /**
+     * 创意-第三方有效播放监测链接
+     */
+    @Excel(name = "创意-第三方有效播放监测链接", width = 15)
+    @ApiModelProperty(value = "创意-第三方有效播放监测链接")
+    private String adPhotoPlayedT3sUrl;
+    /**
+     * 创意-第三方点击按钮监测链接
+     */
+    @Excel(name = "创意-第三方点击按钮监测链接", width = 15)
+    @ApiModelProperty(value = "创意-第三方点击按钮监测链接")
+    private String actionbarClickUrl;
+    /**
+     * 素材来源 1-上限素材,2-高质量素材,3-遗漏素材,4-历史打捞
+     */
+    @Excel(name = "素材来源 1-上限素材,2-高质量素材,3-遗漏素材,4-历史打捞", width = 15)
+    @ApiModelProperty(value = "素材来源 1-上限素材,2-高质量素材,3-遗漏素材,4-历史打捞")
+    private String sourceMaterial;
+    /**
+     * 定时执行生效时间
+     */
+    @ApiModelProperty(value = "定时执行生效时间")
+    private Date effectiveTime;
+    /**
+     * 定时执行失效时间
+     */
+    @ApiModelProperty(value = "定时执行失效时间")
+    private Date expiryTime;
+    /**
+     * 创建时间
+     */
+    @ApiModelProperty(value = "创建时间")
+    private Date createTime;
+    /**
+     * updateTime
+     */
+    @ApiModelProperty(value = "updateTime")
+    private Date updateTime;
+
+    @TableField(exist = false)
+    private Long accountId;
+}

+ 25 - 0
module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/ai/mapper/KuaishouProjectStrategyMapper.java

@@ -0,0 +1,25 @@
+package cn.com.ctop.kuaishou.modules.ai.mapper;
+
+import cn.com.ctop.kuaishou.modules.ai.entity.KuaishouProjectStrategy;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+import java.util.List;
+
+/**
+ * 自动投放-项目策略表
+ *
+ * @author jeecg-boot
+ * 2021-06-24
+ * @version V1.0
+ */
+public interface KuaishouProjectStrategyMapper extends BaseMapper<KuaishouProjectStrategy> {
+
+    List<JSONObject> queryProjectList(JSONObject data);
+
+    List<JSONObject> queryAccountList(JSONObject data);
+
+    JSONObject queryProjectAll(JSONObject data);
+
+    JSONObject queryAccountAll(JSONObject data);
+}

+ 152 - 0
module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/ai/mapper/xml/KuaishouProjectStrategyMapper.xml

@@ -0,0 +1,152 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="cn.com.ctop.kuaishou.modules.ai.mapper.KuaishouProjectStrategyMapper">
+
+    <select id="queryProjectList" resultType="com.alibaba.fastjson.JSONObject">
+        SELECT t1.*,
+               (SELECT COUNT(1) FROM ctop_user_allocation WHERE account_status = 0 and t1.projectId = project_id) as 'allAccountCount',
+               (SELECT COUNT(1) FROM ctop_user_allocation WHERE account_status = 0 and t1.projectId = project_id and project_strategy = 1) as 'successCount',
+               IFNULL(SUM(t2.charge),0) as 'charge',
+               IFNULL(SUM(t2.photo_show),0) as 'photoShow',
+               IFNULL(SUM(t2.photo_click),0) as 'photoClick',
+               IFNULL(SUM(t2.aclick),0) as 'aclick',
+               IFNULL(SUM(t2.bclick),0) as 'bclick',
+               CONCAT(CAST(IFNULL(ROUND(SUM(t2.photo_click)/SUM(t2.photo_show)*100,2),0)as CHAR),'%') as 'photoClickRatio',
+               CONCAT(CAST(IFNULL(ROUND(SUM(t2.bclick)/SUM(t2.aclick)*100,2),0)as CHAR),'%') as 'actionRatio',
+               IFNULL(ROUND(SUM(t2.charge)/SUM(t2.aclick)*1000,2),0) as 'impression1kCost',
+               IFNULL(ROUND(SUM(t2.charge)/SUM(t2.photo_click),2),0) as 'photoClickCost',
+               IFNULL(ROUND(SUM(t2.charge)/SUM(t2.bclick),2),0) as 'actionCost'
+        FROM
+            (
+                SELECT
+                    k1.id,
+                    k1.data_status as 'dataStatus',
+                    k1.project_id as 'projectId',
+                    k3.project_name as 'projectName',
+                    k3.responsible_name as 'responsibleName',
+                    k1.stat_date as 'statDate',
+                    k2.account_id as 'accountId'
+                FROM ctop_ai_kuaishou_project_strategy k1
+                         LEFT JOIN ctop_user_allocation k2 ON k1.project_id = k2.project_id
+                         LEFT JOIN ctop_project k3 ON k1.project_id = k3.id
+                where k3.media_id=2
+                    <if test="projectName != null ">
+                    and  k3.project_name LIKE CONCAT('%',#{projectName},'%')
+                    </if>
+                    <if test="responsibleName != null ">
+                     and k3.responsible_name = LIKE CONCAT('%',#{responsibleName},'%')
+                    </if>
+            ) t1
+                LEFT JOIN ctop_etl_kuaishou_report_account_daily t2 ON t2.account_id = t1.accountId
+        where t2.stat_date &gt;=#{startTime}
+        and t2.stat_date &lt;=#{endTime}
+        GROUP BY t1.projectId
+        <if test="sortCode != '' and sortCode != null ">
+            ORDER BY ${sortCode} ${sortType}
+        </if>
+
+    </select>
+
+    <select id="queryAccountList" resultType="com.alibaba.fastjson.JSONObject">
+        SELECT
+            IFNULL(t1.auth_name,'') as 'authName',
+            IFNULL(t1.account_id,'') as 'accountId',
+            IFNULL(t1.project_strategy,0) as 'projectStrategy',
+            IFNULL(t3.project_name,'') as 'projectName',
+            IFNULL(SUM(t2.charge),0) as 'charge',
+            IFNULL(SUM(t2.photo_show),0) as 'photoShow',
+            IFNULL(SUM(t2.photo_click),0) as 'photoClick',
+            IFNULL(SUM(t2.aclick),0) as 'aclick',
+            IFNULL(SUM(t2.bclick),0) as 'bclick',
+            CONCAT(CAST(IFNULL(ROUND(SUM(t2.photo_click)/SUM(t2.photo_show)*100,2),0)as CHAR),'%') as 'photoClickRatio',
+            CONCAT(CAST(IFNULL(ROUND(SUM(t2.bclick)/SUM(t2.aclick)*100,2),0)as CHAR),'%') as 'actionRatio',
+            IFNULL(ROUND(SUM(t2.charge)/SUM(t2.aclick)*1000,2),0) as 'impression1kCost',
+            IFNULL(ROUND(SUM(t2.charge)/SUM(t2.photo_click),2),0) as 'photoClickCost',
+            IFNULL(ROUND(SUM(t2.charge)/SUM(t2.bclick),2),0) as 'actionCost'
+        FROM ctop_user_allocation t1
+                 LEFT JOIN ctop_etl_kuaishou_report_account_daily t2 ON t2.account_id = t1.account_id
+                 LEFT JOIN ctop_project t3 ON t1.project_id = t3.id
+        where t2.stat_date &gt;=#{startTime}
+          and t2.stat_date &lt;=#{endTime}
+        <if test="projectId != null ">
+            and t1.project_id = #{projectId}
+        </if>
+          <if test="authName != null ">
+              and  t1.auth_name LIKE CONCAT('%',#{authName},'%')
+        </if>
+        GROUP BY t1.account_id
+        <if test="sortCode != '' and sortCode != null ">
+            ORDER BY ${sortCode} ${sortType}
+        </if>
+    </select>
+
+    <select id="queryAccountAll" resultType="com.alibaba.fastjson.JSONObject">
+        SELECT
+            '-' as 'authName',
+            IFNULL(t1.account_id,'') as 'accountId',
+            IFNULL(t1.project_strategy,0) as 'projectStrategy',
+            '-' as 'projectName',
+            IFNULL(SUM(t2.charge),0) as 'charge',
+            IFNULL(SUM(t2.photo_show),0) as 'photoShow',
+            IFNULL(SUM(t2.photo_click),0) as 'photoClick',
+            IFNULL(SUM(t2.aclick),0) as 'aclick',
+            IFNULL(SUM(t2.bclick),0) as 'bclick',
+            CONCAT(CAST(IFNULL(ROUND(SUM(t2.photo_click)/SUM(t2.photo_show)*100,2),0)as CHAR),'%') as 'photoClickRatio',
+            CONCAT(CAST(IFNULL(ROUND(SUM(t2.bclick)/SUM(t2.aclick)*100,2),0)as CHAR),'%') as 'actionRatio',
+            IFNULL(ROUND(SUM(t2.charge)/SUM(t2.aclick)*1000,2),0) as 'impression1kCost',
+            IFNULL(ROUND(SUM(t2.charge)/SUM(t2.photo_click),2),0) as 'photoClickCost',
+            IFNULL(ROUND(SUM(t2.charge)/SUM(t2.bclick),2),0) as 'actionCost'
+        FROM ctop_user_allocation t1
+                 LEFT JOIN ctop_etl_kuaishou_report_account_daily t2 ON t2.account_id = t1.account_id
+                 LEFT JOIN ctop_project t3 ON t1.project_id = t3.id
+        where t2.stat_date &gt;=#{startTime}
+          and t2.stat_date &lt;=#{endTime}
+        <if test="projectId != null ">
+            and t1.project_id = #{projectId}
+        </if>
+          <if test="authName != null ">
+              and  t1.auth_name LIKE CONCAT('%',#{authName},'%')
+        </if>
+    </select>
+
+    <select id="queryProjectAll" resultType="com.alibaba.fastjson.JSONObject">
+        SELECT
+            '-' as 'authName',
+            IFNULL(t1.account_id,'') as 'accountId',
+            IFNULL(t1.project_strategy,0) as 'projectStrategy',
+            '-' as 'projectName',
+            IFNULL(SUM(t2.charge),0) as 'charge',
+            IFNULL(SUM(t2.photo_show),0) as 'photoShow',
+            IFNULL(SUM(t2.photo_click),0) as 'photoClick',
+            IFNULL(SUM(t2.aclick),0) as 'aclick',
+            IFNULL(SUM(t2.bclick),0) as 'bclick',
+            CONCAT(CAST(IFNULL(ROUND(SUM(t2.photo_click)/SUM(t2.photo_show)*100,2),0)as CHAR),'%') as 'photoClickRatio',
+            CONCAT(CAST(IFNULL(ROUND(SUM(t2.bclick)/SUM(t2.aclick)*100,2),0)as CHAR),'%') as 'actionRatio',
+            IFNULL(ROUND(SUM(t2.charge)/SUM(t2.aclick)*1000,2),0) as 'impression1kCost',
+            IFNULL(ROUND(SUM(t2.charge)/SUM(t2.photo_click),2),0) as 'photoClickCost',
+            IFNULL(ROUND(SUM(t2.charge)/SUM(t2.bclick),2),0) as 'actionCost',
+            (SELECT COUNT(1) FROM ctop_user_allocation where project_strategy = 1 AND account_status = 0
+            <if test="projectId != null ">
+                 AND project_id = t1.project_id
+            </if>
+            ) as 'successCount',
+            (SELECT COUNT(1) FROM ctop_user_allocation where account_status = 0
+        <if test="projectId != null ">
+            AND project_id = t1.project_id
+        </if>
+            ) as 'allAccountCount'
+        FROM ctop_user_allocation t1
+                 LEFT JOIN ctop_etl_kuaishou_report_account_daily t2 ON t2.account_id = t1.account_id
+                 LEFT JOIN ctop_project t3 ON t1.project_id = t3.id
+        where t2.stat_date &gt;=#{startTime}
+          and t2.stat_date &lt;=#{endTime}
+        <if test="projectId != null ">
+            and t1.project_id = #{projectId}
+        </if>
+          <if test="authName != null ">
+              and  t1.auth_name LIKE CONCAT('%',#{authName},'%')
+        </if>
+    </select>
+
+
+</mapper>

+ 16 - 0
module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/ai/service/IAiKuaishouProjectCreateCreativeService.java

@@ -0,0 +1,16 @@
+package cn.com.ctop.kuaishou.modules.ai.service;
+
+import cn.com.ctop.kuaishou.modules.ai.entity.KuaishouProjectStrategy;
+
+public interface IAiKuaishouProjectCreateCreativeService {
+
+    void projectAutomaticCreates(KuaishouProjectStrategy strategy);
+
+    void customCreativeSupplement(KuaishouProjectStrategy strategy, Integer hour);
+
+    void customCreativeLimit(KuaishouProjectStrategy strategy);
+
+    // 组创建是否超限
+    Boolean getUnitOverrun(String keyx);
+
+}

+ 22 - 0
module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/ai/service/IKuaishouProjectStrategyService.java

@@ -0,0 +1,22 @@
+package cn.com.ctop.kuaishou.modules.ai.service;
+
+import cn.com.ctop.kuaishou.modules.ai.entity.KuaishouProjectStrategy;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.jeecg.common.api.vo.Result;
+
+/**
+ * 自动投放-项目策略表
+ *
+ * @author jeecg-boot
+ * 2021-06-24
+ * @version V1.0
+ */
+public interface IKuaishouProjectStrategyService extends IService<KuaishouProjectStrategy> {
+
+    Result<Object> queryProjectList(JSONObject data, Integer pageNo, Integer pageSize);
+
+    Result<Object> queryAccountList(JSONObject data);
+
+    Result<Object> queryMatchResult(String id);
+}

File diff ditekan karena terlalu besar
+ 1351 - 0
module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/ai/service/impl/AiKuaishouProjectCreateCreativeServiceImpl.java


+ 58 - 0
module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/ai/service/impl/KuaishouProjectStrategyServiceImpl.java

@@ -0,0 +1,58 @@
+package cn.com.ctop.kuaishou.modules.ai.service.impl;
+
+import cn.com.ctop.common.module.utils.Check;
+import cn.com.ctop.kuaishou.modules.ai.entity.KuaishouProjectStrategy;
+import cn.com.ctop.kuaishou.modules.ai.mapper.KuaishouProjectStrategyMapper;
+import cn.com.ctop.kuaishou.modules.ai.service.IKuaishouProjectStrategyService;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.github.pagehelper.PageHelper;
+import com.github.pagehelper.PageInfo;
+import org.jeecg.common.api.vo.Result;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * 自动投放-项目策略表
+ *
+ * @author jeecg-boot
+ * 2021-06-24
+ * @version V1.0
+ */
+@Service
+public class KuaishouProjectStrategyServiceImpl extends ServiceImpl<KuaishouProjectStrategyMapper, KuaishouProjectStrategy> implements IKuaishouProjectStrategyService {
+
+    @Autowired
+    private KuaishouProjectStrategyMapper kuaishouProjectStrategyMapper;
+
+    @Override
+    public Result<Object> queryProjectList(JSONObject data, Integer pageNo, Integer pageSize) {
+        JSONObject result = new JSONObject();
+        JSONObject allInfo =  kuaishouProjectStrategyMapper.queryProjectAll(data);
+        PageHelper.startPage(pageNo, pageSize);
+        List<JSONObject> list = kuaishouProjectStrategyMapper.queryProjectList(data);
+        result.put("total",allInfo);
+        result.put("pageInfo",new PageInfo<>(list));
+        return Result.ok(result);
+    }
+
+    @Override
+    public Result<Object> queryAccountList(JSONObject data) {
+        JSONObject result = new JSONObject();
+        JSONObject allInfo =  kuaishouProjectStrategyMapper.queryAccountAll(data);
+        Integer pageNo = Check.isNull(data.getInteger("pageNo")) ? 1 : data.getInteger("pageNo");
+        Integer pageSize = Check.isNull(data.getInteger("pageSize")) ? 10 : data.getInteger("pageSize");
+        PageHelper.startPage(pageNo, pageSize);
+        List<JSONObject> list = kuaishouProjectStrategyMapper.queryAccountList(data);
+        result.put("total",allInfo);
+        result.put("pageInfo",new PageInfo<>(list));
+        return Result.ok(result);
+    }
+
+    @Override
+    public Result<Object> queryMatchResult(String id) {
+        return null;
+    }
+}