瀏覽代碼

添加广告计划模板

syh 5 年之前
父節點
當前提交
415900bc1b
共有 34 個文件被更改,包括 3271 次插入9 次删除
  1. 2 0
      jeecg-boot-module-system/src/main/java/org/jeecg/config/ShiroConfig.java
  2. 253 0
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/controller/ByteDanceCreativeTemplateController.java
  3. 41 9
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/controller/ByteDanceTemplateController.java
  4. 253 0
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/controller/BytedanceAdvertisePlanTemplateController.java
  5. 253 0
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/controller/FileInfoController.java
  6. 156 0
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/entity/ByteDanceCreativeTemplate.java
  7. 114 0
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/entity/BytedanceAdvertisePlanTemplate.java
  8. 77 0
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/entity/FileInfo.java
  9. 17 0
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/mapper/ByteDanceCreativeTemplateMapper.java
  10. 17 0
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/mapper/BytedanceAdvertisePlanTemplateMapper.java
  11. 17 0
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/mapper/FileInfoMapper.java
  12. 5 0
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/mapper/xml/ByteDanceCreativeTemplateMapper.xml
  13. 5 0
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/mapper/xml/BytedanceAdvertisePlanTemplateMapper.xml
  14. 5 0
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/mapper/xml/FileInfoMapper.xml
  15. 14 0
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/service/IByteDanceCreativeTemplateService.java
  16. 10 0
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/service/IByteDanceUserOrientationTemplateService.java
  17. 17 0
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/service/IBytedanceAdvertisePlanTemplateService.java
  18. 14 0
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/service/IFileInfoService.java
  19. 19 0
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/service/impl/ByteDanceCreativeTemplateServiceImpl.java
  20. 49 0
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/service/impl/ByteDanceUserOrientationTemplateServiceImpl.java
  21. 45 0
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/service/impl/BytedanceAdvertisePlanTemplateServiceImpl.java
  22. 19 0
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/service/impl/FileInfoServiceImpl.java
  23. 258 0
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/vue/ByteDanceCreativeTemplateList.vue
  24. 224 0
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/vue/BytedanceAdvertisePlanTemplateList.vue
  25. 173 0
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/vue/FileInfoList.vue
  26. 226 0
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/vue/modules/ByteDanceCreativeTemplateModal.vue
  27. 233 0
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/vue/modules/ByteDanceCreativeTemplateModal__Style#Drawer.vue
  28. 182 0
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/vue/modules/BytedanceAdvertisePlanTemplateModal.vue
  29. 189 0
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/vue/modules/BytedanceAdvertisePlanTemplateModal__Style#Drawer.vue
  30. 137 0
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/vue/modules/FileInfoModal.vue
  31. 144 0
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/vue/modules/FileInfoModal__Style#Drawer.vue
  32. 30 0
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/fileupload/controller/UploadController.java
  33. 12 0
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/fileupload/service/IUploadService.java
  34. 61 0
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/fileupload/service/impl/UploadServiceImpl.java

+ 2 - 0
jeecg-boot-module-system/src/main/java/org/jeecg/config/ShiroConfig.java

@@ -92,6 +92,8 @@ public class ShiroConfig {
 		filterChainDefinitionMap.put("/toutiao/dictitem/list", "anon");
 		filterChainDefinitionMap.put("/toutiao/advertiser/**", "anon");
         filterChainDefinitionMap.put("/template/**", "user");
+		//文件上传接口
+		filterChainDefinitionMap.put("/upload/**", "anon");
 
 		//爬虫接口
 		filterChainDefinitionMap.put("/graphql/video", "anon");

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

@@ -0,0 +1,253 @@
+package org.jeecg.modules.ctop.controller;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.common.system.query.QueryGenerator;
+import org.jeecg.common.aspect.annotation.AutoLog;
+import org.jeecg.common.util.oConvertUtils;
+import org.jeecg.modules.ctop.entity.ByteDanceCreativeTemplate;
+import org.jeecg.modules.ctop.service.IByteDanceCreativeTemplateService;
+
+import java.util.Date;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import lombok.extern.slf4j.Slf4j;
+
+import org.jeecgframework.poi.excel.ExcelImportUtil;
+import org.jeecgframework.poi.excel.def.NormalExcelConstants;
+import org.jeecgframework.poi.excel.entity.ExportParams;
+import org.jeecgframework.poi.excel.entity.ImportParams;
+import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.multipart.MultipartHttpServletRequest;
+import org.springframework.web.servlet.ModelAndView;
+import com.alibaba.fastjson.JSON;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+
+/**
+ * @Description: 广告创意模板
+ * @Author: jeecg-boot
+ * @Date: 2019-07-29
+ * @Version: V1.0
+ */
+@Slf4j
+@Api(tags = "广告创意模板")
+@RestController
+@RequestMapping("/ctop/byteDanceCreativeTemplate")
+public class ByteDanceCreativeTemplateController {
+    @Autowired
+    private IByteDanceCreativeTemplateService byteDanceCreativeTemplateService;
+
+    /**
+     * 分页列表查询
+     *
+     * @param byteDanceCreativeTemplate
+     * @param pageNo
+     * @param pageSize
+     * @param req
+     * @return
+     */
+    @AutoLog(value = "广告创意模板-分页列表查询")
+    @ApiOperation(value = "广告创意模板-分页列表查询", notes = "广告创意模板-分页列表查询")
+    @GetMapping(value = "/list")
+    public Result<IPage<ByteDanceCreativeTemplate>> queryPageList(ByteDanceCreativeTemplate byteDanceCreativeTemplate,
+                                                                  @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
+                                                                  @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
+                                                                  HttpServletRequest req) {
+        Result<IPage<ByteDanceCreativeTemplate>> result = new Result<IPage<ByteDanceCreativeTemplate>>();
+        QueryWrapper<ByteDanceCreativeTemplate> queryWrapper = QueryGenerator.initQueryWrapper(byteDanceCreativeTemplate, req.getParameterMap());
+        Page<ByteDanceCreativeTemplate> page = new Page<ByteDanceCreativeTemplate>(pageNo, pageSize);
+        IPage<ByteDanceCreativeTemplate> pageList = byteDanceCreativeTemplateService.page(page, queryWrapper);
+        result.setSuccess(true);
+        result.setResult(pageList);
+        return result;
+    }
+
+    /**
+     * 添加
+     *
+     * @param byteDanceCreativeTemplate
+     * @return
+     */
+    @AutoLog(value = "广告创意模板-添加")
+    @ApiOperation(value = "广告创意模板-添加", notes = "广告创意模板-添加")
+    @PostMapping(value = "/add")
+    public Result<ByteDanceCreativeTemplate> add(@RequestBody ByteDanceCreativeTemplate byteDanceCreativeTemplate) {
+        Result<ByteDanceCreativeTemplate> result = new Result<ByteDanceCreativeTemplate>();
+        try {
+            byteDanceCreativeTemplateService.save(byteDanceCreativeTemplate);
+            result.success("添加成功!");
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+            result.error500("操作失败");
+        }
+        return result;
+    }
+
+    /**
+     * 编辑
+     *
+     * @param byteDanceCreativeTemplate
+     * @return
+     */
+    @AutoLog(value = "广告创意模板-编辑")
+    @ApiOperation(value = "广告创意模板-编辑", notes = "广告创意模板-编辑")
+    @PutMapping(value = "/edit")
+    public Result<ByteDanceCreativeTemplate> edit(@RequestBody ByteDanceCreativeTemplate byteDanceCreativeTemplate) {
+        Result<ByteDanceCreativeTemplate> result = new Result<ByteDanceCreativeTemplate>();
+        ByteDanceCreativeTemplate byteDanceCreativeTemplateEntity = byteDanceCreativeTemplateService.getById(byteDanceCreativeTemplate.getId());
+        if (byteDanceCreativeTemplateEntity == null) {
+            result.error500("未找到对应实体");
+        } else {
+            boolean ok = byteDanceCreativeTemplateService.updateById(byteDanceCreativeTemplate);
+            //TODO 返回false说明什么?
+            if (ok) {
+                result.success("修改成功!");
+            }
+        }
+
+        return result;
+    }
+
+    /**
+     * 通过id删除
+     *
+     * @param id
+     * @return
+     */
+    @AutoLog(value = "广告创意模板-通过id删除")
+    @ApiOperation(value = "广告创意模板-通过id删除", notes = "广告创意模板-通过id删除")
+    @DeleteMapping(value = "/delete")
+    public Result<?> delete(@RequestParam(name = "id", required = true) String id) {
+        try {
+            byteDanceCreativeTemplateService.removeById(id);
+        } catch (Exception e) {
+            log.error("删除失败", e.getMessage());
+            return Result.error("删除失败!");
+        }
+        return Result.ok("删除成功!");
+    }
+
+    /**
+     * 批量删除
+     *
+     * @param ids
+     * @return
+     */
+    @AutoLog(value = "广告创意模板-批量删除")
+    @ApiOperation(value = "广告创意模板-批量删除", notes = "广告创意模板-批量删除")
+    @DeleteMapping(value = "/deleteBatch")
+    public Result<ByteDanceCreativeTemplate> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
+        Result<ByteDanceCreativeTemplate> result = new Result<ByteDanceCreativeTemplate>();
+        if (ids == null || "".equals(ids.trim())) {
+            result.error500("参数不识别!");
+        } else {
+            this.byteDanceCreativeTemplateService.removeByIds(Arrays.asList(ids.split(",")));
+            result.success("删除成功!");
+        }
+        return result;
+    }
+
+    /**
+     * 通过id查询
+     *
+     * @param id
+     * @return
+     */
+    @AutoLog(value = "广告创意模板-通过id查询")
+    @ApiOperation(value = "广告创意模板-通过id查询", notes = "广告创意模板-通过id查询")
+    @GetMapping(value = "/queryById")
+    public Result<ByteDanceCreativeTemplate> queryById(@RequestParam(name = "id", required = true) String id) {
+        Result<ByteDanceCreativeTemplate> result = new Result<ByteDanceCreativeTemplate>();
+        ByteDanceCreativeTemplate byteDanceCreativeTemplate = byteDanceCreativeTemplateService.getById(id);
+        if (byteDanceCreativeTemplate == null) {
+            result.error500("未找到对应实体");
+        } else {
+            result.setResult(byteDanceCreativeTemplate);
+            result.setSuccess(true);
+        }
+        return result;
+    }
+
+    /**
+     * 导出excel
+     *
+     * @param request
+     * @param response
+     */
+    @RequestMapping(value = "/exportXls")
+    public ModelAndView exportXls(HttpServletRequest request, HttpServletResponse response) {
+        // Step.1 组装查询条件
+        QueryWrapper<ByteDanceCreativeTemplate> queryWrapper = null;
+        try {
+            String paramsStr = request.getParameter("paramsStr");
+            if (oConvertUtils.isNotEmpty(paramsStr)) {
+                String deString = URLDecoder.decode(paramsStr, "UTF-8");
+                ByteDanceCreativeTemplate byteDanceCreativeTemplate = JSON.parseObject(deString, ByteDanceCreativeTemplate.class);
+                queryWrapper = QueryGenerator.initQueryWrapper(byteDanceCreativeTemplate, request.getParameterMap());
+            }
+        } catch (UnsupportedEncodingException e) {
+            e.printStackTrace();
+        }
+
+        //Step.2 AutoPoi 导出Excel
+        ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
+        List<ByteDanceCreativeTemplate> pageList = byteDanceCreativeTemplateService.list(queryWrapper);
+        //导出文件名称
+        mv.addObject(NormalExcelConstants.FILE_NAME, "广告创意模板列表");
+        mv.addObject(NormalExcelConstants.CLASS, ByteDanceCreativeTemplate.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<ByteDanceCreativeTemplate> listByteDanceCreativeTemplates = ExcelImportUtil.importExcel(file.getInputStream(), ByteDanceCreativeTemplate.class, params);
+                byteDanceCreativeTemplateService.saveBatch(listByteDanceCreativeTemplates);
+                return Result.ok("文件导入成功!数据行数:" + listByteDanceCreativeTemplates.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("文件导入失败!");
+    }
+
+}

+ 41 - 9
jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/controller/ByteDanceTemplateController.java

@@ -7,14 +7,8 @@ import org.apache.shiro.SecurityUtils;
 import org.jeecg.common.api.vo.Result;
 import org.jeecg.common.system.query.QueryGenerator;
 import org.jeecg.common.system.vo.LoginUser;
-import org.jeecg.modules.ctop.entity.ByteDanceBudgetTemplate;
-import org.jeecg.modules.ctop.entity.ByteDanceCampaignTemplate;
-import org.jeecg.modules.ctop.entity.BytedanceDeliveryTargetTemplate;
-import org.jeecg.modules.ctop.entity.CTopOauthToken;
-import org.jeecg.modules.ctop.service.IByteDanceBudgetTemplateService;
-import org.jeecg.modules.ctop.service.IByteDanceCampaignTemplateService;
-import org.jeecg.modules.ctop.service.IBytedanceDeliveryTargetTemplateService;
-import org.jeecg.modules.ctop.service.ICTopOauthTokenService;
+import org.jeecg.modules.ctop.entity.*;
+import org.jeecg.modules.ctop.service.*;
 import org.jeecg.modules.system.entity.SysDictItem;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
@@ -62,6 +56,42 @@ public class ByteDanceTemplateController {
     }
 
     /**
+     * 用户定向
+     *
+     * @param template
+     * @param req
+     * @return
+     */
+    @PostMapping("userorentation/insert")
+    public Map<String, Object> userOrentationTemplateInsert(@RequestBody ByteDanceUserOrientationTemplate template, HttpServletRequest req) {
+        return orientationTemplateService.insertTemplate(template);
+    }
+
+    /**
+     * 用户定向
+     *
+     * @param template
+     * @param req
+     * @return
+     */
+    @PostMapping("advertiserplan/insert")
+    public Map<String, Object> advertiserplanTemplateInsert(@RequestBody BytedanceAdvertisePlanTemplate template, HttpServletRequest req) {
+        return advertisePlanTemplateService.insertTemplate(template);
+    }
+
+    /**
+     * 预算与出价模板
+     *
+     * @param template
+     * @param req
+     * @return
+     */
+    @PostMapping("userorentation/list")
+    public Result<IPage<ByteDanceUserOrientationTemplate>> userOrentationTemplateList(ByteDanceUserOrientationTemplate template, @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo, @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize, HttpServletRequest req) {
+        return orientationTemplateService.getList(template, pageNo, pageSize, req);
+    }
+
+    /**
      * 预算与出价模板
      *
      * @param template
@@ -96,12 +126,14 @@ public class ByteDanceTemplateController {
     }
 
     @Autowired
+    private IByteDanceUserOrientationTemplateService orientationTemplateService;
+    @Autowired
     private IByteDanceCampaignTemplateService campaignTemplateService;
     @Autowired
     private IByteDanceBudgetTemplateService budgetTemplateService;
     @Autowired
     private IBytedanceDeliveryTargetTemplateService deliveryTargetTemplateService;
     @Autowired
-    private ICTopOauthTokenService tokenService;
+    private IBytedanceAdvertisePlanTemplateService advertisePlanTemplateService;
 
 }

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

@@ -0,0 +1,253 @@
+package org.jeecg.modules.ctop.controller;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.common.system.query.QueryGenerator;
+import org.jeecg.common.aspect.annotation.AutoLog;
+import org.jeecg.common.util.oConvertUtils;
+import org.jeecg.modules.ctop.entity.BytedanceAdvertisePlanTemplate;
+import org.jeecg.modules.ctop.service.IBytedanceAdvertisePlanTemplateService;
+
+import java.util.Date;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import lombok.extern.slf4j.Slf4j;
+
+import org.jeecgframework.poi.excel.ExcelImportUtil;
+import org.jeecgframework.poi.excel.def.NormalExcelConstants;
+import org.jeecgframework.poi.excel.entity.ExportParams;
+import org.jeecgframework.poi.excel.entity.ImportParams;
+import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.multipart.MultipartHttpServletRequest;
+import org.springframework.web.servlet.ModelAndView;
+import com.alibaba.fastjson.JSON;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+
+/**
+ * @Description: 广告计划模板信息
+ * @Author: jeecg-boot
+ * @Date: 2019-07-28
+ * @Version: V1.0
+ */
+@Slf4j
+@Api(tags = "广告计划模板信息")
+@RestController
+@RequestMapping("/ctop/bytedanceAdvertisePlanTemplate")
+public class BytedanceAdvertisePlanTemplateController {
+    @Autowired
+    private IBytedanceAdvertisePlanTemplateService bytedanceAdvertisePlanTemplateService;
+
+    /**
+     * 分页列表查询
+     *
+     * @param bytedanceAdvertisePlanTemplate
+     * @param pageNo
+     * @param pageSize
+     * @param req
+     * @return
+     */
+    @AutoLog(value = "广告计划模板信息-分页列表查询")
+    @ApiOperation(value = "广告计划模板信息-分页列表查询", notes = "广告计划模板信息-分页列表查询")
+    @GetMapping(value = "/list")
+    public Result<IPage<BytedanceAdvertisePlanTemplate>> queryPageList(BytedanceAdvertisePlanTemplate bytedanceAdvertisePlanTemplate,
+                                                                       @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
+                                                                       @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
+                                                                       HttpServletRequest req) {
+        Result<IPage<BytedanceAdvertisePlanTemplate>> result = new Result<IPage<BytedanceAdvertisePlanTemplate>>();
+        QueryWrapper<BytedanceAdvertisePlanTemplate> queryWrapper = QueryGenerator.initQueryWrapper(bytedanceAdvertisePlanTemplate, req.getParameterMap());
+        Page<BytedanceAdvertisePlanTemplate> page = new Page<BytedanceAdvertisePlanTemplate>(pageNo, pageSize);
+        IPage<BytedanceAdvertisePlanTemplate> pageList = bytedanceAdvertisePlanTemplateService.page(page, queryWrapper);
+        result.setSuccess(true);
+        result.setResult(pageList);
+        return result;
+    }
+
+    /**
+     * 添加
+     *
+     * @param bytedanceAdvertisePlanTemplate
+     * @return
+     */
+    @AutoLog(value = "广告计划模板信息-添加")
+    @ApiOperation(value = "广告计划模板信息-添加", notes = "广告计划模板信息-添加")
+    @PostMapping(value = "/add")
+    public Result<BytedanceAdvertisePlanTemplate> add(@RequestBody BytedanceAdvertisePlanTemplate bytedanceAdvertisePlanTemplate) {
+        Result<BytedanceAdvertisePlanTemplate> result = new Result<BytedanceAdvertisePlanTemplate>();
+        try {
+            bytedanceAdvertisePlanTemplateService.save(bytedanceAdvertisePlanTemplate);
+            result.success("添加成功!");
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+            result.error500("操作失败");
+        }
+        return result;
+    }
+
+    /**
+     * 编辑
+     *
+     * @param bytedanceAdvertisePlanTemplate
+     * @return
+     */
+    @AutoLog(value = "广告计划模板信息-编辑")
+    @ApiOperation(value = "广告计划模板信息-编辑", notes = "广告计划模板信息-编辑")
+    @PutMapping(value = "/edit")
+    public Result<BytedanceAdvertisePlanTemplate> edit(@RequestBody BytedanceAdvertisePlanTemplate bytedanceAdvertisePlanTemplate) {
+        Result<BytedanceAdvertisePlanTemplate> result = new Result<BytedanceAdvertisePlanTemplate>();
+        BytedanceAdvertisePlanTemplate bytedanceAdvertisePlanTemplateEntity = bytedanceAdvertisePlanTemplateService.getById(bytedanceAdvertisePlanTemplate.getId());
+        if (bytedanceAdvertisePlanTemplateEntity == null) {
+            result.error500("未找到对应实体");
+        } else {
+            boolean ok = bytedanceAdvertisePlanTemplateService.updateById(bytedanceAdvertisePlanTemplate);
+            //TODO 返回false说明什么?
+            if (ok) {
+                result.success("修改成功!");
+            }
+        }
+
+        return result;
+    }
+
+    /**
+     * 通过id删除
+     *
+     * @param id
+     * @return
+     */
+    @AutoLog(value = "广告计划模板信息-通过id删除")
+    @ApiOperation(value = "广告计划模板信息-通过id删除", notes = "广告计划模板信息-通过id删除")
+    @DeleteMapping(value = "/delete")
+    public Result<?> delete(@RequestParam(name = "id", required = true) String id) {
+        try {
+            bytedanceAdvertisePlanTemplateService.removeById(id);
+        } catch (Exception e) {
+            log.error("删除失败", e.getMessage());
+            return Result.error("删除失败!");
+        }
+        return Result.ok("删除成功!");
+    }
+
+    /**
+     * 批量删除
+     *
+     * @param ids
+     * @return
+     */
+    @AutoLog(value = "广告计划模板信息-批量删除")
+    @ApiOperation(value = "广告计划模板信息-批量删除", notes = "广告计划模板信息-批量删除")
+    @DeleteMapping(value = "/deleteBatch")
+    public Result<BytedanceAdvertisePlanTemplate> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
+        Result<BytedanceAdvertisePlanTemplate> result = new Result<BytedanceAdvertisePlanTemplate>();
+        if (ids == null || "".equals(ids.trim())) {
+            result.error500("参数不识别!");
+        } else {
+            this.bytedanceAdvertisePlanTemplateService.removeByIds(Arrays.asList(ids.split(",")));
+            result.success("删除成功!");
+        }
+        return result;
+    }
+
+    /**
+     * 通过id查询
+     *
+     * @param id
+     * @return
+     */
+    @AutoLog(value = "广告计划模板信息-通过id查询")
+    @ApiOperation(value = "广告计划模板信息-通过id查询", notes = "广告计划模板信息-通过id查询")
+    @GetMapping(value = "/queryById")
+    public Result<BytedanceAdvertisePlanTemplate> queryById(@RequestParam(name = "id", required = true) String id) {
+        Result<BytedanceAdvertisePlanTemplate> result = new Result<BytedanceAdvertisePlanTemplate>();
+        BytedanceAdvertisePlanTemplate bytedanceAdvertisePlanTemplate = bytedanceAdvertisePlanTemplateService.getById(id);
+        if (bytedanceAdvertisePlanTemplate == null) {
+            result.error500("未找到对应实体");
+        } else {
+            result.setResult(bytedanceAdvertisePlanTemplate);
+            result.setSuccess(true);
+        }
+        return result;
+    }
+
+    /**
+     * 导出excel
+     *
+     * @param request
+     * @param response
+     */
+    @RequestMapping(value = "/exportXls")
+    public ModelAndView exportXls(HttpServletRequest request, HttpServletResponse response) {
+        // Step.1 组装查询条件
+        QueryWrapper<BytedanceAdvertisePlanTemplate> queryWrapper = null;
+        try {
+            String paramsStr = request.getParameter("paramsStr");
+            if (oConvertUtils.isNotEmpty(paramsStr)) {
+                String deString = URLDecoder.decode(paramsStr, "UTF-8");
+                BytedanceAdvertisePlanTemplate bytedanceAdvertisePlanTemplate = JSON.parseObject(deString, BytedanceAdvertisePlanTemplate.class);
+                queryWrapper = QueryGenerator.initQueryWrapper(bytedanceAdvertisePlanTemplate, request.getParameterMap());
+            }
+        } catch (UnsupportedEncodingException e) {
+            e.printStackTrace();
+        }
+
+        //Step.2 AutoPoi 导出Excel
+        ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
+        List<BytedanceAdvertisePlanTemplate> pageList = bytedanceAdvertisePlanTemplateService.list(queryWrapper);
+        //导出文件名称
+        mv.addObject(NormalExcelConstants.FILE_NAME, "广告计划模板信息列表");
+        mv.addObject(NormalExcelConstants.CLASS, BytedanceAdvertisePlanTemplate.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<BytedanceAdvertisePlanTemplate> listBytedanceAdvertisePlanTemplates = ExcelImportUtil.importExcel(file.getInputStream(), BytedanceAdvertisePlanTemplate.class, params);
+                bytedanceAdvertisePlanTemplateService.saveBatch(listBytedanceAdvertisePlanTemplates);
+                return Result.ok("文件导入成功!数据行数:" + listBytedanceAdvertisePlanTemplates.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("文件导入失败!");
+    }
+
+}

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

@@ -0,0 +1,253 @@
+package org.jeecg.modules.ctop.controller;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.common.system.query.QueryGenerator;
+import org.jeecg.common.aspect.annotation.AutoLog;
+import org.jeecg.common.util.oConvertUtils;
+import org.jeecg.modules.ctop.entity.FileInfo;
+import org.jeecg.modules.ctop.service.IFileInfoService;
+
+import java.util.Date;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import lombok.extern.slf4j.Slf4j;
+
+import org.jeecgframework.poi.excel.ExcelImportUtil;
+import org.jeecgframework.poi.excel.def.NormalExcelConstants;
+import org.jeecgframework.poi.excel.entity.ExportParams;
+import org.jeecgframework.poi.excel.entity.ImportParams;
+import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.multipart.MultipartHttpServletRequest;
+import org.springframework.web.servlet.ModelAndView;
+import com.alibaba.fastjson.JSON;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+
+/**
+ * @Description: 文件信息
+ * @Author: jeecg-boot
+ * @Date: 2019-07-28
+ * @Version: V1.0
+ */
+@Slf4j
+@Api(tags = "文件信息")
+@RestController
+@RequestMapping("/ctop/fileInfo")
+public class FileInfoController {
+    @Autowired
+    private IFileInfoService fileInfoService;
+
+    /**
+     * 分页列表查询
+     *
+     * @param fileInfo
+     * @param pageNo
+     * @param pageSize
+     * @param req
+     * @return
+     */
+    @AutoLog(value = "文件信息-分页列表查询")
+    @ApiOperation(value = "文件信息-分页列表查询", notes = "文件信息-分页列表查询")
+    @GetMapping(value = "/list")
+    public Result<IPage<FileInfo>> queryPageList(FileInfo fileInfo,
+                                                 @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
+                                                 @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
+                                                 HttpServletRequest req) {
+        Result<IPage<FileInfo>> result = new Result<IPage<FileInfo>>();
+        QueryWrapper<FileInfo> queryWrapper = QueryGenerator.initQueryWrapper(fileInfo, req.getParameterMap());
+        Page<FileInfo> page = new Page<FileInfo>(pageNo, pageSize);
+        IPage<FileInfo> pageList = fileInfoService.page(page, queryWrapper);
+        result.setSuccess(true);
+        result.setResult(pageList);
+        return result;
+    }
+
+    /**
+     * 添加
+     *
+     * @param fileInfo
+     * @return
+     */
+    @AutoLog(value = "文件信息-添加")
+    @ApiOperation(value = "文件信息-添加", notes = "文件信息-添加")
+    @PostMapping(value = "/add")
+    public Result<FileInfo> add(@RequestBody FileInfo fileInfo) {
+        Result<FileInfo> result = new Result<FileInfo>();
+        try {
+            fileInfoService.save(fileInfo);
+            result.success("添加成功!");
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+            result.error500("操作失败");
+        }
+        return result;
+    }
+
+    /**
+     * 编辑
+     *
+     * @param fileInfo
+     * @return
+     */
+    @AutoLog(value = "文件信息-编辑")
+    @ApiOperation(value = "文件信息-编辑", notes = "文件信息-编辑")
+    @PutMapping(value = "/edit")
+    public Result<FileInfo> edit(@RequestBody FileInfo fileInfo) {
+        Result<FileInfo> result = new Result<FileInfo>();
+        FileInfo fileInfoEntity = fileInfoService.getById(fileInfo.getId());
+        if (fileInfoEntity == null) {
+            result.error500("未找到对应实体");
+        } else {
+            boolean ok = fileInfoService.updateById(fileInfo);
+            //TODO 返回false说明什么?
+            if (ok) {
+                result.success("修改成功!");
+            }
+        }
+
+        return result;
+    }
+
+    /**
+     * 通过id删除
+     *
+     * @param id
+     * @return
+     */
+    @AutoLog(value = "文件信息-通过id删除")
+    @ApiOperation(value = "文件信息-通过id删除", notes = "文件信息-通过id删除")
+    @DeleteMapping(value = "/delete")
+    public Result<?> delete(@RequestParam(name = "id", required = true) String id) {
+        try {
+            fileInfoService.removeById(id);
+        } catch (Exception e) {
+            log.error("删除失败", e.getMessage());
+            return Result.error("删除失败!");
+        }
+        return Result.ok("删除成功!");
+    }
+
+    /**
+     * 批量删除
+     *
+     * @param ids
+     * @return
+     */
+    @AutoLog(value = "文件信息-批量删除")
+    @ApiOperation(value = "文件信息-批量删除", notes = "文件信息-批量删除")
+    @DeleteMapping(value = "/deleteBatch")
+    public Result<FileInfo> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
+        Result<FileInfo> result = new Result<FileInfo>();
+        if (ids == null || "".equals(ids.trim())) {
+            result.error500("参数不识别!");
+        } else {
+            this.fileInfoService.removeByIds(Arrays.asList(ids.split(",")));
+            result.success("删除成功!");
+        }
+        return result;
+    }
+
+    /**
+     * 通过id查询
+     *
+     * @param id
+     * @return
+     */
+    @AutoLog(value = "文件信息-通过id查询")
+    @ApiOperation(value = "文件信息-通过id查询", notes = "文件信息-通过id查询")
+    @GetMapping(value = "/queryById")
+    public Result<FileInfo> queryById(@RequestParam(name = "id", required = true) String id) {
+        Result<FileInfo> result = new Result<FileInfo>();
+        FileInfo fileInfo = fileInfoService.getById(id);
+        if (fileInfo == null) {
+            result.error500("未找到对应实体");
+        } else {
+            result.setResult(fileInfo);
+            result.setSuccess(true);
+        }
+        return result;
+    }
+
+    /**
+     * 导出excel
+     *
+     * @param request
+     * @param response
+     */
+    @RequestMapping(value = "/exportXls")
+    public ModelAndView exportXls(HttpServletRequest request, HttpServletResponse response) {
+        // Step.1 组装查询条件
+        QueryWrapper<FileInfo> queryWrapper = null;
+        try {
+            String paramsStr = request.getParameter("paramsStr");
+            if (oConvertUtils.isNotEmpty(paramsStr)) {
+                String deString = URLDecoder.decode(paramsStr, "UTF-8");
+                FileInfo fileInfo = JSON.parseObject(deString, FileInfo.class);
+                queryWrapper = QueryGenerator.initQueryWrapper(fileInfo, request.getParameterMap());
+            }
+        } catch (UnsupportedEncodingException e) {
+            e.printStackTrace();
+        }
+
+        //Step.2 AutoPoi 导出Excel
+        ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
+        List<FileInfo> pageList = fileInfoService.list(queryWrapper);
+        //导出文件名称
+        mv.addObject(NormalExcelConstants.FILE_NAME, "文件信息列表");
+        mv.addObject(NormalExcelConstants.CLASS, FileInfo.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<FileInfo> listFileInfos = ExcelImportUtil.importExcel(file.getInputStream(), FileInfo.class, params);
+                fileInfoService.saveBatch(listFileInfos);
+                return Result.ok("文件导入成功!数据行数:" + listFileInfos.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("文件导入失败!");
+    }
+
+}

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

@@ -0,0 +1,156 @@
+package org.jeecg.modules.ctop.entity;
+
+import java.io.Serializable;
+import java.util.Date;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.annotation.TableField;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import org.springframework.format.annotation.DateTimeFormat;
+import org.jeecgframework.poi.excel.annotation.Excel;
+
+/**
+ * @Description: 广告创意模板
+ * @Author: jeecg-boot
+ * @Date: 2019-07-29
+ * @Version: V1.0
+ */
+@Data
+@TableName("ctop_bytedance_creative_template")
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value = "ctop_bytedance_creative_template对象", description = "广告创意模板")
+public class ByteDanceCreativeTemplate {
+
+    /**
+     * id
+     */
+    @TableId(type = IdType.UUID)
+    @ApiModelProperty(value = "id")
+    private Integer id;
+    /**
+     * 用户头条id
+     */
+    @Excel(name = "用户头条id", width = 15)
+    @ApiModelProperty(value = "用户头条id")
+    private String accountId;
+    /**
+     * 广告主id
+     */
+    @Excel(name = "广告主id", width = 15)
+    @ApiModelProperty(value = "广告主id")
+    private Integer advertiserId;
+    /**
+     * 广告计划id
+     */
+    @Excel(name = "广告计划id", width = 15)
+    @ApiModelProperty(value = "广告计划id")
+    private Integer adId;
+    /**
+     * 视频id
+     */
+    @Excel(name = "视频id", width = 15)
+    @ApiModelProperty(value = "视频id")
+    private Integer videoId;
+    /**
+     * 图片id
+     */
+    @Excel(name = "图片id", width = 15)
+    @ApiModelProperty(value = "图片id")
+    private Integer imageId;
+    /**
+     * 创意文案
+     */
+    @Excel(name = "创意文案", width = 15)
+    @ApiModelProperty(value = "创意文案")
+    private String createText;
+    /**
+     * 来源
+     */
+    @Excel(name = "来源", width = 15)
+    @ApiModelProperty(value = "来源")
+    private String source;
+    /**
+     * 图片生成视频
+     */
+    @Excel(name = "图片生成视频", width = 15)
+    @ApiModelProperty(value = "图片生成视频")
+    private String imageToVideo;
+    /**
+     * 最优衍生计划
+     */
+    @Excel(name = "最优衍生计划", width = 15)
+    @ApiModelProperty(value = "最优衍生计划")
+    private String derivativePlan;
+    /**
+     * 是否开启广告评论
+     */
+    @Excel(name = "是否开启广告评论", width = 15)
+    @ApiModelProperty(value = "是否开启广告评论")
+    private String commentOpen;
+    /**
+     * 展现方式
+     */
+    @Excel(name = "展现方式", width = 15)
+    @ApiModelProperty(value = "展现方式")
+    private String presentType;
+    /**
+     * 创意分类
+     */
+    @Excel(name = "创意分类", width = 15)
+    @ApiModelProperty(value = "创意分类")
+    private String creativeCategory;
+    /**
+     * 创意标签
+     */
+    @Excel(name = "创意标签", width = 15)
+    @ApiModelProperty(value = "创意标签")
+    private String createTitle;
+    /**
+     * 第三方监测链接展示
+     */
+    @Excel(name = "第三方监测链接展示", width = 15)
+    @ApiModelProperty(value = "第三方监测链接展示")
+    private String monitorLinkDisplay;
+    /**
+     * 第三方监测链接点击
+     */
+    @Excel(name = "第三方监测链接点击", width = 15)
+    @ApiModelProperty(value = "第三方监测链接点击")
+    private String monitorLinkClick;
+    /**
+     * 第三方监测链接视频播放
+     */
+    @Excel(name = "第三方监测链接视频播放", width = 15)
+    @ApiModelProperty(value = "第三方监测链接视频播放")
+    private String monitorLinkPlay;
+    /**
+     * 第三方监测链接视频播完
+     */
+    @Excel(name = "第三方监测链接视频播完", width = 15)
+    @ApiModelProperty(value = "第三方监测链接视频播完")
+    private String monitorLinkPlayed;
+    /**
+     * status
+     */
+    @Excel(name = "status", width = 15)
+    @ApiModelProperty(value = "status")
+    private Integer status;
+    /**
+     * createTime
+     */
+    @ApiModelProperty(value = "createTime")
+    private Date createTime;
+    /**
+     * updateTime
+     */
+    @ApiModelProperty(value = "updateTime")
+    private Date updateTime;
+}

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

@@ -0,0 +1,114 @@
+package org.jeecg.modules.ctop.entity;
+
+import java.io.Serializable;
+import java.util.Date;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.annotation.TableField;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import org.springframework.format.annotation.DateTimeFormat;
+import org.jeecgframework.poi.excel.annotation.Excel;
+
+/**
+ * @Description: 广告计划模板信息
+ * @Author: jeecg-boot
+ * @Date: 2019-07-28
+ * @Version: V1.0
+ */
+@Data
+@TableName("ctop_bytedance_advertise_plan_template")
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value = "ctop_bytedance_advertise_plan_template对象", description = "广告计划模板信息")
+public class BytedanceAdvertisePlanTemplate {
+
+    /**
+     * id
+     */
+    @TableId(type = IdType.AUTO)
+    @ApiModelProperty(value = "id")
+    private Integer id;
+    /**
+     * 头条账号id
+     */
+    @Excel(name = "头条账号id", width = 15)
+    @ApiModelProperty(value = "头条账号id")
+    private Long accountId;
+    /**
+     * 广告主id
+     */
+    @Excel(name = "广告主id", width = 15)
+    @ApiModelProperty(value = "广告主id")
+    private String advertiserId;
+    /**
+     * 广告组模板id
+     */
+    @Excel(name = "广告组模板id", width = 15)
+    @ApiModelProperty(value = "广告组模板id")
+    private Long campaignTemplateId;
+    /**
+     * 投放范围
+     */
+    @Excel(name = "投放范围", width = 15)
+    @ApiModelProperty(value = "投放范围")
+    private String deliveryRange;
+    /**
+     * 用户定向模板id
+     */
+    @Excel(name = "用户定向模板id", width = 15)
+    @ApiModelProperty(value = "用户定向模板id")
+    private Long userOrentationTemplateId;
+    /**
+     * 预算与出价模板id
+     */
+    @Excel(name = "预算与出价模板id", width = 15)
+    @ApiModelProperty(value = "预算与出价模板id")
+    private Long budgetTemplateId;
+    /**
+     * 投放目标模板id
+     */
+    @Excel(name = "投放目标模板id", width = 15)
+    @ApiModelProperty(value = "投放目标模板id")
+    private Integer deliveryTargetTemplateId;
+    /**
+     * 指定视频id
+     */
+    @Excel(name = "指定视频id", width = 15)
+    @ApiModelProperty(value = "指定视频id")
+    private Integer videoId;
+    /**
+     * 指定封面图id
+     */
+    @Excel(name = "指定封面图id", width = 15)
+    @ApiModelProperty(value = "指定封面图id")
+    private Integer imageId;
+    /**
+     * 创意文案信息
+     */
+    @Excel(name = "创意文案信息", width = 15)
+    @ApiModelProperty(value = "创意文案信息")
+    private String creativeText;
+    /**
+     * 迭代数量
+     */
+    @Excel(name = "迭代数量", width = 15)
+    @ApiModelProperty(value = "迭代数量")
+    private Integer iteratorNum;
+    /**
+     * createTime
+     */
+    @ApiModelProperty(value = "createTime")
+    private Date createTime;
+    /**
+     * updateTime
+     */
+    @ApiModelProperty(value = "updateTime")
+    private Date updateTime;
+}

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

@@ -0,0 +1,77 @@
+package org.jeecg.modules.ctop.entity;
+
+import java.io.Serializable;
+import java.util.Date;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.annotation.TableField;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import org.springframework.format.annotation.DateTimeFormat;
+import org.jeecgframework.poi.excel.annotation.Excel;
+
+/**
+ * @Description: 文件信息
+ * @Author: jeecg-boot
+ * @Date: 2019-07-28
+ * @Version: V1.0
+ */
+@Data
+@TableName("ctop_file_info")
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value = "ctop_file_info对象", description = "文件信息")
+public class FileInfo {
+
+    /**
+     * id
+     */
+    @TableId(type = IdType.AUTO)
+    @ApiModelProperty(value = "id")
+    private Long id;
+    /**
+     * 文件名称
+     */
+    @Excel(name = "文件名称", width = 15)
+    @ApiModelProperty(value = "文件名称")
+    private String fileName;
+    /**
+     * 文件类型
+     */
+    @Excel(name = "文件类型", width = 15)
+    @ApiModelProperty(value = "文件类型")
+    private String type;
+
+    /**
+     * 文件类型
+     */
+    @Excel(name = "所属平台类型", width = 15)
+    @ApiModelProperty(value = "所属平台类型")
+    private String platformType;
+
+    /**
+     * 文件访问路径
+     */
+    @Excel(name = "文件地址", width = 15)
+    @ApiModelProperty(value = "文件地址")
+    private String path;
+    @Excel(name = "文件访问路径", width = 15)
+    @ApiModelProperty(value = "文件访问路径")
+    private String fileUrl;
+    /**
+     * createTime
+     */
+    @ApiModelProperty(value = "createTime")
+    private Date createTime;
+    /**
+     * updateTime
+     */
+    @ApiModelProperty(value = "updateTime")
+    private Date updateTime;
+}

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

@@ -0,0 +1,17 @@
+package org.jeecg.modules.ctop.mapper;
+
+import java.util.List;
+
+import org.apache.ibatis.annotations.Param;
+import org.jeecg.modules.ctop.entity.ByteDanceCreativeTemplate;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * @Description: 广告创意模板
+ * @Author: jeecg-boot
+ * @Date: 2019-07-29
+ * @Version: V1.0
+ */
+public interface ByteDanceCreativeTemplateMapper extends BaseMapper<ByteDanceCreativeTemplate> {
+
+}

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

@@ -0,0 +1,17 @@
+package org.jeecg.modules.ctop.mapper;
+
+import java.util.List;
+
+import org.apache.ibatis.annotations.Param;
+import org.jeecg.modules.ctop.entity.BytedanceAdvertisePlanTemplate;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * @Description: 广告计划模板信息
+ * @Author: jeecg-boot
+ * @Date: 2019-07-28
+ * @Version: V1.0
+ */
+public interface BytedanceAdvertisePlanTemplateMapper extends BaseMapper<BytedanceAdvertisePlanTemplate> {
+
+}

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

@@ -0,0 +1,17 @@
+package org.jeecg.modules.ctop.mapper;
+
+import java.util.List;
+
+import org.apache.ibatis.annotations.Param;
+import org.jeecg.modules.ctop.entity.FileInfo;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * @Description: 文件信息
+ * @Author: jeecg-boot
+ * @Date: 2019-07-28
+ * @Version: V1.0
+ */
+public interface FileInfoMapper extends BaseMapper<FileInfo> {
+
+}

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

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

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

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

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

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

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

@@ -0,0 +1,14 @@
+package org.jeecg.modules.ctop.service;
+
+import org.jeecg.modules.ctop.entity.ByteDanceCreativeTemplate;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ * @Description: 广告创意模板
+ * @Author: jeecg-boot
+ * @Date: 2019-07-29
+ * @Version: V1.0
+ */
+public interface IByteDanceCreativeTemplateService extends IService<ByteDanceCreativeTemplate> {
+
+}

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

@@ -1,7 +1,14 @@
 package org.jeecg.modules.ctop.service;
 
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.modules.ctop.entity.ByteDanceBudgetTemplate;
 import org.jeecg.modules.ctop.entity.ByteDanceUserOrientationTemplate;
 import com.baomidou.mybatisplus.extension.service.IService;
+import org.jeecg.modules.ctop.entity.BytedanceDeliveryTargetTemplate;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.Map;
 
 /**
  * @Description: 今日头条受众模板信息
@@ -11,4 +18,7 @@ import com.baomidou.mybatisplus.extension.service.IService;
  */
 public interface IByteDanceUserOrientationTemplateService extends IService<ByteDanceUserOrientationTemplate> {
 
+    Map<String, Object> insertTemplate(ByteDanceUserOrientationTemplate template);
+
+    Result<IPage<ByteDanceUserOrientationTemplate>> getList(ByteDanceUserOrientationTemplate template, Integer pageNo, Integer pageSize, HttpServletRequest req);
 }

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

@@ -0,0 +1,17 @@
+package org.jeecg.modules.ctop.service;
+
+import org.jeecg.modules.ctop.entity.BytedanceAdvertisePlanTemplate;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+import java.util.Map;
+
+/**
+ * @Description: 广告计划模板信息
+ * @Author: jeecg-boot
+ * @Date: 2019-07-28
+ * @Version: V1.0
+ */
+public interface IBytedanceAdvertisePlanTemplateService extends IService<BytedanceAdvertisePlanTemplate> {
+
+    Map<String, Object> insertTemplate(BytedanceAdvertisePlanTemplate template);
+}

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

@@ -0,0 +1,14 @@
+package org.jeecg.modules.ctop.service;
+
+import org.jeecg.modules.ctop.entity.FileInfo;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ * @Description: 文件信息
+ * @Author: jeecg-boot
+ * @Date: 2019-07-28
+ * @Version: V1.0
+ */
+public interface IFileInfoService extends IService<FileInfo> {
+
+}

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

@@ -0,0 +1,19 @@
+package org.jeecg.modules.ctop.service.impl;
+
+import org.jeecg.modules.ctop.entity.ByteDanceCreativeTemplate;
+import org.jeecg.modules.ctop.mapper.ByteDanceCreativeTemplateMapper;
+import org.jeecg.modules.ctop.service.IByteDanceCreativeTemplateService;
+import org.springframework.stereotype.Service;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+
+/**
+ * @Description: 广告创意模板
+ * @Author: jeecg-boot
+ * @Date: 2019-07-29
+ * @Version: V1.0
+ */
+@Service
+public class ByteDanceCreativeTemplateServiceImpl extends ServiceImpl<ByteDanceCreativeTemplateMapper, ByteDanceCreativeTemplate> implements IByteDanceCreativeTemplateService {
+
+}

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

@@ -1,12 +1,29 @@
 package org.jeecg.modules.ctop.service.impl;
 
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import org.apache.shiro.SecurityUtils;
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.common.system.query.QueryGenerator;
+import org.jeecg.common.system.vo.LoginUser;
+import org.jeecg.modules.ctop.entity.ByteDanceBudgetTemplate;
 import org.jeecg.modules.ctop.entity.ByteDanceUserOrientationTemplate;
+import org.jeecg.modules.ctop.entity.BytedanceDeliveryTargetTemplate;
+import org.jeecg.modules.ctop.entity.CTopOauthToken;
 import org.jeecg.modules.ctop.mapper.ByteDanceUserOrientationTemplateMapper;
+import org.jeecg.modules.ctop.mapper.BytedanceDeliveryTargetTemplateMapper;
 import org.jeecg.modules.ctop.service.IByteDanceUserOrientationTemplateService;
+import org.jeecg.modules.ctop.service.ICTopOauthTokenService;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 
+import javax.servlet.http.HttpServletRequest;
+import java.util.HashMap;
+import java.util.Map;
+
 /**
  * @Description: 今日头条受众模板信息
  * @Author: jeecg-boot
@@ -16,4 +33,36 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 @Service
 public class ByteDanceUserOrientationTemplateServiceImpl extends ServiceImpl<ByteDanceUserOrientationTemplateMapper, ByteDanceUserOrientationTemplate> implements IByteDanceUserOrientationTemplateService {
 
+    @Override
+    public Map<String, Object> insertTemplate(ByteDanceUserOrientationTemplate template) {
+        Map<String, Object> resultMap = new HashMap<>();
+        LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
+        CTopOauthToken token = tokenService.getOAuthTokenByAccountId(user.getId());
+        template.setAccountId(token.getAccountId());
+        template.setAdvertiserId(token.getAdvertiserId());
+        template.setStatus(1);
+        templateMapper.insert(template);
+        resultMap.put("success", true);
+        resultMap.put("message", "投放目标模板保存成功");
+        return resultMap;
+    }
+
+    @Override
+    public Result<IPage<ByteDanceUserOrientationTemplate>> getList(ByteDanceUserOrientationTemplate template, Integer pageNo, Integer pageSize, HttpServletRequest req) {
+        LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
+        CTopOauthToken token = tokenService.getOAuthTokenByAccountId(user.getId());
+        Result<IPage<ByteDanceUserOrientationTemplate>> result = new Result<>();
+        QueryWrapper<ByteDanceUserOrientationTemplate> queryWrapper = QueryGenerator.initQueryWrapper(template, req.getParameterMap());
+        queryWrapper.eq("advertiser_id", token.getAdvertiserId()).orderByDesc("create_time");
+        Page<ByteDanceUserOrientationTemplate> page = new Page<>(pageNo, pageSize);
+        IPage<ByteDanceUserOrientationTemplate> pageList = this.page(page, queryWrapper);
+        result.setSuccess(true);
+        result.setResult(pageList);
+        return result;
+    }
+
+    @Autowired
+    private ICTopOauthTokenService tokenService;
+    @Autowired
+    private ByteDanceUserOrientationTemplateMapper templateMapper;
 }

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

@@ -0,0 +1,45 @@
+package org.jeecg.modules.ctop.service.impl;
+
+import org.apache.shiro.SecurityUtils;
+import org.jeecg.common.system.vo.LoginUser;
+import org.jeecg.modules.ctop.entity.BytedanceAdvertisePlanTemplate;
+import org.jeecg.modules.ctop.entity.CTopOauthToken;
+import org.jeecg.modules.ctop.mapper.BytedanceAdvertisePlanTemplateMapper;
+import org.jeecg.modules.ctop.service.IBytedanceAdvertisePlanTemplateService;
+import org.jeecg.modules.ctop.service.ICTopOauthTokenService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @Description: 广告计划模板信息
+ * @Author: jeecg-boot
+ * @Date: 2019-07-28
+ * @Version: V1.0
+ */
+@Service
+public class BytedanceAdvertisePlanTemplateServiceImpl extends ServiceImpl<BytedanceAdvertisePlanTemplateMapper, BytedanceAdvertisePlanTemplate> implements IBytedanceAdvertisePlanTemplateService {
+
+    @Override
+    public Map<String, Object> insertTemplate(BytedanceAdvertisePlanTemplate template) {
+        Map<String, Object> resultMap = new HashMap<>();
+        LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
+        CTopOauthToken token = tokenService.getOAuthTokenByAccountId(user.getId());
+        template.setAccountId(token.getAccountId());
+        template.setAdvertiserId(token.getAdvertiserId());
+//        template.setStatus(1);
+        templateMapper.insert(template);
+        resultMap.put("success", true);
+        resultMap.put("message", "投放目标模板保存成功");
+        return resultMap;
+    }
+
+    @Autowired
+    private BytedanceAdvertisePlanTemplateMapper templateMapper;
+    @Autowired
+    private ICTopOauthTokenService tokenService;
+}

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

@@ -0,0 +1,19 @@
+package org.jeecg.modules.ctop.service.impl;
+
+import org.jeecg.modules.ctop.entity.FileInfo;
+import org.jeecg.modules.ctop.mapper.FileInfoMapper;
+import org.jeecg.modules.ctop.service.IFileInfoService;
+import org.springframework.stereotype.Service;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+
+/**
+ * @Description: 文件信息
+ * @Author: jeecg-boot
+ * @Date: 2019-07-28
+ * @Version: V1.0
+ */
+@Service
+public class FileInfoServiceImpl extends ServiceImpl<FileInfoMapper, FileInfo> implements IFileInfoService {
+
+}

+ 258 - 0
jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/vue/ByteDanceCreativeTemplateList.vue

@@ -0,0 +1,258 @@
+<template>
+    <a-card :bordered="false">
+
+        <!-- 查询区域 -->
+        <div class="table-page-search-wrapper">
+            <a-form layout="inline">
+                <a-row :gutter="24">
+
+                    <a-col :md="6" :sm="8">
+                        <a-form-item label="用户头条id">
+                            <a-input placeholder="请输入用户头条id" v-model="queryParam.accountId"></a-input>
+                        </a-form-item>
+                    </a-col>
+                    <a-col :md="6" :sm="8">
+                        <a-form-item label="广告主id">
+                            <a-input placeholder="请输入广告主id" v-model="queryParam.advertiserId"></a-input>
+                        </a-form-item>
+                    </a-col>
+                    <template v-if="toggleSearchStatus">
+                        <a-col :md="6" :sm="8">
+                            <a-form-item label="广告计划id">
+                                <a-input placeholder="请输入广告计划id" v-model="queryParam.adId"></a-input>
+                            </a-form-item>
+                        </a-col>
+                        <a-col :md="6" :sm="8">
+                            <a-form-item label="视频id">
+                                <a-input placeholder="请输入视频id" v-model="queryParam.videoId"></a-input>
+                            </a-form-item>
+                        </a-col>
+                        <a-col :md="6" :sm="8">
+                            <a-form-item label="图片id">
+                                <a-input placeholder="请输入图片id" v-model="queryParam.imageId"></a-input>
+                            </a-form-item>
+                        </a-col>
+                    </template>
+                    <a-col :md="6" :sm="8">
+            <span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
+              <a-button type="primary" @click="searchQuery" icon="search">查询</a-button>
+              <a-button type="primary" @click="searchReset" icon="reload" style="margin-left: 8px">重置</a-button>
+              <a @click="handleToggleSearch" style="margin-left: 8px">
+                {{ toggleSearchStatus ? '收起' : '展开' }}
+                <a-icon :type="toggleSearchStatus ? 'up' : 'down'"/>
+              </a>
+            </span>
+                    </a-col>
+
+                </a-row>
+            </a-form>
+        </div>
+
+        <!-- 操作按钮区域 -->
+        <div class="table-operator">
+            <a-button @click="handleAdd" type="primary" icon="plus">新增</a-button>
+            <a-button type="primary" icon="download" @click="handleExportXls('广告创意模板')">导出</a-button>
+            <a-upload name="file" :showUploadList="false" :multiple="false" :headers="tokenHeader"
+                      :action="importExcelUrl" @change="handleImportExcel">
+                <a-button type="primary" icon="import">导入</a-button>
+            </a-upload>
+            <a-dropdown v-if="selectedRowKeys.length > 0">
+                <a-menu slot="overlay">
+                    <a-menu-item key="1" @click="batchDel">
+                        <a-icon type="delete"/>
+                        删除
+                    </a-menu-item>
+                </a-menu>
+                <a-button style="margin-left: 8px"> 批量操作
+                    <a-icon type="down"/>
+                </a-button>
+            </a-dropdown>
+        </div>
+
+        <!-- table区域-begin -->
+        <div>
+            <div class="ant-alert ant-alert-info" style="margin-bottom: 16px;">
+                <i class="anticon anticon-info-circle ant-alert-icon"></i> 已选择 <a style="font-weight: 600">{{
+                selectedRowKeys.length }}</a>项
+                <a style="margin-left: 24px" @click="onClearSelected">清空</a>
+            </div>
+
+            <a-table
+                    ref="table"
+                    size="middle"
+                    bordered
+                    rowKey="id"
+                    :columns="columns"
+                    :dataSource="dataSource"
+                    :pagination="ipagination"
+                    :loading="loading"
+                    :rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}"
+                    @change="handleTableChange">
+
+        <span slot="action" slot-scope="text, record">
+          <a @click="handleEdit(record)">编辑</a>
+
+          <a-divider type="vertical"/>
+          <a-dropdown>
+            <a class="ant-dropdown-link">更多 <a-icon type="down"/></a>
+            <a-menu slot="overlay">
+              <a-menu-item>
+                <a-popconfirm title="确定删除吗?" @confirm="() => handleDelete(record.id)">
+                  <a>删除</a>
+                </a-popconfirm>
+              </a-menu-item>
+            </a-menu>
+          </a-dropdown>
+        </span>
+
+            </a-table>
+        </div>
+        <!-- table区域-end -->
+
+        <!-- 表单区域 -->
+        <byteDanceCreativeTemplate-modal ref="modalForm" @ok="modalFormOk"></byteDanceCreativeTemplate-modal>
+    </a-card>
+</template>
+
+<script>
+    import ByteDanceCreativeTemplateModal from './modules/ByteDanceCreativeTemplateModal'
+    import {JeecgListMixin} from '@/mixins/JeecgListMixin'
+
+    export default {
+        name: "ByteDanceCreativeTemplateList",
+        mixins: [JeecgListMixin],
+        components: {
+            ByteDanceCreativeTemplateModal
+        },
+        data() {
+            return {
+                description: '广告创意模板管理页面',
+                // 表头
+                columns: [
+                    {
+                        title: '#',
+                        dataIndex: '',
+                        key: 'rowIndex',
+                        width: 60,
+                        align: "center",
+                        customRender: function (t, r, index) {
+                            return parseInt(index) + 1;
+                        }
+                    },
+                    {
+                        title: '用户头条id',
+                        align: "center",
+                        dataIndex: 'accountId'
+                    },
+                    {
+                        title: '广告主id',
+                        align: "center",
+                        dataIndex: 'advertiserId'
+                    },
+                    {
+                        title: '广告计划id',
+                        align: "center",
+                        dataIndex: 'adId'
+                    },
+                    {
+                        title: '视频id',
+                        align: "center",
+                        dataIndex: 'videoId'
+                    },
+                    {
+                        title: '图片id',
+                        align: "center",
+                        dataIndex: 'imageId'
+                    },
+                    {
+                        title: '创意文案',
+                        align: "center",
+                        dataIndex: 'createText'
+                    },
+                    {
+                        title: '来源',
+                        align: "center",
+                        dataIndex: 'source'
+                    },
+                    {
+                        title: '图片生成视频',
+                        align: "center",
+                        dataIndex: 'imageToVideo'
+                    },
+                    {
+                        title: '最优衍生计划',
+                        align: "center",
+                        dataIndex: 'derivativePlan'
+                    },
+                    {
+                        title: '是否开启广告评论',
+                        align: "center",
+                        dataIndex: 'commentOpen'
+                    },
+                    {
+                        title: '展现方式',
+                        align: "center",
+                        dataIndex: 'presentType'
+                    },
+                    {
+                        title: '创意分类',
+                        align: "center",
+                        dataIndex: 'creativeCategory'
+                    },
+                    {
+                        title: '创意标签',
+                        align: "center",
+                        dataIndex: 'createTitle'
+                    },
+                    {
+                        title: '第三方监测链接展示',
+                        align: "center",
+                        dataIndex: 'monitorLinkDisplay'
+                    },
+                    {
+                        title: '第三方监测链接点击',
+                        align: "center",
+                        dataIndex: 'monitorLinkClick'
+                    },
+                    {
+                        title: '第三方监测链接视频播放',
+                        align: "center",
+                        dataIndex: 'monitorLinkPlay'
+                    },
+                    {
+                        title: '第三方监测链接视频播完',
+                        align: "center",
+                        dataIndex: 'monitorLinkPlayed'
+                    },
+                    {
+                        title: 'status',
+                        align: "center",
+                        dataIndex: 'status'
+                    },
+                    {
+                        title: '操作',
+                        dataIndex: 'action',
+                        align: "center",
+                        scopedSlots: {customRender: 'action'},
+                    }
+                ],
+                url: {
+                    list: "/ctop/byteDanceCreativeTemplate/list",
+                    delete: "/ctop/byteDanceCreativeTemplate/delete",
+                    deleteBatch: "/ctop/byteDanceCreativeTemplate/deleteBatch",
+                    exportXlsUrl: "ctop/byteDanceCreativeTemplate/exportXls",
+                    importExcelUrl: "ctop/byteDanceCreativeTemplate/importExcel",
+                },
+            }
+        },
+        computed: {
+            importExcelUrl: function () {
+                return `${window._CONFIG['domianURL']}/${this.url.importExcelUrl}`;
+            }
+        },
+        methods: {}
+    }
+</script>
+<style scoped>
+    @import '~@assets/less/common.less'
+</style>

+ 224 - 0
jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/vue/BytedanceAdvertisePlanTemplateList.vue

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

+ 173 - 0
jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/vue/FileInfoList.vue

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

+ 226 - 0
jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/vue/modules/ByteDanceCreativeTemplateModal.vue

@@ -0,0 +1,226 @@
+<template>
+    <a-modal
+            :title="title"
+            :width="800"
+            :visible="visible"
+            :confirmLoading="confirmLoading"
+            @ok="handleOk"
+            @cancel="handleCancel"
+            cancelText="关闭">
+
+        <a-spin :spinning="confirmLoading">
+            <a-form :form="form">
+
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="用户头条id">
+                    <a-input placeholder="请输入用户头条id" v-decorator="['accountId', {}]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="广告主id">
+                    <a-input placeholder="请输入广告主id" v-decorator="['advertiserId', {}]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="广告计划id">
+                    <a-input placeholder="请输入广告计划id" v-decorator="['adId', {}]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="视频id">
+                    <a-input placeholder="请输入视频id" v-decorator="['videoId', {}]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="图片id">
+                    <a-input placeholder="请输入图片id" v-decorator="['imageId', {}]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="创意文案">
+                    <a-input placeholder="请输入创意文案" v-decorator="['createText', {}]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="来源">
+                    <a-input placeholder="请输入来源" v-decorator="['source', {}]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="图片生成视频">
+                    <a-input placeholder="请输入图片生成视频" v-decorator="['imageToVideo', {}]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="最优衍生计划">
+                    <a-input placeholder="请输入最优衍生计划" v-decorator="['derivativePlan', {}]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="是否开启广告评论">
+                    <a-input placeholder="请输入是否开启广告评论" v-decorator="['commentOpen', {}]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="展现方式">
+                    <a-input placeholder="请输入展现方式" v-decorator="['presentType', {}]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="创意分类">
+                    <a-input placeholder="请输入创意分类" v-decorator="['creativeCategory', {}]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="创意标签">
+                    <a-input placeholder="请输入创意标签" v-decorator="['createTitle', {}]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="第三方监测链接展示">
+                    <a-input placeholder="请输入第三方监测链接展示" v-decorator="['monitorLinkDisplay', {}]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="第三方监测链接点击">
+                    <a-input placeholder="请输入第三方监测链接点击" v-decorator="['monitorLinkClick', {}]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="第三方监测链接视频播放">
+                    <a-input placeholder="请输入第三方监测链接视频播放" v-decorator="['monitorLinkPlay', {}]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="第三方监测链接视频播完">
+                    <a-input placeholder="请输入第三方监测链接视频播完" v-decorator="['monitorLinkPlayed', {}]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="status">
+                    <a-input-number v-decorator="[ 'status', validatorRules.status ]"/>
+                </a-form-item>
+
+            </a-form>
+        </a-spin>
+    </a-modal>
+</template>
+
+<script>
+    import {httpAction} from '@/api/manage'
+    import pick from 'lodash.pick'
+    import moment from "moment"
+
+    export default {
+        name: "ByteDanceCreativeTemplateModal",
+        data() {
+            return {
+                title: "操作",
+                visible: false,
+                model: {},
+                labelCol: {
+                    xs: {span: 24},
+                    sm: {span: 5},
+                },
+                wrapperCol: {
+                    xs: {span: 24},
+                    sm: {span: 16},
+                },
+
+                confirmLoading: false,
+                form: this.$form.createForm(this),
+                validatorRules: {
+                    status: {rules: [{required: true, message: '请输入status!'}]},
+                },
+                url: {
+                    add: "/ctop/byteDanceCreativeTemplate/add",
+                    edit: "/ctop/byteDanceCreativeTemplate/edit",
+                },
+            }
+        },
+        created() {
+        },
+        methods: {
+            add() {
+                this.edit({});
+            },
+            edit(record) {
+                this.form.resetFields();
+                this.model = Object.assign({}, record);
+                this.visible = true;
+                this.$nextTick(() => {
+                    this.form.setFieldsValue(pick(this.model, 'accountId', 'advertiserId', 'adId', 'videoId', 'imageId', 'createText', 'source', 'imageToVideo', 'derivativePlan', 'commentOpen', 'presentType', 'creativeCategory', 'createTitle', 'monitorLinkDisplay', 'monitorLinkClick', 'monitorLinkPlay', 'monitorLinkPlayed', 'status'))
+                    //时间格式化
+                });
+
+            },
+            close() {
+                this.$emit('close');
+                this.visible = false;
+            },
+            handleOk() {
+                const that = this;
+                // 触发表单验证
+                this.form.validateFields((err, values) => {
+                    if (!err) {
+                        that.confirmLoading = true;
+                        let httpurl = '';
+                        let method = '';
+                        if (!this.model.id) {
+                            httpurl += this.url.add;
+                            method = 'post';
+                        } else {
+                            httpurl += this.url.edit;
+                            method = 'put';
+                        }
+                        let formData = Object.assign(this.model, values);
+                        //时间格式化
+
+                        console.log(formData)
+                        httpAction(httpurl, formData, method).then((res) => {
+                            if (res.success) {
+                                that.$message.success(res.message);
+                                that.$emit('ok');
+                            } else {
+                                that.$message.warning(res.message);
+                            }
+                        }).finally(() => {
+                            that.confirmLoading = false;
+                            that.close();
+                        })
+
+
+                    }
+                })
+            },
+            handleCancel() {
+                this.close()
+            },
+
+
+        }
+    }
+</script>
+
+<style lang="less" scoped>
+
+</style>

+ 233 - 0
jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/vue/modules/ByteDanceCreativeTemplateModal__Style#Drawer.vue

@@ -0,0 +1,233 @@
+<template>
+    <a-drawer
+            :title="title"
+            :width="800"
+            placement="right"
+            :closable="false"
+            @close="close"
+            :visible="visible"
+    >
+
+        <a-spin :spinning="confirmLoading">
+            <a-form :form="form">
+
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="用户头条id">
+                    <a-input placeholder="请输入用户头条id" v-decorator="['accountId', {}]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="广告主id">
+                    <a-input placeholder="请输入广告主id" v-decorator="['advertiserId', {}]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="广告计划id">
+                    <a-input placeholder="请输入广告计划id" v-decorator="['adId', {}]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="视频id">
+                    <a-input placeholder="请输入视频id" v-decorator="['videoId', {}]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="图片id">
+                    <a-input placeholder="请输入图片id" v-decorator="['imageId', {}]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="创意文案">
+                    <a-input placeholder="请输入创意文案" v-decorator="['createText', {}]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="来源">
+                    <a-input placeholder="请输入来源" v-decorator="['source', {}]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="图片生成视频">
+                    <a-input placeholder="请输入图片生成视频" v-decorator="['imageToVideo', {}]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="最优衍生计划">
+                    <a-input placeholder="请输入最优衍生计划" v-decorator="['derivativePlan', {}]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="是否开启广告评论">
+                    <a-input placeholder="请输入是否开启广告评论" v-decorator="['commentOpen', {}]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="展现方式">
+                    <a-input placeholder="请输入展现方式" v-decorator="['presentType', {}]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="创意分类">
+                    <a-input placeholder="请输入创意分类" v-decorator="['creativeCategory', {}]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="创意标签">
+                    <a-input placeholder="请输入创意标签" v-decorator="['createTitle', {}]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="第三方监测链接展示">
+                    <a-input placeholder="请输入第三方监测链接展示" v-decorator="['monitorLinkDisplay', {}]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="第三方监测链接点击">
+                    <a-input placeholder="请输入第三方监测链接点击" v-decorator="['monitorLinkClick', {}]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="第三方监测链接视频播放">
+                    <a-input placeholder="请输入第三方监测链接视频播放" v-decorator="['monitorLinkPlay', {}]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="第三方监测链接视频播完">
+                    <a-input placeholder="请输入第三方监测链接视频播完" v-decorator="['monitorLinkPlayed', {}]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="status">
+                    <a-input-number v-decorator="[ 'status', validatorRules.status ]"/>
+                </a-form-item>
+
+            </a-form>
+        </a-spin>
+        <a-button type="primary" @click="handleOk">确定</a-button>
+        <a-button type="primary" @click="handleCancel">取消</a-button>
+    </a-drawer>
+</template>
+
+<script>
+    import {httpAction} from '@/api/manage'
+    import pick from 'lodash.pick'
+    import moment from "moment"
+
+    export default {
+        name: "ByteDanceCreativeTemplateModal",
+        data() {
+            return {
+                title: "操作",
+                visible: false,
+                model: {},
+                labelCol: {
+                    xs: {span: 24},
+                    sm: {span: 5},
+                },
+                wrapperCol: {
+                    xs: {span: 24},
+                    sm: {span: 16},
+                },
+
+                confirmLoading: false,
+                form: this.$form.createForm(this),
+                validatorRules: {
+                    status: {rules: [{required: true, message: '请输入status!'}]},
+                },
+                url: {
+                    add: "/ctop/byteDanceCreativeTemplate/add",
+                    edit: "/ctop/byteDanceCreativeTemplate/edit",
+                },
+            }
+        },
+        created() {
+        },
+        methods: {
+            add() {
+                this.edit({});
+            },
+            edit(record) {
+                this.form.resetFields();
+                this.model = Object.assign({}, record);
+                this.visible = true;
+                this.$nextTick(() => {
+                    this.form.setFieldsValue(pick(this.model, 'accountId', 'advertiserId', 'adId', 'videoId', 'imageId', 'createText', 'source', 'imageToVideo', 'derivativePlan', 'commentOpen', 'presentType', 'creativeCategory', 'createTitle', 'monitorLinkDisplay', 'monitorLinkClick', 'monitorLinkPlay', 'monitorLinkPlayed', 'status'))
+                    //时间格式化
+                });
+
+            },
+            close() {
+                this.$emit('close');
+                this.visible = false;
+            },
+            handleOk() {
+                const that = this;
+                // 触发表单验证
+                this.form.validateFields((err, values) => {
+                    if (!err) {
+                        that.confirmLoading = true;
+                        let httpurl = '';
+                        let method = '';
+                        if (!this.model.id) {
+                            httpurl += this.url.add;
+                            method = 'post';
+                        } else {
+                            httpurl += this.url.edit;
+                            method = 'put';
+                        }
+                        let formData = Object.assign(this.model, values);
+                        //时间格式化
+
+                        console.log(formData)
+                        httpAction(httpurl, formData, method).then((res) => {
+                            if (res.success) {
+                                that.$message.success(res.message);
+                                that.$emit('ok');
+                            } else {
+                                that.$message.warning(res.message);
+                            }
+                        }).finally(() => {
+                            that.confirmLoading = false;
+                            that.close();
+                        })
+
+
+                    }
+                })
+            },
+            handleCancel() {
+                this.close()
+            },
+
+
+        }
+    }
+</script>
+
+<style lang="less" scoped>
+    /** Button按钮间距 */
+    .ant-btn {
+        margin-left: 30px;
+        margin-bottom: 30px;
+        float: right;
+    }
+</style>

+ 182 - 0
jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/vue/modules/BytedanceAdvertisePlanTemplateModal.vue

@@ -0,0 +1,182 @@
+<template>
+    <a-modal
+            :title="title"
+            :width="800"
+            :visible="visible"
+            :confirmLoading="confirmLoading"
+            @ok="handleOk"
+            @cancel="handleCancel"
+            cancelText="关闭">
+
+        <a-spin :spinning="confirmLoading">
+            <a-form :form="form">
+
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="头条账号id">
+                    <a-input placeholder="请输入头条账号id" v-decorator="['accountId', {}]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="广告主id">
+                    <a-input placeholder="请输入广告主id" v-decorator="['advertiserId', {}]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="广告组模板id">
+                    <a-input placeholder="请输入广告组模板id" v-decorator="['campaignTemplateId', {}]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="投放范围">
+                    <a-input placeholder="请输入投放范围" v-decorator="['deliveryRange', {}]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="用户定向模板id">
+                    <a-input placeholder="请输入用户定向模板id" v-decorator="['userOrentationTemplateId', {}]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="预算与出价模板id">
+                    <a-input placeholder="请输入预算与出价模板id" v-decorator="['budgetTemplateId', {}]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="投放目标模板id">
+                    <a-input placeholder="请输入投放目标模板id" v-decorator="['deliveryTargetTemplateId', {}]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="指定视频id">
+                    <a-input placeholder="请输入指定视频id" v-decorator="['videoId', {}]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="指定封面图id">
+                    <a-input placeholder="请输入指定封面图id" v-decorator="['imageId', {}]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="创意文案信息">
+                    <a-input placeholder="请输入创意文案信息" v-decorator="['creativeText', {}]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="迭代数量">
+                    <a-input-number v-decorator="[ 'iteratorNum', {}]"/>
+                </a-form-item>
+
+            </a-form>
+        </a-spin>
+    </a-modal>
+</template>
+
+<script>
+    import {httpAction} from '@/api/manage'
+    import pick from 'lodash.pick'
+    import moment from "moment"
+
+    export default {
+        name: "BytedanceAdvertisePlanTemplateModal",
+        data() {
+            return {
+                title: "操作",
+                visible: false,
+                model: {},
+                labelCol: {
+                    xs: {span: 24},
+                    sm: {span: 5},
+                },
+                wrapperCol: {
+                    xs: {span: 24},
+                    sm: {span: 16},
+                },
+
+                confirmLoading: false,
+                form: this.$form.createForm(this),
+                validatorRules: {},
+                url: {
+                    add: "/ctop/bytedanceAdvertisePlanTemplate/add",
+                    edit: "/ctop/bytedanceAdvertisePlanTemplate/edit",
+                },
+            }
+        },
+        created() {
+        },
+        methods: {
+            add() {
+                this.edit({});
+            },
+            edit(record) {
+                this.form.resetFields();
+                this.model = Object.assign({}, record);
+                this.visible = true;
+                this.$nextTick(() => {
+                    this.form.setFieldsValue(pick(this.model, 'accountId', 'advertiserId', 'campaignTemplateId', 'deliveryRange', 'userOrentationTemplateId', 'budgetTemplateId', 'deliveryTargetTemplateId', 'videoId', 'imageId', 'creativeText', 'iteratorNum'))
+                    //时间格式化
+                });
+
+            },
+            close() {
+                this.$emit('close');
+                this.visible = false;
+            },
+            handleOk() {
+                const that = this;
+                // 触发表单验证
+                this.form.validateFields((err, values) => {
+                    if (!err) {
+                        that.confirmLoading = true;
+                        let httpurl = '';
+                        let method = '';
+                        if (!this.model.id) {
+                            httpurl += this.url.add;
+                            method = 'post';
+                        } else {
+                            httpurl += this.url.edit;
+                            method = 'put';
+                        }
+                        let formData = Object.assign(this.model, values);
+                        //时间格式化
+
+                        console.log(formData)
+                        httpAction(httpurl, formData, method).then((res) => {
+                            if (res.success) {
+                                that.$message.success(res.message);
+                                that.$emit('ok');
+                            } else {
+                                that.$message.warning(res.message);
+                            }
+                        }).finally(() => {
+                            that.confirmLoading = false;
+                            that.close();
+                        })
+
+
+                    }
+                })
+            },
+            handleCancel() {
+                this.close()
+            },
+
+
+        }
+    }
+</script>
+
+<style lang="less" scoped>
+
+</style>

+ 189 - 0
jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/vue/modules/BytedanceAdvertisePlanTemplateModal__Style#Drawer.vue

@@ -0,0 +1,189 @@
+<template>
+    <a-drawer
+            :title="title"
+            :width="800"
+            placement="right"
+            :closable="false"
+            @close="close"
+            :visible="visible"
+    >
+
+        <a-spin :spinning="confirmLoading">
+            <a-form :form="form">
+
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="头条账号id">
+                    <a-input placeholder="请输入头条账号id" v-decorator="['accountId', {}]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="广告主id">
+                    <a-input placeholder="请输入广告主id" v-decorator="['advertiserId', {}]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="广告组模板id">
+                    <a-input placeholder="请输入广告组模板id" v-decorator="['campaignTemplateId', {}]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="投放范围">
+                    <a-input placeholder="请输入投放范围" v-decorator="['deliveryRange', {}]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="用户定向模板id">
+                    <a-input placeholder="请输入用户定向模板id" v-decorator="['userOrentationTemplateId', {}]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="预算与出价模板id">
+                    <a-input placeholder="请输入预算与出价模板id" v-decorator="['budgetTemplateId', {}]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="投放目标模板id">
+                    <a-input placeholder="请输入投放目标模板id" v-decorator="['deliveryTargetTemplateId', {}]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="指定视频id">
+                    <a-input placeholder="请输入指定视频id" v-decorator="['videoId', {}]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="指定封面图id">
+                    <a-input placeholder="请输入指定封面图id" v-decorator="['imageId', {}]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="创意文案信息">
+                    <a-input placeholder="请输入创意文案信息" v-decorator="['creativeText', {}]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="迭代数量">
+                    <a-input-number v-decorator="[ 'iteratorNum', {}]"/>
+                </a-form-item>
+
+            </a-form>
+        </a-spin>
+        <a-button type="primary" @click="handleOk">确定</a-button>
+        <a-button type="primary" @click="handleCancel">取消</a-button>
+    </a-drawer>
+</template>
+
+<script>
+    import {httpAction} from '@/api/manage'
+    import pick from 'lodash.pick'
+    import moment from "moment"
+
+    export default {
+        name: "BytedanceAdvertisePlanTemplateModal",
+        data() {
+            return {
+                title: "操作",
+                visible: false,
+                model: {},
+                labelCol: {
+                    xs: {span: 24},
+                    sm: {span: 5},
+                },
+                wrapperCol: {
+                    xs: {span: 24},
+                    sm: {span: 16},
+                },
+
+                confirmLoading: false,
+                form: this.$form.createForm(this),
+                validatorRules: {},
+                url: {
+                    add: "/ctop/bytedanceAdvertisePlanTemplate/add",
+                    edit: "/ctop/bytedanceAdvertisePlanTemplate/edit",
+                },
+            }
+        },
+        created() {
+        },
+        methods: {
+            add() {
+                this.edit({});
+            },
+            edit(record) {
+                this.form.resetFields();
+                this.model = Object.assign({}, record);
+                this.visible = true;
+                this.$nextTick(() => {
+                    this.form.setFieldsValue(pick(this.model, 'accountId', 'advertiserId', 'campaignTemplateId', 'deliveryRange', 'userOrentationTemplateId', 'budgetTemplateId', 'deliveryTargetTemplateId', 'videoId', 'imageId', 'creativeText', 'iteratorNum'))
+                    //时间格式化
+                });
+
+            },
+            close() {
+                this.$emit('close');
+                this.visible = false;
+            },
+            handleOk() {
+                const that = this;
+                // 触发表单验证
+                this.form.validateFields((err, values) => {
+                    if (!err) {
+                        that.confirmLoading = true;
+                        let httpurl = '';
+                        let method = '';
+                        if (!this.model.id) {
+                            httpurl += this.url.add;
+                            method = 'post';
+                        } else {
+                            httpurl += this.url.edit;
+                            method = 'put';
+                        }
+                        let formData = Object.assign(this.model, values);
+                        //时间格式化
+
+                        console.log(formData)
+                        httpAction(httpurl, formData, method).then((res) => {
+                            if (res.success) {
+                                that.$message.success(res.message);
+                                that.$emit('ok');
+                            } else {
+                                that.$message.warning(res.message);
+                            }
+                        }).finally(() => {
+                            that.confirmLoading = false;
+                            that.close();
+                        })
+
+
+                    }
+                })
+            },
+            handleCancel() {
+                this.close()
+            },
+
+
+        }
+    }
+</script>
+
+<style lang="less" scoped>
+    /** Button按钮间距 */
+    .ant-btn {
+        margin-left: 30px;
+        margin-bottom: 30px;
+        float: right;
+    }
+</style>

+ 137 - 0
jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/vue/modules/FileInfoModal.vue

@@ -0,0 +1,137 @@
+<template>
+    <a-modal
+            :title="title"
+            :width="800"
+            :visible="visible"
+            :confirmLoading="confirmLoading"
+            @ok="handleOk"
+            @cancel="handleCancel"
+            cancelText="关闭">
+
+        <a-spin :spinning="confirmLoading">
+            <a-form :form="form">
+
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="文件名称">
+                    <a-input placeholder="请输入文件名称" v-decorator="['fileName', validatorRules.fileName ]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="文件类型">
+                    <a-input placeholder="请输入文件类型" v-decorator="['type', {}]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="文件访问路径">
+                    <a-input placeholder="请输入文件访问路径" v-decorator="['path', validatorRules.path ]"/>
+                </a-form-item>
+
+            </a-form>
+        </a-spin>
+    </a-modal>
+</template>
+
+<script>
+    import {httpAction} from '@/api/manage'
+    import pick from 'lodash.pick'
+    import moment from "moment"
+
+    export default {
+        name: "FileInfoModal",
+        data() {
+            return {
+                title: "操作",
+                visible: false,
+                model: {},
+                labelCol: {
+                    xs: {span: 24},
+                    sm: {span: 5},
+                },
+                wrapperCol: {
+                    xs: {span: 24},
+                    sm: {span: 16},
+                },
+
+                confirmLoading: false,
+                form: this.$form.createForm(this),
+                validatorRules: {
+                    fileName: {rules: [{required: true, message: '请输入文件名称!'}]},
+                    path: {rules: [{required: true, message: '请输入文件访问路径!'}]},
+                },
+                url: {
+                    add: "/ctop/fileInfo/add",
+                    edit: "/ctop/fileInfo/edit",
+                },
+            }
+        },
+        created() {
+        },
+        methods: {
+            add() {
+                this.edit({});
+            },
+            edit(record) {
+                this.form.resetFields();
+                this.model = Object.assign({}, record);
+                this.visible = true;
+                this.$nextTick(() => {
+                    this.form.setFieldsValue(pick(this.model, 'fileName', 'type', 'path'))
+                    //时间格式化
+                });
+
+            },
+            close() {
+                this.$emit('close');
+                this.visible = false;
+            },
+            handleOk() {
+                const that = this;
+                // 触发表单验证
+                this.form.validateFields((err, values) => {
+                    if (!err) {
+                        that.confirmLoading = true;
+                        let httpurl = '';
+                        let method = '';
+                        if (!this.model.id) {
+                            httpurl += this.url.add;
+                            method = 'post';
+                        } else {
+                            httpurl += this.url.edit;
+                            method = 'put';
+                        }
+                        let formData = Object.assign(this.model, values);
+                        //时间格式化
+
+                        console.log(formData)
+                        httpAction(httpurl, formData, method).then((res) => {
+                            if (res.success) {
+                                that.$message.success(res.message);
+                                that.$emit('ok');
+                            } else {
+                                that.$message.warning(res.message);
+                            }
+                        }).finally(() => {
+                            that.confirmLoading = false;
+                            that.close();
+                        })
+
+
+                    }
+                })
+            },
+            handleCancel() {
+                this.close()
+            },
+
+
+        }
+    }
+</script>
+
+<style lang="less" scoped>
+
+</style>

+ 144 - 0
jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/vue/modules/FileInfoModal__Style#Drawer.vue

@@ -0,0 +1,144 @@
+<template>
+    <a-drawer
+            :title="title"
+            :width="800"
+            placement="right"
+            :closable="false"
+            @close="close"
+            :visible="visible"
+    >
+
+        <a-spin :spinning="confirmLoading">
+            <a-form :form="form">
+
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="文件名称">
+                    <a-input placeholder="请输入文件名称" v-decorator="['fileName', validatorRules.fileName ]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="文件类型">
+                    <a-input placeholder="请输入文件类型" v-decorator="['type', {}]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="文件访问路径">
+                    <a-input placeholder="请输入文件访问路径" v-decorator="['path', validatorRules.path ]"/>
+                </a-form-item>
+
+            </a-form>
+        </a-spin>
+        <a-button type="primary" @click="handleOk">确定</a-button>
+        <a-button type="primary" @click="handleCancel">取消</a-button>
+    </a-drawer>
+</template>
+
+<script>
+    import {httpAction} from '@/api/manage'
+    import pick from 'lodash.pick'
+    import moment from "moment"
+
+    export default {
+        name: "FileInfoModal",
+        data() {
+            return {
+                title: "操作",
+                visible: false,
+                model: {},
+                labelCol: {
+                    xs: {span: 24},
+                    sm: {span: 5},
+                },
+                wrapperCol: {
+                    xs: {span: 24},
+                    sm: {span: 16},
+                },
+
+                confirmLoading: false,
+                form: this.$form.createForm(this),
+                validatorRules: {
+                    fileName: {rules: [{required: true, message: '请输入文件名称!'}]},
+                    path: {rules: [{required: true, message: '请输入文件访问路径!'}]},
+                },
+                url: {
+                    add: "/ctop/fileInfo/add",
+                    edit: "/ctop/fileInfo/edit",
+                },
+            }
+        },
+        created() {
+        },
+        methods: {
+            add() {
+                this.edit({});
+            },
+            edit(record) {
+                this.form.resetFields();
+                this.model = Object.assign({}, record);
+                this.visible = true;
+                this.$nextTick(() => {
+                    this.form.setFieldsValue(pick(this.model, 'fileName', 'type', 'path'))
+                    //时间格式化
+                });
+
+            },
+            close() {
+                this.$emit('close');
+                this.visible = false;
+            },
+            handleOk() {
+                const that = this;
+                // 触发表单验证
+                this.form.validateFields((err, values) => {
+                    if (!err) {
+                        that.confirmLoading = true;
+                        let httpurl = '';
+                        let method = '';
+                        if (!this.model.id) {
+                            httpurl += this.url.add;
+                            method = 'post';
+                        } else {
+                            httpurl += this.url.edit;
+                            method = 'put';
+                        }
+                        let formData = Object.assign(this.model, values);
+                        //时间格式化
+
+                        console.log(formData)
+                        httpAction(httpurl, formData, method).then((res) => {
+                            if (res.success) {
+                                that.$message.success(res.message);
+                                that.$emit('ok');
+                            } else {
+                                that.$message.warning(res.message);
+                            }
+                        }).finally(() => {
+                            that.confirmLoading = false;
+                            that.close();
+                        })
+
+
+                    }
+                })
+            },
+            handleCancel() {
+                this.close()
+            },
+
+
+        }
+    }
+</script>
+
+<style lang="less" scoped>
+    /** Button按钮间距 */
+    .ant-btn {
+        margin-left: 30px;
+        margin-bottom: 30px;
+        float: right;
+    }
+</style>

+ 30 - 0
jeecg-boot-module-system/src/main/java/org/jeecg/modules/fileupload/controller/UploadController.java

@@ -0,0 +1,30 @@
+package org.jeecg.modules.fileupload.controller;
+
+import org.jeecg.modules.fileupload.service.IUploadService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.HashMap;
+import java.util.Map;
+
+@RestController
+@RequestMapping("upload")
+public class UploadController {
+    @Autowired
+    private IUploadService uploadService;
+
+    @PostMapping(value = "image", consumes = "multipart/form-data;charset=utf-8")
+    public Map<String, Object> uploadImage(@RequestParam("multipartFile") MultipartFile multipartFile, String type, HttpServletRequest request) {
+        return uploadService.imageUpload(multipartFile, request, type);
+    }
+
+    @PostMapping(value = "video", consumes = "multipart/form-data;charset=utf-8")
+    public Map<String, Object> uploadVideo(@RequestParam("multipartFile") MultipartFile multipartFile, String type, HttpServletRequest request) {
+        return uploadService.videoUpload(multipartFile, request, type);
+    }
+}

+ 12 - 0
jeecg-boot-module-system/src/main/java/org/jeecg/modules/fileupload/service/IUploadService.java

@@ -0,0 +1,12 @@
+package org.jeecg.modules.fileupload.service;
+
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.Map;
+
+public interface IUploadService {
+    Map<String, Object> imageUpload(MultipartFile multipartFile, HttpServletRequest request, String type);
+
+    Map<String, Object> videoUpload(MultipartFile multipartFile, HttpServletRequest request, String type);
+}

+ 61 - 0
jeecg-boot-module-system/src/main/java/org/jeecg/modules/fileupload/service/impl/UploadServiceImpl.java

@@ -0,0 +1,61 @@
+package org.jeecg.modules.fileupload.service.impl;
+
+import cn.com.ctop.common.utils.FileEntity;
+import cn.com.ctop.common.utils.FileUploadTool;
+import org.jeecg.modules.ctop.entity.FileInfo;
+import org.jeecg.modules.ctop.mapper.FileInfoMapper;
+import org.jeecg.modules.fileupload.service.IUploadService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.HashMap;
+import java.util.Map;
+
+@Service
+public class UploadServiceImpl implements IUploadService {
+
+    @Autowired
+    private FileInfoMapper fileInfoMapper;
+
+    @Override
+    public Map<String, Object> imageUpload(MultipartFile multipartFile, HttpServletRequest request, String type) {
+        Map<String, Object> resultMap = new HashMap<>();
+        String savaPath = "D:\\upload\\image";
+        FileUploadTool fileUploadTool = new FileUploadTool();
+        FileEntity entity;
+        entity = fileUploadTool.createFile(multipartFile, request, savaPath);
+        FileInfo fileInfo = new FileInfo();
+        fileInfo.setFileName(entity.getTitleOrig());
+        fileInfo.setPath(entity.getPath());
+        fileInfo.setType("IMAGE");
+        fileInfo.setFileUrl("http://photocdn.sohu.com/20111207/Img328215620.jpg");
+        fileInfo.setPlatformType(type);
+        fileInfoMapper.insert(fileInfo);
+        resultMap.put("message", "文件上传成功");
+        resultMap.put("success", true);
+        resultMap.put("fileInfo", fileInfo);
+        return resultMap;
+    }
+
+    @Override
+    public Map<String, Object> videoUpload(MultipartFile multipartFile, HttpServletRequest request, String type) {
+        Map<String, Object> resultMap = new HashMap<>();
+        String savaPath = "D:\\upload\\video";
+        FileUploadTool fileUploadTool = new FileUploadTool();
+        FileEntity entity;
+        entity = fileUploadTool.createFile(multipartFile, request, savaPath);
+        FileInfo fileInfo = new FileInfo();
+        fileInfo.setFileName(entity.getTitleOrig() + entity.getType());
+        fileInfo.setPath(entity.getPath());
+        fileInfo.setType("VIDEO");
+        fileInfo.setFileUrl("http://photocdn.sohu.com/20111207/Img328215620.jpg");
+        fileInfo.setPlatformType(type);
+        fileInfoMapper.insert(fileInfo);
+        resultMap.put("message", "文件上传成功");
+        resultMap.put("success", true);
+        resultMap.put("fileInfo", fileInfo);
+        return resultMap;
+    }
+}