Просмотр исходного кода

Merge branch 'master' into test

# Conflicts:
#	jeecg-boot-base/jeecg-boot-base-api/jeecg-system-cloud-api/src/main/java/org/jeecg/common/system/api/ISysBaseAPI.java
#	jeecg-boot-base/jeecg-boot-base-api/jeecg-system-cloud-api/src/main/java/org/jeecg/common/system/api/fallback/SysBaseAPIFallback.java
yangzian 3 лет назад
Родитель
Сommit
e18997e1d0
100 измененных файлов с 8960 добавлено и 380 удалено
  1. 1 0
      .gitignore
  2. 427 0
      jeecg-boot-base/jeecg-boot-base-api/jeecg-system-cloud-api/src/main/java/org/jeecg/common/system/api/ISysBaseAPI.java
  3. 272 0
      jeecg-boot-base/jeecg-boot-base-api/jeecg-system-cloud-api/src/main/java/org/jeecg/common/system/api/fallback/SysBaseAPIFallback.java
  4. 0 1
      jeecg-boot-base/jeecg-boot-base-api/jeecg-system-local-api/pom.xml
  5. 13 0
      jeecg-boot-base/jeecg-boot-base-api/jeecg-system-local-api/src/main/java/org/jeecg/common/system/api/ICommonService.java
  6. 23 13
      jeecg-boot-base/jeecg-boot-base-core/pom.xml
  7. 2 2
      jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/api/CommonAPI.java
  8. 0 47
      jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/api/desform/ISysTranslateAPI.java
  9. 2 0
      jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/api/dto/LogDTO.java
  10. 0 5
      jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/api/dto/message/MessageDTO.java
  11. 1 0
      jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/api/dto/message/TemplateMessageDTO.java
  12. 22 2
      jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/api/vo/Result.java
  13. 22 38
      jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/aspect/DictAspect.java
  14. 4 5
      jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/aspect/PermissionDataAspect.java
  15. 18 0
      jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/aspect/annotation/Dict.java
  16. 186 0
      jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/system/entity/SysDepart.java
  17. 82 0
      jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/system/entity/SysDict.java
  18. 183 0
      jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/system/entity/SysPermission.java
  19. 82 0
      jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/system/entity/SysPermissionDataRule.java
  20. 223 0
      jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/system/entity/SysUser.java
  21. 38 0
      jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/system/mapper/CoreMapper.java
  22. 46 0
      jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/system/mapper/CorePermissionMapper.java
  23. 59 0
      jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/system/mapper/xml/CoreMapper.xml
  24. 79 0
      jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/system/mapper/xml/CorePermissionMapper.xml
  25. 39 0
      jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/system/service/ICoreService.java
  26. 221 0
      jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/system/service/impl/CoreServiceImpl.java
  27. 3 48
      jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/util/CommonUtils.java
  28. 20 0
      jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/util/DateUtils.java
  29. 0 122
      jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/util/DySmsHelper.java
  30. 39 0
      jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/util/MD5Util.java
  31. 2 6
      jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/util/MinioUtil.java
  32. 1 3
      jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/util/oss/OssBootUtil.java
  33. 6 5
      jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/config/AutoPoiDictConfig.java
  34. 16 1
      jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/config/mybatis/MybatisPlusConfig.java
  35. 0 38
      jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/config/oss/MinioConfig.java
  36. 0 34
      jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/config/oss/OssConfiguration.java
  37. 2 1
      jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/config/shiro/ShiroConfig.java
  38. 3 9
      jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/service/impl/BaseCommonServiceImpl.java
  39. 76 0
      jeecg-boot-bytedance-ad/pom.xml
  40. 21 0
      jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/JeecgBootBytedanceAdApplication.java
  41. 524 0
      jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/controller/AiBytedanceAdvertiserStrategyController.java
  42. 428 0
      jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/controller/BytedanceGeneralCopywriterController.java
  43. 116 0
      jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/controller/BytedanceRejectReasonController.java
  44. 339 0
      jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/controller/BytedanceReportController.java
  45. 379 0
      jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/controller/BytedanceVideoSlogenInfoController.java
  46. 59 0
      jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/controller/MaterialInfoController.java
  47. 78 0
      jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/dockapi/MarketingService.java
  48. 1228 0
      jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/dockapi/MarketingServiceImpl.java
  49. 42 0
      jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/entity/AiBytedanceAdDplinkInfo.java
  50. 335 0
      jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/entity/AiBytedanceAdvertiserStrategy.java
  51. 69 0
      jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/entity/AiBytedanceAutocreateLog.java
  52. 41 0
      jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/entity/AiBytedanceCampaignDplinkInfo.java
  53. 540 0
      jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/entity/ByteDanceAdvertisePlan.java
  54. 249 0
      jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/entity/ByteDanceAdvertiser.java
  55. 147 0
      jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/entity/ByteDanceAudiencePackage.java
  56. 152 0
      jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/entity/ByteDanceCampaign.java
  57. 162 0
      jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/entity/ByteDanceCreative.java
  58. 107 0
      jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/entity/ByteDanceCreativeMaterial.java
  59. 108 0
      jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/entity/ByteDanceCreativeWordPackage.java
  60. 84 0
      jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/entity/ByteDanceGeneralCopywriter.java
  61. 116 0
      jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/entity/ByteDanceVideoInfo.java
  62. 59 0
      jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/entity/BytedanceAiVideoCreativeLog.java
  63. 72 0
      jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/entity/BytedanceAreaInfo.java
  64. 79 0
      jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/entity/BytedanceImageInfo.java
  65. 42 0
      jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/entity/BytedanceIndustryInfo.java
  66. 62 0
      jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/entity/BytedanceInterestCategory.java
  67. 27 0
      jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/entity/BytedanceMaterialRejectReason.java
  68. 22 0
      jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/entity/BytedancePlanRejectReason.java
  69. 82 0
      jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/entity/BytedanceVideoSlogenInfo.java
  70. 19 0
      jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/entity/LowQualityRejectReason.java
  71. 75 0
      jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/entity/RuleDataAccount.java
  72. 61 0
      jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/entity/UpdAdStaOrCpaOrBudget.java
  73. 166 0
      jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/enums/BytedanceConvertType.java
  74. 134 0
      jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/enums/BytedanceCreativeMatTypeEnum.java
  75. 14 0
      jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/mapper/AiBytedanceAdDplinkInfoMapper.java
  76. 25 0
      jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/mapper/AiBytedanceAdvertiserStrategyMapper.java
  77. 17 0
      jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/mapper/AiBytedanceAutocreateLogMapper.java
  78. 14 0
      jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/mapper/AiBytedanceCampaignDplinkInfoMapper.java
  79. 31 0
      jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/mapper/ByteDanceAdvertisePlanMapper.java
  80. 14 0
      jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/mapper/ByteDanceAdvertiserMapper.java
  81. 14 0
      jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/mapper/ByteDanceAudiencePackageMapper.java
  82. 17 0
      jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/mapper/ByteDanceCampaignMapper.java
  83. 18 0
      jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/mapper/ByteDanceCreativeMapper.java
  84. 14 0
      jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/mapper/ByteDanceCreativeMaterialMapper.java
  85. 26 0
      jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/mapper/ByteDanceGeneralCopywriterMapper.java
  86. 53 0
      jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/mapper/ByteDanceVideoInfoMapper.java
  87. 14 0
      jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/mapper/BytedanceAiVideoCreativeLogMapper.java
  88. 15 0
      jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/mapper/BytedanceAreaInfoMapper.java
  89. 22 0
      jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/mapper/BytedanceImageInfoMapper.java
  90. 17 0
      jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/mapper/BytedanceMaterialRejectReasonMapper.java
  91. 14 0
      jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/mapper/BytedancePlanRejectReasonMapper.java
  92. 21 0
      jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/mapper/BytedanceVideoSlogenInfoMapper.java
  93. 15 0
      jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/mapper/LowQualityRejectReasonMapper.java
  94. 14 0
      jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/mapper/RuleDataAccountMapper.java
  95. 5 0
      jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/mapper/xml/AiBytedanceAdDplinkInfoMapper.xml
  96. 65 0
      jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/mapper/xml/AiBytedanceAdvertiserStrategyMapper.xml
  97. 5 0
      jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/mapper/xml/AiBytedanceAutocreateLogMapper.xml
  98. 5 0
      jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/mapper/xml/AiBytedanceCampaignDplinkInfoMapper.xml
  99. 54 0
      jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/mapper/xml/ByteDanceAdvertisePlanMapper.xml
  100. 0 0
      jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/mapper/xml/ByteDanceAdvertiserMapper.xml

+ 1 - 0
.gitignore

@@ -31,4 +31,5 @@ gen
 # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
 hs_err_pid*
 **/target/
+**/.mvn/
 #application.yml

+ 427 - 0
jeecg-boot-base/jeecg-boot-base-api/jeecg-system-cloud-api/src/main/java/org/jeecg/common/system/api/ISysBaseAPI.java

@@ -0,0 +1,427 @@
+package org.jeecg.common.system.api;
+
+import com.alibaba.fastjson.JSONObject;
+import org.jeecg.common.api.CommonAPI;
+import org.jeecg.common.api.dto.OnlineAuthDTO;
+import org.jeecg.common.api.dto.message.*;
+import org.jeecg.common.constant.ServiceNameConstants;
+import org.jeecg.common.system.api.factory.SysBaseAPIFallbackFactory;
+import org.jeecg.common.system.vo.*;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.stereotype.Component;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestParam;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * 相比较local版
+ * 去掉了一些方法:
+ * addLog getDatabaseType queryAllDepart
+ * queryAllUser(Wrapper wrapper) queryAllUser(String[] userIds, int pageNo, int pageSize)
+ * 修改了一些方法:
+ * createLog
+ * sendSysAnnouncement 只保留了一个,其余全部干掉
+ *
+ * cloud接口数量43  local:35 common:9  额外一个特殊queryAllRole一个当两个用
+ */
+@Component
+@FeignClient(contextId = "sysBaseRemoteApi", value = ServiceNameConstants.SYSTEM_SERVICE, fallbackFactory = SysBaseAPIFallbackFactory.class)
+public interface ISysBaseAPI extends CommonAPI {
+
+    /**
+     * 1发送系统消息
+     * @param message 使用构造器赋值参数 如果不设置category(消息类型)则默认为2 发送系统消息
+     */
+    @PostMapping("/sys/api/sendSysAnnouncement")
+    void sendSysAnnouncement(@RequestBody MessageDTO message);
+
+    /**
+     * 2发送消息 附带业务参数
+     * @param message 使用构造器赋值参数
+     */
+    @PostMapping("/sys/api/sendBusAnnouncement")
+    void sendBusAnnouncement(@RequestBody BusMessageDTO message);
+
+    /**
+     * 3通过模板发送消息
+     * @param message 使用构造器赋值参数
+     */
+    @PostMapping("/sys/api/sendTemplateAnnouncement")
+    void sendTemplateAnnouncement(@RequestBody TemplateMessageDTO message);
+
+    /**
+     * 4通过模板发送消息 附带业务参数
+     * @param message 使用构造器赋值参数
+     */
+    @PostMapping("/sys/api/sendBusTemplateAnnouncement")
+    void sendBusTemplateAnnouncement(@RequestBody BusTemplateMessageDTO message);
+
+    /**
+     * 5通过消息中心模板,生成推送内容
+     * @param templateDTO 使用构造器赋值参数
+     * @return
+     */
+    @PostMapping("/sys/api/parseTemplateByCode")
+    String parseTemplateByCode(@RequestBody TemplateDTO templateDTO);
+
+    /**
+     * 6根据用户id查询用户信息
+     * @param id
+     * @return
+     */
+    @GetMapping("/sys/api/getUserById")
+    LoginUser getUserById(@RequestParam("id") String id);
+
+    /**
+     * 7通过用户账号查询角色集合
+     * @param username
+     * @return
+     */
+    @GetMapping("/sys/api/getRolesByUsername")
+    List<String> getRolesByUsername(@RequestParam("username") String username);
+
+    /**
+     * 8通过用户账号查询部门集合
+     * @param username
+     * @return 部门 id
+     */
+    @GetMapping("/sys/api/getDepartIdsByUsername")
+    List<String> getDepartIdsByUsername(@RequestParam("username") String username);
+
+    /**
+     * 9通过用户账号查询部门 name
+     * @param username
+     * @return 部门 name
+     */
+    @GetMapping("/sys/api/getDepartNamesByUsername")
+    List<String> getDepartNamesByUsername(@RequestParam("username") String username);
+
+    /**
+     * 10获取数据字典
+     * @param code
+     * @return
+     */
+    @GetMapping("/sys/api/queryDictItemsByCode")
+    List<DictModel> queryDictItemsByCode(@RequestParam("code") String code);
+
+    /** 11查询所有的父级字典,按照create_time排序 */
+    @GetMapping("/sys/api/queryAllDict")
+    List<DictModel> queryAllDict();
+
+    /**
+     * 12查询所有分类字典
+     * @return
+     */
+    @GetMapping("/sys/api/queryAllDSysCategory")
+    List<SysCategoryModel> queryAllDSysCategory();
+
+    /**
+     * 13获取表数据字典
+     * @param table
+     * @param text
+     * @param code
+     * @return
+     */
+    @GetMapping("/sys/api/queryTableDictItemsByCode")
+    List<DictModel> queryTableDictItemsByCode(@RequestParam("table") String table, @RequestParam("text") String text, @RequestParam("code") String code);
+
+    /**
+     * 14查询所有部门 作为字典信息 id -->value,departName -->text
+     * @return
+     */
+    @GetMapping("/sys/api/queryAllDepartBackDictModel")
+    List<DictModel> queryAllDepartBackDictModel();
+
+    /**
+     * 15根据业务类型 busType 及业务 busId 修改消息已读
+     */
+    @GetMapping("/sys/api/updateSysAnnounReadFlag")
+    public void updateSysAnnounReadFlag(@RequestParam("busType") String busType, @RequestParam("busId")String busId);
+
+    /**
+     * 16查询表字典 支持过滤数据
+     * @param table
+     * @param text
+     * @param code
+     * @param filterSql
+     * @return
+     */
+    @GetMapping("/sys/api/queryFilterTableDictInfo")
+    List<DictModel> queryFilterTableDictInfo(@RequestParam("table") String table, @RequestParam("text") String text, @RequestParam("code") String code, @RequestParam("filterSql") String filterSql);
+
+    /**
+     * 17查询指定table的 text code 获取字典,包含text和value
+     * @param table
+     * @param text
+     * @param code
+     * @param keyArray
+     * @return
+     */
+    @Deprecated
+    @GetMapping("/sys/api/queryTableDictByKeys")
+    public List<String> queryTableDictByKeys(@RequestParam("table") String table, @RequestParam("text") String text, @RequestParam("code") String code, @RequestParam("keyArray") String[] keyArray);
+
+    /**
+     * 18查询所有用户 返回ComboModel
+     * @return
+     */
+    @GetMapping("/sys/api/queryAllUserBackCombo")
+    public List<ComboModel> queryAllUserBackCombo();
+
+    /**
+     * 19分页查询用户 返回JSONObject
+     * @return
+     */
+    @GetMapping("/sys/api/queryAllUser")
+    public JSONObject queryAllUser(@RequestParam(name="userIds",required=false)String userIds, @RequestParam(name="pageNo",required=false) Integer pageNo,@RequestParam(name="pageSize",required=false) int pageSize);
+
+
+    /**
+     * 20获取所有角色 带参
+     * roleIds 默认选中角色
+     * @return
+     */
+    @GetMapping("/sys/api/queryAllRole")
+    public List<ComboModel> queryAllRole(@RequestParam(name = "roleIds",required = false)String[] roleIds);
+
+    /**
+     * 21通过用户账号查询角色Id集合
+     * @param username
+     * @return
+     */
+    @GetMapping("/sys/api/getRoleIdsByUsername")
+    public List<String> getRoleIdsByUsername(@RequestParam("username")String username);
+
+    /**
+     * 22通过部门编号查询部门id
+     * @param orgCode
+     * @return
+     */
+    @GetMapping("/sys/api/getDepartIdsByOrgCode")
+    public String getDepartIdsByOrgCode(@RequestParam("orgCode")String orgCode);
+
+    /**
+     * 23查询所有部门
+     * @return
+     */
+    @GetMapping("/sys/api/getAllSysDepart")
+    public List<SysDepartModel> getAllSysDepart();
+
+    /**
+     * 24查找父级部门
+     * @param departId
+     * @return
+     */
+    @GetMapping("/sys/api/getParentDepartId")
+    DictModel getParentDepartId(@RequestParam("departId")String departId);
+
+    /**
+     * 25根据部门Id获取部门负责人
+     * @param deptId
+     * @return
+     */
+    @GetMapping("/sys/api/getDeptHeadByDepId")
+    public List<String> getDeptHeadByDepId(@RequestParam("deptId") String deptId);
+
+    /**
+     * 26给指定用户发消息
+     * @param userIds
+     * @param cmd
+     */
+    @GetMapping("/sys/api/sendWebSocketMsg")
+    public void sendWebSocketMsg(@RequestParam("userIds")String[] userIds, @RequestParam("cmd") String cmd);
+
+    /**
+     * 27根据id获取所有参与用户
+     * userIds
+     * @return
+     */
+    @GetMapping("/sys/api/queryAllUserByIds")
+    public List<LoginUser> queryAllUserByIds(@RequestParam("userIds") String[] userIds);
+
+    /**
+     * 28将会议签到信息推动到预览
+     * userIds
+     * @return
+     * @param userId
+     */
+    @GetMapping("/sys/api/meetingSignWebsocket")
+    void meetingSignWebsocket(@RequestParam("userId")String userId);
+
+    /**
+     * 29根据name获取所有参与用户
+     * userNames
+     * @return
+     */
+    @GetMapping("/sys/api/queryUserByNames")
+    List<LoginUser> queryUserByNames(@RequestParam("userNames")String[] userNames);
+
+
+    /**
+     * 30获取用户的角色集合
+     * @param username
+     * @return
+     */
+    @GetMapping("/sys/api/getUserRoleSet")
+    Set<String> getUserRoleSet(@RequestParam("username")String username);
+
+    /**
+     * 31获取用户的权限集合
+     * @param username
+     * @return
+     */
+    @GetMapping("/sys/api/getUserPermissionSet")
+    Set<String> getUserPermissionSet(@RequestParam("username") String username);
+
+    /**
+     * 32判断是否有online访问的权限
+     * @param onlineAuthDTO
+     * @return
+     */
+    @PostMapping("/sys/api/hasOnlineAuth")
+    boolean hasOnlineAuth(@RequestBody OnlineAuthDTO onlineAuthDTO);
+
+    /**
+     * 33通过部门id获取部门全部信息
+     */
+    @GetMapping("/sys/api/selectAllById")
+    SysDepartModel selectAllById(@RequestParam("id") String id);
+
+    /**
+     * 34根据用户id查询用户所属公司下所有用户ids
+     * @param userId
+     * @return
+     */
+    @GetMapping("/sys/api/queryDeptUsersByUserId")
+    List<String> queryDeptUsersByUserId(@RequestParam("userId") String userId);
+
+
+    //---
+
+    /**
+     * 35查询用户角色信息
+     * @param username
+     * @return
+     */
+    @GetMapping("/sys/api/queryUserRoles")
+    Set<String> queryUserRoles(@RequestParam("username")String username);
+
+    /**
+     * 36查询用户权限信息
+     * @param username
+     * @return
+     */
+    @GetMapping("/sys/api/queryUserAuths")
+    Set<String> queryUserAuths(@RequestParam("username")String username);
+
+    /**
+     * 37根据 id 查询数据库中存储的 DynamicDataSourceModel
+     *
+     * @param dbSourceId
+     * @return
+     */
+    @GetMapping("/sys/api/getDynamicDbSourceById")
+    DynamicDataSourceModel getDynamicDbSourceById(@RequestParam("dbSourceId") String dbSourceId);
+
+    /**
+     * 38根据 code 查询数据库中存储的 DynamicDataSourceModel
+     *
+     * @param dbSourceCode
+     * @return
+     */
+    @GetMapping("/sys/api/getDynamicDbSourceByCode")
+    DynamicDataSourceModel getDynamicDbSourceByCode(@RequestParam("dbSourceCode") String dbSourceCode);
+
+    /**
+     * 39根据用户账号查询用户信息 CommonAPI中定义
+     * @param username
+     */
+    @GetMapping("/sys/api/getUserByName")
+    LoginUser getUserByName(@RequestParam("username") String username);
+
+    /**
+     * 40字典表的 翻译
+     * @param table
+     * @param text
+     * @param code
+     * @param key
+     * @return
+     */
+    @GetMapping("/sys/api/translateDictFromTable")
+    String translateDictFromTable(@RequestParam("table") String table, @RequestParam("text") String text, @RequestParam("code") String code, @RequestParam("key") String key,@RequestParam("extendsKey") String extendsKey, @RequestParam("extendsValue") String extendsValue);
+
+    /**
+     * 41普通字典的翻译
+     * @param code
+     * @param key
+     * @return
+     */
+    @GetMapping("/sys/api/translateDict")
+    String translateDict(@RequestParam("code") String code, @RequestParam("key") String key,@RequestParam("extendsKey") String extendsKey, @RequestParam("extendsValue") String extendsValue);
+
+    /**
+     * 42查询数据权限
+     * @return
+     */
+    @GetMapping("/sys/api/queryPermissionDataRule")
+    List<SysPermissionDataRuleModel> queryPermissionDataRule(@RequestParam("component") String component, @RequestParam("requestPath")String requestPath, @RequestParam("username") String username);
+
+    /**
+     * 43查询用户信息
+     * @param username
+     * @return
+     */
+    @GetMapping("/sys/api/getCacheUser")
+    SysUserCacheInfo getCacheUser(@RequestParam("username") String username);
+
+    /**
+     * 36根据多个用户账号(逗号分隔),查询返回多个用户信息
+     * @param usernames
+     * @return
+     */
+    @GetMapping("/sys/api/queryUsersByUsernames")
+    List<JSONObject> queryUsersByUsernames(String usernames);
+
+    /**
+     * 37根据多个用户ID(逗号分隔),查询返回多个用户信息
+     * @param ids
+     * @return
+     */
+    @GetMapping("/sys/api/queryUsersByIds")
+    List<JSONObject> queryUsersByIds(String ids);
+
+    /**
+     * 38根据多个部门编码(逗号分隔),查询返回多个部门信息
+     * @param orgCodes
+     * @return
+     */
+    @GetMapping("/sys/api/queryDepartsByOrgcodes")
+    List<JSONObject> queryDepartsByOrgcodes(String orgCodes);
+    /**
+     * 39根据多个部门编码(逗号分隔),查询返回多个部门信息
+     * @param ids
+     * @return
+     */
+    @GetMapping("/sys/api/queryDepartsByOrgIds")
+    List<JSONObject> queryDepartsByOrgIds(String ids);
+    
+    /**
+     * 40发送邮件消息
+     * @param email
+     * @param title
+     * @param content
+     */
+    @GetMapping("/sys/api/sendEmailMsg")
+    void sendEmailMsg(@RequestParam("email")String email,@RequestParam("title")String title,@RequestParam("content")String content);
+    /**
+     * 41 获取公司下级部门和公司下所有用户id
+     * @param orgCode
+     */
+    @GetMapping("/sys/api/getDeptUserByOrgCode")
+    List<Map> getDeptUserByOrgCode(@RequestParam("orgCode")String orgCode);
+}

+ 272 - 0
jeecg-boot-base/jeecg-boot-base-api/jeecg-system-cloud-api/src/main/java/org/jeecg/common/system/api/fallback/SysBaseAPIFallback.java

@@ -0,0 +1,272 @@
+package org.jeecg.common.system.api.fallback;
+
+import com.alibaba.fastjson.JSONObject;
+import lombok.Setter;
+import lombok.extern.slf4j.Slf4j;
+import org.jeecg.common.api.dto.OnlineAuthDTO;
+import org.jeecg.common.api.dto.message.*;
+import org.jeecg.common.system.api.ISysBaseAPI;
+import org.jeecg.common.system.vo.*;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * 进入fallback的方法 检查是否token未设置
+ */
+@Slf4j
+public class SysBaseAPIFallback implements ISysBaseAPI {
+
+    @Setter
+    private Throwable cause;
+
+    @Override
+    public void sendSysAnnouncement(MessageDTO message) {
+        log.error("发送消息失败 {}", cause);
+    }
+
+    @Override
+    public void sendBusAnnouncement(BusMessageDTO message) {
+        log.error("发送消息失败 {}", cause);
+    }
+
+    @Override
+    public void sendTemplateAnnouncement(TemplateMessageDTO message) {
+        log.error("发送消息失败 {}", cause);
+    }
+
+    @Override
+    public void sendBusTemplateAnnouncement(BusTemplateMessageDTO message) {
+        log.error("发送消息失败 {}", cause);
+    }
+
+    @Override
+    public String parseTemplateByCode(TemplateDTO templateDTO) {
+        log.error("通过模板获取消息内容失败 {}", cause);
+        return null;
+    }
+
+    @Override
+    public LoginUser getUserById(String id) {
+        return null;
+    }
+
+    @Override
+    public List<String> getRolesByUsername(String username) {
+        return null;
+    }
+
+    @Override
+    public List<String> getDepartIdsByUsername(String username) {
+        return null;
+    }
+
+    @Override
+    public List<String> getDepartNamesByUsername(String username) {
+        return null;
+    }
+
+    @Override
+    public List<DictModel> queryDictItemsByCode(String code) {
+        return null;
+    }
+
+    @Override
+    public List<DictModel> queryAllDict() {
+        return null;
+    }
+
+    @Override
+    public List<SysCategoryModel> queryAllDSysCategory() {
+        return null;
+    }
+
+    @Override
+    public List<DictModel> queryTableDictItemsByCode(String table, String text, String code) {
+        return null;
+    }
+
+    @Override
+    public List<DictModel> queryAllDepartBackDictModel() {
+        return null;
+    }
+
+    @Override
+    public void updateSysAnnounReadFlag(String busType, String busId) {
+
+    }
+
+    @Override
+    public List<DictModel> queryFilterTableDictInfo(String table, String text, String code, String filterSql) {
+        return null;
+    }
+
+    @Override
+    public List<String> queryTableDictByKeys(String table, String text, String code, String[] keyArray) {
+        log.error("queryTableDictByKeys查询失败 {}", cause);
+        return null;
+    }
+
+    @Override
+    public List<ComboModel> queryAllUserBackCombo() {
+        return null;
+    }
+
+    @Override
+    public JSONObject queryAllUser(String userIds, Integer pageNo, int pageSize) {
+        return null;
+    }
+
+    @Override
+    public List<ComboModel> queryAllRole(String[] roleIds) {
+        log.error("获取角色信息失败 {}", cause);
+        return null;
+    }
+
+    @Override
+    public List<String> getRoleIdsByUsername(String username) {
+        return null;
+    }
+
+    @Override
+    public String getDepartIdsByOrgCode(String orgCode) {
+        return null;
+    }
+
+    @Override
+    public List<SysDepartModel> getAllSysDepart() {
+        return null;
+    }
+
+    @Override
+    public DictModel getParentDepartId(String departId) {
+        return null;
+    }
+
+    @Override
+    public List<String> getDeptHeadByDepId(String deptId) {
+        return null;
+    }
+
+    @Override
+    public void sendWebSocketMsg(String[] userIds, String cmd) {
+
+    }
+
+    @Override
+    public List<LoginUser> queryAllUserByIds(String[] userIds) {
+        return null;
+    }
+
+    @Override
+    public void meetingSignWebsocket(String userId) {
+
+    }
+
+    @Override
+    public List<LoginUser> queryUserByNames(String[] userNames) {
+        return null;
+    }
+
+    @Override
+    public Set<String> getUserRoleSet(String username) {
+        return null;
+    }
+
+    @Override
+    public Set<String> getUserPermissionSet(String username) {
+        return null;
+    }
+
+    @Override
+    public boolean hasOnlineAuth(OnlineAuthDTO onlineAuthDTO) {
+        return false;
+    }
+
+    @Override
+    public SysDepartModel selectAllById(String id) {
+        return null;
+    }
+
+    @Override
+    public List<String> queryDeptUsersByUserId(String userId) {
+        return null;
+    }
+
+    @Override
+    public Set<String> queryUserRoles(String username) {
+        return null;
+    }
+
+    @Override
+    public Set<String> queryUserAuths(String username) {
+        return null;
+    }
+
+    @Override
+    public DynamicDataSourceModel getDynamicDbSourceById(String dbSourceId) {
+        return null;
+    }
+
+    @Override
+    public DynamicDataSourceModel getDynamicDbSourceByCode(String dbSourceCode) {
+        return null;
+    }
+
+    @Override
+    public LoginUser getUserByName(String username) {
+        log.error("通过用户名获取当前登录用户信息 {}", cause);
+        return null;
+    }
+
+    @Override
+    public String translateDictFromTable(String table, String text, String code, String key,String ekey,String evalue) {
+        return null;
+    }
+
+    @Override
+    public String translateDict(String code, String key,String ekey,String evalue) {
+        return null;
+    }
+
+    @Override
+    public List<SysPermissionDataRuleModel> queryPermissionDataRule(String component, String requestPath, String username) {
+        return null;
+    }
+
+    @Override
+    public SysUserCacheInfo getCacheUser(String username) {
+        log.error("获取用户信息失败 {}", cause);
+        return null;
+    }
+
+    @Override
+    public List<JSONObject> queryUsersByUsernames(String usernames) {
+        return null;
+    }
+
+    @Override
+    public List<JSONObject> queryUsersByIds(String ids) {
+        return null;
+    }
+
+    @Override
+    public List<JSONObject> queryDepartsByOrgcodes(String orgCodes) {
+        return null;
+    }
+    @Override
+    public void sendEmailMsg(String email,String title,String content) {
+
+    }
+
+    @Override
+    public List<Map> getDeptUserByOrgCode(String orgCode) {
+        return null;
+    }
+
+    @Override
+    public List<JSONObject> queryDepartsByOrgIds(String ids) {
+        return null;
+    }
+}

+ 0 - 1
jeecg-boot-base/jeecg-boot-base-api/jeecg-system-local-api/pom.xml

@@ -8,7 +8,6 @@
         <version>2.4.5</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
-
     <artifactId>jeecg-system-local-api</artifactId>
     <dependencies>
         <!--nacos discovery-->

+ 13 - 0
jeecg-boot-base/jeecg-boot-base-api/jeecg-system-local-api/src/main/java/org/jeecg/common/system/api/ICommonService.java

@@ -0,0 +1,13 @@
+package org.jeecg.common.system.api;
+
+/**
+ * <p>
+ * 用户表 服务类
+ * </p>
+ *
+ * @Author scott
+ * @since 2018-12-20
+ */
+public interface ICommonService {
+    String getRoleCodeByUserId(String userId);
+}

+ 23 - 13
jeecg-boot-base/jeecg-boot-base-core/pom.xml

@@ -216,28 +216,38 @@
 			<artifactId>guava</artifactId>
 			<version>${guava.version}</version>
 		</dependency>
+		<!-- 第三方登录  -->
+		<dependency>
+			<groupId>com.xkcoding.justauth</groupId>
+			<artifactId>justauth-spring-boot-starter</artifactId>
+		</dependency>
+		<!--<dependency>
+			<groupId>com.squareup.okhttp3</groupId>
+			<artifactId>okhttp</artifactId>
+		</dependency>
+-->
+
+		<!-- pagehelper-->
+		<dependency>
+			<groupId>com.github.pagehelper</groupId>
+			<artifactId>pagehelper</artifactId>
+			<version>5.1.10</version>
+			<scope>compile</scope>
+		</dependency>
 
-		<!-- 阿里云短信 -->
 		<dependency>
-			<groupId>com.aliyun</groupId>
-			<artifactId>aliyun-java-sdk-dysmsapi</artifactId>
-			<version>${aliyun-java-sdk-dysmsapi.version}</version>
+			<groupId>com.google.code.gson</groupId>
+			<artifactId>gson</artifactId>
+			<version>2.8.6</version>
 		</dependency>
+
 		<!-- aliyun oss -->
 		<dependency>
 			<groupId>com.aliyun.oss</groupId>
 			<artifactId>aliyun-sdk-oss</artifactId>
 			<version>${aliyun.oss.version}</version>
 		</dependency>
-		<!-- 第三方登录  -->
-		<dependency>
-			<groupId>com.xkcoding.justauth</groupId>
-			<artifactId>justauth-spring-boot-starter</artifactId>
-		</dependency>
-		<dependency>
-			<groupId>com.squareup.okhttp3</groupId>
-			<artifactId>okhttp</artifactId>
-		</dependency>
+
 	</dependencies>
 
 </project>

+ 2 - 2
jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/api/CommonAPI.java

@@ -54,7 +54,7 @@ public interface CommonAPI {
      * @param key
      * @return
      */
-    String translateDictFromTable(String table, String text, String code, String key);
+    String translateDictFromTable(String table, String text, String code, String key,String extendsKey,String extendsValue);
 
     /**
      * 7普通字典的翻译
@@ -62,7 +62,7 @@ public interface CommonAPI {
      * @param key
      * @return
      */
-    String translateDict(String code, String key);
+    String translateDict(String code, String key,String extendsKey,String extendsValue);
 
     /**
      * 8查询数据权限

+ 0 - 47
jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/api/desform/ISysTranslateAPI.java

@@ -1,47 +0,0 @@
-package org.jeecg.common.api.desform;
-
-import org.jeecg.common.system.vo.DictModel;
-
-import java.util.List;
-import java.util.Map;
-
-/**
- * 表单设计器【System】翻译API接口
- *
- * @author sunjianlei
- */
-public interface ISysTranslateAPI {
-
-    /**
-     * 查询分类字典翻译
-     */
-    List<String> categoryLoadDictItem(String ids);
-
-    /**
-     * 根据字典code加载字典text
-     *
-     * @param dictCode 顺序:tableName,text,code
-     * @param keys     要查询的key
-     * @return
-     */
-    List<String> dictLoadDictItem(String dictCode, String keys);
-
-    /**
-     * 获取字典数据
-     *
-     * @param dictCode 顺序:tableName,text,code
-     * @param dictCode 要查询的key
-     * @return
-     */
-    List<DictModel> dictGetDictItems(String dictCode);
-
-    /**
-     * 【JSearchSelectTag下拉搜索组件专用接口】
-     * 大数据量的字典表 走异步加载  即前端输入内容过滤数据
-     *
-     * @param dictCode 字典code格式:table,text,code
-     * @return
-     */
-    List<DictModel> dictLoadDict(String dictCode, String keyword, Integer pageSize);
-
-}

+ 2 - 0
jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/api/dto/LogDTO.java

@@ -1,6 +1,8 @@
 package org.jeecg.common.api.dto;
+
 import lombok.Data;
 import org.jeecg.common.system.vo.LoginUser;
+
 import java.io.Serializable;
 import java.util.Date;
 

+ 0 - 5
jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/api/dto/message/MessageDTO.java

@@ -24,11 +24,6 @@ public class MessageDTO implements Serializable {
     protected String toUser;
 
     /**
-     * 发送给所有人
-     */
-    protected boolean toAll;
-
-    /**
      * 消息主题
      */
     protected String title;

+ 1 - 0
jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/api/dto/message/TemplateMessageDTO.java

@@ -1,6 +1,7 @@
 package org.jeecg.common.api.dto.message;
 
 import lombok.Data;
+
 import java.io.Serializable;
 import java.util.Map;
 

+ 22 - 2
jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/api/vo/Result.java

@@ -115,13 +115,33 @@ public class Result<T> implements Serializable {
 
 	public static<T> Result<T> error(String msg, T data) {
 		Result<T> r = new Result<T>();
-		r.setSuccess(false);
-		r.setCode(CommonConstant.SC_INTERNAL_SERVER_ERROR_500);
+		r.setSuccess(true);
+		r.setCode(CommonConstant.SC_OK_200);
 		r.setMessage(msg);
 		r.setResult(data);
 		return r;
 	}
 
+	public static<T> Result<T> successMsg(String msg,T t) {
+		Result<T> r = new Result<T>();
+		r.setSuccess(true);
+		r.setCode(CommonConstant.STATUS_NORMAL);
+		r.setResult(t);
+		r.setMessage(msg);
+		return r;
+	}
+
+	public static<T> Result<T> errorMsg(String msg) {
+		Result<T> r = new Result<T>();
+		r.setSuccess(true);
+		r.setCode(CommonConstant.STATUS_DISABLE);
+		//r.setResult(t);
+		r.setMessage(msg);
+		return r;
+	}
+
+
+	
 	public static Result<Object> error(String msg) {
 		return error(CommonConstant.SC_INTERNAL_SERVER_ERROR_500, msg);
 	}

+ 22 - 38
jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/aspect/DictAspect.java

@@ -10,22 +10,22 @@ import org.aspectj.lang.ProceedingJoinPoint;
 import org.aspectj.lang.annotation.Around;
 import org.aspectj.lang.annotation.Aspect;
 import org.aspectj.lang.annotation.Pointcut;
-import org.jeecg.common.api.CommonAPI;
 import org.jeecg.common.api.vo.Result;
 import org.jeecg.common.aspect.annotation.Dict;
 import org.jeecg.common.constant.CommonConstant;
-import org.jeecg.modules.base.service.BaseCommonService;
+import org.jeecg.common.system.service.ICoreService;
 import org.jeecg.common.util.oConvertUtils;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.stereotype.Component;
 import org.springframework.util.StringUtils;
+
 import java.lang.reflect.Field;
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
 
+
 /**
  * @Description: 字典aop类
  * @Author: dangzhenghui
@@ -36,20 +36,19 @@ import java.util.List;
 @Component
 @Slf4j
 public class DictAspect {
-
-    @Autowired
-    private CommonAPI commonAPI;
     @Autowired
-    public RedisTemplate redisTemplate;
+    private ICoreService coreService;
 
-    // 定义切点Pointcut
-    @Pointcut("execution(public * org.jeecg.modules..*.*Controller.*(..))")
+    /**
+     * 定义切点Pointcut
+     */
+    @Pointcut("execution(public * org.jeecg.modules..*.*Controller.*(..))||execution(public * cn.com.ctop..*.*Controller.*(..))||execution(public * ctop.bytedane.ad..*.*Controller.*(..))")
     public void excudeService() {
     }
 
     @Around("excudeService()")
     public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
-    	long time1=System.currentTimeMillis();	
+        long time1 = System.currentTimeMillis();
         Object result = pjp.proceed();
         long time2=System.currentTimeMillis();
         log.debug("获取JSON数据 耗时:"+(time2-time1)+"ms");
@@ -104,17 +103,24 @@ public class DictAspect {
                             String code = field.getAnnotation(Dict.class).dicCode();
                             String text = field.getAnnotation(Dict.class).dicText();
                             String table = field.getAnnotation(Dict.class).dictTable();
+                            String extendsKey = field.getAnnotation(Dict.class).extendsKey();
+                            if("".equals(extendsKey.trim())){
+                                extendsKey = null;
+                            }
+                            String extendsValue = field.getAnnotation(Dict.class).extendsValue();
+                            if("".equals(extendsValue.trim())){
+                                extendsValue = null;
+                            }
                             String key = String.valueOf(item.get(field.getName()));
-
                             //翻译字典值对应的txt
-                            String textValue = translateDictValue(code, text, table, key);
+                            String textValue = translateDictValue(code, text, table, key,extendsKey,extendsValue);
 
                             log.debug(" 字典Val : "+ textValue);
                             log.debug(" __翻译字典字段__ "+field.getName() + CommonConstant.DICT_TEXT_SUFFIX+": "+ textValue);
                             item.put(field.getName() + CommonConstant.DICT_TEXT_SUFFIX, textValue);
                         }
                         //date类型默认转换string格式化日期
-                        if (field.getType().getName().equals("java.util.Date")&&field.getAnnotation(JsonFormat.class)==null&&item.get(field.getName())!=null){
+                        if ("java.util.Date".equals(field.getType().getName()) && field.getAnnotation(JsonFormat.class) == null && item.get(field.getName()) != null) {
                             SimpleDateFormat aDate=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                             item.put(field.getName(), aDate.format(new Date((Long) item.get(field.getName()))));
                         }
@@ -135,7 +141,7 @@ public class DictAspect {
      * @param key
      * @return
      */
-    private String translateDictValue(String code, String text, String table, String key) {
+    private String translateDictValue(String code, String text, String table, String key,String extendsKey,String extendsValue) {
     	if(oConvertUtils.isEmpty(key)) {
     		return null;
     	}
@@ -147,32 +153,11 @@ public class DictAspect {
             if (k.trim().length() == 0) {
                 continue; //跳过循环
             }
-            //update-begin--Author:scott -- Date:20210531 ----for: !56 优化微服务应用下存在表字段需要字典翻译时加载缓慢问题-----
             if (!StringUtils.isEmpty(table)){
-                log.info("--DictAspect------dicTable="+ table+" ,dicText= "+text+" ,dicCode="+code);
-                String keyString = String.format("sys:cache:dictTable::SimpleKey [%s,%s,%s,%s]",table,text,code,k.trim());
-                if (redisTemplate.hasKey(keyString)){
-                    try {
-                        tmpValue = oConvertUtils.getString(redisTemplate.opsForValue().get(keyString));
-                    } catch (Exception e) {
-                        log.warn(e.getMessage());
-                    }
-                }else {
-                    tmpValue= commonAPI.translateDictFromTable(table,text,code,k.trim());
-                }
+                tmpValue= coreService.queryTableDictTextByKey(table,text,code,k.trim(),extendsKey,extendsValue);
             }else {
-                String keyString = String.format("sys:cache:dict::%s:%s",code,k.trim());
-                if (redisTemplate.hasKey(keyString)){
-                    try {
-                        tmpValue = oConvertUtils.getString(redisTemplate.opsForValue().get(keyString));
-                    } catch (Exception e) {
-                       log.warn(e.getMessage());
-                    }
-                }else {
-                    tmpValue = commonAPI.translateDict(code, k.trim());
-                }
+                tmpValue = coreService.queryDictTextByKey(code, k.trim(),extendsKey,extendsValue);
             }
-            //update-end--Author:scott -- Date:20210531 ----for: !56 优化微服务应用下存在表字段需要字典翻译时加载缓慢问题-----
 
             if (tmpValue != null) {
                 if (!"".equals(textValue.toString())) {
@@ -184,5 +169,4 @@ public class DictAspect {
         }
         return textValue.toString();
     }
-
 }

+ 4 - 5
jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/aspect/PermissionDataAspect.java

@@ -8,6 +8,7 @@ import org.aspectj.lang.annotation.Pointcut;
 import org.aspectj.lang.reflect.MethodSignature;
 import org.jeecg.common.api.CommonAPI;
 import org.jeecg.common.aspect.annotation.PermissionData;
+import org.jeecg.common.system.service.ICoreService;
 import org.jeecg.common.system.util.JeecgDataAutorUtils;
 import org.jeecg.common.system.util.JwtUtil;
 import org.jeecg.common.system.vo.SysPermissionDataRuleModel;
@@ -31,10 +32,8 @@ import java.util.List;
 @Component
 @Slf4j
 public class PermissionDataAspect {
-
     @Autowired
-    private CommonAPI commonAPI;
-
+    private ICoreService coreService;
     @Pointcut("@annotation(org.jeecg.common.aspect.annotation.PermissionData)")
     public void pointCut() {
 
@@ -55,12 +54,12 @@ public class PermissionDataAspect {
         String username = JwtUtil.getUserNameByToken(request);
         //查询数据权限信息
         //TODO 微服务情况下也得支持缓存机制
-        List<SysPermissionDataRuleModel> dataRules = commonAPI.queryPermissionDataRule(component, requestPath, username);
+        List<SysPermissionDataRuleModel> dataRules = coreService.queryPermissionDataRule(component, requestPath, username);
         if(dataRules!=null && dataRules.size()>0) {
             //临时存储
             JeecgDataAutorUtils.installDataSearchConditon(request, dataRules);
             //TODO 微服务情况下也得支持缓存机制
-            SysUserCacheInfo userinfo = commonAPI.getCacheUser(username);
+            SysUserCacheInfo userinfo = coreService.getCacheUser(username);
             JeecgDataAutorUtils.installUserInfo(request, userinfo);
         }
         return  point.proceed();

+ 18 - 0
jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/aspect/annotation/Dict.java

@@ -39,4 +39,22 @@ public @interface Dict {
      * @return 返回类型: String
      */
     String dictTable() default "";
+
+    /**
+     * 方法描述: 数据字典表
+     * 作    者: dangzhenghui
+     * 日    期: 2019年03月17日-下午9:37:16
+     *
+     * @return 返回类型: String
+     */
+    String extendsKey() default "";
+
+    /**
+     * 方法描述: 数据字典表
+     * 作    者: dangzhenghui
+     * 日    期: 2019年03月17日-下午9:37:16
+     *
+     * @return 返回类型: String
+     */
+    String extendsValue() default "";
 }

+ 186 - 0
jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/system/entity/SysDepart.java

@@ -0,0 +1,186 @@
+package org.jeecg.common.system.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+import org.jeecg.common.aspect.annotation.Dict;
+import org.jeecgframework.poi.excel.annotation.Excel;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.io.Serializable;
+import java.util.Date;
+import java.util.Objects;
+
+/**
+ * <p>
+ * 部门表
+ * <p>
+ *
+ * @Author Steve
+ * @Since 2019-01-22
+ */
+@Data
+@TableName("sys_depart")
+public class SysDepart implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * ID
+     */
+    @TableId(type = IdType.ID_WORKER_STR)
+    private String id;
+    /**
+     * 父机构ID
+     */
+    private String parentId;
+    /**
+     * 机构/部门名称
+     */
+    @Excel(name = "机构/部门名称", width = 15)
+    private String departName;
+    /**
+     * 英文名
+     */
+    @Excel(name = "英文名", width = 15)
+    private String departNameEn;
+    /**
+     * 缩写
+     */
+    private String departNameAbbr;
+    /**
+     * 排序
+     */
+    @Excel(name = "排序", width = 15)
+    private Integer departOrder;
+    /**
+     * 描述
+     */
+    @Excel(name = "描述", width = 15)
+    private String description;
+    /**
+     * 机构类别 1组织机构,2岗位
+     */
+    @Excel(name = "机构类别", width = 15, dicCode = "org_category")
+    private String orgCategory;
+    /**
+     * 机构类型
+     */
+    private String orgType;
+    /**
+     * 机构编码
+     */
+    @Excel(name = "机构编码", width = 15)
+    private String orgCode;
+    /**
+     * 手机号
+     */
+    @Excel(name = "手机号", width = 15)
+    private String mobile;
+    /**
+     * 传真
+     */
+    @Excel(name = "传真", width = 15)
+    private String fax;
+    /**
+     * 地址
+     */
+    @Excel(name = "地址", width = 15)
+    private String address;
+    /**
+     * 备注
+     */
+    @Excel(name = "备注", width = 15)
+    private String memo;
+    /**
+     * 状态(1启用,0不启用)
+     */
+    @Dict(dicCode = "depart_status")
+    private String status;
+    /**
+     * 删除状态(0,正常,1已删除)
+     */
+    @Dict(dicCode = "del_flag")
+    private String delFlag;
+    /**
+     * 创建人
+     */
+    private String createBy;
+    /**
+     * 创建日期
+     */
+    @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date createTime;
+    /**
+     * 更新人
+     */
+    private String updateBy;
+    /**
+     * 更新日期
+     */
+    @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date updateTime;
+    /**
+     * 领导 ID
+     */
+    private String leaderId;
+
+    @TableField(exist = false)
+    private String title;
+
+    /**
+     * 领导姓名
+     */
+    private String leaderName;
+
+    /**
+     * 重写equals方法
+     */
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+        if (!super.equals(o)) {
+            return false;
+        }
+        SysDepart depart = (SysDepart) o;
+        return Objects.equals(id, depart.id) &&
+                Objects.equals(parentId, depart.parentId) &&
+                Objects.equals(departName, depart.departName) &&
+                Objects.equals(departNameEn, depart.departNameEn) &&
+                Objects.equals(departNameAbbr, depart.departNameAbbr) &&
+                Objects.equals(departOrder, depart.departOrder) &&
+                Objects.equals(description, depart.description) &&
+                Objects.equals(orgType, depart.orgType) &&
+                Objects.equals(orgCode, depart.orgCode) &&
+                Objects.equals(mobile, depart.mobile) &&
+                Objects.equals(fax, depart.fax) &&
+                Objects.equals(address, depart.address) &&
+                Objects.equals(memo, depart.memo) &&
+                Objects.equals(status, depart.status) &&
+                Objects.equals(delFlag, depart.delFlag) &&
+                Objects.equals(createBy, depart.createBy) &&
+                Objects.equals(createTime, depart.createTime) &&
+                Objects.equals(updateBy, depart.updateBy) &&
+                Objects.equals(updateTime, depart.updateTime);
+    }
+
+    /**
+     * 重写hashCode方法
+     */
+    @Override
+    public int hashCode() {
+        return Objects.hash(super.hashCode(), id, parentId, departName,
+                departNameEn, departNameAbbr, departOrder, description,
+                orgType, orgCode, mobile, fax, address, memo, status,
+                delFlag, createBy, createTime, updateBy, updateTime);
+    }
+}

+ 82 - 0
jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/system/entity/SysDict.java

@@ -0,0 +1,82 @@
+package org.jeecg.common.system.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableLogic;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * <p>
+ * 字典表
+ * </p>
+ *
+ * @Author zhangweijian
+ * @since 2018-12-28
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+public class SysDict implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * id
+     */
+    @TableId(type = IdType.ID_WORKER_STR)
+    private String id;
+
+    /**
+     * [预留字段,暂时无用]
+     * 字典类型,0 string,1 number类型,2 boolean
+     * 前端js对stirng类型和number类型 boolean 类型敏感,需要区分。在select 标签匹配的时候会用到
+     * 默认为string类型
+     */
+    private Integer type;
+
+    /**
+     * 字典名称
+     */
+    private String dictName;
+
+    /**
+     * 字典编码
+     */
+    private String dictCode;
+
+    /**
+     * 描述
+     */
+    private String description;
+
+    /**
+     * 删除状态
+     */
+    @TableLogic
+    private Integer delFlag;
+
+    /**
+     * 创建人
+     */
+    private String createBy;
+
+    /**
+     * 创建时间
+     */
+    private Date createTime;
+
+    /**
+     * 更新人
+     */
+    private String updateBy;
+
+    /**
+     * 更新时间
+     */
+    private Date updateTime;
+}

+ 183 - 0
jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/system/entity/SysPermission.java

@@ -0,0 +1,183 @@
+package org.jeecg.common.system.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+import org.jeecg.common.aspect.annotation.Dict;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * <p>
+ * 菜单权限表
+ * </p>
+ *
+ * @Author scott
+ * @since 2018-12-21
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+public class SysPermission implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * id
+	 */
+	@TableId(type = IdType.ID_WORKER_STR)
+	private String id;
+
+	/**
+	 * 父id
+	 */
+	private String parentId;
+
+	/**
+	 * 菜单名称
+	 */
+	private String name;
+
+	/**
+	 * 菜单权限编码,例如:“sys:schedule:list,sys:schedule:info”,多个逗号隔开
+	 */
+	private String perms;
+	/**
+	 * 权限策略1显示2禁用
+	 */
+	private String permsType;
+
+	/**
+	 * 菜单图标
+	 */
+	private String icon;
+
+	/**
+	 * 组件
+	 */
+	private String component;
+
+	/**
+	 * 组件名字
+	 */
+	private String componentName;
+
+	/**
+	 * 路径
+	 */
+	private String url;
+	/**
+	 * 一级菜单跳转地址
+	 */
+	private String redirect;
+
+	/**
+	 * 菜单排序
+	 */
+	private Double sortNo;
+
+	/**
+	 * 类型(0:一级菜单;1:子菜单 ;2:按钮权限)
+	 */
+	@Dict(dicCode = "menu_type")
+	private Integer menuType;
+
+	/**
+	 * 是否叶子节点: 1:是  0:不是
+	 */
+	@TableField(value="is_leaf")
+	private boolean leaf;
+
+	/**
+	 * 是否路由菜单: 0:不是  1:是(默认值1)
+	 */
+	@TableField(value="is_route")
+	private boolean route;
+
+
+	/**
+	 * 是否缓存页面: 0:不是  1:是(默认值1)
+	 */
+	@TableField(value="keep_alive")
+	private boolean keepAlive;
+
+	/**
+	 * 描述
+	 */
+	private String description;
+
+	/**
+	 * 创建人
+	 */
+	private String createBy;
+
+	/**
+	 * 删除状态 0正常 1已删除
+	 */
+	private Integer delFlag;
+
+	/**
+	 * 是否配置菜单的数据权限 1是0否 默认0
+	 */
+	private Integer ruleFlag;
+
+	/**
+	 * 是否隐藏路由菜单: 0否,1是(默认值0)
+	 */
+	private boolean hidden;
+
+	/**
+	 * 创建时间
+	 */
+	private Date createTime;
+
+	/**
+	 * 更新人
+	 */
+	private String updateBy;
+
+	/**
+	 * 更新时间
+	 */
+	private Date updateTime;
+
+	/**按钮权限状态(0无效1有效)*/
+	private String status;
+
+	/**alwaysShow*/
+    private boolean alwaysShow;
+
+
+	/*update_begin author:wuxianquan date:20190908 for:实体增加字段 */
+    /** 外链菜单打开方式 0/内部打开 1/外部打开 */
+    private boolean internalOrExternal;
+	/*update_end author:wuxianquan date:20190908 for:实体增加字段 */
+
+    public SysPermission() {
+
+    }
+    public SysPermission(boolean index) {
+    	if(index) {
+    		this.id = "9502685863ab87f0ad1134142788a385";
+        	this.name="首页";
+        	this.component="dashboard/Analysis";
+        	this.componentName="dashboard-analysis";
+        	this.url="/dashboard/analysis";
+        	this.icon="home";
+        	this.menuType=0;
+        	this.sortNo=0.0;
+        	this.ruleFlag=0;
+        	this.delFlag=0;
+        	this.alwaysShow=false;
+        	this.route=true;
+        	this.keepAlive=true;
+        	this.leaf=true;
+        	this.hidden=false;
+    	}
+
+    }
+}

+ 82 - 0
jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/system/entity/SysPermissionDataRule.java

@@ -0,0 +1,82 @@
+package org.jeecg.common.system.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * <p>
+ * 菜单权限规则表
+ * </p>
+ *
+ * @Author huangzhilin
+ * @since 2019-03-29
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+public class SysPermissionDataRule implements Serializable {
+	
+	private static final long serialVersionUID = 1L;
+	
+	/**
+	 * id
+	 */
+	@TableId(type = IdType.ASSIGN_ID)
+	private String id;
+	
+	/**
+	 * 对应的菜单id
+	 */
+	private String permissionId;
+	
+	/**
+	 * 规则名称
+	 */
+	private String ruleName;
+	
+	/**
+	 * 字段
+	 */
+	private String ruleColumn;
+	
+	/**
+	 * 条件
+	 */
+	private String ruleConditions;
+	
+	/**
+	 * 规则值
+	 */
+	private String ruleValue;
+	
+	/**
+	 * 状态值 1有效 0无效
+	 */
+	private String status;
+	
+	/**
+	 * 创建时间
+	 */
+	private Date createTime;
+	
+	/**
+	 * 创建人
+	 */
+	private String createBy;
+	
+	/**
+	 * 修改时间
+	 */
+	private Date updateTime;
+	
+	/**
+	 * 修改人
+	 */
+	private String updateBy;
+}

+ 223 - 0
jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/system/entity/SysUser.java

@@ -0,0 +1,223 @@
+package org.jeecg.common.system.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableLogic;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+import org.jeecg.common.aspect.annotation.Dict;
+import org.jeecgframework.poi.excel.annotation.Excel;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * <p>
+ * 用户表
+ * </p>
+ *
+ * @Author scott
+ * @since 2018-12-20
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+public class SysUser implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * id
+     */
+    @TableId(type = IdType.UUID)
+    private String id;
+
+    private String departId;
+
+    /**
+     * 登录账号
+     */
+    @Excel(name = "登录账号", width = 15)
+    private String username;
+
+    /**
+     * 真实姓名
+     */
+    @Excel(name = "真实姓名", width = 15)
+    private String realname;
+
+    /**
+     * 密码
+     */
+    @JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
+    private String password;
+
+    /**
+     * md5密码盐
+     */
+    @JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
+    private String salt;
+
+    /**
+     * 头像
+     */
+    @Excel(name = "头像", width = 15,type = 2)
+    private String avatar;
+
+    /**
+     * 生日
+     */
+    @Excel(name = "生日", width = 15, format = "yyyy-MM-dd")
+    @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd")
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
+    private Date birthday;
+
+    /**
+     * 性别(1:男 2:女)
+     */
+    @Excel(name = "性别", width = 15, dicCode = "sex")
+    @Dict(dicCode = "sex")
+    private Integer sex;
+
+    /**
+     * 电子邮件
+     */
+    @Excel(name = "电子邮件", width = 15)
+    private String email;
+
+    /**
+     * 电话
+     */
+    @Excel(name = "电话", width = 15)
+    private String phone;
+
+    /**
+     * 部门code(当前选择登录部门)
+     */
+    private String orgCode;
+
+    /**
+     * 状态(1:正常  2:冻结 )
+     */
+    @Excel(name = "状态", width = 15,dicCode="user_status")
+    @Dict(dicCode = "user_status")
+    private Integer status;
+
+    /**
+     * 删除状态(0,正常,1已删除)
+     */
+    @Excel(name = "删除状态", width = 15,dicCode="del_flag")
+    @TableLogic
+    private Integer delFlag;
+
+    /**
+     * 工号,唯一键
+     */
+    @Excel(name = "工号", width = 15)
+    private String workNo;
+
+    /**
+     * 职务,关联职务表
+     */
+    @Excel(name = "职务", width = 15)
+    private String post;
+
+    /**
+     * 座机号
+     */
+    @Excel(name = "座机号", width = 15)
+    private String telephone;
+
+    /**
+     * 创建人
+     */
+    private String createBy;
+
+    /**
+     * 创建时间
+     */
+    private Date createTime;
+
+    /**
+     * 更新人
+     */
+    private String updateBy;
+
+    /**
+     * 更新时间
+     */
+    private Date updateTime;
+    /**
+     * 同步工作流引擎1同步0不同步
+     */
+    private Integer activitiSync;
+
+    /**
+     * 身份(0 普通成员 1 上级)
+     */
+    @Excel(name="(1普通成员 2上级)",width = 15)
+    private Integer userIdentity;
+
+    /**
+     * 负责部门
+     */
+    @Excel(name="负责部门",width = 15,dictTable ="sys_depart",dicText = "depart_name",dicCode = "id")
+    @Dict(dictTable ="sys_depart",dicText = "depart_name",dicCode = "id")
+    private String departIds;
+
+
+    /**
+     * 第三方登录的唯一标识
+     */
+    private String thirdId;
+
+    /**
+     * 第三方类型 <br>
+     * (github/github,wechat_enterprise/企业微信,dingtalk/钉钉)
+     */
+    private String thirdType;
+
+    /**
+     * 职务
+     */
+    @TableField(exist = false)
+    private String position;
+    /**
+     * 区域
+     */
+    @TableField(exist = false)
+    private String area;
+    /**
+     * 部门
+     */
+    @TableField(exist = false)
+    private String depart;
+
+    /**
+     * 角色
+     */
+    @TableField(exist = false)
+    private String roleName;
+
+    /**
+     * 组织机构名称
+     */
+    @TableField(exist = false)
+    private String departName;
+
+    /**
+     * 领导 ID
+     */
+    private String leaderId;
+
+    /**
+     * 领导姓名
+     */
+    private String leaderName;
+
+}

+ 38 - 0
jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/system/mapper/CoreMapper.java

@@ -0,0 +1,38 @@
+package org.jeecg.common.system.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Param;
+import org.jeecg.common.system.entity.SysDepart;
+import org.jeecg.common.system.entity.SysDict;
+import org.jeecg.common.system.entity.SysPermissionDataRule;
+import org.jeecg.common.system.entity.SysUser;
+import org.jeecg.common.system.vo.DictModel;
+
+import java.util.List;
+
+/**
+ * <p>
+ * 字典表 Mapper 接口
+ * </p>
+ *
+ * @Author zhangweijian
+ * @since 2018-12-28
+ */
+public interface CoreMapper extends BaseMapper<SysDict> {
+	//1
+	String queryDictTextByKey(@Param("code") String code,@Param("key") String key,@Param("extendsKey") String extendsKey,@Param("extendsValue")String extendsValue);
+	//2
+	String queryTableDictTextByKey(@Param("table") String table,@Param("text") String text,@Param("code") String code,@Param("key") String key,@Param("extendsKey") String extendsKey,@Param("extendsValue")String extendsValue);
+
+	SysUser getUserByName(@Param("username")String username);
+
+	List<SysDepart> queryUserDeparts(@Param("userId")String id);
+
+	List<String> queryDataRuleIds(@Param("username") String username,@Param("permissionId") String permissionId);
+
+	List<DictModel> queryDictItemsByCode(@Param("code")String code);
+
+	List<SysPermissionDataRule> selectSysPermissionDataRuleList(@Param("idList") List<String> idList, @Param("status") int status);
+
+	List<DictModel> queryTableDictItemsByCode(@Param("table")String dicTable, @Param("text")String dicText, @Param("code")String dicCode);
+}

+ 46 - 0
jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/system/mapper/CorePermissionMapper.java

@@ -0,0 +1,46 @@
+package org.jeecg.common.system.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
+import org.apache.ibatis.annotations.Update;
+import org.jeecg.common.system.entity.SysPermission;
+
+import java.util.List;
+
+/**
+ * <p>
+ * 菜单权限表 Mapper 接口
+ * </p>
+ *
+ * @Author scott
+ * @since 2018-12-21
+ */
+public interface CorePermissionMapper extends BaseMapper<SysPermission> {
+
+	/**
+	  *   根据用户查询用户权限
+	 */
+	public List<SysPermission> queryByUser(@Param("username") String username);
+
+	/**
+	 *   修改菜单状态字段: 是否子节点
+	 */
+	@Update("update sys_permission set is_leaf=#{leaf} where id = #{id}")
+	public int setMenuLeaf(@Param("id") String id, @Param("leaf") int leaf);
+
+	/**
+	  *   获取模糊匹配规则的数据权限URL
+	 */
+	@Select("SELECT url FROM sys_permission WHERE del_flag = 0 and menu_type = 2 and url like '%*%'")
+    public List<String> queryPermissionUrlWithStar();
+
+
+	/**
+	 * 根据用户账号查询菜单权限
+	 * @param sysPermission
+	 * @param username
+	 * @return
+	 */
+	public int queryCountByUsername(@Param("username") String username, @Param("permission") SysPermission sysPermission);
+}

+ 59 - 0
jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/system/mapper/xml/CoreMapper.xml

@@ -0,0 +1,59 @@
+<?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.common.system.mapper.CoreMapper">
+	<!-- 通过字典code获取字典数据 -->
+	<select id="queryDictTextByKey" parameterType="String"  resultType="String">
+		   select s.item_text from sys_dict_item s
+		   where s.dict_id = (select id from sys_dict where dict_code = #{code})
+		   and s.item_value = #{key}
+		<if test="extendsKey != null and extendsValue != null">
+			and s.${extendsKey} = #{extendsValue}
+		</if>
+	</select>
+
+	<!--通过查询指定table的 text code key 获取字典值-->
+	<select id="queryTableDictTextByKey" parameterType="String" resultType="String">
+		   select ${text} as "text" from ${table} where ${code}= #{key}
+		<if test="extendsKey!=null and extendsValue!=null">
+			and ${extendsKey} = #{extendsValue}
+		</if>
+	</select>
+	<select id="queryDataRuleIds" resultType="java.lang.String">
+			select data_rule_ids
+			from sys_role_permission a
+			join sys_permission b on a.permission_id = b.id
+			join sys_role c on a.role_id = c.id
+			join sys_user_role d on d.role_id = c.id
+			join sys_user e on d.user_id = e.id
+			where e.username = #{username} and b.id =  #{permissionId}
+			<!--update begin Author:lvdandan  Date:20200213 for:加入部门权限 -->
+			union
+			select data_rule_ids
+			from sys_depart_role_permission a
+			join sys_permission b on a.permission_id = b.id
+			join sys_depart_role c on a.role_id = c.id
+			join sys_depart_role_user d on d.drole_id = c.id
+			join sys_user e on d.user_id = e.id
+			where e.username = #{username} and b.id = #{permissionId}
+			<!--update end Author:lvdandan  Date:20200213 for:加入部门权限 -->
+	</select>
+	<select id="selectSysPermissionDataRuleList"
+			resultType="org.jeecg.common.system.entity.SysPermissionDataRule">
+		select * from sys_permission_data_rule
+		where 1 = 1
+		and staus = #{status}
+		and id in
+		<foreach collection="idList" item="item" separator=","
+				 open="(" close=")">
+			#{item}
+		</foreach>
+	</select>
+    <select id="queryDictItemsByCode" resultType="org.jeecg.common.system.vo.DictModel">
+		select s.item_value as "value",s.item_text as "text" from sys_dict_item s
+		where dict_id = (select id from sys_dict where dict_code = #{code})
+		order by s.sort_order asc
+	</select>
+	<select id="queryTableDictItemsByCode" resultType="org.jeecg.common.system.vo.DictModel">
+		select ${text} as "text",${code} as "value" from ${table}
+	</select>
+</mapper>

+ 79 - 0
jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/system/mapper/xml/CorePermissionMapper.xml

@@ -0,0 +1,79 @@
+<?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.common.system.mapper.CorePermissionMapper">
+
+	<!-- 通过<resultMap>映射实体类属性名和表的字段名对应关系 -->
+	<resultMap id="SysPermission" type="org.jeecg.common.system.entity.SysPermission">
+	   	<!-- result属性映射非匹配字段 -->
+		<result column="is_route" property="route"/>
+	    <result column="keep_alive" property="keepAlive"/>
+	    <result column="is_leaf" property="leaf"/>
+	</resultMap>
+	
+	<!-- 获取登录用户拥有的权限 -->
+	<select id="queryByUser" parameterType="Object"  resultMap="SysPermission">
+		   SELECT * FROM (
+			   SELECT p.*
+			   FROM  sys_permission p
+			   WHERE (exists(
+						select a.id from sys_role_permission a
+						join sys_role b on a.role_id = b.id
+						join sys_user_role c on c.role_id = b.id
+						join sys_user d on d.id = c.user_id
+						where p.id = a.permission_id AND d.username = #{username,jdbcType=VARCHAR}
+					)
+					or (p.url like '%:code' and p.url like '/online%' and p.hidden = 1)
+					or p.url = '/online')
+			   and p.del_flag = 0
+			<!--update begin Author:lvdandan  Date:20200213 for:加入部门权限 -->
+			   UNION
+			   SELECT p.*
+			   FROM  sys_permission p
+			   WHERE exists(
+					select a.id from sys_depart_role_permission a
+					join sys_depart_role b on a.role_id = b.id
+					join sys_depart_role_user c on c.drole_id = b.id
+					join sys_user d on d.id = c.user_id
+					where p.id = a.permission_id AND d.username = #{username,jdbcType=VARCHAR}
+			   )
+			   and p.del_flag = 0
+			<!--update end Author:lvdandan  Date:20200213 for:加入部门权限 -->
+		   ) h order by h.sort_no ASC
+	</select>
+
+
+	<!-- 根据用户账号查询菜单权限 -->
+	<select id="queryCountByUsername" parameterType="Object" resultType="int">
+		select sum(cnt) from (
+		  select count(*) as cnt
+			from sys_role_permission a
+			join sys_permission b on a.permission_id = b.id
+			join sys_role c on a.role_id = c.id
+			join sys_user_role d on d.role_id = c.id
+			join sys_user e on d.user_id = e.id
+			where e.username = #{username}
+			<if test="permission.id !=null and permission.id != ''">
+				and b.id =  #{permission.id}
+			</if>
+			<if test="permission.url !=null and permission.url != ''">
+				and b.url =  #{permission.url}
+			</if>
+		union all
+		  select count(*) as cnt
+			from sys_permission z
+		    join sys_depart_role_permission y on z.id = y.permission_id
+			join sys_depart_role x on y.role_id = x.id
+			join sys_depart_role_user w on w.drole_id = x.id
+			join sys_user v on w.user_id = v.id
+			where v.username = #{username}
+			<if test="permission.id !=null and permission.id != ''">
+				and z.id =  #{permission.id}
+			</if>
+			<if test="permission.url !=null and permission.url != ''">
+				and z.url =  #{permission.url}
+			</if>
+		) temp
+	</select>
+	
+
+</mapper>

+ 39 - 0
jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/system/service/ICoreService.java

@@ -0,0 +1,39 @@
+package org.jeecg.common.system.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.jeecg.common.constant.CacheConstant;
+import org.jeecg.common.system.entity.SysDict;
+import org.jeecg.common.system.vo.DictModel;
+import org.jeecg.common.system.vo.LoginUser;
+import org.jeecg.common.system.vo.SysPermissionDataRuleModel;
+import org.jeecg.common.system.vo.SysUserCacheInfo;
+import org.springframework.cache.annotation.Cacheable;
+
+import java.util.List;
+
+/**
+ * <p>
+ * 字典表 服务类
+ * </p>
+ *
+ * @Author zhangweijian
+ * @since 2018-12-28
+ */
+public interface ICoreService extends IService<SysDict> {
+	//2
+    public String queryDictTextByKey(String code, String key,String extendsKey,String extendsValue);
+
+    //1
+	String queryTableDictTextByKey(String table, String text, String code, String key,String extendsKey,String extendsValue);
+	//3
+    List<SysPermissionDataRuleModel> queryPermissionDataRule(String component, String requestPath, String username);
+
+    SysUserCacheInfo getCacheUser(String username);
+
+    @Cacheable(cacheNames= CacheConstant.SYS_USERS_CACHE, key="#username")
+    LoginUser getUserByName(String username);
+
+    List<DictModel> queryDictItemsByCode(String dicCode);
+
+    List<DictModel> queryTableDictItemsByCode(String dicTable, String dicText, String dicCode);
+}

+ 221 - 0
jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/system/service/impl/CoreServiceImpl.java

@@ -0,0 +1,221 @@
+package org.jeecg.common.system.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import lombok.extern.slf4j.Slf4j;
+import org.jeecg.common.aspect.UrlMatchEnum;
+import org.jeecg.common.constant.CacheConstant;
+import org.jeecg.common.constant.CommonConstant;
+import org.jeecg.common.system.entity.*;
+import org.jeecg.common.system.mapper.CoreMapper;
+import org.jeecg.common.system.mapper.CorePermissionMapper;
+import org.jeecg.common.system.service.ICoreService;
+import org.jeecg.common.system.vo.DictModel;
+import org.jeecg.common.system.vo.LoginUser;
+import org.jeecg.common.system.vo.SysPermissionDataRuleModel;
+import org.jeecg.common.system.vo.SysUserCacheInfo;
+import org.jeecg.common.util.oConvertUtils;
+import org.springframework.beans.BeanUtils;
+import org.springframework.cache.annotation.Cacheable;
+import org.springframework.stereotype.Service;
+import org.springframework.util.AntPathMatcher;
+import org.springframework.util.PathMatcher;
+
+import javax.annotation.Resource;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * <p>
+ * 字典表 服务实现类
+ * </p>
+ *
+ * @Author zhangweijian
+ * @since 2018-12-28
+ */
+@Service
+@Slf4j
+public class CoreServiceImpl extends ServiceImpl<CoreMapper, SysDict> implements ICoreService {
+
+    @Resource
+    private CoreMapper coreMapper;
+    @Resource
+	private CorePermissionMapper corePermissionMapper;
+	/**
+	 * 通过查询指定code 获取字典值text
+	 * @param code
+	 * @param key
+	 * @return
+	 */
+	@Override
+	public String queryDictTextByKey(String code, String key,String extendsKey,String extendsValue) {
+		return coreMapper.queryDictTextByKey(code, key,extendsKey,extendsValue);
+	}
+
+	/**
+	 * 通过查询指定table的 text code 获取字典值text
+	 * dictTableCache采用redis缓存有效期10分钟
+	 * @param table
+	 * @param text
+	 * @param code
+	 * @param key
+	 * @return
+	 */
+	@Override
+	public String queryTableDictTextByKey(String table,String text,String code, String key,String extendsKey,String extendsValue) {
+		return coreMapper.queryTableDictTextByKey(table,text,code,key,extendsKey,extendsValue);
+	}
+
+	@Override
+	public List<SysPermissionDataRuleModel> queryPermissionDataRule(String component, String requestPath, String username) {
+		List<SysPermission> currentSyspermission = null;
+		if(oConvertUtils.isNotEmpty(component)) {
+			//1.通过注解属性pageComponent 获取菜单
+			LambdaQueryWrapper<SysPermission> query = new LambdaQueryWrapper<SysPermission>();
+			query.eq(SysPermission::getDelFlag,0);
+			query.eq(SysPermission::getComponent, component);
+			currentSyspermission = corePermissionMapper.selectList(query);
+		}else {
+			//1.直接通过前端请求地址查询菜单
+			LambdaQueryWrapper<SysPermission> query = new LambdaQueryWrapper<SysPermission>();
+			query.eq(SysPermission::getMenuType,2);
+			query.eq(SysPermission::getDelFlag,0);
+			query.eq(SysPermission::getUrl, requestPath);
+			currentSyspermission = corePermissionMapper.selectList(query);
+			//2.未找到 再通过自定义匹配URL 获取菜单
+			if(currentSyspermission==null || currentSyspermission.size()==0) {
+				//通过自定义URL匹配规则 获取菜单(实现通过菜单配置数据权限规则,实际上针对获取数据接口进行数据规则控制)
+				String userMatchUrl = UrlMatchEnum.getMatchResultByUrl(requestPath);
+				LambdaQueryWrapper<SysPermission> queryQserMatch = new LambdaQueryWrapper<SysPermission>();
+				queryQserMatch.eq(SysPermission::getMenuType, 1);
+				queryQserMatch.eq(SysPermission::getDelFlag, 0);
+				queryQserMatch.eq(SysPermission::getUrl, userMatchUrl);
+				if(oConvertUtils.isNotEmpty(userMatchUrl)){
+					currentSyspermission = corePermissionMapper.selectList(queryQserMatch);
+				}
+			}
+			//3.未找到 再通过正则匹配获取菜单
+			if(currentSyspermission==null || currentSyspermission.size()==0) {
+				//通过正则匹配权限配置
+				String regUrl = getRegexpUrl(requestPath);
+				if(regUrl!=null) {
+					currentSyspermission = corePermissionMapper.selectList(new LambdaQueryWrapper<SysPermission>().eq(SysPermission::getMenuType,2).eq(SysPermission::getUrl, regUrl).eq(SysPermission::getDelFlag,0));
+				}
+			}
+		}
+		if(currentSyspermission!=null && currentSyspermission.size()>0){
+			List<SysPermissionDataRuleModel> dataRules = new ArrayList<SysPermissionDataRuleModel>();
+			for (SysPermission sysPermission : currentSyspermission) {
+				// update-begin--Author:scott Date:20191119 for:数据权限规则编码不规范,项目存在相同包名和类名 #722
+				List<SysPermissionDataRule> temp = queryPermissionDataRules(username, sysPermission.getId());
+				if(temp!=null && temp.size()>0) {
+					//dataRules.addAll(temp);
+					dataRules = oConvertUtils.entityListToModelList(temp,SysPermissionDataRuleModel.class);
+				}
+				// update-end--Author:scott Date:20191119 for:数据权限规则编码不规范,项目存在相同包名和类名 #722
+			}
+			return dataRules;
+		}
+		return null;
+	}
+
+	/**
+	 * 匹配前端传过来的地址 匹配成功返回正则地址
+	 * AntPathMatcher匹配地址
+	 *()* 匹配0个或多个字符
+	 *()**匹配0个或多个目录
+	 */
+	private String getRegexpUrl(String url) {
+		List<String> list = corePermissionMapper.queryPermissionUrlWithStar();
+		if(list!=null && list.size()>0) {
+			for (String p : list) {
+				PathMatcher matcher = new AntPathMatcher();
+				if(matcher.match(p, url)) {
+					return p;
+				}
+			}
+		}
+		return null;
+	}
+
+	public List<SysPermissionDataRule> queryPermissionDataRules(String username,String permissionId) {
+		List<String> idsList = coreMapper.queryDataRuleIds(username, permissionId);
+		//update-begin--Author:scott  Date:20191119  for:数据权限失效问题处理--------------------
+		if(idsList==null || idsList.size()==0) {
+			return null;
+		}
+		//update-end--Author:scott  Date:20191119  for:数据权限失效问题处理--------------------
+		List<String> idList = new ArrayList<>();
+		for (String ids : idsList) {
+			if(oConvertUtils.isEmpty(ids)) {
+				continue;
+			}
+			String[] arr = ids.split(",");
+			for (String id : arr) {
+				if(oConvertUtils.isNotEmpty(id)) {
+					idList.add(id);
+				}
+			}
+		}
+		if(idList.size()==0) {
+			return null;
+		}
+		return coreMapper.selectSysPermissionDataRuleList(idList,1);
+	}
+
+	@Override
+	public SysUserCacheInfo getCacheUser(String username) {
+		SysUserCacheInfo info = new SysUserCacheInfo();
+		info.setOneDepart(true);
+		LoginUser user = this.getUserByName(username);
+		if(user!=null) {
+			info.setSysUserCode(user.getUsername());
+			info.setSysUserName(user.getRealname());
+			info.setSysOrgCode(user.getOrgCode());
+		}
+		//多部门支持in查询
+		List<SysDepart> list = coreMapper.queryUserDeparts(user.getId());
+		List<String> sysMultiOrgCode = new ArrayList<String>();
+		if(list==null || list.size()==0) {
+			//当前用户无部门
+			//sysMultiOrgCode.add("0");
+		}else if(list.size()==1) {
+			sysMultiOrgCode.add(list.get(0).getOrgCode());
+		}else {
+			info.setOneDepart(false);
+			for (SysDepart dpt : list) {
+				sysMultiOrgCode.add(dpt.getOrgCode());
+			}
+		}
+		info.setSysMultiOrgCode(sysMultiOrgCode);
+		return info;
+	}
+
+	@Override
+	@Cacheable(cacheNames= CacheConstant.SYS_USERS_CACHE, key="#username")
+	public LoginUser getUserByName(String username) {
+		if(oConvertUtils.isEmpty(username)) {
+			return null;
+		}
+		LoginUser loginUser = new LoginUser();
+		SysUser sysUser = coreMapper.getUserByName(username);
+		if(sysUser==null) {
+			return null;
+		}
+		BeanUtils.copyProperties(sysUser, loginUser);
+		return loginUser;
+	}
+
+	@Override
+	public List<DictModel> queryDictItemsByCode(String dicCode) {
+		return coreMapper.queryDictItemsByCode(dicCode);
+	}
+
+	@Override
+	public List<DictModel> queryTableDictItemsByCode(String dicTable, String dicText, String dicCode) {
+		return coreMapper.queryTableDictItemsByCode(dicTable,dicText,dicCode);
+	}
+}

+ 3 - 48
jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/util/CommonUtils.java

@@ -1,7 +1,5 @@
 package org.jeecg.common.util;
 
-import cn.hutool.core.util.StrUtil;
-import cn.hutool.extra.pinyin.PinyinUtil;
 import lombok.extern.slf4j.Slf4j;
 import org.jeecg.common.constant.CommonConstant;
 import org.jeecg.common.constant.DataBaseConstant;
@@ -14,7 +12,6 @@ import org.springframework.web.multipart.MultipartFile;
 import javax.sql.DataSource;
 import java.io.ByteArrayInputStream;
 import java.io.File;
-import java.io.IOException;
 import java.io.InputStream;
 import java.sql.Connection;
 import java.sql.DatabaseMetaData;
@@ -75,8 +72,7 @@ public class CommonUtils {
             fileName = fileName.substring(pos + 1);
         }
         //替换上传文件名字的特殊字符
-        fileName = fileName.replace("=","").replace(",","").replace("&","")
-                .replace("#", "").replace("“", "").replace("”", "");
+        fileName = fileName.replace("=","").replace(",","").replace("&","").replace("#", "");
         //替换上传文件名字中的空格
         fileName=fileName.replaceAll("\\s","");
         return fileName;
@@ -108,44 +104,6 @@ public class CommonUtils {
         }
         return url;
     }
-    /**
-     * 本地文件上传
-     * @param mf 文件
-     * @param bizPath  自定义路径
-     * @return
-     */
-    public static String uploadLocal(MultipartFile mf,String bizPath,String uploadpath){
-        try {
-            String fileName = null;
-            File file = new File(uploadpath + File.separator + bizPath + File.separator );
-            if (!file.exists()) {
-                file.mkdirs();// 创建文件根目录
-            }
-            String orgName = mf.getOriginalFilename();// 获取文件名
-            orgName = CommonUtils.getFileName(orgName);
-            if(orgName.indexOf(".")!=-1){
-                fileName = orgName.substring(0, orgName.lastIndexOf(".")) + "_" + System.currentTimeMillis() + orgName.substring(orgName.lastIndexOf("."));
-            }else{
-                fileName = orgName+ "_" + System.currentTimeMillis();
-            }
-            String savePath = file.getPath() + File.separator + fileName;
-            File savefile = new File(savePath);
-            FileCopyUtils.copy(mf.getBytes(), savefile);
-            String dbpath = null;
-            if(oConvertUtils.isNotEmpty(bizPath)){
-                dbpath = bizPath + File.separator + fileName;
-            }else{
-                dbpath = fileName;
-            }
-            if (dbpath.contains("\\")) {
-                dbpath = dbpath.replace("\\", "/");
-            }
-            return dbpath;
-        } catch (IOException e) {
-            log.error(e.getMessage(), e);
-        }
-        return "";
-    }
 
     /**
      * 统一全局上传 带桶
@@ -172,7 +130,7 @@ public class CommonUtils {
             return getDatabaseTypeByDataSource(dataSource);
         } catch (SQLException e) {
             //e.printStackTrace();
-            log.warn(e.getMessage(),e);
+            log.warn(e.getMessage());
             return "";
         }
     }
@@ -197,11 +155,8 @@ public class CommonUtils {
                     DB_TYPE = DataBaseConstant.DB_TYPE_SQLSERVER;
                 }else if(dbType.indexOf("postgresql")>=0) {
                     DB_TYPE = DataBaseConstant.DB_TYPE_POSTGRESQL;
-                }else if(dbType.indexOf("mariadb")>=0) {
-                    DB_TYPE = DataBaseConstant.DB_TYPE_MARIADB;
                 }else {
-                    log.error("数据库类型:[" + dbType + "]不识别!");
-                    //throw new JeecgBootException("数据库类型:["+dbType+"]不识别!");
+                    throw new JeecgBootException("数据库类型:["+dbType+"]不识别!");
                 }
             } catch (Exception e) {
                 log.error(e.getMessage(), e);

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

@@ -101,6 +101,13 @@ public class DateUtils extends PropertyEditorSupport {
     // 各种方式获取的Date
     // ////////////////////////////////////////////////////////////////////////////
 
+    public static Date addSecond(Date date, int seconds) {
+        Calendar calendar = Calendar.getInstance();
+        calendar.setTime(date);
+        calendar.add(Calendar.SECOND, seconds);
+        return calendar.getTime();
+    }
+
     /**
      * 当前日期
      *
@@ -363,6 +370,11 @@ public class DateUtils extends PropertyEditorSupport {
         return datetimeFormat.get().format(getCalendar().getTime());
     }
 
+    public static String formatDateTime(Long time) {
+        return datetimeFormat.get().format(time);
+    }
+
+
     /**
      * 获取时间字符串
      */
@@ -647,4 +659,12 @@ public class DateUtils extends PropertyEditorSupport {
         return calendar.get(Calendar.YEAR);
     }
 
+
+
+    public static Date addHour(Date date, int hour) {
+        Calendar calendar = Calendar.getInstance();
+        calendar.setTime(date);
+        calendar.add(Calendar.HOUR_OF_DAY, hour);
+        return calendar.getTime();
+    }
 }

+ 0 - 122
jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/util/DySmsHelper.java

@@ -1,122 +0,0 @@
-package org.jeecg.common.util;
-
-import org.jeecg.config.StaticConfig;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.alibaba.fastjson.JSONObject;
-import com.aliyuncs.DefaultAcsClient;
-import com.aliyuncs.IAcsClient;
-import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest;
-import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
-import com.aliyuncs.exceptions.ClientException;
-import com.aliyuncs.profile.DefaultProfile;
-import com.aliyuncs.profile.IClientProfile;
-
-/**
- * Created on 17/6/7.
- * 短信API产品的DEMO程序,工程中包含了一个SmsDemo类,直接通过
- * 执行main函数即可体验短信产品API功能(只需要将AK替换成开通了云通信-短信产品功能的AK即可)
- * 工程依赖了2个jar包(存放在工程的libs目录下)
- * 1:aliyun-java-sdk-core.jar
- * 2:aliyun-java-sdk-dysmsapi.jar
- *
- * 备注:Demo工程编码采用UTF-8
- * 国际短信发送请勿参照此DEMO
- */
-public class DySmsHelper {
-	
-	private final static Logger logger=LoggerFactory.getLogger(DySmsHelper.class);
-
-    //产品名称:云通信短信API产品,开发者无需替换
-    static final String product = "Dysmsapi";
-    //产品域名,开发者无需替换
-    static final String domain = "dysmsapi.aliyuncs.com";
-
-    // TODO 此处需要替换成开发者自己的AK(在阿里云访问控制台寻找)
-    static  String accessKeyId;
-    static  String accessKeySecret;
-
-    public static void setAccessKeyId(String accessKeyId) {
-        DySmsHelper.accessKeyId = accessKeyId;
-    }
-
-    public static void setAccessKeySecret(String accessKeySecret) {
-        DySmsHelper.accessKeySecret = accessKeySecret;
-    }
-
-    public static String getAccessKeyId() {
-        return accessKeyId;
-    }
-
-    public static String getAccessKeySecret() {
-        return accessKeySecret;
-    }
-    
-    
-    public static boolean sendSms(String phone,JSONObject templateParamJson,DySmsEnum dySmsEnum) throws ClientException {
-    	//可自助调整超时时间
-        System.setProperty("sun.net.client.defaultConnectTimeout", "10000");
-        System.setProperty("sun.net.client.defaultReadTimeout", "10000");
-
-        //update-begin-author:taoyan date:20200811 for:配置类数据获取
-        StaticConfig staticConfig = SpringContextUtils.getBean(StaticConfig.class);
-        setAccessKeyId(staticConfig.getAccessKeyId());
-        setAccessKeySecret(staticConfig.getAccessKeySecret());
-        //update-end-author:taoyan date:20200811 for:配置类数据获取
-        
-        //初始化acsClient,暂不支持region化
-        IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, accessKeySecret);
-        DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", product, domain);
-        IAcsClient acsClient = new DefaultAcsClient(profile);
-        
-        //验证json参数
-        validateParam(templateParamJson,dySmsEnum);
-        
-        //组装请求对象-具体描述见控制台-文档部分内容
-        SendSmsRequest request = new SendSmsRequest();
-        //必填:待发送手机号
-        request.setPhoneNumbers(phone);
-        //必填:短信签名-可在短信控制台中找到
-        request.setSignName(dySmsEnum.getSignName());
-        //必填:短信模板-可在短信控制台中找到
-        request.setTemplateCode(dySmsEnum.getTemplateCode());
-        //可选:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}"时,此处的值为
-        request.setTemplateParam(templateParamJson.toJSONString());
-        
-        //选填-上行短信扩展码(无特殊需求用户请忽略此字段)
-        //request.setSmsUpExtendCode("90997");
-
-        //可选:outId为提供给业务方扩展字段,最终在短信回执消息中将此值带回给调用者
-        //request.setOutId("yourOutId");
-
-        boolean result = false;
-
-        //hint 此处可能会抛出异常,注意catch
-        SendSmsResponse sendSmsResponse = acsClient.getAcsResponse(request);
-        logger.info("短信接口返回的数据----------------");
-        logger.info("{Code:" + sendSmsResponse.getCode()+",Message:" + sendSmsResponse.getMessage()+",RequestId:"+ sendSmsResponse.getRequestId()+",BizId:"+sendSmsResponse.getBizId()+"}");
-        if ("OK".equals(sendSmsResponse.getCode())) {
-            result = true;
-        }
-        return result;
-        
-    }
-    
-    private static void validateParam(JSONObject templateParamJson,DySmsEnum dySmsEnum) {
-    	String keys = dySmsEnum.getKeys();
-    	String [] keyArr = keys.split(",");
-    	for(String item :keyArr) {
-    		if(!templateParamJson.containsKey(item)) {
-    			throw new RuntimeException("模板缺少参数:"+item);
-    		}
-    	}
-    }
-    
-
-//    public static void main(String[] args) throws ClientException, InterruptedException {
-//    	JSONObject obj = new JSONObject();
-//    	obj.put("code", "1234");
-//    	sendSms("13800138000", obj, DySmsEnum.FORGET_PASSWORD_TEMPLATE_CODE);
-//    }
-}

+ 39 - 0
jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/util/MD5Util.java

@@ -1,8 +1,40 @@
 package org.jeecg.common.util;
 
+import org.springframework.util.DigestUtils;
+
+import java.io.FileInputStream;
 import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
 
 public class MD5Util {
+	private static ThreadLocal<MessageDigest> MD5 = new ThreadLocal<MessageDigest>() {
+		@Override
+		protected MessageDigest initialValue() {
+			try {
+				return MessageDigest.getInstance("MD5");
+			} catch (NoSuchAlgorithmException e) {
+				throw new IllegalStateException("No md5 algorithm found");
+			}
+		}
+	};
+
+	public static String toHexStr(byte[] bytes) {
+		int j = bytes.length;
+		char[] str = new char[j * 2];
+		int k = 0;
+		for (int i = 0; i < j; i++) {
+			byte byte0 = bytes[i];
+			str[k++] = HEX_DIGITS_CHAR[byte0 >>> 4 & 0xf];
+			str[k++] = HEX_DIGITS_CHAR[byte0 & 0xf];
+		}
+		return String.valueOf(str);
+	}
+
+	public static String getMd5(String url) {
+		MessageDigest md5 = MD5.get();
+		md5.reset();
+		return toHexStr(md5.digest(url.getBytes()));
+	}
 
 	public static String byteArrayToHexString(byte b[]) {
 		StringBuffer resultSb = new StringBuffer();
@@ -40,4 +72,11 @@ public class MD5Util {
 	private static final String hexDigits[] = { "0", "1", "2", "3", "4", "5",
 			"6", "7", "8", "9", "a", "b", "c", "d", "e", "f" };
 
+	private static final String[] HEX_DIGITS = {"0", "1", "2", "3", "4", "5",
+			"6", "7", "8", "9", "a", "b", "c", "d", "e", "f" };
+	private static final char[] HEX_DIGITS_CHAR = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
+
+	public static String getFileMd5(String path) throws Exception {
+		return DigestUtils.md5DigestAsHex(new FileInputStream(path));
+	}
 }

+ 2 - 6
jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/util/MinioUtil.java

@@ -75,11 +75,7 @@ public class MinioUtil {
                 orgName=file.getName();
             }
             orgName = CommonUtils.getFileName(orgName);
-            String objectName = bizPath+"/"
-                                +( orgName.indexOf(".")==-1
-                                   ?orgName + "_" + System.currentTimeMillis()
-                                   :orgName.substring(0, orgName.lastIndexOf(".")) + "_" + System.currentTimeMillis() + orgName.substring(orgName.lastIndexOf("."))
-                                 );
+            String objectName = bizPath+"/"+orgName.substring(0, orgName.lastIndexOf(".")) + "_" + System.currentTimeMillis() + orgName.substring(orgName.lastIndexOf("."));
 
             // 使用putObject上传一个本地文件到存储桶中。
             if(objectName.startsWith("/")){
@@ -176,7 +172,7 @@ public class MinioUtil {
         if (minioClient == null) {
             try {
                 minioClient = MinioClient.builder()
-                        .endpoint(minioUrl)
+                        //.endpoint(minioUrl)
                         .credentials(minioName, minioPass)
                         .build();
             } catch (Exception e) {

+ 1 - 3
jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/util/oss/OssBootUtil.java

@@ -111,9 +111,7 @@ public class OssBootUtil {
               orgName=file.getName();
             }
             orgName = CommonUtils.getFileName(orgName);
-            String fileName = orgName.indexOf(".")==-1
-                              ?orgName + "_" + System.currentTimeMillis()
-                              :orgName.substring(0, orgName.lastIndexOf(".")) + "_" + System.currentTimeMillis() + orgName.substring(orgName.lastIndexOf("."));
+            String fileName = orgName.substring(0, orgName.lastIndexOf(".")) + "_" + System.currentTimeMillis() + orgName.substring(orgName.lastIndexOf("."));
             if (!fileDir.endsWith("/")) {
                 fileDir = fileDir.concat("/");
             }

+ 6 - 5
jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/config/AutoPoiDictConfig.java

@@ -2,9 +2,11 @@ package org.jeecg.config;
 
 import lombok.extern.slf4j.Slf4j;
 import org.jeecg.common.api.CommonAPI;
+import org.jeecg.common.system.service.ICoreService;
 import org.jeecg.common.system.vo.DictModel;
 import org.jeecg.common.util.oConvertUtils;
 import org.jeecgframework.dict.service.AutoPoiDictServiceI;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Lazy;
 import org.springframework.stereotype.Service;
 
@@ -25,9 +27,8 @@ import java.util.List;
 @Slf4j
 @Service
 public class AutoPoiDictConfig implements AutoPoiDictServiceI {
-	@Lazy
-	@Resource
-	private CommonAPI commonAPI;
+	@Autowired
+	private ICoreService coreService;
 
 	/**
 	 * 通过字典查询easypoi,所需字典文本
@@ -42,11 +43,11 @@ public class AutoPoiDictConfig implements AutoPoiDictServiceI {
 		List<DictModel> dictList = null;
 		// step.1 如果没有字典表则使用系统字典表
 		if (oConvertUtils.isEmpty(dicTable)) {
-			dictList = commonAPI.queryDictItemsByCode(dicCode);
+			dictList = coreService.queryDictItemsByCode(dicCode);
 		} else {
 			try {
 				dicText = oConvertUtils.getString(dicText, dicCode);
-				dictList = commonAPI.queryTableDictItemsByCode(dicTable, dicText, dicCode);
+				dictList = coreService.queryTableDictItemsByCode(dicTable, dicText, dicCode);
 			} catch (Exception e) {
 				log.error(e.getMessage(),e);
 			}

+ 16 - 1
jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/config/mybatis/MybatisPlusConfig.java

@@ -1,5 +1,7 @@
 package org.jeecg.config.mybatis;
 
+import com.baomidou.mybatisplus.autoconfigure.ConfigurationCustomizer;
+import com.baomidou.mybatisplus.core.MybatisConfiguration;
 import com.baomidou.mybatisplus.core.parser.ISqlParser;
 import com.baomidou.mybatisplus.core.parser.ISqlParserFilter;
 import com.baomidou.mybatisplus.core.toolkit.PluginUtils;
@@ -26,7 +28,7 @@ import java.util.List;
  *
  */
 @Configuration
-@MapperScan(value={"org.jeecg.modules.**.mapper*"})
+@MapperScan(value={"org.jeecg.**.mapper*","cn.com.ctop.**.mapper*","ctop.bytedance.ad.**.mapper*"})
 public class MybatisPlusConfig {
 
     /**
@@ -139,4 +141,17 @@ public class MybatisPlusConfig {
 //        return new PerformanceInterceptor();
 //    }
 
+
+
+    @Bean
+    ConfigurationCustomizer mybatisConfigurationCustomizer() {
+        return new ConfigurationCustomizer() {
+            @Override
+            public void customize(MybatisConfiguration configuration) {
+                configuration.addInterceptor(new com.github.pagehelper.PageInterceptor());
+            }
+        };
+    }
+
+
 }

+ 0 - 38
jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/config/oss/MinioConfig.java

@@ -1,38 +0,0 @@
-package org.jeecg.config.oss;
-
-import lombok.extern.slf4j.Slf4j;
-import org.jeecg.common.util.MinioUtil;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-
-/**
- * Minio文件上传配置文件
- */
-@Slf4j
-@Configuration
-public class MinioConfig {
-    @Value(value = "${jeecg.minio.minio_url}")
-    private String minioUrl;
-    @Value(value = "${jeecg.minio.minio_name}")
-    private String minioName;
-    @Value(value = "${jeecg.minio.minio_pass}")
-    private String minioPass;
-    @Value(value = "${jeecg.minio.bucketName}")
-    private String bucketName;
-
-    @Bean
-    public void initMinio(){
-        if(!minioUrl.startsWith("http")){
-            minioUrl = "http://" + minioUrl;
-        }
-        if(!minioUrl.endsWith("/")){
-            minioUrl = minioUrl.concat("/");
-        }
-        MinioUtil.setMinioUrl(minioUrl);
-        MinioUtil.setMinioName(minioName);
-        MinioUtil.setMinioPass(minioPass);
-        MinioUtil.setBucketName(bucketName);
-    }
-
-}

+ 0 - 34
jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/config/oss/OssConfiguration.java

@@ -1,34 +0,0 @@
-package org.jeecg.config.oss;
-
-import org.jeecg.common.util.oss.OssBootUtil;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-
-/**
- * 云存储 配置
- */
-@Configuration
-public class OssConfiguration {
-
-    @Value("${jeecg.oss.endpoint}")
-    private String endpoint;
-    @Value("${jeecg.oss.accessKey}")
-    private String accessKeyId;
-    @Value("${jeecg.oss.secretKey}")
-    private String accessKeySecret;
-    @Value("${jeecg.oss.bucketName}")
-    private String bucketName;
-    @Value("${jeecg.oss.staticDomain:}")
-    private String staticDomain;
-
-
-    @Bean
-    public void initOssBootConfiguration() {
-        OssBootUtil.setEndPoint(endpoint);
-        OssBootUtil.setAccessKeyId(accessKeyId);
-        OssBootUtil.setAccessKeySecret(accessKeySecret);
-        OssBootUtil.setBucketName(bucketName);
-        OssBootUtil.setStaticDomain(staticDomain);
-    }
-}

+ 2 - 1
jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/config/shiro/ShiroConfig.java

@@ -134,7 +134,8 @@ public class ShiroConfig {
         filterChainDefinitionMap.put("/websocket/**", "anon");//系统通知和公告
         filterChainDefinitionMap.put("/newsWebsocket/**", "anon");//CMS模块
         filterChainDefinitionMap.put("/vxeSocket/**", "anon");//JVxeTable无痕刷新示例
-
+        //
+        filterChainDefinitionMap.put("/advertiser/aiBytedanceAdvertiserStrategy/**", "anon");
 
         //性能监控  TODO 存在安全漏洞泄露TOEKN(durid连接池也有)
         filterChainDefinitionMap.put("/actuator/**", "anon");

+ 3 - 9
jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/service/impl/BaseCommonServiceImpl.java

@@ -4,23 +4,17 @@ import com.baomidou.mybatisplus.core.toolkit.IdWorker;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.shiro.SecurityUtils;
 import org.jeecg.common.api.dto.LogDTO;
-import org.jeecg.common.constant.CacheConstant;
-import org.jeecg.modules.base.mapper.BaseCommonMapper;
-import org.jeecg.modules.base.service.BaseCommonService;
 import org.jeecg.common.system.vo.LoginUser;
-import org.jeecg.common.system.vo.SysPermissionDataRuleModel;
-import org.jeecg.common.system.vo.SysUserCacheInfo;
 import org.jeecg.common.util.IPUtils;
 import org.jeecg.common.util.SpringContextUtils;
 import org.jeecg.common.util.oConvertUtils;
-import org.springframework.cache.annotation.Cacheable;
+import org.jeecg.modules.base.mapper.BaseCommonMapper;
+import org.jeecg.modules.base.service.BaseCommonService;
 import org.springframework.stereotype.Service;
-import org.springframework.util.AntPathMatcher;
-import org.springframework.util.PathMatcher;
 
 import javax.annotation.Resource;
 import javax.servlet.http.HttpServletRequest;
-import java.util.*;
+import java.util.Date;
 
 @Service
 @Slf4j

+ 76 - 0
jeecg-boot-bytedance-ad/pom.xml

@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>jeecg-boot-parent</artifactId>
+        <groupId>org.jeecgframework.boot</groupId>
+        <version>2.4.5</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+    <artifactId>jeecg-boot-bytedance-ad</artifactId>
+    <dependencies>
+        <dependency>
+            <groupId>org.jeecgframework.boot</groupId>
+            <artifactId>jeecg-boot-base-core</artifactId>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.jeecgframework.boot</groupId>
+                    <artifactId>hibernate-re</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <!--引入微服务启动依赖 starter-->
+        <dependency>
+            <groupId>org.jeecgframework.boot</groupId>
+            <artifactId>jeecg-boot-starter-cloud</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.jeecgframework.boot</groupId>
+            <artifactId>jeecg-system-local-api</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpmime</artifactId>
+            <version>4.5.10</version>
+        </dependency>
+        <dependency>
+            <groupId>com.github.tony19</groupId>
+            <artifactId>apktool-lib</artifactId>
+            <version>1.4.4-3</version>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.googlecode.plist</groupId>
+            <artifactId>dd-plist</artifactId>
+            <version>1.16</version>
+            <scope>compile</scope>
+        </dependency>
+
+    </dependencies>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+            </plugin>
+        </plugins>
+        <resources>
+            <!-- 解决MyBatis配置文件引入问题 -->
+            <resource>
+                <directory>src/main/java</directory>
+                <includes>
+                    <include>**/*.properties</include>
+                    <include>**/*.xml</include>
+                </includes>
+                <!-- 是否替换资源中的属性-->
+                <filtering>true</filtering>
+            </resource>
+            <resource>
+                <directory>src/main/resources</directory>
+                <filtering>true</filtering>
+            </resource>
+        </resources>
+    </build>
+</project>

+ 21 - 0
jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/JeecgBootBytedanceAdApplication.java

@@ -0,0 +1,21 @@
+package ctop.bytedance.ad;
+
+import com.alibaba.dubbo.config.spring.context.annotation.EnableDubbo;
+import org.apache.shiro.spring.boot.autoconfigure.ShiroAnnotationProcessorAutoConfiguration;
+import org.apache.shiro.spring.boot.autoconfigure.ShiroAutoConfiguration;
+import org.apache.shiro.spring.boot.autoconfigure.ShiroBeanAutoConfiguration;
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.cloud.openfeign.EnableFeignClients;
+import org.springframework.context.annotation.ComponentScan;
+
+@SpringBootApplication(exclude = {ShiroAnnotationProcessorAutoConfiguration.class, ShiroAutoConfiguration.class, ShiroBeanAutoConfiguration.class})
+@EnableDubbo
+@ComponentScan(basePackages = {"ctop.bytedance.ad","org.jeecg"})
+public class JeecgBootBytedanceAdApplication {
+
+    public static void main(String[] args) {
+        SpringApplication.run(JeecgBootBytedanceAdApplication.class, args);
+    }
+}

+ 524 - 0
jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/controller/AiBytedanceAdvertiserStrategyController.java

@@ -0,0 +1,524 @@
+package ctop.bytedance.ad.advertise.controller;
+
+import com.alibaba.dubbo.config.annotation.Reference;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import ctop.bytedance.ad.advertise.dockapi.MarketingService;
+import ctop.bytedance.ad.advertise.entity.AiBytedanceAdvertiserStrategy;
+import ctop.bytedance.ad.advertise.entity.RuleDataAccount;
+import ctop.bytedance.ad.advertise.entity.UpdAdStaOrCpaOrBudget;
+import ctop.bytedance.ad.advertise.service.IAiBytedanceAdvertiserStrategyService;
+import ctop.bytedance.ad.advertise.service.IRuleDataAccountService;
+import ctop.bytedance.ad.advertise.vo.AdConvertQueryVo;
+import ctop.bytedance.ad.advertise.vo.AdGroupSearchVo;
+import ctop.bytedance.ad.advertise.vo.PlanSearchVo;
+import ctop.bytedance.ad.common.constant.BytedanceConstant;
+import ctop.bytedance.ad.common.entity.CtopOauthToken;
+import ctop.bytedance.ad.common.entity.MaterialImageInfo;
+import ctop.bytedance.ad.common.entity.UserAllocation;
+import ctop.bytedance.ad.common.service.ICtopOauthTokenService;
+import ctop.bytedance.ad.common.service.IMaterialImageInfoService;
+import ctop.bytedance.ad.common.service.IUserAllocationService;
+import ctop.bytedance.ad.common.utils.*;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.common.system.api.ICommonService;
+import org.jeecg.common.system.query.QueryGenerator;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletRequest;
+import java.math.BigDecimal;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+/**
+ * 头条智能投放账户配置信息表
+ * @author jeecg-boot
+ * @date   2021-04-20
+ * @version V1.0
+ */
+@RestController
+@RequestMapping("/advertiser/aiBytedanceAdvertiserStrategy")
+@Api(tags="头条智能投放账户配置信息表")
+@Slf4j
+public class AiBytedanceAdvertiserStrategyController {
+	@Autowired
+	private IAiBytedanceAdvertiserStrategyService aiBytedanceAdvertiserStrategyService;
+	@Autowired
+	private IRuleDataAccountService ruleDataAccountService;
+	@Autowired
+	private IMaterialImageInfoService materialImageInfoService;
+	@Autowired
+	private MarketingService marketingService;
+	@Autowired
+	private ICtopOauthTokenService tokenService;
+	@Autowired
+	private IUserAllocationService userAllocationService;
+	@Reference
+	private ICommonService commonService;
+
+	/**
+	  * 分页列表查询
+	 * @param aiBytedanceAdvertiserStrategy
+	 * @param pageNo
+	 * @param pageSize
+	 * @param req
+	 * @return
+	 */
+	@ApiOperation(value="头条智能投放账户配置信息表-分页列表查询", notes="头条智能投放账户配置信息表-分页列表查询")
+	@GetMapping(value = "/list")
+	public Result<IPage<AiBytedanceAdvertiserStrategy>> queryPageList(AiBytedanceAdvertiserStrategy aiBytedanceAdvertiserStrategy,
+																	  @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
+																	  @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
+																	  HttpServletRequest req) {
+		Result<IPage<AiBytedanceAdvertiserStrategy>> result = new Result<>();
+		QueryWrapper<AiBytedanceAdvertiserStrategy> queryWrapper = QueryGenerator.initQueryWrapper(aiBytedanceAdvertiserStrategy, req.getParameterMap());
+		//获取用户角色code
+		String roleCode = commonService.getRoleCodeByUserId(aiBytedanceAdvertiserStrategy.getLoginUserId());
+		if(null != roleCode && !BytedanceConstant.COMMON_ROLE_CODE_ADMIN.equals(roleCode)){
+			queryWrapper.eq("user_id", aiBytedanceAdvertiserStrategy.getLoginUserId());
+		}
+		queryWrapper.orderByDesc("create_time");
+		Page<AiBytedanceAdvertiserStrategy> page = new Page<>(pageNo, pageSize);
+		//查询
+		IPage<AiBytedanceAdvertiserStrategy> pageList = aiBytedanceAdvertiserStrategyService.page(page, queryWrapper);
+		pageList.getRecords().forEach(pojo ->{
+			if (!Check.isNull(pojo.getAccountId())){
+				UserAllocation allocation = userAllocationService.getByAccountId(pojo.getAccountId());
+				if(null!=allocation){
+					pojo.setAccountName(allocation.getAuthName());
+				}
+				QueryWrapper<RuleDataAccount> ruleDataAccountQueryWrapper = new QueryWrapper<>();
+				ruleDataAccountQueryWrapper.eq("account_id",pojo.getAccountId());
+				//获取消耗 余额
+				RuleDataAccount ruleDataAccountVo =  ruleDataAccountService.getOne(ruleDataAccountQueryWrapper);
+				if (!Check.isNull(ruleDataAccountVo)){
+					//消耗
+					pojo.setCost(ruleDataAccountVo.getCost());
+					//余额
+					pojo.setValidBalance(ruleDataAccountVo.getValidBalance());
+				}else {
+					pojo.setCost(new BigDecimal(0));
+					pojo.setValidBalance(new BigDecimal(0));
+				}
+				//拼接 目标转化出价
+				pojo.setAdCpaBidStr("FIX".equalsIgnoreCase(pojo.getAdBidCreateType()) ? pojo.getAdCpaBid().toString() : (pojo.getAdMinBid() + "~" + pojo.getAdMaxBid()));
+			}
+		});
+
+		result.setSuccess(true);
+		result.setResult(pageList);
+		return result;
+	}
+
+	/**
+	  *   添加配置信息
+	 * @param aiBytedanceAdvertiserStrategy
+	 * @return
+	 */
+	@ApiOperation(value="头条智能投放账户配置信息表-添加", notes="头条智能投放账户配置信息表-添加")
+	@PostMapping(value = "/addBytedanceStrategy")
+	public Result addBytedanceStrategy(@RequestBody AiBytedanceAdvertiserStrategy aiBytedanceAdvertiserStrategy) {
+		try {
+			//复制功能 防止前端传id到后台
+			aiBytedanceAdvertiserStrategy.setId(null);
+			// 组名称 计划名称 是否重复
+			/*Result<AiBytedanceAdvertiserStrategy> resultName = aiBytedanceAdvertiserStrategyService.getStrategyInfoByName(aiBytedanceAdvertiserStrategy);
+			if (!resultName.isSuccess()) {
+				return Result.error(resultName.getMessage());
+			}*/
+
+			return aiBytedanceAdvertiserStrategyService.addBytedanceStrategy(aiBytedanceAdvertiserStrategy);
+		} catch (Exception e) {
+			log.error(e.getMessage(),e);
+			return Result.error("请求失败,请联系开发人员!");
+		}
+	}
+
+	/**
+	  *  编辑
+	 * @param aiBytedanceAdvertiserStrategy
+	 * @return
+	 */
+	@ApiOperation(value="头条智能投放账户配置信息表-编辑", notes="头条智能投放账户配置信息表-编辑")
+	@PutMapping(value = "/edit")
+	public Result<AiBytedanceAdvertiserStrategy> edit(@RequestBody AiBytedanceAdvertiserStrategy aiBytedanceAdvertiserStrategy) {
+		// 组名称 计划名称 是否重复
+		/*
+		Result<AiBytedanceAdvertiserStrategy> resultName = aiBytedanceAdvertiserStrategyService.getStrategyInfoByName(aiBytedanceAdvertiserStrategy);
+		if (!resultName.isSuccess()) {
+			return Result.errorMsg(resultName.getMessage());
+		}
+		*/
+		CtopOauthToken token = tokenService.getOauthTokenByAccountId(String.valueOf(aiBytedanceAdvertiserStrategy.getAccountId()));
+		//修改后预算金额不能低于当前已消费金额的105%
+		QueryWrapper<RuleDataAccount> ruleDataAccountQueryWrapper = new QueryWrapper<>();
+		ruleDataAccountQueryWrapper.eq("account_id",aiBytedanceAdvertiserStrategy.getAccountId());
+		//获取消耗 余额
+		RuleDataAccount ruleDataAccountVo = ruleDataAccountService.getOne(ruleDataAccountQueryWrapper);
+		// 值 为0 不限预算
+		// !0 指定预算
+		if (!aiBytedanceAdvertiserStrategy.getAccountBudget().equals(new BigDecimal("0"))){
+			//花费 0 不校验
+			int zero= Check.isNull(ruleDataAccountVo) ? 0 : ruleDataAccountVo.getCost().compareTo(BigDecimal.ZERO);
+			if (zero != 0){
+				//  前者 < 后者
+				int a = aiBytedanceAdvertiserStrategy.getAccountBudget().compareTo(ruleDataAccountVo.getCost().multiply(new BigDecimal(1.05)));
+				if (a == -1){
+					return Result.errorMsg("预算金额不能低于当前已消费金额的105%");
+				}
+			}
+		}
+
+		//不修改用户id
+		aiBytedanceAdvertiserStrategy.setUserId(null);
+		//商品卖点
+		aiBytedanceAdvertiserStrategy.setCreativeProductSellingPoints(StringUtils.join(aiBytedanceAdvertiserStrategy.getProductSellingPoints(), ","));
+		//广告位置
+		aiBytedanceAdvertiserStrategy.setCreativeInventoryType(StringUtils.join(aiBytedanceAdvertiserStrategy.getCreativeInventoryTypes(), ","));
+		//创意标签
+		aiBytedanceAdvertiserStrategy.setCreativeAdKeywords(StringUtils.join(aiBytedanceAdvertiserStrategy.getAdKeywords(), ","));
+
+		AiBytedanceAdvertiserStrategy aiBytedanceAdvertiserStrategyEntity = aiBytedanceAdvertiserStrategyService.getById(aiBytedanceAdvertiserStrategy.getId());
+		if (aiBytedanceAdvertiserStrategyEntity == null) {
+			return Result.errorMsg("未找到对应实体");
+		} else {
+			boolean ok = aiBytedanceAdvertiserStrategyService.updateById(aiBytedanceAdvertiserStrategy);
+			if (!ok) {
+				return Result.errorMsg("修改失败!");
+			}
+			//账户预算 同步 头条
+			//BUDGET_MODE_DAY-日预算
+			// BUDGET_MODE_INFINITE-不限
+			String accountBudgetMode = aiBytedanceAdvertiserStrategy.getAccountBudgetMode().equals("1") ? "BUDGET_MODE_INFINITE" : "BUDGET_MODE_DAY";
+			Result resultBudget = marketingService.updateBudget(token,accountBudgetMode,aiBytedanceAdvertiserStrategy.getAccountBudget());
+			/*if (!resultBudget.isSuccess()){
+				return Result.errorMsg(resultBudget.getMessage());
+			}*/
+
+		}
+		return Result.successMsg("修改成功!", null);
+
+	}
+
+	/**
+	  *   通过id删除
+	 * @param id
+	 * @return
+	 */
+	@ApiOperation(value="头条智能投放账户配置信息表-通过id删除", notes="头条智能投放账户配置信息表-通过id删除")
+	@DeleteMapping(value = "/delete")
+	public Result<?> delete(@RequestParam(name="id") String id) {
+		try {
+			aiBytedanceAdvertiserStrategyService.removeById(id);
+		} catch (Exception e) {
+			log.error("删除失败",e);
+			return Result.error("删除失败!");
+		}
+		return Result.successMsg("删除成功!",null);
+	}
+
+	/**
+	 *  批量删除
+	 * @param ids
+	 * @return
+	 */
+	@ApiOperation(value="头条智能投放账户配置信息表-批量删除", notes="头条智能投放账户配置信息表-批量删除")
+	@DeleteMapping(value = "/deleteBatch")
+	public Result<AiBytedanceAdvertiserStrategy> deleteBatch(@RequestParam(name="ids") String ids) {
+		Result<AiBytedanceAdvertiserStrategy> result = new Result<>();
+		if(ids==null || "".equals(ids.trim())) {
+			result.error500("参数不识别!");
+		}else {
+			this.aiBytedanceAdvertiserStrategyService.removeByIds(Arrays.asList(ids.split(",")));
+			result.success("删除成功!");
+		}
+		return result;
+	}
+
+	/**
+	  * 通过id查询
+	 * @param id
+	 * @return
+	 */
+	@ApiOperation(value="头条智能投放账户配置信息表-通过id查询", notes="头条智能投放账户配置信息表-通过id查询")
+	@GetMapping(value = "/queryById")
+	public Result<AiBytedanceAdvertiserStrategy> queryById(@RequestParam(name="id",required=true) String id) {
+		Result<AiBytedanceAdvertiserStrategy> result = new Result<>();
+		AiBytedanceAdvertiserStrategy aiBytedanceAdvertiserStrategy = aiBytedanceAdvertiserStrategyService.getById(id);
+		if(aiBytedanceAdvertiserStrategy==null) {
+			result.error500("未找到对应实体");
+		}else {
+			//商品卖点
+			if (!Check.isNull(aiBytedanceAdvertiserStrategy.getCreativeProductSellingPoints())){
+				aiBytedanceAdvertiserStrategy.setProductSellingPoints(aiBytedanceAdvertiserStrategy.getCreativeProductSellingPoints().split(","));
+			}
+			//广告位置
+			if (!Check.isNull(aiBytedanceAdvertiserStrategy.getCreativeInventoryType())){
+				aiBytedanceAdvertiserStrategy.setCreativeInventoryTypes(aiBytedanceAdvertiserStrategy.getCreativeInventoryType().split(","));
+			}
+			//创意标签
+			if (!Check.isNull(aiBytedanceAdvertiserStrategy.getCreativeAdKeywords())){
+				aiBytedanceAdvertiserStrategy.setAdKeywords(aiBytedanceAdvertiserStrategy.getCreativeAdKeywords().split(","));
+			}
+			//素材图片url
+			MaterialImageInfo materialImageInfo = materialImageInfoService.getByCode(aiBytedanceAdvertiserStrategy.getCreativeProductImageCode());
+			if(null!=materialImageInfo){
+				aiBytedanceAdvertiserStrategy.setImageUrl(materialImageInfo.getUrl());
+			}
+			result.setResult(aiBytedanceAdvertiserStrategy);
+			result.setSuccess(true);
+		}
+		return result;
+	}
+
+	@ApiOperation(value="头条智能投放账户配置信息-修改状态(0开-1关)", notes="头条智能投放账户配置信息-修改状态(0开-1关)")
+	@PutMapping(value = "/updStaById")
+	public Result updStaById(@RequestParam("id")String id,
+							 @ApiParam("状态(0开-1关)") @RequestParam("state") String state,
+							 @ApiParam("账户id") @RequestParam("accountId") String accountId,
+							 @ApiParam("素材类型") @RequestParam("creativeImageMode") String creativeImageMode) {
+		try {
+			return aiBytedanceAdvertiserStrategyService.updStaById(id,state,accountId,creativeImageMode);
+		}catch (Exception e){
+			log.error("修改状态(0开-1关)失败",e);
+			return Result.error("请求失败,请联系开发人员!");
+		}
+
+	}
+
+	@ApiOperation(value="头条智能投放账户配置信息-修改出价;预算", notes="头条智能投放账户配置信息-修改出价;预算")
+	@PutMapping(value = "/updStaOrCpaOrBudgetById")
+	public Result updStaOrCpaOrBudgetById(UpdAdStaOrCpaOrBudget updAdStaOrCpaOrBudget) {
+		try {
+			return aiBytedanceAdvertiserStrategyService.updStaOrCpaOrBudgetById(updAdStaOrCpaOrBudget);
+		}catch (Exception e){
+			log.error("修改出价-预算失败",e);
+			return Result.error("请求失败,请联系开发人员!");
+		}
+
+	}
+
+	@ApiOperation(value="头条智能投放账户配置-获取行业类别", notes="头条智能投放账户配置-获取行业类别")
+	@GetMapping(value = "/getIndustryList")
+	public Result getIndustryList(@RequestParam("accountId") String accountId, @RequestParam(value = "type",defaultValue = "ADVERTISER") String type) {
+		try {
+			return aiBytedanceAdvertiserStrategyService.getIndustryList(accountId,type);
+		}catch (Exception e){
+			log.error("创建失败",e);
+			return Result.error("请求失败,请联系开发人员!");
+		}
+	}
+
+	@ApiOperation(value="头条智能投放账户配置-获取广告组", notes="头条智能投放账户配置-获取广告组")
+	@PostMapping(value = "/getCampaignGroupList")
+	public Result getCampaignGroup(List<AdGroupSearchVo> adGroupSearchVoList,
+								   @RequestParam("accountId") String accountId,
+								   @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
+								   @RequestParam(name="pageSize", defaultValue="10") Integer pageSize) {
+		try {
+			return aiBytedanceAdvertiserStrategyService.getCampaignGroup(accountId,adGroupSearchVoList,pageNo,pageSize);
+		}catch (Exception e){
+			log.error("获取广告组异常。",e);
+			return Result.error("请求失败,请联系开发人员!");
+		}
+	}
+
+	@ApiOperation(value="头条智能投放账户配置-获取广告计划", notes="头条智能投放账户配置-获取广告计划")
+	@PostMapping(value = "/getCampaignPlanList")
+	public Result getCampaignPlanList(PlanSearchVo planSearchVoList,
+								   @RequestParam("accountId") String accountId,
+								   @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
+								   @RequestParam(name="pageSize", defaultValue="10") Integer pageSize) {
+		try {
+			return aiBytedanceAdvertiserStrategyService.getCampaignPlan(accountId,planSearchVoList,pageNo,pageSize);
+		}catch (Exception e){
+			log.error("获取广告计划异常。",e);
+			return Result.error("请求失败,请联系开发人员!");
+		}
+	}
+
+	@ApiOperation(value="头条智能投放账户配置-获取创意详细信息", notes="头条智能投放账户配置-获取创意详细信息")
+	@PostMapping(value = "/creativeReadInfo")
+	public Result creativeReadInfo(@RequestParam("accountId") String accountId,@RequestParam("adId") String adId) {
+		try {
+			return aiBytedanceAdvertiserStrategyService.creativeReadInfo(accountId,adId);
+		}catch (Exception e){
+			log.error("获取广告组异常。",e);
+			return Result.error("请求失败,请联系开发人员!");
+		}
+	}
+
+	@ApiOperation(value="查询广告计划可用转化目标", notes="查询广告计划可用转化目标")
+	@PostMapping(value = "/getToolConvert")
+	public Result getToolConvert(@RequestBody AdConvertQueryVo adConvertQueryVo) {
+		try {
+			return aiBytedanceAdvertiserStrategyService.getToolConvert(adConvertQueryVo);
+		}catch (Exception e){
+			log.error("查询广告计划可用转化目标异常",e);
+			return Result.error("请求失败,请联系开发人员!");
+		}
+	}
+
+	@ApiOperation(value="智能投放测试创建计划", notes="智能投放测试创建计划")
+	@GetMapping("testCreateCreativeLimit")
+	public Map<String, Object> testCreateCreativeLimit(Long accountId, Integer hour) {
+		Map<String, Object> result = new HashMap<>();
+		List<AiBytedanceAdvertiserStrategy> strategys = aiBytedanceAdvertiserStrategyService.getByAccountId(accountId,0);
+		strategys.forEach(strategy->{
+			aiBytedanceAdvertiserStrategyService.customCreativeSupplement(strategy, hour,strategy.getAdOpenUrl());
+		});
+		ResultMapUtils.setResultMap(result, StatusCode.COMMON_SUCCESS);
+		return result;
+	}
+
+	static ExecutorService executorService = Executors.newFixedThreadPool(5);
+
+	@GetMapping("autoCreateCreative")
+	public Map<String, Object> autoCreateCreative(Integer hour) {
+		Map<String, Object> result = new HashMap<>();
+		List<AiBytedanceAdvertiserStrategy> strategys = aiBytedanceAdvertiserStrategyService.getByAccountId(null,0);
+		if (strategys == null||strategys.isEmpty()) {
+			ResultMapUtils.setResultMap(result, StatusCode.COMMON_PARAM_ERROR);
+			return result;
+		}
+		strategys.forEach(strategy -> executorService.submit(()->{
+			aiBytedanceAdvertiserStrategyService.customCreativeSupplement(strategy, hour,strategy.getAdOpenUrl());
+		}));
+		ResultMapUtils.setResultMap(result, StatusCode.COMMON_SUCCESS);
+		return result;
+	}
+
+	/**
+	 *
+	 * 根据下载链接获取应用包名
+	 *
+	 * @param urlPath 下载链接
+	 * @return org.jeecg.common.api.vo.Result
+	 * @author zianY
+	 */
+	@ApiOperation(value="根据下载链接获取应用包名", notes="根据下载链接获取应用包名")
+	@GetMapping(value = "/getPackageNameByUrl")
+	public Result getPackageNameByUrl(@RequestParam("urlPath") String urlPath) {
+		try {
+			Map<String,Object> map = new HashMap();
+			//根据下载链接上传附件
+			urlPath = LoadFileUtil.downLoadFromUrl(urlPath, "appFiles");
+			// android 根据附件地址 读取 apk 信息
+			map = ApkUtils.readAPK(urlPath);
+			if (!map.get("code").toString().equals("-1")){
+				map.put("platform", "APP_ANDROID");
+			}else {
+				//ios
+				map = ApkUtils.readIPA(urlPath);
+				if (!map.get("code").toString().equals("-1")){
+					map.put("platform", "APP_IOS");
+				}
+			}
+			if (map.get("code").toString().equals("-1")){
+				return Result.error(map.get("error").toString()+"请输入正确的链接。");
+			}
+			return Result.successMsg("根据下载链接获取应用包名成功", map);
+		}catch (Exception e){
+			log.error("根据下载链接获取应用包名异常",e);
+			return Result.error("请求失败,请联系开发人员!");
+		}
+	}
+
+	@ApiOperation(value="获取行动号召", notes="获取行动号召")
+	@GetMapping(value = "/getAdActionText")
+	public Result getAdActionText(@RequestParam(value = "accountId",required = false) String accountId,
+								  @RequestParam(value = "landingType",required = false) String landingType,
+								  @RequestParam(value = "advancedCreativeType",required = false) String advancedCreativeType) {
+		try {
+			if (Check.isNull(accountId)){
+				return Result.errorMsg("请选择账户。");
+			}
+			if (Check.isNull(landingType)){
+				return Result.errorMsg("投放内容不能为空");
+			}
+			return aiBytedanceAdvertiserStrategyService.getAdActionText(accountId,landingType,advancedCreativeType);
+		}catch (Exception e){
+			log.error("获取行动号召异常",e);
+			return Result.error("请求失败,请联系开发人员!");
+		}
+	}
+
+	@ApiOperation(value="获取定向包", notes="获取定向包")
+	@GetMapping(value = "/getAdAudiencePackage")
+	public Result getAdAudiencePackage(@RequestParam(value = "accountId",required = false) String accountId,
+									   @RequestParam(value = "landingType",required = false) String landingType,
+									   @RequestParam(value = "deliveryRange",required = false) String deliveryRange) {
+		try {
+			if (Check.isNull(accountId)){
+				return Result.errorMsg("请选择账户。");
+			}
+			// 默认 定向包
+			Result resultDefault = aiBytedanceAdvertiserStrategyService.getAdAudiencePackage(accountId,landingType,"DEFAULT");
+			//穿山甲定向包
+			Result resultUnion = aiBytedanceAdvertiserStrategyService.getAdAudiencePackage(accountId,landingType,"UNION");
+			List listDefault = (List) resultDefault.getResult();
+			List listUnion = (List) resultUnion.getResult();
+			listDefault.addAll(listUnion);
+			return Result.successMsg("获取定向包成功。",listDefault);
+		}catch (Exception e){
+			log.error("获取定向包异常",e);
+			return Result.error("请求失败,请联系开发人员!");
+		}
+	}
+
+	@ApiOperation(value="获取人群包列表信息", notes="获取人群包列表信息")
+	@GetMapping(value = "/getDMPCustomAudience")
+	public Result getDMPCustomAudience(@RequestParam(value = "accountId",required = false) String accountId) {
+		try {
+			if (Check.isNull(accountId)){
+				return Result.errorMsg("请选择账户。");
+			}
+			return aiBytedanceAdvertiserStrategyService.getDMPCustomAudience(accountId);
+		}catch (Exception e){
+			log.error("获取人群包列表异常",e);
+			return Result.error("请求失败,请联系开发人员!");
+		}
+	}
+
+	@ApiOperation(value="创建定向包", notes="创建定向包")
+	@PostMapping(value = "/createAudiencePackage")
+	public Result createAudiencePackage(@RequestParam("accountId") String accountId) {
+		try {
+			return aiBytedanceAdvertiserStrategyService.createAudiencePackage(accountId);
+		}catch (Exception e){
+			log.error("创建定向包异常",e);
+			return Result.error("请求失败,请联系开发人员!");
+		}
+	}
+
+
+	@ApiOperation(value="获取橙子建站站点列表", notes="获取橙子建站站点列表")
+	@GetMapping(value = "/getChengZiSite")
+	public Result getChengZiSite(@RequestParam("accountId") String accountId) {
+		try {
+			return aiBytedanceAdvertiserStrategyService.getChengZiSite(accountId);
+		}catch (Exception e){
+			log.error("获取橙子建站站点列表异常",e);
+			return Result.error("请求失败,请联系开发人员!");
+		}
+	}
+
+
+
+
+
+
+
+
+}

+ 428 - 0
jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/controller/BytedanceGeneralCopywriterController.java

@@ -0,0 +1,428 @@
+package ctop.bytedance.ad.advertise.controller;
+
+import com.alibaba.dubbo.config.annotation.Reference;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.common.system.api.ICommonService;
+import org.jeecg.common.system.query.QueryGenerator;
+import org.jeecg.common.util.oConvertUtils;
+import ctop.bytedance.ad.advertise.entity.ByteDanceCreativeWordPackage;
+import ctop.bytedance.ad.advertise.entity.ByteDanceGeneralCopywriter;
+import ctop.bytedance.ad.advertise.service.IByteDanceGeneralCopywriterService;
+import ctop.bytedance.ad.common.utils.Check;
+import ctop.bytedance.ad.common.utils.ExcelUtil;
+import ctop.bytedance.ad.common.utils.StringUtils;
+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 javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * 头条通用文案上传接口
+ * @author jeecg-boot
+ * @date   2021-04-20
+ * @version V1.0
+ */
+@RestController
+@RequestMapping("/advertiser/bytedanceGeneralCopywriter")
+@Api(tags="头条通用文案")
+@Slf4j
+public class BytedanceGeneralCopywriterController {
+    @Autowired
+    private IByteDanceGeneralCopywriterService byteDanceGeneralCopywriterService;
+    @Reference
+    private ICommonService commonService;
+
+
+    @ApiOperation(value="通用文案库-上传excel", notes="通用文案库-上传excel")
+    @PostMapping("/loadExcel")
+    public Result<ByteDanceGeneralCopywriter> loadExcel(
+            @RequestParam("accountId") String accountId,
+            @RequestParam("excelFile") MultipartFile excelFile){
+        Result<ByteDanceGeneralCopywriter> result = new Result<>();
+        List<ByteDanceGeneralCopywriter> byteDanceGeneralCopywriterList = new ArrayList<ByteDanceGeneralCopywriter>();
+        String[] accountIds = new String[]{accountId};
+        if(accountId.contains(",")){
+            accountIds = accountId.split(",");
+        }
+        try {
+            List<String> list = ExcelUtil.readExcel(excelFile);
+
+            for (String accountIdStr:accountIds) {
+                for (String str: list) {
+                    ByteDanceGeneralCopywriter byteDanceGeneralCopywriter = new ByteDanceGeneralCopywriter(Long.parseLong(accountIdStr),str);
+                    int len = StringUtils.lengthAsSlogan(str);
+                    int left = str.indexOf("{");
+                    int right = str.indexOf("}");
+                    if(left >= 0 || right >= 0){
+                        List<String> strs = new ArrayList<>();
+                        ByteDanceCreativeWordPackage creativeWordPackage = byteDanceGeneralCopywriterService.selectCreativeWordPackageByName(str.substring(left+1, right));
+                        strs.add(creativeWordPackage.getCreativeWordId().toString());
+                        len = len - (right - left) + creativeWordPackage.getMaxWordLen();
+                        String nextStr = str.substring(right+1,str.length());
+                        left = nextStr.indexOf("{");
+                        right = nextStr.indexOf("}");
+                        if(left >= 0 || right >= 0){
+                            ByteDanceCreativeWordPackage creativeWordPackage2 = byteDanceGeneralCopywriterService.selectCreativeWordPackageByName(nextStr.substring(left+1, right));
+                            strs.add(creativeWordPackage2.getCreativeWordId().toString());
+                            len = len - (right - left) + creativeWordPackage2.getMaxWordLen();
+                        }
+                        byteDanceGeneralCopywriter.setCreativeWordIds(Arrays.toString(strs.toArray()).replaceAll(" ",""));
+                    }
+                    //校验标题长度,长度小于5和大于30的全部过滤
+                    if(len<5 || len>30){
+                        continue;
+                    }
+
+                    //截取{}中的内容,匹配动态词包id,拼接数组存储
+                    byteDanceGeneralCopywriterList.add(byteDanceGeneralCopywriter);
+                }
+            }
+
+
+            byteDanceGeneralCopywriterService.saveBatch(byteDanceGeneralCopywriterList);
+            result.success("添加成功"+byteDanceGeneralCopywriterList.size()+"条"+",失败"+(list.size() * accountIds.length - byteDanceGeneralCopywriterList.size())+"条");
+            result.setCode(0);
+        } catch (IOException e) {
+            result.error500("动态词包格式错误,请重新上传!");
+        }
+        return result;
+    }
+
+
+    /**
+     * 分页列表查询
+     * @param byteDanceGeneralCopywriter
+     * @param pageNo
+     * @param pageSize
+     * @param req
+     * @return
+     */
+    @ApiOperation(value="通用文案库-分页列表查询", notes="通用文案库-分页列表查询")
+    @GetMapping(value = "/list")
+    public Result<IPage<ByteDanceGeneralCopywriter>> queryPageList(ByteDanceGeneralCopywriter byteDanceGeneralCopywriter,
+                                                                   @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
+                                                                   @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
+                                                                   HttpServletRequest req) {
+        Result<IPage<ByteDanceGeneralCopywriter>> result = new Result<>();
+        QueryWrapper<ByteDanceGeneralCopywriter> queryWrapper = QueryGenerator.initQueryWrapper(byteDanceGeneralCopywriter, req.getParameterMap());
+        Page<ByteDanceGeneralCopywriter> page = new Page<ByteDanceGeneralCopywriter>(pageNo, pageSize);
+        IPage<ByteDanceGeneralCopywriter> pageList = byteDanceGeneralCopywriterService.page(page, queryWrapper);
+        result.setSuccess(true);
+        result.setResult(pageList);
+        return result;
+    }
+
+    @ApiOperation(value="通用文案报表展示", notes="通用文案报表展示")
+    @GetMapping(value = "/queryPageListByText")
+    public Result queryPageListByText(
+                                      @RequestParam(value = "userId",defaultValue = "") String userId,
+                                      @RequestParam(value = "accountId",defaultValue = "") String accountId,
+                                      @RequestParam(value = "keyWord",defaultValue = "") String keyWord,
+                                      @RequestParam(value = "startTime",defaultValue = "") String startTime,
+                                      @RequestParam(value = "endTime",defaultValue = "") String endTime,
+                                      @RequestParam(value = "pageNo", defaultValue="1") Integer pageNo,
+                                      @RequestParam(value = "pageSize", defaultValue="10") Integer pageSize,
+                                      @RequestParam(value = "status",required = false)  Integer status
+
+    ) {
+        try {
+
+            String roleCode = commonService.getRoleCodeByUserId(userId);
+            if (Check.isNull(roleCode)){
+                return Result.errorMsg("请输入正确的用户id。");
+            }
+            //角色为 管理员并且projectId是空表示:全量查询
+            if ("admin".equals(roleCode) && Check.isNull(accountId)) {
+                accountId = "admin";	//传递projectId为admin
+            }
+
+            return byteDanceGeneralCopywriterService.getGeneralCopywriterReport(userId, accountId, keyWord, status, startTime, endTime, pageNo, pageSize);
+        }catch (Exception e){
+            log.error("通用文案数据-获取文案维度创意报表数据异常",e);
+            return Result.error("请求失败,请联系开发人员!");
+        }
+    }
+
+    /**
+     *   添加
+     * @param byteDanceGeneralCopywriter
+     * @return
+     */
+    @ApiOperation(value="通用文案库-添加", notes="通用文案库-添加")
+    @PostMapping(value = "/add")
+    public Result<ByteDanceGeneralCopywriter> add(@RequestBody ByteDanceGeneralCopywriter byteDanceGeneralCopywriter) {
+        Result<ByteDanceGeneralCopywriter> result = new Result<>();
+        try {
+            byteDanceGeneralCopywriterService.save(byteDanceGeneralCopywriter);
+            result.success("添加成功!");
+        } catch (Exception e) {
+            log.error(e.getMessage(),e);
+            result.error500("操作失败");
+        }
+        return result;
+    }
+
+
+    /**
+     *   批量添加
+     * @param byteDanceGeneralCopywriterList
+     * @return
+     */
+    @ApiOperation(value="通用文案库-批量添加", notes="通用文案库-批量添加")
+    @PostMapping(value = "/addList")
+    public Result<List> add(@RequestBody List<ByteDanceGeneralCopywriter> byteDanceGeneralCopywriterList) {
+        Result<List> result = new Result<>();
+        try {
+            byteDanceGeneralCopywriterService.saveBatch(byteDanceGeneralCopywriterList);
+            result.success("添加成功!");
+        } catch (Exception e) {
+            log.error(e.getMessage(),e);
+            result.error500("操作失败");
+        }
+        return result;
+    }
+
+    /**
+     *  编辑
+     * @param byteDanceGeneralCopywriter
+     * @return
+     */
+    @ApiOperation(value="通用文案库-编辑", notes="通用文案库-编辑")
+    @PostMapping(value = "/edit")
+    public Result<ByteDanceGeneralCopywriter> edit(@RequestBody ByteDanceGeneralCopywriter byteDanceGeneralCopywriter) {
+
+        Result<ByteDanceGeneralCopywriter> result = new Result<>();
+        try{
+            ByteDanceGeneralCopywriter byteDanceGeneralCopywriterEntity = byteDanceGeneralCopywriterService.getById(byteDanceGeneralCopywriter.getId());
+            if(byteDanceGeneralCopywriterEntity==null) {
+                return result.error500("未找到对应实体");
+            }
+//            LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
+            byteDanceGeneralCopywriter.setUpdateTime(new Date());
+
+            String title = byteDanceGeneralCopywriter.getTextCopywriter();
+            title = title.trim().replaceAll("[\\{]{2,}", "{");
+            title = title.trim().replaceAll("[\\}]{2,}", "}");
+
+            String reg = "\\{[\\u4e00-\\u9fa5\\-]{2,6}\\}";
+            Pattern pattern = Pattern.compile(reg);
+            Matcher matcher = pattern.matcher(title);
+            JSONArray creativeWordIdsArray = new JSONArray();
+
+            int len = StringUtils.lengthAsSlogan(title);
+            int left = title.indexOf("{");
+            int right = title.indexOf("}");
+            if (left >= 0 || right >= 0) {
+                int times = 0;
+                while (matcher.find()) { //此处find()每次被调用后,会偏移到下一个匹配
+                    times++;
+                    if (times >= 3) {
+                        return result.error500("动态词包不合法,词包数量超过2个");
+                    }
+                    String matchStr = matcher.group();//获取当前匹配的值
+                    title = title.replace(matchStr,"");
+
+                    ByteDanceCreativeWordPackage creativeWordPackage = byteDanceGeneralCopywriterService.selectCreativeWordPackageByName(matchStr.substring(1, matchStr.length() - 1));
+                    if (Check.isNull(creativeWordPackage)) {
+                        return result.error500("动态词包不合法,词包不存在或者含有单独的非词包大括号");
+                    }
+                    creativeWordIdsArray.add(creativeWordPackage.getCreativeWordId());
+                    len = len - (right - left) + creativeWordPackage.getMaxWordLen();
+                    left = title.indexOf("{");
+                    right = title.indexOf("}");
+                }
+                if(title.contains("{") || title.contains("}")){
+                    return result.error500("文案含有词包特殊字符,请检查");
+                }
+                byteDanceGeneralCopywriter.setCreativeWordIds(creativeWordIdsArray.toJSONString());
+            }
+            //校验标题长度,长度小于5和大于30的全部过滤
+            if (len < 5 || len > 30) {
+                return result.error500("文案长度不合法,小于5或大于30");
+            }
+
+            boolean ok = byteDanceGeneralCopywriterService.updateById(byteDanceGeneralCopywriter);
+            if(ok) {
+                result.success("修改成功!");
+                result.setCode(0);
+            }
+            return result;
+        } catch (Exception e) {
+            log.error(e.getMessage(),e);
+            return result.error500("操作失败");
+        }
+    }
+
+    /**
+     *   通过id删除
+     * @param id
+     * @return
+     */
+    @ApiOperation(value="通用文案库-通过id删除", notes="通用文案库-通过id删除")
+    @DeleteMapping(value = "/delete")
+    public Result<?> delete(@RequestParam(name="id") String id) {
+        Result result = new Result();
+        try {
+            ByteDanceGeneralCopywriter generalCopywriter = byteDanceGeneralCopywriterService.getById(id);
+            if(null == generalCopywriter||generalCopywriter.getStatus() == 0){
+                return result.ok("此文案不存在或者已经被删除");
+            }
+            generalCopywriter.setStatus(0);
+            generalCopywriter.setUpdateTime(new Date());
+            boolean ok = byteDanceGeneralCopywriterService.updateById(generalCopywriter);
+            if(ok){
+                result.setMessage("删除成功!");
+                result.setCode(0);
+            }
+            return result;
+        } catch (Exception e) {
+            log.error("删除失败",e.getMessage());
+            return result.error500("删除失败!");
+        }
+
+    }
+
+
+    /**
+     *  批量删除
+     * @param ids
+     * @return
+     */
+    @ApiOperation(value="通用文案库-批量删除", notes="通用文案库-批量删除")
+    @DeleteMapping(value = "/deleteBatch")
+    public Result<ByteDanceGeneralCopywriter> deleteBatch(@RequestParam(name="ids") String ids) {
+        Result<ByteDanceGeneralCopywriter> result = new Result<>();
+        if(ids==null || "".equals(ids.trim())) {
+            result.error500("参数不识别!");
+        }else {
+            this.byteDanceGeneralCopywriterService.removeByIds(Arrays.asList(ids.split(",")));
+            result.success("删除成功!");
+        }
+        return result;
+    }
+
+    /**
+     * 通过id查询
+     * @param id
+     * @return
+     */
+    @ApiOperation(value="通用文案库-通过id查询", notes="通用文案库-通过id查询")
+    @GetMapping(value = "/queryById")
+    public Result<ByteDanceGeneralCopywriter> queryById(@RequestParam(name="id",required=true) String id) {
+        Result<ByteDanceGeneralCopywriter> result = new Result<>();
+        ByteDanceGeneralCopywriter byteDanceGeneralCopywriter = byteDanceGeneralCopywriterService.getById(id);
+        if(byteDanceGeneralCopywriter==null) {
+            result.error500("未找到对应实体");
+        }else {
+            result.setResult(byteDanceGeneralCopywriter);
+            result.setSuccess(true);
+        }
+        return result;
+    }
+
+    @ApiOperation(value="通用文案库-通过id查询", notes="通用文案库-通过id查询")
+    @GetMapping(value = "/queryByTextCopywriter")
+    public Result<List<ByteDanceGeneralCopywriter>> queryByCopywriter(@RequestParam(name="textCopywriter",required=true) String textCopywriter) {
+        Result<List<ByteDanceGeneralCopywriter>> result = new Result<>();
+        List<ByteDanceGeneralCopywriter> byteDanceGeneralCopywriter = byteDanceGeneralCopywriterService.selectAllDataByTextCopywriter(textCopywriter);
+        if(byteDanceGeneralCopywriter==null) {
+            result.error500("未找到对应实体");
+        }else {
+            result.setResult(byteDanceGeneralCopywriter);
+            result.setSuccess(true);
+        }
+        return result;
+    }
+
+
+    /**
+     * 导出excel
+     *
+     * @param request
+     * @param response
+     */
+    @RequestMapping(value = "/exportXls")
+    public ModelAndView exportXls(HttpServletRequest request, HttpServletResponse response) {
+        // Step.1 组装查询条件
+        QueryWrapper<ByteDanceGeneralCopywriter> queryWrapper = null;
+        try {
+            String paramsStr = request.getParameter("paramsStr");
+            if (oConvertUtils.isNotEmpty(paramsStr)) {
+                String deString = URLDecoder.decode(paramsStr, "UTF-8");
+                ByteDanceGeneralCopywriter byteDanceGeneralCopywriter = JSON.parseObject(deString, ByteDanceGeneralCopywriter.class);
+                queryWrapper = QueryGenerator.initQueryWrapper(byteDanceGeneralCopywriter, request.getParameterMap());
+            }
+        } catch (UnsupportedEncodingException e) {
+            e.printStackTrace();
+        }
+
+        //Step.2 AutoPoi 导出Excel
+        ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
+        List<ByteDanceGeneralCopywriter> pageList = byteDanceGeneralCopywriterService.list(queryWrapper);
+        //导出文件名称
+        mv.addObject(NormalExcelConstants.FILE_NAME, "通用文案库列表");
+        mv.addObject(NormalExcelConstants.CLASS, ByteDanceGeneralCopywriter.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<ByteDanceGeneralCopywriter> listByteDanceGeneralCopywriters = ExcelImportUtil.importExcel(file.getInputStream(), ByteDanceGeneralCopywriter.class, params);
+                byteDanceGeneralCopywriterService.saveBatch(listByteDanceGeneralCopywriters);
+                return Result.ok("文件导入成功!数据行数:" + listByteDanceGeneralCopywriters.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("文件导入失败!");
+    }
+
+}

+ 116 - 0
jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/controller/BytedanceRejectReasonController.java

@@ -0,0 +1,116 @@
+package ctop.bytedance.ad.advertise.controller;
+
+import com.alibaba.fastjson.JSONArray;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.common.util.DateUtils;
+import ctop.bytedance.ad.advertise.dockapi.MarketingService;
+import ctop.bytedance.ad.advertise.entity.ByteDanceAdvertisePlan;
+import ctop.bytedance.ad.advertise.service.BytedanceRejectReasonService;
+import ctop.bytedance.ad.advertise.service.IByteDanceAdvertisePlanService;
+import ctop.bytedance.ad.common.entity.CtopOauthToken;
+import ctop.bytedance.ad.common.service.ICtopOauthTokenService;
+import ctop.bytedance.ad.common.utils.Check;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+/**
+ * 广告计划审核建议
+ * @author hxc
+ * 2021-06-28
+ * @version V1.0
+ */
+@Slf4j
+@Api(tags="广告计划审核建议")
+@RestController
+@RequestMapping("/ctop/bytedanceRejectReason")
+public class BytedanceRejectReasonController {
+
+
+
+    static ExecutorService executorService = Executors.newFixedThreadPool(5);
+    @Autowired
+    MarketingService marketingService;
+    @Autowired
+    private ICtopOauthTokenService tokenService;
+    @Autowired
+    IByteDanceAdvertisePlanService byteDanceAdvertisePlanService;
+    @Autowired
+    BytedanceRejectReasonService bytedanceRejectReasonService;
+
+    /**
+     *  编辑
+     * @param hour : 获取当前时间近几个小时的数据。根据广告计划表,近hour个小时新增进来的计划信息,更新他们的审核建议
+     * @return
+     */
+    @ApiOperation(value="广告计划审核建议-从接口获取数据落库", notes="广告计划审核建议-从接口获取数据落库")
+    @GetMapping(value = "/getReasonInRecentHours")
+    public Result getReasonInRecentHours(@RequestParam(value = "hour",required = false) Integer hour) {
+        Result result = new Result();
+        List<CtopOauthToken> tokens = tokenService.selectToutiaoToken();
+        if (null == tokens || tokens.isEmpty()) {
+            System.out.println("未获取到token");
+            result.setCode(500);
+            result.setMessage("未获取到token");
+            return result;
+        }
+
+        System.out.println("---------------------------------->>"+tokens.size()+"个token<<----------------------------------");
+
+        tokens.forEach(token -> executorService.submit(()->getRejectReasonByToken(token, hour)));
+
+
+        return result.success("调用任务已开启");
+    }
+
+
+    public void getRejectReasonByToken(CtopOauthToken token, Integer hour){
+
+            if(token.getAccessTokenExpiresIn().before(new Date())){
+                log.info("token已过期,accountId ==> {}",token.getAccountId());
+                return;
+            }
+
+            List<ByteDanceAdvertisePlan> allPlansByAccountId = byteDanceAdvertisePlanService.getAllPlansByAccountId(token.getAccountId(), Check.isNull(hour)?null:DateUtils.formatDate(DateUtils.addHour(new Date(),-hour),"yyyy-MM-dd HH:mm:ss"));
+
+            if(Check.isNull(allPlansByAccountId) || allPlansByAccountId.size() < 1){
+                return;
+            }
+            List<String> adids = new ArrayList<>();
+            allPlansByAccountId.forEach(plan -> adids.add(plan.getId().toString()));
+
+
+            while(adids.size() > 10){
+                List<String> mulAdids = adids.subList(0,10);
+//                System.out.println("查询的计划是"+Arrays.toString(mulAdids.toArray()));
+                Result dataListResult = marketingService.getRejectReason(token, token.getAccountId().toString(), mulAdids);
+                if(dataListResult.getMessage().toString().contains("No permission to operate account")){
+                    return;
+                }
+                if(Check.isNull(dataListResult.getResult()) || dataListResult.getCode().equals(500)){
+                    continue;
+                }
+                JSONArray jsonArray = JSONArray.parseArray(dataListResult.getResult().toString());
+                bytedanceRejectReasonService.saveRejectReasonToDb(jsonArray,token.getAccountId());
+                adids.removeAll(mulAdids);
+            }
+            Result dataListResult = marketingService.getRejectReason(token, token.getAccountId().toString(), adids);
+            if(Check.isNull(dataListResult.getResult())|| dataListResult.getCode().equals(500)){
+                return;
+            }
+            JSONArray jsonArray = JSONArray.parseArray(dataListResult.getResult().toString());
+            bytedanceRejectReasonService.saveRejectReasonToDb(jsonArray,token.getAccountId());
+        }
+
+}

+ 339 - 0
jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/controller/BytedanceReportController.java

@@ -0,0 +1,339 @@
+package ctop.bytedance.ad.advertise.controller;
+
+import com.alibaba.dubbo.config.annotation.Reference;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.jeecg.common.api.vo.Result;
+import ctop.bytedance.ad.advertise.dockapi.MarketingService;
+import ctop.bytedance.ad.advertise.entity.AiBytedanceAdvertiserStrategy;
+import ctop.bytedance.ad.advertise.entity.ByteDanceAdvertisePlan;
+import ctop.bytedance.ad.advertise.service.IByteDanceAdvertisePlanService;
+import ctop.bytedance.ad.advertise.vo.PlanSearchVo;
+import ctop.bytedance.ad.common.entity.CtopOauthToken;
+import ctop.bytedance.ad.common.service.ICtopOauthTokenService;
+import ctop.bytedance.ad.common.utils.Check;
+import ctop.bytedance.ad.report.service.IBytedanceAdvertiserHourlyReportService;
+import ctop.bytedance.ad.report.service.IBytedancePlanHourlyReportService;
+import ctop.bytedance.ad.report.service.IBytedanceReportMaterialDailyService;
+import org.jeecg.common.system.api.ICommonService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 投放数据
+ * @author jeecg-boot
+ * @date   2021-05-18
+ * @version V1.0
+ */
+@RestController
+@RequestMapping("/advertiser/bytedanceReportController")
+@Api(tags="投放数据")
+@Slf4j
+public class BytedanceReportController {
+	@Autowired
+	private IBytedanceAdvertiserHourlyReportService bytedanceAdvertiserHourlyReportService;
+
+	@Autowired
+	private IBytedancePlanHourlyReportService bytedancePlanHourlyReportService;
+
+	@Autowired
+	private IBytedanceReportMaterialDailyService bytedanceReportMaterialDailyService;
+
+	@Reference
+	private ICommonService commonService;
+
+	@Autowired
+	private MarketingService marketingService;
+
+	@Autowired
+	private ICtopOauthTokenService tokenService;
+
+	@Autowired
+	private IByteDanceAdvertisePlanService byteDanceAdvertisePlanService;
+
+
+
+	@ApiOperation(value="投放数据-获取当前用户花费最高的的账户", notes="投放数据-获取当前用户花费最高的的账户")
+	@GetMapping(value = "/initAccountIdAndTime")
+	public Result initAccountIdAndTime(@RequestParam("userId") String userId,
+										 @RequestParam(value = "type",defaultValue = "bytedance") String type) {
+		try {
+			//查询用户角色
+			String roleCode = commonService.getRoleCodeByUserId(userId);
+			if (Check.isNull(roleCode)){
+				return Result.errorMsg("请输入正确的用户id。");
+			}
+			//角色为 管理员 || 销售 || 媒介 查询全部
+			if ("admin".equals(roleCode) || roleCode.contains("sale") || "meidaManager".equals(roleCode)) {
+				userId = null;
+			}
+			return bytedanceAdvertiserHourlyReportService.initAccountIdAndTime(userId,type);
+		}catch (Exception e){
+			log.error("投放数据-获取当前用户花费最高的的账户异常",e);
+			return Result.error("请求失败,请联系开发人员!");
+		}
+	}
+
+
+
+
+
+	@ApiOperation(value="投放数据-获取花费和同比", notes="投放数据-获取花费和同比")
+	@GetMapping(value = "/getReportYearOnYearCost")
+	public Result getReportYearOnYearCost(@RequestParam("accountId") String accountId,
+										 @RequestParam("startTime") String startTime,
+										 @RequestParam("endTime") String endTime) {
+		try {
+			return bytedanceAdvertiserHourlyReportService.getReportYearOnYearCost(accountId,startTime,endTime);
+		}catch (Exception e){
+			log.error("投放数据-获取花费和环比异常",e);
+			return Result.error("请求失败,请联系开发人员!");
+		}
+	}
+
+
+
+
+	@ApiOperation(value="投放数据-查询账户余额", notes="投放数据-查询账户余额")
+	@GetMapping(value = "/getAccountCost")
+	public Result getAccountCost(@RequestParam("accountId") String accountId) {
+		try {
+			return bytedanceAdvertiserHourlyReportService.getAccountCost(accountId);
+		}catch (Exception e){
+			log.error("投放数据-获取花费和环比异常",e);
+			return Result.error("请求失败,请联系开发人员!");
+		}
+	}
+
+
+	@ApiOperation(value="投放数据-查询计划数据", notes="投放数据-查询计划数据")
+	@GetMapping(value = "/getReportPlanCost")
+	public Result getReportPlanCost(@RequestParam("accountId") String accountId,
+									@RequestParam("startTime") String startTime,
+									@RequestParam("endTime") String endTime,
+									@RequestParam(value = "pageNum",defaultValue = "1") Integer pageNum,
+									@RequestParam(value = "pageSize",defaultValue = "10") Integer pageSize) {
+		try {
+			return bytedanceAdvertiserHourlyReportService.getReportPlanCost(accountId,startTime,endTime,pageNum,pageSize);
+		}catch (Exception e){
+			log.error("投放数据-获取花费和环比异常",e);
+			return Result.error("请求失败,请联系开发人员!");
+		}
+	}
+
+
+
+	@ApiOperation(value="投放数据-更新计划出价-bid", notes="投放数据-更新计划出价")
+	@GetMapping(value = "/updateADBid")
+	public Result updateADBid(@RequestParam("accountId") String accountId,
+							  @RequestParam("adId") String adId,
+							  @RequestParam("bid") BigDecimal bid) {
+		try {
+			CtopOauthToken token = tokenService.getOauthTokenByAccountId(accountId);
+			List<Map<String, Object>> listMap = new ArrayList<>();
+			Map<String, Object> map = new HashMap<>();
+			map.put("ad_id",adId);
+			map.put("bid",bid);
+			listMap.add(map);
+			Result result = marketingService.updatePlanBid(token,accountId,listMap);
+			if (!result.isSuccess()){
+				return Result.errorMsg(result.getMessage());
+			}
+			ByteDanceAdvertisePlan byteDanceAdvertisePlan = new ByteDanceAdvertisePlan();
+			byteDanceAdvertisePlan.setId(Long.valueOf(adId));
+			byteDanceAdvertisePlan.setBid(bid);
+			//更新 表 定向包id
+			byteDanceAdvertisePlanService.updatePlanOrPackage(byteDanceAdvertisePlan);
+			return Result.successMsg("修改出价成功。",null);
+		}catch (Exception e){
+			log.error("投放数据-更新计划出价-bid异常",e);
+			return Result.error("请求失败,请联系开发人员!");
+		}
+	}
+
+
+	@ApiOperation(value="投放数据-更新计划出价-cpaBid", notes="投放数据-更新计划出价")
+	@GetMapping(value = "/updateADCpaBid")
+	public Result updateADCpaBid(@RequestParam("accountId") String accountId,
+									@RequestParam("adId") String adId,
+									@RequestParam("cpaBid") BigDecimal cpaBid) {
+		try {
+			CtopOauthToken token = tokenService.getOauthTokenByAccountId(accountId);
+			PlanSearchVo planSearchVo = new PlanSearchVo();
+			String[] ids = adId.split(",");
+			planSearchVo.setIds(ids);
+			//2 获取广告计划
+			Result result = marketingService.getPlanList(token,planSearchVo,1,1000);
+			if (!result.isSuccess()){
+				return Result.errorMsg(result.getMessage());
+			}
+			JSONObject jsonObject =JSONObject.parseObject(result.getResult().toString());
+			JSONArray array = jsonObject.getJSONArray("list");
+			List<Map<String,Object>> dataList = JSONArray.parseObject(array.toJSONString(),List.class);
+
+			for (Map<String, Object> map : dataList) {
+				String modifyTime = map.get("modify_time").toString();
+				AiBytedanceAdvertiserStrategy strategy = new AiBytedanceAdvertiserStrategy();
+				strategy.setAccountId(Long.valueOf(accountId));
+				strategy.setAdCpaBid(cpaBid);
+				//3 修改广告计划 中的 cpaBid
+				Result resultUpd = marketingService.updateAdvertiserPlan(token,adId,modifyTime,strategy);
+				if (!resultUpd.isSuccess()){
+					return Result.errorMsg(resultUpd.getMessage());
+				}
+				ByteDanceAdvertisePlan byteDanceAdvertisePlan = new ByteDanceAdvertisePlan();
+				byteDanceAdvertisePlan.setId(Long.valueOf(adId));
+				byteDanceAdvertisePlan.setCpaBid(cpaBid);
+				//更新 表 bid || 定向包id || 状态
+				byteDanceAdvertisePlanService.updatePlanOrPackage(byteDanceAdvertisePlan);
+			}
+
+			return Result.successMsg("修改出价成功。",null);
+		}catch (Exception e){
+			log.error("投放数据-更新计划出价-cpaBid异常",e);
+			return Result.error("请求失败,请联系开发人员!");
+		}
+	}
+
+
+	@ApiOperation(value="投放数据-获取计划已有定向包", notes="投放数据-获取计划已有定向包")
+	@GetMapping(value = "/getADAudiencePackageId")
+	public Result getADAudiencePackageId(@RequestParam("accountId") String accountId,
+										  @RequestParam("adId") String adId) {
+		try {
+			//1 获取token
+			CtopOauthToken token = tokenService.getOauthTokenByAccountId(accountId);
+			PlanSearchVo planSearchVo = new PlanSearchVo();
+			String[] ids = adId.split(",");
+			planSearchVo.setIds(ids);
+			//2 获取广告计划
+			Result result = marketingService.getPlanList(token,planSearchVo,1,1000);
+			if (!result.isSuccess()){
+				return Result.errorMsg(result.getMessage());
+			}
+			JSONObject jsonObject =JSONObject.parseObject(result.getResult().toString());
+			JSONArray array = jsonObject.getJSONArray("list");
+			List<Map<String,Object>> dataList = JSONArray.parseObject(array.toJSONString(),List.class);
+			Map<String,String> resultMap = new HashMap<>();
+			for (Map<String, Object> map : dataList) {
+				String packageId = Check.isNull(map.get("audience_package_id")) ? "" : map.get("audience_package_id") .toString();
+				resultMap.put("packageId",packageId);
+			}
+			return Result.successMsg("获取计划定向包id", resultMap);
+		}catch (Exception e){
+			log.error("投放数据-获取计划已有定向包异常",e);
+			return Result.error("请求失败,请联系开发人员!");
+		}
+	}
+
+
+
+
+
+	@ApiOperation(value="投放数据-更新计划定向包", notes="投放数据-更新计划定向包")
+	@GetMapping(value = "/updateADAudiencePackage")
+	public Result updateADAudiencePackage(@RequestParam("accountId") String accountId,
+									@RequestParam("adId") String adId,
+									@RequestParam("audiencePackageId") String audiencePackageId) {
+		try {
+			//1 获取token
+			CtopOauthToken token = tokenService.getOauthTokenByAccountId(accountId);
+			PlanSearchVo planSearchVo = new PlanSearchVo();
+			String[] ids = adId.split(",");
+			planSearchVo.setIds(ids);
+			//2 获取广告计划
+			Result result = marketingService.getPlanList(token,planSearchVo,1,1000);
+			if (!result.isSuccess()){
+				return Result.errorMsg(result.getMessage());
+			}
+			JSONObject jsonObject =JSONObject.parseObject(result.getResult().toString());
+			JSONArray array = jsonObject.getJSONArray("list");
+			List<Map<String,Object>> dataList = JSONArray.parseObject(array.toJSONString(),List.class);
+
+			for (Map<String, Object> map : dataList) {
+				String modifyTime = map.get("modify_time").toString();
+				AiBytedanceAdvertiserStrategy strategy = new AiBytedanceAdvertiserStrategy();
+				strategy.setAccountId(Long.valueOf(accountId));
+				strategy.setAdAudiencePackageId(audiencePackageId);
+				//3 修改广告计划 中的 定向包id
+				Result resultUpd = marketingService.updateAdvertiserPlan(token,adId,modifyTime,strategy);
+				if (!resultUpd.isSuccess()){
+					return Result.errorMsg(resultUpd.getMessage());
+				}
+				ByteDanceAdvertisePlan byteDanceAdvertisePlan = new ByteDanceAdvertisePlan();
+				byteDanceAdvertisePlan.setId(Long.valueOf(adId));
+				byteDanceAdvertisePlan.setAudiencePackageId(audiencePackageId);
+				//更新 表 定向包id
+				byteDanceAdvertisePlanService.updatePlanOrPackage(byteDanceAdvertisePlan);
+			}
+			return Result.successMsg("更新计划定向包", null);
+		}catch (Exception e){
+			log.error("投放数据-更新计划定向包异常",e);
+			return Result.error("请求失败,请联系开发人员!");
+		}
+	}
+
+
+	@ApiOperation(value="投放数据-更新计划状态", notes="投放数据-更新计划状态")
+	@GetMapping(value = "/updPlanStatus")
+	public Result updPlanStatus(@RequestParam("accountId") String accountId,
+							  @RequestParam("adId") Long adId,
+							  @RequestParam("optStatus") String optStatus) {
+		try {
+			CtopOauthToken token = tokenService.getOauthTokenByAccountId(accountId);
+			List<Long> list = new ArrayList<>();
+			list.add(adId);
+			//api 更新计划状态
+			Result result = marketingService.updPlanStatus(token,list,optStatus);
+			if (result.isSuccess()){
+				ByteDanceAdvertisePlan byteDanceAdvertisePlan = new ByteDanceAdvertisePlan();
+				byteDanceAdvertisePlan.setId(adId);
+				byteDanceAdvertisePlan.setOptStatus(optStatus.equalsIgnoreCase("enable") ? "AD_STATUS_ENABLE" : "AD_STATUS_DISABLE");
+				//更新 表 计划状态
+				byteDanceAdvertisePlanService.updatePlanOrPackage(byteDanceAdvertisePlan);
+				return Result.successMsg(result.getMessage(), null);
+			}
+			return Result.errorMsg(result.getMessage());
+		}catch (Exception e){
+			log.error("投放数据-更新计划状态异常",e);
+			return Result.error("请求失败,请联系开发人员!");
+		}
+	}
+
+
+
+
+	@ApiOperation(value="投放数据-素材维度展示", notes="投放数据-素材维度展示")
+	@GetMapping(value = "/selectMaterialDailyReport")
+	public Result selectMaterialDailyReport(@RequestParam("accountId") String accountId,
+					@RequestParam(value = "startTime",defaultValue = "") String startTime,
+					@RequestParam(value = "endTime",defaultValue = "") String endTime,
+					@RequestParam(value = "pageNum",defaultValue = "1") Integer pageNum,
+					@RequestParam(value = "pageSize",defaultValue = "10") Integer pageSize){
+		try {
+			return bytedanceReportMaterialDailyService.getMaterialDailyReportByAccountId(accountId,startTime,endTime,pageNum,pageSize);
+		}catch (Exception e){
+			log.error("投放数据-获取素材维度报表数据异常",e);
+			return Result.error("请求失败,请联系开发人员!");
+		}
+	}
+
+
+
+
+
+
+
+}

+ 379 - 0
jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/controller/BytedanceVideoSlogenInfoController.java

@@ -0,0 +1,379 @@
+package ctop.bytedance.ad.advertise.controller;
+
+import com.alibaba.dubbo.config.annotation.Reference;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.shiro.SecurityUtils;
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.common.system.api.ICommonService;
+import org.jeecg.common.system.query.QueryGenerator;
+import org.jeecg.common.system.vo.LoginUser;
+import ctop.bytedance.ad.advertise.entity.ByteDanceCreativeWordPackage;
+import ctop.bytedance.ad.advertise.entity.BytedanceVideoSlogenInfo;
+import ctop.bytedance.ad.advertise.service.IByteDanceGeneralCopywriterService;
+import ctop.bytedance.ad.advertise.service.IBytedanceVideoSlogenInfoService;
+import ctop.bytedance.ad.common.entity.MaterialInfo;
+import ctop.bytedance.ad.common.service.IMaterialInfoService;
+import ctop.bytedance.ad.common.utils.Check;
+import ctop.bytedance.ad.common.utils.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * 头条视频文案信息
+ * @author jeecg-boot
+ * 2021-04-19
+ * @version V1.0
+ */
+@Slf4j
+@Api(tags="头条视频文案信息")
+@RestController
+@RequestMapping("/ctop/bytedanceVideoSlogenInfo")
+public class BytedanceVideoSlogenInfoController {
+	@Autowired
+	private IBytedanceVideoSlogenInfoService bytedanceVideoSlogenInfoService;
+	@Autowired
+	private IMaterialInfoService materialInfoService;
+	@Reference
+	private ICommonService commonService;
+
+	@Autowired
+	private IByteDanceGeneralCopywriterService byteDanceGeneralCopywriterService;
+	/**
+	  * 分页列表查询
+	 * @param slogenInfo
+	 * @param pageNo
+	 * @param pageSize
+	 * @param req
+	 * @return
+	 */
+	@ApiOperation(value="头条视频文案信息-分页列表查询", notes="头条视频文案信息-分页列表查询")
+	@GetMapping(value = "/list")
+	public Result<IPage<BytedanceVideoSlogenInfo>> queryPageList(BytedanceVideoSlogenInfo slogenInfo,
+																 @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
+																 @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
+																 HttpServletRequest req) {
+		Result<IPage<BytedanceVideoSlogenInfo>> result = new Result<>();
+//		slogenInfo.setStatus(1);		//默认不传为所有,传了1是正常,传0是已删除
+		QueryWrapper<BytedanceVideoSlogenInfo> queryWrapper = QueryGenerator.initQueryWrapper(slogenInfo, req.getParameterMap());
+		Page<BytedanceVideoSlogenInfo> page = new Page<>(pageNo, pageSize);
+		IPage<BytedanceVideoSlogenInfo> pageList = bytedanceVideoSlogenInfoService.page(page, queryWrapper);
+		result.setSuccess(true);
+		result.setResult(pageList);
+		return result;
+	}
+
+	@ApiOperation(value="指定文案报表数据展示", notes="指定文案报表数据展示")
+	@GetMapping(value = "/queryPageListByText")
+	public Result queryPageListByText(@RequestParam("userId") String userId,
+									  @RequestParam(value = "projectId",defaultValue = "") String projectId,
+									  @RequestParam(value = "keyWord",defaultValue = "") String keyWord,
+									  @RequestParam(value = "startTime",defaultValue = "") String startTime,
+									  @RequestParam(value = "endTime",defaultValue = "") String endTime,
+									  @RequestParam(value = "pageNo", defaultValue="1") Integer pageNo,
+									  @RequestParam(value = "pageSize", defaultValue="10") Integer pageSize,
+									  @RequestParam(value = "status",required = false) Integer status
+									) {
+		try {
+			//查询用户角色
+			String roleCode = commonService.getRoleCodeByUserId(userId);
+			if (Check.isNull(roleCode)){
+				return Result.errorMsg("请输入正确的用户id。");
+			}
+			//角色为 管理员并且projectId是空表示:全量查询
+			if ("admin".equals(roleCode) && Check.isNull(projectId)) {
+				projectId = "admin";	//传递projectId为admin
+			}
+			return bytedanceVideoSlogenInfoService.getVideoSlogenReport(userId, projectId,keyWord,status, startTime,endTime,pageNo,pageSize);
+		}catch (Exception e){
+			log.error("指定文案-获取指定文案维度创意报表数据异常",e);
+			return Result.error("请求失败,请联系开发人员!");
+		}
+	}
+
+	/**
+	  *   添加
+	 * @param slogenInfo
+	 * @return
+	 */
+	@ApiOperation(value="头条视频文案信息-添加", notes="头条视频文案信息-添加")
+	@PostMapping(value = "/add")
+	public Result<BytedanceVideoSlogenInfo> add(@RequestBody BytedanceVideoSlogenInfo slogenInfo) {
+		Result<BytedanceVideoSlogenInfo> result = new Result<>();
+		try {
+			bytedanceVideoSlogenInfoService.save(slogenInfo);
+			result.success("添加成功!");
+			return result;
+		} catch (Exception e) {
+			log.error(e.getMessage(),e);
+			result.error500("操作失败");
+			return result;
+		}
+	}
+
+	/**
+	 *   添加
+	 * @param
+	 * @param
+	 * @param
+	 * @return
+	 */
+	@ApiOperation(value="头条视频文案信息-批量添加", notes="头条视频文案信息-批量添加")
+	@PostMapping(value = "/addList")
+	public Result<BytedanceVideoSlogenInfo> addList(@RequestBody MaterialInfo materialInfo) {
+		Result<BytedanceVideoSlogenInfo> result = new Result<>();
+		try {
+			String userId = materialInfo.getUserId();
+			JSONArray slogenArray = materialInfo.getSlogans();
+			for (int i = 0;i<slogenArray.size();i++) {
+				JSONObject slogenInfo = slogenArray.getJSONObject(i);
+				String title = slogenInfo.getString("title");
+				title = title.trim().replaceAll("[\\{]{2,}","{");
+				title = title.trim().replaceAll("[\\}]{2,}","}");
+                slogenInfo.put("title",title);
+				String reg = "\\{[\\u4e00-\\u9fa5\\-]{2,6}\\}";
+				Pattern pattern = Pattern.compile(reg);
+				Matcher matcher = pattern.matcher(title);
+				JSONArray creativeWordIdsArray = new JSONArray();
+
+				int len = StringUtils.lengthAsSlogan(title);
+				int left = title.indexOf("{");
+				int right = title.indexOf("}");
+				if(left >= 0 || right >= 0){
+				int times = 0;
+					while (matcher.find()) { //此处find()每次被调用后,会偏移到下一个匹配
+						times++;
+						if(times>=3){
+							return  Result.errorMsg("动态词包不合法,词包数量超过2个");
+						}
+						String matchStr = matcher.group();//获取当前匹配的值
+						title = title.replace(matchStr,"");
+
+						ByteDanceCreativeWordPackage creativeWordPackage = byteDanceGeneralCopywriterService.selectCreativeWordPackageByName(matchStr.substring(1,matchStr.length()-1));
+						if(Check.isNull(creativeWordPackage)){
+							return  Result.errorMsg("动态词包不合法,词包不存在或者含有单独的非词包大括号");
+						}
+						creativeWordIdsArray.add(creativeWordPackage.getCreativeWordId());
+						len = len - (right - left) + creativeWordPackage.getMaxWordLen();
+						left = title.indexOf("{");
+						right = title.indexOf("}");
+					}
+					if(title.contains("{") || title.contains("}")){
+						return result.error500("大括号单独出现或大括号中内容不合法");
+					}
+					slogenInfo.put("creative_word_ids",creativeWordIdsArray.toJSONString());
+				}
+				//校验标题长度,长度小于5和大于30的全部过滤
+				if(len<5 || len>30){
+					return result.error500("文案长度不合法,小于5或大于30");
+				}
+			}
+
+			JSONArray materialIds = materialInfo.getMaterialIds();
+			for(int i=0;i<materialIds.size();i++){
+				MaterialInfo materialInfo2 = materialInfoService.getById(materialIds.get(i).toString());
+				String videoCode = materialInfo2.getCode();
+				Long projectId = materialInfo2.getProjectId();
+				bytedanceVideoSlogenInfoService.insertSlogans(projectId,videoCode,slogenArray,userId);
+			}
+			result.success("添加成功!");
+			result.setCode(0);
+			return result;
+		} catch (Exception e) {
+			log.error(e.getMessage(),e);
+			result.error500("操作失败");
+			return result;
+		}
+	}
+
+	/**
+	 *  编辑
+	 * @param slogenInfo 文案信息
+	 * @return
+	 */
+	@ApiOperation(value="头条视频文案信息-编辑", notes="头条视频文案信息-编辑")
+	@PostMapping(value = "/edit")
+	public Result<BytedanceVideoSlogenInfo> edit(@RequestBody BytedanceVideoSlogenInfo slogenInfo) {
+		Result<BytedanceVideoSlogenInfo> result = new Result<>();
+		try{
+			List<BytedanceVideoSlogenInfo> videoSlogenInfoList = bytedanceVideoSlogenInfoService.getVideoSlogenBySlogenAndProjectId(slogenInfo.getSlogan(),slogenInfo.getProjectId());
+		if(videoSlogenInfoList==null) {
+			return result.error500("未找到对应实体");
+		}
+
+
+		String title = slogenInfo.getNewSlogan();
+		title = title.trim().replaceAll("[\\{]{2,}", "{");
+		title = title.trim().replaceAll("[\\}]{2,}", "}");
+		slogenInfo.setNewSlogan(title);
+
+		String reg = "\\{[\\u4e00-\\u9fa5\\-]{2,6}\\}";
+		Pattern pattern = Pattern.compile(reg);
+		Matcher matcher = pattern.matcher(title);
+		JSONArray creativeWordIdsArray = new JSONArray();
+
+		int len = StringUtils.lengthAsSlogan(title);
+		int left = title.indexOf("{");
+		int right = title.indexOf("}");
+		if (left >= 0 || right >= 0) {
+			int times = 0;
+			while (matcher.find()) { //此处find()每次被调用后,会偏移到下一个匹配
+				times++;
+				if (times >= 3) {
+					return result.error500("动态词包不合法,词包数量超过2个");
+				}
+				String matchStr = matcher.group();//获取当前匹配的值
+				title = title.replace(matchStr,"");
+
+				ByteDanceCreativeWordPackage creativeWordPackage = byteDanceGeneralCopywriterService.selectCreativeWordPackageByName(matchStr.substring(1, matchStr.length() - 1));
+				if (Check.isNull(creativeWordPackage)) {
+					return result.error500("动态词包不合法,词包不存在或者含有单独的非词包大括号");
+				}
+				creativeWordIdsArray.add(creativeWordPackage.getCreativeWordId());
+				len = len - (right - left) + creativeWordPackage.getMaxWordLen();
+				left = title.indexOf("{");
+				right = title.indexOf("}");
+			}
+			if(title.contains("{") || title.contains("}")){
+				return result.error500("文案含有词包特殊字符,请检查");
+			}
+		}
+		//校验标题长度,长度小于5和大于30的全部过滤
+		if (len < 5 || len > 30) {
+			return result.error500("文案长度不合法,小于5或大于30");
+		}
+
+			LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
+			for (BytedanceVideoSlogenInfo videoSlogenInfo:videoSlogenInfoList
+				 ) {
+				videoSlogenInfo.setSlogan(slogenInfo.getNewSlogan());
+				videoSlogenInfo.setUpdateBy(user.getId());
+				videoSlogenInfo.setUpdateTime(new Date());
+				videoSlogenInfo.setCreativeWordIds(creativeWordIdsArray.toJSONString());
+			}
+
+		boolean ok = bytedanceVideoSlogenInfoService.updateBatchById(videoSlogenInfoList);
+			if(ok) {
+				result.success("修改成功!");
+				result.setCode(0);
+			}
+		return result;
+		} catch (Exception e) {
+			log.error(e.getMessage(),e);
+			result.error500("操作失败");
+			return result;
+		}
+	}
+
+	/**
+	 *   通过id删除
+	 * @param id
+	 * @return
+	 */
+	@ApiOperation(value="头条视频文案信息-通过id删除", notes="头条视频文案信息-通过id删除")
+	@DeleteMapping(value = "/delete")
+	public Result<?> delete(@RequestParam(name="id") String id) {
+		try {
+			BytedanceVideoSlogenInfo slogenInfo = bytedanceVideoSlogenInfoService.getById(id);
+			if(null == slogenInfo||slogenInfo.getStatus() == 0){
+				return Result.ok("此文案不存在或者已经被删除");
+			}
+			slogenInfo.setStatus(0);
+			LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
+			slogenInfo.setUpdateTime(new Date());
+			slogenInfo.setCreateBy(user.getId());
+			bytedanceVideoSlogenInfoService.updateById(slogenInfo);
+			return Result.ok("删除成功!");
+		} catch (Exception e) {
+			log.error("删除失败",e.getMessage());
+			return Result.error("删除失败!");
+		}
+	}
+	/**
+	 *   通过id删除
+	 * @param
+	 * @return
+	 */
+	@ApiOperation(value="头条视频文案信息-通过id删除", notes="头条视频文案信息-通过id删除")
+	@DeleteMapping(value = "/deleteBySlogenAndProjectId")
+	public Result<?> deleteBySlogenAndProjectId(@RequestParam(name="slogan") String slogan, @RequestParam(name="projectId") Long projectId) {
+		try {
+			Result result = new Result();
+			List<BytedanceVideoSlogenInfo> videoSlogenInfoList = bytedanceVideoSlogenInfoService.getVideoSlogenBySlogenAndProjectId(slogan,projectId);
+			if(Check.isNull(videoSlogenInfoList)) {
+				return result.ok("此文案不存在或者已经被删除");
+			}
+			LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
+			videoSlogenInfoList.forEach(videoSlogenInfo->{
+				videoSlogenInfo.setStatus(0);
+				videoSlogenInfo.setUpdateTime(new Date());
+				videoSlogenInfo.setCreateBy(user.getId());});
+
+			boolean ok = bytedanceVideoSlogenInfoService.updateBatchById(videoSlogenInfoList);
+			if(ok) {
+				result.success("删除成功!");
+				result.setCode(0);
+			}
+			return result;
+		} catch (Exception e) {
+			log.error("删除失败",e.getMessage());
+			return Result.error("删除失败!");
+		}
+	}
+
+	/**
+	 * 通过id查询
+	 * @param id
+	 * @return
+	 */
+	@ApiOperation(value="头条视频文案信息-通过id查询", notes="头条视频文案信息-通过id查询")
+	@GetMapping(value = "/queryById")
+	public Result<BytedanceVideoSlogenInfo> queryById(@RequestParam(name="id") String id) {
+		Result<BytedanceVideoSlogenInfo> result = new Result<>();
+		BytedanceVideoSlogenInfo bytedanceVideoSlogenInfo = bytedanceVideoSlogenInfoService.getById(id);
+		if(bytedanceVideoSlogenInfo==null) {
+			result.error500("未找到对应实体");
+			return result;
+		}
+		result.setResult(bytedanceVideoSlogenInfo);
+		result.setSuccess(true);
+		return result;
+	}
+
+	/**
+	 * 通过slogen和projectId查询
+	 * @param
+	 * @return
+	 */
+	@ApiOperation(value="头条视频文案信息-通过文案内容和项目id查询", notes="头条视频文案信息-通过文案内容和项目id查询")
+	@GetMapping(value = "/queryBySlogenAndProjectId")
+	public Result<BytedanceVideoSlogenInfo> queryBySlogenAndProjectId(@RequestParam(name="slogan") String slogan, @RequestParam(name="projectId") Long projectId) {
+
+		Result<BytedanceVideoSlogenInfo> result = new Result<>();
+		List<BytedanceVideoSlogenInfo> videoSlogenInfoList = bytedanceVideoSlogenInfoService.getVideoSlogenBySlogenAndProjectId(slogan,projectId);
+		if(Check.isNull(videoSlogenInfoList)) {
+			result.error500("未找到对应实体");
+			return result;
+		}
+        List<String> materialNameArray = new ArrayList<>();
+        videoSlogenInfoList.forEach(videoSlogenInfo->materialNameArray.add(videoSlogenInfo.getMaterialName()));
+        BytedanceVideoSlogenInfo bytedanceVideoSlogenInfo = videoSlogenInfoList.get(0);
+        bytedanceVideoSlogenInfo.setMaterialNameArray(materialNameArray);
+		result.setResult(bytedanceVideoSlogenInfo);
+		result.setSuccess(true);
+		return result;
+	}
+}

+ 59 - 0
jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/controller/MaterialInfoController.java

@@ -0,0 +1,59 @@
+package ctop.bytedance.ad.advertise.controller;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.jeecg.common.api.vo.Result;
+import ctop.bytedance.ad.common.service.IMaterialInfoService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * 头条智能投放账户配置信息表
+ * @author jeecg-boot
+ * @date   2021-04-20
+ * @version V1.0
+ */
+@RestController
+@RequestMapping("/advertiser/materialInfoController")
+@Api(tags="视频素材")
+@Slf4j
+public class MaterialInfoController {
+	@Autowired
+	private IMaterialInfoService materialInfoService;
+
+
+
+	@ApiOperation(value="素材下线", notes="素材下线")
+	@GetMapping(value = "/updMaterialOfflineById")
+	public Result updMaterialOfflineById(@RequestParam("id") String id,
+								  		@RequestParam("offlineFlag") Integer offlineFlag) {
+		try {
+			List<String> listIds = Arrays.asList(id.split(","));
+			if (listIds.size() > 8){
+				return Result.errorMsg("已选视频素材最多支持8个。");
+			}
+			return materialInfoService.updMaterialOfflineById(listIds,offlineFlag);
+		}catch (Exception e){
+			log.error("素材下线异常",e);
+			return Result.error("请求失败,请联系开发人员!");
+		}
+	}
+
+
+
+
+
+
+
+
+
+
+
+}

+ 78 - 0
jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/dockapi/MarketingService.java

@@ -0,0 +1,78 @@
+package ctop.bytedance.ad.advertise.dockapi;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import org.jeecg.common.api.vo.Result;
+import ctop.bytedance.ad.advertise.entity.AiBytedanceAdvertiserStrategy;
+import ctop.bytedance.ad.advertise.vo.AdConvertQueryVo;
+import ctop.bytedance.ad.advertise.vo.ByteDanceSearchVo;
+import ctop.bytedance.ad.advertise.vo.PlanSearchVo;
+import ctop.bytedance.ad.common.entity.CtopOauthToken;
+
+import java.math.BigDecimal;
+import java.util.List;
+import java.util.Map;
+
+public interface MarketingService {
+    Result getBudget(CtopOauthToken token, List<Long> advertiser_ids);
+
+    Result updateBudget(CtopOauthToken token, String budgetMode, BigDecimal budget);
+
+    Result selectCustomAudience(CtopOauthToken token);
+
+    Result getCreativeRejectReason(CtopOauthToken token, String creativeIds);
+
+    Result getMaterialRead(CtopOauthToken token, String[] creativeIds);
+
+    Result updateCreativeStatus(CtopOauthToken token, String[] creativeIds, String optStatus);
+
+    Result createCampaign(CtopOauthToken token, JSONObject params);
+
+    JSONObject videoCoverSuggest(CtopOauthToken token, JSONObject params);
+
+    Result createAdvertiserPlan(CtopOauthToken token, JSONObject params, AiBytedanceAdvertiserStrategy strategy);
+
+    JSONObject creativeCreate(CtopOauthToken token, Long adId, JSONObject params);
+
+    Result creativeRead(CtopOauthToken token, String advertiserId, String adId);
+
+    Result getAdvertiserCreativeByPageNumber(CtopOauthToken token, Integer pageNumber, List<ByteDanceSearchVo> byteDanceSearchVoList);
+
+    Result getRejectReason(CtopOauthToken token, String advertiserId, List<String> adIds);
+
+    Result updatePlanBid(CtopOauthToken token, String advertiserId, List<Map<String, Object>> listMap);
+
+    Result updatePlanBudget(CtopOauthToken token, String advertiserId, List<Map<String, Object>> listMap);
+
+    Result updPlanStatus(CtopOauthToken token, List<Long> adIds, String optStatus);
+
+    Result getPlanList(CtopOauthToken token, PlanSearchVo planSearchVo, Integer pageNo, Integer pageSize);
+
+    Result updateCampaignStatus(CtopOauthToken token, List<String> campaignIds, String optStatus);
+
+    Result getCampaignGroupList(CtopOauthToken token, String accountId, JSONArray ids, int page, int pageSize);
+
+    Result updateCampaign(CtopOauthToken token, String campaignId, String modifyTime, String campaignName, String budgetMode, String budget);
+
+    Result updateAdvertiserPlan(CtopOauthToken token, String planId, String modifyTime, AiBytedanceAdvertiserStrategy strategy);
+
+    Result creativeUpdate(CtopOauthToken token, String adId, String modifyTime, JSONObject data);
+
+    Result getToolIndustryList(CtopOauthToken token, String type);
+
+    Result getToolConvertQuery(CtopOauthToken token, AdConvertQueryVo convertQueryVo);
+
+    JSONObject imageUpload(CtopOauthToken token, String imageUrl);
+
+    JSONObject getSuggestImageId(CtopOauthToken token, String vid);
+
+    Result getActionText(CtopOauthToken token, String landing_type,String advanced_creative_type);
+
+    Result getAudiencePackage(CtopOauthToken token,String landingType,String deliveryRange);
+
+    Result getAudiencePackageRead(CtopOauthToken token,String accountId,List<Integer> ids);
+
+    Result createAudiencePackage(CtopOauthToken token);
+
+    Result getSite(CtopOauthToken token);
+}

Разница между файлами не показана из-за своего большого размера
+ 1228 - 0
jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/dockapi/MarketingServiceImpl.java


+ 42 - 0
jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/entity/AiBytedanceAdDplinkInfo.java

@@ -0,0 +1,42 @@
+package ctop.bytedance.ad.advertise.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * 头条计划dplink标识创建记录
+ * @author jeecg-boot
+ * @date   2021-04-26
+ * @version V1.0
+ */
+@Data
+@TableName("ctop_ai_bytedance_ad_dplink_info")
+public class AiBytedanceAdDplinkInfo {
+    
+	/**id*/
+	@TableId(type = IdType.AUTO)
+	private Long id;
+	/**dpLinkIndex*/
+	private Long dpLinkIndex;
+	/**status*/
+	private Integer status;
+	/**计划id*/
+	private Long adId;
+	/**accountId*/
+	private Long accountId;
+
+	private String imageMode;
+
+	private BigDecimal adBid;
+	/**strategyId*/
+	private Long strategyId;
+	/**createTime*/
+	private Date createTime;
+	/**updateTime*/
+	private Date updateTime;
+}

+ 335 - 0
jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/entity/AiBytedanceAdvertiserStrategy.java

@@ -0,0 +1,335 @@
+package ctop.bytedance.ad.advertise.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import org.jeecg.common.aspect.annotation.Dict;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * 头条智能投放账户配置信息表
+ * @author jeecg-boot
+ * @date   2021-04-20
+ * @version V1.0
+ */
+@Data
+@TableName("ctop_ai_bytedance_advertiser_strategy")
+public class AiBytedanceAdvertiserStrategy{
+
+	/**id*/
+	@TableId(type = IdType.AUTO)
+	private Long id;
+	private Long accountId;
+	@TableField(exist = false)
+	private String accountName;
+
+	/**组名称*/
+	private String campaignName;
+	/**
+	 * 是否使用自定义dplink标识
+	 */
+	private Integer dpLinkIndexUsed;
+	/**
+	 * dpLink组层级开始下标
+	 */
+	private Long dpLinkStartIndex;
+	/**6
+	 * dpLink组层级结束下标
+	 */
+	private Long dpLinkEndIndex;
+	/**
+	 * 策略下组最大创建数
+	 */
+	private Integer campaignCnt;
+	/**
+	 * 单个广告组下的计划最大创建数
+	 */
+	private Long campaignAdCnt;
+	/**广告类型*/
+	private String advertisingType;
+	/**账户预算类型*/
+	private String accountBudgetMode;
+	/**账户预算*/
+	private BigDecimal accountBudget;
+	/**组预算类型*/
+	private String campaignBudgetMode;
+	/**组预算*/
+	private Integer campaignBudget;
+	/**推广目的*/
+	private String campaignLandingType;
+	/**广告组商品类型*/
+	private String campaignDeliveryRelatedNum;
+	/**计划名称*/
+	private String adName;
+	/**投放范围(投放范围)*/
+	private String adDeliveryRange;
+	/**投放形式(投放范围)*/
+	private String adUnionVideoType;
+	/**下载方式(投放目标)*/
+	private String adDownloadType;
+	/**下载链接(投放目标)*/
+	private String adDownloadUrl;
+	/**快应用链接(投放目标)*/
+	private String adQuickAppUrl;
+	/**落地页链接(投放目标)*/
+	private String adExternalUrl;
+	/**下载的应用类型(投放目标)*/
+	private String adAppType;
+	/**应用包名(投放目标)*/
+	private String adPackage;
+	/**优先从系统应用商店下载(投放目标)*/
+	private String adDownloadMode;
+	/**转化目标OPCM时必填(投放目标)*/
+	private Long adConvertId;
+	/**直达链接(投放目标)*/
+	private String adOpenUrl;
+	/**附加创意类型(投放目标)*/
+	private String adAdvancedCreativeType;
+	/**应用描述(选择游戏礼包码时必填)(投放目标)*/
+	private String adGamePackageDesc;
+	/**游戏礼包码id(投放目标)*/
+	private Integer adGamePackageBatchId;
+	/**应用图片集(投放目标)*/
+	private String adGamePackageThumbnailId;
+
+	/**定向类型 add-新建定向;choice-选择定向*/
+	private String adDirectionalFlag;
+
+	/**定向包Id(用户定向)*/
+	private String adAudiencePackageId;
+	/**地域(用户定向)*/
+	private String adDistrict;
+	/**地域定向详细(用户定向)*/
+	private String adCity;
+	/**商圈id(用户定向)*/
+	private String adBusinessIds;
+	/**位置类型(用户定向)*/
+	private String adLocationType;
+	/**性别(用户定向)*/
+	private String adGender;
+	/**年龄(用户定向)*/
+	private String adAge;
+	/**定向人群包类型  1-定向 2-排除 3-同时定向和排除*/
+	private String adRetargetingTagsType;
+	/**定向人群包(用户定向)*/
+	private String adRetargetingTagsInclude;
+	/**排除人群包(用户定向)*/
+	private String adRetargetingTagsExclude;
+	/**行为兴趣(用户定向)*/
+	private String adInterestActionMode;
+	/**行为场景(用户定向)*/
+	private String adActionScene;
+	/**用户发生行为天数(用户定向)*/
+	private Integer adActionDays;
+	/**行为类目词(用户定向)*/
+	private String adActionCategories;
+	/**行为关键词(用户定向)*/
+	private String adActionWords;
+	/**兴趣类目词(用户定向)*/
+	private String adInterestCategories;
+	/**行为关键词(用户定向)*/
+	private String adInterestWords;
+	/**抖音达人互动用户行为类型(用户定向)*/
+	private String adAwemeFanBehaviors;
+	/**抖音达人分类ID列表(用户定向)*/
+	private String adAwemeFanCategories;
+	/**抖音达人ID列表(用户定向)*/
+	private String adAwemeFanAccounts;
+	/**账号粉丝相似人群(用户定向)*/
+	private String adAwemeFansNumbers;
+	/**过滤高活跃用户(用户定向)*/
+	private Integer adFilterAwemeAbnormalActive;
+	/**过滤高关注数用户(用户定向)*/
+	private Integer adFilterAwemeFansCount;
+	/**过滤自己的粉丝(用户定向)*/
+	private Integer adFilterOwnAwemeFans;
+	/**媒体定向(用户定向)*/
+	private String adSuperiorPopularityType;
+	/**定向逻辑(用户定向)*/
+	private String adFlowPackage;
+	/**排除定向逻辑(用户定向)*/
+	private String adExcludeFlowPackage;
+	/**平台(用户定向)*/
+	private String adPlatform;
+	/**最低安卓版本(用户定向)*/
+	private String adAndroidOsv;
+	/**最低IOS版本(用户定向)*/
+	private String adAdIosOsv;
+	/**设备类型(用户定向)*/
+	private String adDeviceType;
+	/**网络类型(用户定向)*/
+	private String adAc;
+	/**运营商(用户定向)*/
+	private String adCarrier;
+	/**过滤已安装(用户定向)*/
+	private Integer adHideIfExists;
+	/**过滤时间范围(用户定向)*/
+	private String adConvertedTimeDuration;
+	/**过滤已转化用户(用户定向)*/
+	private String adHideIfConverted;
+	/**新用户(用户定向)*/
+	private String adActivateType;
+	/**文章分类(用户定向)*/
+	private String adArticleCategory;
+	/**手机品牌(用户定向)*/
+	private String adDeviceBrand;
+	/**手机价格(用户定向)*/
+	private String adLaunchPrice;
+	/**是否启用智能放量(用户定向)*/
+	private String adAutoExtendEnabled;
+	/**可放开定向(用户定向)*/
+	private String adAutoExtendTargets;
+	/**投放场景-出价方式*/
+	private String adSmartBidType;
+	/**是否调整自动出价*/
+	private Integer adAdjustCpa;
+	/**竞价策略*/
+	private String adFlowControlMode;
+	/**预算类型*/
+	private String adBudgetMode;
+	/**计划预算*/
+	private Integer adBudget;
+	/**投放时间类型*/
+	private String adScheduleType;
+	/**投放开始时间 */
+	private String adStartTime;
+	/**投放结束时间*/
+	private String adEndTime;
+	/**投放时段*/
+	private String adScheduleTime;
+	/**付费方式*/
+	private String adPricing;
+	/**
+	 * 智能投放计划创建出价方式
+	 * 固定出价 FIX
+	 * 随机出价 RAND
+	 * 阶梯出价 STEP
+	 * */
+	private String adBidCreateType;
+	/**转化出价最小值*/
+	private BigDecimal adMinBid;
+	/**转化出价最大值*/
+	private BigDecimal adMaxBid;
+	/**转化出价阶梯出价步长*/
+	private BigDecimal adStepBid;
+	/**转化出价*/
+	private BigDecimal adBid;
+	/**目标转化出价*/
+	private BigDecimal adCpaBid;
+	//拼接 目标转化出价-前端展示
+	@TableField(exist = false)
+	private String adCpaBidStr;
+	/**深度优化方式*/
+	private String adDeepBidType;
+	/**深度优化出价*/
+	private BigDecimal adDeepCpabid;
+	/**鲁班目标ROI出价策略系数*/
+	private BigDecimal adLubanRoiGoal;
+	/**深度转化ROI系数*/
+	private BigDecimal adRoiGoal;
+	/**广告位置*/
+	private String creativeInventoryType;
+	@TableField(exist = false)
+	private String[] creativeInventoryTypes;
+	/**优选广告位*/
+	private Integer creativeSmartInventory;
+	/**场景广告位*/
+	private String creativeSceneInventory;
+	/**创意方式*/
+	private String creativeMaterialMode;
+	/**程序化创意包id*/
+	private Integer creativeProceduralPackageId;
+	/**自动生成视频素材*/
+	private Integer creativeIsPresentedVideo;
+	/**是否开启衍生计划*/
+	private Integer creativeGenerateDerivedAd;
+	/**素材类型*/
+	private String creativeImageMode;
+	/**广告来源*/
+	private String creativeSource;
+	/**品牌主页*/
+	private String creativeIesCoreUserId;
+	/**作品页隐藏广告内容*/
+	private Integer creativeIsFeedAndFavSee;
+	/**是否自动生成素材*/
+	private Integer creativeAutoGenerateSwitch;
+	/**应用名*/
+	private String creativeAppName;
+	/**app副标题*/
+	private String creativeSubTitle;
+	/**安卓应用下载详情页*/
+	private String creativeWebUrl;
+	/**行动号召按钮*/
+	private String creativeActionText;
+	/**搭配试玩素材url*/
+	private String creativePlayableUrl;
+	/**是否关闭评论*/
+	private Integer creativeIsCommentDisable;
+	/**商品卖点*/
+	private String creativeProductSellingPoints;
+	//商品卖点
+	@TableField(exist = false)
+	private String[] productSellingPoints;
+
+	/**商品描述-卡片标题*/
+	private String creativeProductDescription;
+	/**推广卡片的行动号召*/
+	private String creativeCallToAction;
+	/**是否使用智能优选*/
+	private Boolean creativeEnablePersonalAction;
+	/**商品卡片id*/
+	private String creativeProductImageId;
+	//商品卡片md5
+	private String creativeProductImageCode;
+	/**创意展现方式*/
+	private String creativeDisplayMode;
+	//允许客户端下载视频功能 0开启;1关闭
+	private Integer creativeDownloadStatus;
+	/**创意分类*/
+	private String creativeThirdIndustryId;
+
+	/**创意标签*/
+	private String creativeAdKeywords;
+	@TableField(exist = false)
+	private String[] adKeywords;
+
+	/**展示监测链接*/
+	private String creativeTrackUrl;
+	/**点击监测链接*/
+	private String creativeActionTrackUrl;
+	/**视频有效播放监测链接*/
+	private String creativeVideoPlayEffectiveTrackUrl;
+	/**视频播放监测链接*/
+	private String creativeVideoPlayTrackUrl;
+	/**数据发送方式*/
+	private String creativeTrackUrlSendType;
+	/**状态*/
+	private Integer status;
+	/**创建时间*/
+	private Date createTime;
+	/**更新时间*/
+	private Date updateTime;
+	/**创建人id*/
+	private String userId;
+
+	@TableField(exist = false)
+	private String loginUserId;
+
+	@TableField(exist = false)
+	private String imageUrl;
+
+	//消耗
+	@TableField(exist = false)
+	private BigDecimal cost;
+	//余额
+	@TableField(exist = false)
+	private BigDecimal validBalance;
+
+
+
+
+}

+ 69 - 0
jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/entity/AiBytedanceAutocreateLog.java

@@ -0,0 +1,69 @@
+package ctop.bytedance.ad.advertise.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;
+
+
+/**
+ * 自动创建计划日志
+ * @author jeecg-boot
+ * @date   2021-07-05
+ * @version V1.0
+ */
+@Data
+@TableName("ctop_ai_bytedance_autocreate_log")
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value="ctop_ai_bytedance_autocreate_log对象", description="自动创建计划日志")
+public class AiBytedanceAutocreateLog {
+
+	/**主键id*/
+	@TableId(type = IdType.AUTO)
+	@ApiModelProperty(value = "主键id")
+	private Integer id;
+	/**账户id*/
+	@Excel(name = "账户id", width = 15)
+	@ApiModelProperty(value = "账户id")
+	private Long accountId;
+	/**类型*/
+	@Excel(name = "类型", width = 15)
+	@ApiModelProperty(value = "类型")
+	private String execType;
+	/**代码*/
+	@Excel(name = "代码", width = 15)
+	@ApiModelProperty(value = "代码")
+	private Integer code;
+	/**返回消息*/
+	@Excel(name = "返回消息", width = 15)
+	@ApiModelProperty(value = "返回消息")
+	private String message;
+	/**创建调用接口的参数*/
+	@Excel(name = "创建调用接口的参数", width = 15)
+	@ApiModelProperty(value = "创建调用接口的参数")
+	private String createParam;
+	/**创建时间*/
+	@ApiModelProperty(value = "创建时间")
+	private Date createTime;
+
+	public AiBytedanceAutocreateLog(){}
+
+	public AiBytedanceAutocreateLog(Long accountId, String execType, Integer code, String message, String createParam){
+		this.accountId = accountId;
+		this.execType = execType;
+		this.code = code;
+		this.message = message;
+		this.createParam = createParam;
+	}
+}

+ 41 - 0
jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/entity/AiBytedanceCampaignDplinkInfo.java

@@ -0,0 +1,41 @@
+package ctop.bytedance.ad.advertise.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ * 头条组dplink标识创建记录
+ * @author jeecg-boot
+ * @date   2021-04-26
+ * @version V1.0
+ */
+@Data
+@TableName("ctop_ai_bytedance_campaign_dplink_info")
+public class AiBytedanceCampaignDplinkInfo {
+    
+	/**id*/
+	@TableId(type = IdType.AUTO)
+	private Long id;
+	/**name*/
+	private String name;
+	/**startIndex*/
+	private Integer startIndex;
+	/**endIndex*/
+	private Integer endIndex;
+	/**status*/
+	private Integer status;
+	/**创建id*/
+	private Long campaignId;
+	/**createTime*/
+	private Date createTime;
+	/**updateTime*/
+	private Date updateTime;
+	/**accountId*/
+	private Long accountId;
+	/**strategyId*/
+	private Long strategyId;
+}

+ 540 - 0
jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/entity/ByteDanceAdvertisePlan.java

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

+ 249 - 0
jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/entity/ByteDanceAdvertiser.java

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

+ 147 - 0
jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/entity/ByteDanceAudiencePackage.java

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

+ 152 - 0
jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/entity/ByteDanceCampaign.java

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

+ 162 - 0
jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/entity/ByteDanceCreative.java

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

+ 107 - 0
jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/entity/ByteDanceCreativeMaterial.java

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

+ 108 - 0
jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/entity/ByteDanceCreativeWordPackage.java

@@ -0,0 +1,108 @@
+package ctop.bytedance.ad.advertise.entity;
+
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+import org.jeecgframework.poi.excel.annotation.Excel;
+
+import java.util.Date;
+
+@Data
+@TableName("ctop_bytedance_creative_word_package")
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value = "ctop_bytedance_creative_word_package对象", description = "今日头条创意词包")
+public class ByteDanceCreativeWordPackage {
+
+
+    /**id*/
+    @TableId(type = IdType.UUID)
+    @ApiModelProperty(value = "id")
+    private Integer id;
+    /**creativeWordId*/
+    @Excel(name = "creativeWordId", width = 15)
+    @ApiModelProperty(value = "creativeWordId")
+    private Integer creativeWordId;
+    /**name*/
+    @Excel(name = "name", width = 15)
+    @ApiModelProperty(value = "name")
+    private String name;
+    /**defaultWord*/
+    @Excel(name = "defaultWord", width = 15)
+    @ApiModelProperty(value = "defaultWord")
+    private String defaultWord;
+    /**words*/
+    @Excel(name = "words", width = 15)
+    @ApiModelProperty(value = "words")
+    private Object words;
+    /**contentType*/
+    @Excel(name = "contentType", width = 15)
+    @ApiModelProperty(value = "contentType")
+    private String contentType;
+    /**maxWordLen*/
+    @Excel(name = "maxWordLen", width = 15)
+    @ApiModelProperty(value = "maxWordLen")
+    private Integer maxWordLen;
+    /**status*/
+    @Excel(name = "status", width = 15)
+    @ApiModelProperty(value = "status")
+    private String status;
+    /**userRate*/
+    @Excel(name = "userRate", width = 15)
+    @ApiModelProperty(value = "userRate")
+    private Float userRate;
+    /**createTime*/
+    @ApiModelProperty(value = "createTime")
+    private Date createTime;
+    /**updateTime*/
+    @ApiModelProperty(value = "updateTime")
+    private Date updateTime;
+
+
+
+    public ByteDanceCreativeWordPackage(){}
+
+    public ByteDanceCreativeWordPackage(JSONObject jsonObject){
+        int creativeWordId = jsonObject.getInteger("creative_word_id");
+        this.creativeWordId = creativeWordId;
+
+        int maxWordLen = jsonObject.getInteger("max_word_len");
+        this.maxWordLen = maxWordLen;
+
+        String name = jsonObject.getString("name");
+        if (null != name && !"".equals(name.trim())) {
+            this.name = name;
+        }
+
+        String defaultWord = jsonObject.getString("default_word");
+        if (null != defaultWord && !"".equals(defaultWord.trim())) {
+            this.defaultWord = defaultWord;
+        }
+
+        String words = jsonObject.getString("words");
+        if (null != words && !"".equals(words.trim())) {
+            this.words = words;
+        }
+
+        String contentType = jsonObject.getString("content_type");
+        if (null != contentType && !"".equals(contentType.trim())) {
+            this.contentType = contentType;
+        }
+
+        String status = jsonObject.getString("status");
+        if (null != status && !"".equals(status.trim())) {
+            this.status = status;
+        }
+
+        Float userRate = jsonObject.getFloat("user_rate");
+        this.userRate = userRate;
+    }
+
+
+}

+ 84 - 0
jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/entity/ByteDanceGeneralCopywriter.java

@@ -0,0 +1,84 @@
+package ctop.bytedance.ad.advertise.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+import ctop.bytedance.ad.common.utils.Check;
+import org.jeecgframework.poi.excel.annotation.Excel;
+
+import java.util.Date;
+
+/**
+ * 通用文案库
+ * @author jeecg-boot
+ * @date   2021-05-28
+ * @version V1.0
+ */
+@Data
+@TableName("ctop_bytedance_general_copywriter")
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value="ctop_bytedance_general_copywriter对象", description="通用文案库")
+public class ByteDanceGeneralCopywriter {
+    
+	/**id*/
+	@TableId(type = IdType.UUID)
+    @ApiModelProperty(value = "id")
+	private String id;
+	/**广告账户ID(相当于头条返回的access_token数据中的advertiser_id)*/
+	@Excel(name = "广告账户ID(相当于头条返回的access_token数据中的advertiser_id)", width = 15)
+    @ApiModelProperty(value = "广告账户ID(相当于头条返回的access_token数据中的advertiser_id)")
+	private Long accountId;
+	/**文案*/
+	@Excel(name = "文案", width = 15)
+    @ApiModelProperty(value = "文案")
+	private String textCopywriter;
+	/**动态词包id数组*/
+	@Excel(name = "动态词包id数组", width = 15)
+    @ApiModelProperty(value = "动态词包id数组")
+	private String creativeWordIds;
+	/**状态 0:启用 1:禁用*/
+	@Excel(name = "状态 0:启用 1:禁用", width = 15)
+    @ApiModelProperty(value = "状态 0:启用 1:禁用")
+	private Integer status;
+	/**createTime*/
+    @ApiModelProperty(value = "createTime")
+	private Date createTime;
+	/**updateTime*/
+    @ApiModelProperty(value = "updateTime")
+	private Date updateTime;
+
+    public ByteDanceGeneralCopywriter(){}
+
+    public ByteDanceGeneralCopywriter(Long accountId, String textCopywriter){
+		if (!Check.isNull(accountId)) {
+			this.accountId = accountId;
+		}
+
+		if(!Check.isNull(textCopywriter)){
+			this.textCopywriter = textCopywriter;
+		}
+
+
+	}
+
+	public ByteDanceGeneralCopywriter(Long accountId, String textCopywriter, String creativeWordIds){
+		if (!Check.isNull(accountId)) {
+			this.accountId = accountId;
+		}
+
+		if(!Check.isNull(textCopywriter)){
+			this.textCopywriter = textCopywriter;
+		}
+
+		if(!Check.isNull(creativeWordIds)){
+			this.creativeWordIds = creativeWordIds;
+		}
+	}
+
+}

+ 116 - 0
jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/entity/ByteDanceVideoInfo.java

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

+ 59 - 0
jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/entity/BytedanceAiVideoCreativeLog.java

@@ -0,0 +1,59 @@
+package ctop.bytedance.ad.advertise.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+import org.jeecg.common.util.DateUtils;
+
+import java.util.Date;
+import java.util.UUID;
+
+/**
+ * 视频创建创意记录信息
+ * @author jeecg-boot
+ * @date   2021-05-19
+ * @version V1.0
+ */
+@Data
+@TableName("ctop_bytedance_ai_video_creative_log")
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+public class BytedanceAiVideoCreativeLog {
+    
+	/**id*/
+	@TableId(type = IdType.AUTO)
+	private Long id;
+	private Long accountId;
+	/**videoCode*/
+	private String videoCode;
+	private Long campaignId;
+	private Long adId;
+	/**creativeUuid*/
+	private String creativeUuid;
+	/**strategyId*/
+	private Long strategyId;
+	/**stateDate*/
+	private String stateDate;
+	/**status*/
+	private Integer status;
+	/**createTime*/
+	private Date createTime;
+	/**updateTime*/
+	private Date updateTime;
+
+	public BytedanceAiVideoCreativeLog(AiBytedanceAdvertiserStrategy strategy, Long adId, Long campaignId, ByteDanceVideoInfo video) {
+		this.accountId = strategy.getAccountId();
+		this.strategyId = strategy.getId();
+		this.adId = adId;
+		this.campaignId = campaignId;
+		this.videoCode = video.getSignature();
+		this.creativeUuid = UUID.randomUUID().toString();
+		this.stateDate = DateUtils.formatDate();
+		this.createTime = new Date();
+		this.updateTime = new Date();
+		this.status = 1;
+	}
+}

+ 72 - 0
jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/entity/BytedanceAreaInfo.java

@@ -0,0 +1,72 @@
+package ctop.bytedance.ad.advertise.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+import org.jeecgframework.poi.excel.annotation.Excel;
+
+import java.util.Date;
+
+/**
+ * 省市县信息
+ *
+ * @author jeecg-boot
+ * @version V1.0
+ * @date 2019-09-17
+ */
+@Data
+@TableName("ctop_bytedance_area_info")
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value = "ctop_bytedance_area_info对象", description = "省市县信息")
+public class BytedanceAreaInfo {
+    /**
+     * id
+     */
+    @TableId(type = IdType.UUID)
+    @ApiModelProperty(value = "id")
+    private Integer id;
+    /**
+     * name
+     */
+    @Excel(name = "name", width = 15)
+    @ApiModelProperty(value = "name")
+    private String name;
+    /**
+     * code
+     */
+    @Excel(name = "code", width = 15)
+    @ApiModelProperty(value = "code")
+    private String code;
+    /**
+     * parentCode
+     */
+    @Excel(name = "parentCode", width = 15)
+    @ApiModelProperty(value = "parentCode")
+    private String parentCode;
+    /**
+     * level
+     */
+    @Excel(name = "level", width = 15)
+    @ApiModelProperty(value = "level")
+    private Integer level;
+    /**
+     * createTime
+     */
+    @ApiModelProperty(value = "createTime")
+    private Date createTime;
+    /**
+     * updateTime
+     */
+    @ApiModelProperty(value = "updateTime")
+    private Date updateTime;
+
+    @TableField(exist = false)
+    private Boolean hasChild;
+}

+ 79 - 0
jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/entity/BytedanceImageInfo.java

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

+ 42 - 0
jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/entity/BytedanceIndustryInfo.java

@@ -0,0 +1,42 @@
+package ctop.bytedance.ad.advertise.entity;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+import org.jeecgframework.poi.excel.annotation.Excel;
+
+import java.util.Date;
+
+/**
+ * 头条行业类别
+ * @author jeecg-boot
+ * @date   2020-07-30
+ * @version V1.0
+ */
+@Data
+@TableName("ctop_bytedance_industry_info")
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value="ctop_bytedance_industry_info对象", description="头条行业类别")
+public class BytedanceIndustryInfo {
+
+	/**id*/
+	@TableId
+	private Long id;
+	/**name*/
+	private String name;
+	/**code*/
+	private String code;
+	/**parentCode*/
+	private String parentCode;
+	/**level*/
+	private Integer level;
+	/**createTime*/
+	private Date createTime;
+	/**updateTime*/
+	private Date updateTime;
+}

+ 62 - 0
jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/entity/BytedanceInterestCategory.java

@@ -0,0 +1,62 @@
+package ctop.bytedance.ad.advertise.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+import org.jeecgframework.poi.excel.annotation.Excel;
+
+import java.util.Date;
+
+/**
+ * 兴趣分类信息
+ *
+ * @author jeecg-boot
+ * @version V1.0
+ * @date 2019-09-18
+ */
+@Data
+@TableName("ctop_bytedance_interest_category")
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value = "ctop_bytedance_interest_category对象", description = "兴趣分类信息")
+public class BytedanceInterestCategory {
+
+    /**
+     * id
+     */
+    @TableId(type = IdType.AUTO)
+    private Long id;
+    /**
+     * 名称
+     */
+    private String name;
+    /**
+     * code
+     */
+    private String code;
+    /**
+     * parentCode
+     */
+    private String parentCode;
+    /**
+     * level
+     */
+    private Integer level;
+    /**
+     * createTime
+     */
+    private Date createTime;
+    /**
+     * updateTime
+     */
+    private Date updateTime;
+
+    @TableField(exist = false)
+    private Boolean hasChild;
+}

+ 27 - 0
jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/entity/BytedanceMaterialRejectReason.java

@@ -0,0 +1,27 @@
+package ctop.bytedance.ad.advertise.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.util.Date;
+@Data
+@TableName("ctop_bytedance_material_reject_reason")
+public class BytedanceMaterialRejectReason {
+    private String videoId;
+
+    private String imageId;
+
+    private String title;
+
+    private String rejectReason;
+
+    private Integer isLowQuality;
+
+    private Date createTime;
+
+    private Long accountId;
+
+    private Long adId;
+}

+ 22 - 0
jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/entity/BytedancePlanRejectReason.java

@@ -0,0 +1,22 @@
+package ctop.bytedance.ad.advertise.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.util.Date;
+@Data
+@TableName("ctop_bytedance_plan_reject_reason")
+public class BytedancePlanRejectReason {
+    private Long adId;
+
+    private String rejectItem;
+
+    private String rejectReason;
+
+    private Integer isLowQuality;
+
+    private Date createTime;
+
+    private Long accountId;
+
+}

+ 82 - 0
jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/entity/BytedanceVideoSlogenInfo.java

@@ -0,0 +1,82 @@
+package ctop.bytedance.ad.advertise.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 头条视频文案信息
+ * @author jeecg-boot
+ * 2021-04-19
+ * @version V1.0
+ */
+@Data
+@TableName("ctop_bytedance_video_slogen_info")
+public class BytedanceVideoSlogenInfo {
+
+	/**id*/
+	@TableId(type = IdType.AUTO)
+	private Long id;
+	/**videoCode*/
+	private String videoCode;
+	@TableField(exist=false)
+	private String materialName;
+	@TableField(exist=false)
+	private List<String> materialNameArray;
+	/**slogan*/
+	private String slogan;
+	@TableField(exist=false)
+	private String newSlogan;
+	/**createTime*/
+	private Date createTime;
+	/**updateTime*/
+	private Date updateTime;
+	/**createBy*/
+	private String createBy;
+	/**updateBy*/
+	private String updateBy;
+	/**status*/
+	private Integer status;
+	private String creativeWordIds;
+	private Long projectId;
+	public BytedanceVideoSlogenInfo(String videoCode, String slogan, String userId) {
+		this.videoCode = videoCode;
+		this.slogan = slogan;
+		this.createBy = userId;
+		this.updateBy = userId;
+		this.createTime = new Date();
+		this.updateTime = new Date();
+		this.status = 1;
+	}
+
+	public BytedanceVideoSlogenInfo(String videoCode, String slogan, String userId, String creativeWordIds) {
+		this.videoCode = videoCode;
+		this.slogan = slogan;
+		this.createBy = userId;
+		this.updateBy = userId;
+		this.createTime = new Date();
+		this.updateTime = new Date();
+		this.status = 1;
+		this.creativeWordIds = creativeWordIds;
+	}
+
+	public BytedanceVideoSlogenInfo(Long projectId, String videoCode, String slogan, String userId, String creativeWordIds) {
+		this.videoCode = videoCode;
+		this.slogan = slogan;
+		this.createBy = userId;
+		this.updateBy = userId;
+		this.createTime = new Date();
+		this.updateTime = new Date();
+		this.status = 1;
+		this.creativeWordIds = creativeWordIds;
+		this.projectId = projectId;
+	}
+
+	public BytedanceVideoSlogenInfo() {
+	}
+}

+ 19 - 0
jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/entity/LowQualityRejectReason.java

@@ -0,0 +1,19 @@
+package ctop.bytedance.ad.advertise.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.util.Date;
+
+
+@Data
+@TableName("ctop_low_quality_reject_reason")
+public class LowQualityRejectReason {
+    private Integer id;
+
+    private String auditRejectReason;
+
+    private Integer status;
+
+    private Date createTime;
+}

+ 75 - 0
jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/entity/RuleDataAccount.java

@@ -0,0 +1,75 @@
+package ctop.bytedance.ad.advertise.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+import org.jeecgframework.poi.excel.annotation.Excel;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * 规则账户清洗数据
+ * @author jeecg-boot
+ * @date   2020-11-16
+ * @version V1.0
+ */
+@Data
+@TableName("ctop_rule_data_account")
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value="ctop_rule_data_account对象", description="规则账户清洗数据")
+public class RuleDataAccount {
+
+	/**id*/
+    @ApiModelProperty(value = "id")
+	private Long id;
+	/**账户id*/
+	@Excel(name = "账户id", width = 15)
+    @ApiModelProperty(value = "账户id")
+	private Long accountId;
+	/**账户name*/
+	@Excel(name = "账户id", width = 15)
+	@ApiModelProperty(value = "账户id")
+	private String accountName;
+	/**消耗*/
+	@Excel(name = "消耗", width = 15)
+    @ApiModelProperty(value = "消耗")
+	private BigDecimal cost;
+	/**validBalance*/
+	@Excel(name = "validBalance", width = 15)
+    @ApiModelProperty(value = "validBalance")
+	private BigDecimal validBalance;
+	/**转化数*/
+	@Excel(name = "转化数", width = 15)
+    @ApiModelProperty(value = "转化数")
+	private Long convertNum;
+	/**转化成本*/
+	@Excel(name = "转化成本", width = 15)
+    @ApiModelProperty(value = "转化成本")
+	private BigDecimal convertCost;
+	/**次留数*/
+	@Excel(name = "次留数", width = 15)
+    @ApiModelProperty(value = "次留数")
+	private Long nextDayOpenNum;
+	/**nextDayOpenCost*/
+	@Excel(name = "nextDayOpenCost", width = 15)
+    @ApiModelProperty(value = "nextDayOpenCost")
+	private BigDecimal nextDayOpenCost;
+
+	private BigDecimal nextDayOpenRate;
+
+	/**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;
+}

+ 61 - 0
jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/entity/UpdAdStaOrCpaOrBudget.java

@@ -0,0 +1,61 @@
+package ctop.bytedance.ad.advertise.entity;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Administrator
+ * 2021/4/22
+ **/
+@Data
+@ApiModel(description = "修改出价,预算-vo")
+public class UpdAdStaOrCpaOrBudget implements Serializable {
+
+    private String id;
+    @ApiModelProperty(value = "1-修改出价 2-修改预算")
+    private String type;
+    @ApiModelProperty(value = "广告主id")
+    private String accountId;
+
+    List<Map<String,Object>> list;
+
+    @ApiModelProperty(value = "计划id")
+    private String adId;
+
+
+    /**
+     * 智能投放计划创建出价方式
+     * 固定出价 FIX
+     * 随机出价 RAND
+     * 阶梯出价 STEP
+     * */
+    private String adBidCreateType;
+    /**转化出价最小值*/
+    private BigDecimal adMinBid;
+    /**转化出价最大值*/
+    private BigDecimal adMaxBid;
+    /**转化出价阶梯出价步长*/
+    private BigDecimal adStepBid;
+    /**目标转化出价*/
+    private BigDecimal adCpaBid;
+
+
+    @ApiModelProperty(value = "预算")
+    private String budget;
+    /**
+     * 1 不限
+     * 2 指定预算
+     */
+    @ApiModelProperty(value = "预算类型")
+    private String budgetType;
+    @ApiModelProperty(value = "花费")
+    private BigDecimal cost;
+
+
+}

+ 166 - 0
jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/enums/BytedanceConvertType.java

@@ -0,0 +1,166 @@
+package ctop.bytedance.ad.advertise.enums;
+
+public enum BytedanceConvertType {
+    AD_CONVERT_TYPE_PHONE("AD_CONVERT_TYPE_PHONE", 1L, "电话拨打"),
+    AD_CONVERT_TYPE_FORM("AD_CONVERT_TYPE_FORM", 2L, "表单提交"),
+    AD_CONVERT_TYPE_MAP_SEARCH("AD_CONVERT_TYPE_MAP_SEARCH", 3L, "地图搜索"),
+    AD_CONVERT_TYPE_DOWNLOAD_FINISH("AD_CONVERT_TYPE_DOWNLOAD_FINISH", 4L, "下载完成"),
+    AD_CONVERT_TYPE_BUTTON("AD_CONVERT_TYPE_BUTTON", 5L, "按钮跳转"),
+    AD_CONVERT_TYPE_XPATH("AD_CONVERT_TYPE_XPATH", 6L, "xpath类型转换"),
+    AD_CONVERT_TYPE_VIEW("AD_CONVERT_TYPE_VIEW", 7L, "关键页面浏览"),
+    AD_CONVERT_TYPE_ACTIVE("AD_CONVERT_TYPE_ACTIVE", 8L, "激活"),
+    AD_CONVERT_TYPE_DOWNLOAD_START("AD_CONVERT_TYPE_DOWNLOAD_START", 9L, "下载按钮download_start"),
+    AD_CONVERT_TYPE_QQ("AD_CONVERT_TYPE_QQ", 10L, "qq咨询"),
+    AD_CONVERT_TYPE_LOTTERY("AD_CONVERT_TYPE_LOTTERY", 11L, "抽奖"),
+    AD_CONVERT_TYPE_VOTE("AD_CONVERT_TYPE_VOTE", 12L, "投票"),
+    AD_CONVERT_TYPE_ACTIVE_REGISTER("AD_CONVERT_TYPE_ACTIVE_REGISTER", 13L, "激活且注册"),
+    AD_CONVERT_TYPE_PAY("AD_CONVERT_TYPE_PAY", 14L, "激活且付费"),
+    AD_CONVERT_TYPE_INSTALL_FINISH("AD_CONVERT_TYPE_INSTALL_FINISH", 15L, "安装完成"),
+    AD_CONVERT_TYPE_PHONE_CONFIRM("AD_CONVERT_TYPE_PHONE_CONFIRM", 16L, "智能电话-确认拨打"),
+    AD_CONVERT_TYPE_PHONE_CONNECT("AD_CONVERT_TYPE_PHONE_CONNECT", 17L, "智能电话-确认接通"),
+    AD_CONVERT_TYPE_PHONE_EFFECTIVE("AD_CONVERT_TYPE_PHONE_EFFECTIVE", 18L, "智能电话-有效接通"),
+    AD_CONVERT_TYPE_CONSULT_EFFECTIVE("AD_CONVERT_TYPE_CONSULT_EFFECTIVE", 19L, "有效咨询"),
+    AD_CONVERT_TYPE_APP_ORDER("AD_CONVERT_TYPE_APP_ORDER", 20L, "app内下单(电商)"),
+    AD_CONVERT_TYPE_APP_UV("AD_CONVERT_TYPE_APP_UV", 21L, "app内访问"),
+    AD_CONVERT_TYPE_APP_CART("AD_CONVERT_TYPE_APP_CART", 22L, "app内添加购物车(电商)"),
+    AD_CONVERT_TYPE_APP_PAY("AD_CONVERT_TYPE_APP_PAY", 23L, "app内付费"),
+    AD_CONVERT_TYPE_SALES_LEAD("AD_CONVERT_TYPE_SALES_LEAD", 24L, "销售线索"),
+    AD_CONVERT_TYPE_GAME_ADDICTION("AD_CONVERT_TYPE_GAME_ADDICTION", 25L, "关键行为(原深度转化)"),
+    AD_CONVERT_TYPE_CUSTOMER_EFFECTIVE("AD_CONVERT_TYPE_CUSTOMER_EFFECTIVE", 26L, "有效获客"),
+    AD_CONVERT_TYPE_EFFECTIVE_COPY("AD_CONVERT_TYPE_EFFECTIVE_COPY", 27L, "关键页面到达&有效内容复制"),
+    AD_CONVERT_TYPE_COUPON("AD_CONVERT_TYPE_COUPON", 28L, "卡券领取"),
+    AD_CONVERT_TYPE_APP_DETAIL_UV("AD_CONVERT_TYPE_APP_DETAIL_UV", 29L, "app内详情页到站uv"),
+    AD_CONVERT_TYPE_RSS("AD_CONVERT_TYPE_RSS", 30L, "账号关注"),
+    AD_CONVERT_TYPE_FORM_CONNECT("AD_CONVERT_TYPE_FORM_CONNECT", 31L, "表单提交-已接通"),
+    AD_CONVERT_TYPE_FORM_ANSWER("AD_CONVERT_TYPE_FORM_ANSWER", 32L, "有效沟通"),
+    AD_CONVERT_TYPE_DIALBACK("AD_CONVERT_TYPE_DIALBACK", 33L, "提交回呼电话"),
+    AD_CONVERT_TYPE_DIALBACK_CONFIRM("AD_CONVERT_TYPE_DIALBACK_CONFIRM", 34L, "回呼电话-确认拨打"),
+    AD_CONVERT_TYPE_DIALBACK_CONNECT("AD_CONVERT_TYPE_DIALBACK_CONNECT", 35L, "回呼电话-确认接通"),
+    AD_CONVERT_TYPE_FORM_DEEP("AD_CONVERT_TYPE_FORM_DEEP", 36L, "分层表单"),
+    AD_CONVERT_TYPE_UPDATE_LEVEL("AD_CONVERT_TYPE_UPDATE_LEVEL", 37L, "激活且升级"),
+    AD_CONVERT_TYPE_CREATE_GAMEROLE("AD_CONVERT_TYPE_CREATE_GAMEROLE", 38L, "激活且创建角色"),
+    AD_CONVERT_TYPE_NEXT_DAY_OPEN("AD_CONVERT_TYPE_NEXT_DAY_OPEN", 39L, "激活且次留"),
+    AD_CONVERT_TYPE_INVALID_CLUE("AD_CONVERT_TYPE_INVALID_CLUE", 40L, "无效线索"),
+    AD_CONVERT_TYPE_INTENTION_CLUE("AD_CONVERT_TYPE_INTENTION_CLUE", 41L, "有意向客户"),
+    AD_CONVERT_TYPE_HIGH_VALUE_CLUE("AD_CONVERT_TYPE_HIGH_VALUE_CLUE", 42L, "高价值客户"),
+    AD_CONVERT_TYPE_PAID_CLUE("AD_CONVERT_TYPE_PAID_CLUE", 43L, "已成单"),
+    AD_CONVERT_TYPE_NATIVE_ACTION("AD_CONVERT_TYPE_NATIVE_ACTION", 44L, "原生互动"),
+    AD_CONVERT_TYPE_LIKE_ACTION("AD_CONVERT_TYPE_LIKE_ACTION", 45L, "视频点赞"),
+    AD_CONVERT_TYPE_FOLLOW_ACTION("AD_CONVERT_TYPE_FOLLOW_ACTION", 46L, "账户关注"),
+    AD_CONVERT_TYPE_COMMENT_ACTION("AD_CONVERT_TYPE_COMMENT_ACTION", 47L, "视频评论"),
+    AD_CONVERT_TYPE_LOCATION_ACTION("AD_CONVERT_TYPE_LOCATION_ACTION", 48L, "POI点击"),
+    AD_CONVERT_TYPE_SHOPPING_ACTION("AD_CONVERT_TYPE_SHOPPING_ACTION", 49L, "购物车点击"),
+    AD_CONVERT_TYPE_REDIRECT_TO_SHOP("AD_CONVERT_TYPE_REDIRECT_TO_SHOP", 50L, "调起店铺"),
+    AD_CONVERT_TYPE_LINK_ACTION("AD_CONVERT_TYPE_LINK_ACTION", 51L, "link点击"),
+    AD_CONVERT_TYPE_DEEP_PURCHASE("AD_CONVERT_TYPE_DEEP_PURCHASE", 52L, "多次付费"),
+    AD_CONVERT_TYPE_SUCCESSORDER_ACTION("AD_CONVERT_TYPE_SUCCESSORDER_ACTION", 53L, "小店转化"),
+    AD_CONVERT_TYPE_POI_COLLECT("AD_CONVERT_TYPE_POI_COLLECT", 60L, "poi地址点击"),
+    AD_CONVERT_TYPE_POI_ADDRESS_CLICK("AD_CONVERT_TYPE_POI_ADDRESS_CLICK", 61L, "poi收藏"),
+    AD_CONVERT_TYPE_RESERVATION("AD_CONVERT_TYPE_RESERVATION", 62L, "poi预定"),
+    AD_CONVERT_TYPE_MESSAGE_ACTION("AD_CONVERT_TYPE_MESSAGE_ACTION", 63L, "私信消息"),
+    AD_CONVERT_TYPE_SHARE_ACTION("AD_CONVERT_TYPE_SHARE_ACTION", 65L, "分享"),
+    AD_CONVERT_TYPE_CLICK_LANDING_PAGE("AD_CONVERT_TYPE_CLICK_LANDING_PAGE", 66L, "访问推广详情页"),
+    AD_CONVERT_TYPE_CLICK_SHOPWINDOW("AD_CONVERT_TYPE_CLICK_SHOPWINDOW", 67L, "访问主页商品橱窗"),
+    AD_CONVERT_TYPE_CLICK_DOWNLOAD("AD_CONVERT_TYPE_CLICK_DOWNLOAD", 68L, "访问主页下载应用"),
+    AD_CONVERT_TYPE_CLICK_CALL_DY("AD_CONVERT_TYPE_CLICK_CALL_DY", 69L, "点击主页内电话拨打"),
+    AD_CONVERT_TYPE_CLICK_WEBSITE("AD_CONVERT_TYPE_CLICK_WEBSITE", 70L, "访问主页官网"),
+    AD_CONVERT_PAGE_VIEW("AD_CONVERT_PAGE_VIEW", 93L, "访问目标页面"),
+    AD_CONVERT_TYPE_MESSAGE("AD_CONVERT_TYPE_MESSAGE", 94L, "短信"),
+    AD_CONVERT_TYPE_REDIRECT("AD_CONVERT_TYPE_REDIRECT", 95L, "页面跳转"),
+    AD_CONVERT_TYPE_SHOPPING("AD_CONVERT_TYPE_SHOPPING", 96L, "商品购买"),
+    AD_CONVERT_TYPE_CONSULT("AD_CONVERT_TYPE_CONSULT", 97L, "在线咨询"),
+    AD_CONVERT_TYPE_WECHAT("AD_CONVERT_TYPE_WECHAT", 98L, "微信"),
+    AD_CONVERT_TYPE_OTHER("AD_CONVERT_TYPE_OTHER", 99L, "其他"),
+    AD_CONVERT_TYPE_MULTIPLE("AD_CONVERT_TYPE_MULTIPLE", 100L, "多转化事件"),
+    AD_CONVERT_TYPE_POI_MULTIPLE("AD_CONVERT_TYPE_POI_MULTIPLE", 101L, "POI门店多转化目标"),
+    AD_CONVERT_TYPE_MULTI_NATIVE_ACTION("AD_CONVERT_TYPE_MULTI_NATIVE_ACTION", 102L, "互动"),
+    AD_CONVERT_TYPE_LOAN_COMPLETION("AD_CONVERT_TYPE_LOAN_COMPLETION", 103L, "互联网金融-完件"),
+    AD_CONVERT_TYPE_PRE_LOAN_CREDIT("AD_CONVERT_TYPE_PRE_LOAN_CREDIT", 104L, "互联网金融-预授信"),
+    AD_CONVERT_TYPE_LOAN_CREDIT("AD_CONVERT_TYPE_LOAN_CREDIT", 105L, "互联网金融-授信"),
+    AD_CONVERT_TYPE_IDCARD_INFORMATION("AD_CONVERT_TYPE_IDCARD_INFORMATION", 106L, "身份证信息填写完成"),
+    AD_CONVERT_TYPE_BANKCARD_INFORMATION("AD_CONVERT_TYPE_BANKCARD_INFORMATION", 107L, "银行卡信息填写完成"),
+    AD_CONVERT_TYPE_PERSONAL_INFORMATION("AD_CONVERT_TYPE_PERSONAL_INFORMATION", 108L, "补充个人信息填写完成"),
+    AD_CONVERT_TYPE_CERTIFICATION_INFORMATION("AD_CONVERT_TYPE_CERTIFICATION_INFORMATION", 109L, "用户活体认证信息上传完成"),
+    AD_CONVERT_TYPE_LT_ROI("AD_CONVERT_TYPE_LT_ROI", 110L, "广告变现ROI"),
+    AD_CONVERT_TYPE_LIVE_HOMEPAGE("AD_CONVERT_TYPE_LIVE_HOMEPAGE", 111L, "直播导流"),
+    AD_CONVERT_TYPE_REDIRECT_TO_STORE("AD_CONVERT_TYPE_REDIRECT_TO_STORE", 113L, "店铺导流"),
+    AD_CONVERT_TYPE_FEED_LIVE_HOMEPAGE("AD_CONVERT_TYPE_FEED_LIVE_HOMEPAGE", 120L, "火山feed进入直播页"),
+    AD_CONVERT_TYPE_AUTHORIZATION("AD_CONVERT_TYPE_AUTHORIZATION", 121L, "授权(电商)"),
+    AD_CONVERT_TYPE_COMMODITY_CLICK("AD_CONVERT_TYPE_COMMODITY_CLICK", 122L, "快上电商推广目的"),
+    AD_CONVERT_TYPE_CONSULT_CLUE("AD_CONVERT_TYPE_CONSULT_CLUE", 123L, "留咨咨询"),
+    AD_CONVERT_TYPE_BOOST("AD_CONVERT_TYPE_BOOST", 124L, "自然助推"),
+    AD_CONVERT_TYPE_STAY_TIME("AD_CONVERT_TYPE_STAY_TIME", 125L, "店铺停留"),
+    AD_CONVERT_TYPE_PURCHASE_OF_GOODS("AD_CONVERT_TYPE_PURCHASE_OF_GOODS", 156L, "商品签收"),
+    AD_CONVERT_TYPE_PURCHASE_ROI("AD_CONVERT_TYPE_PURCHASE_ROI", 160L, "付费ROI"),
+    AD_CONVERT_TYPE_LIVE_NATIVE_ACITON("AD_CONVERT_TYPE_LIVE_NATIVE_ACITON", 162L, "直播间原生互动"),
+    AD_CONVERT_TYPE_LIVE_FOLLOW_ACITON("AD_CONVERT_TYPE_LIVE_FOLLOW_ACITON", 163L, "直播间关注"),
+    AD_CONVERT_TYPE_LIVE_COMMENT_ACTION("AD_CONVERT_TYPE_LIVE_COMMENT_ACTION", 164L, "直播间评论"),
+    AD_CONVERT_TYPE_LIVE_GIFT_ACTION("AD_CONVERT_TYPE_LIVE_GIFT_ACTION", 165L, "直播间内打赏"),
+    AD_CONVERT_TYPE_LIVE_SLIDECART_CLICK_ACTION("AD_CONVERT_TYPE_LIVE_SLIDECART_CLICK_ACTION", 166L, "直播间查看购物车"),
+    AD_CONVERT_TYPE_LIVE_CLICK_PRODUCT_ACTION("AD_CONVERT_TYPE_LIVE_CLICK_PRODUCT_ACTION", 167L, "直播间查看商品"),
+    AD_CONVERT_TYPE_LIVE_ENTER_ACTION("AD_CONVERT_TYPE_LIVE_ENTER_ACTION", 171L, "直播间观看"),
+    AD_CONVERT_TYPE_LIVE_SUCCESSORDER_ACTION("AD_CONVERT_TYPE_LIVE_SUCCESSORDER_ACTION", 172L, "直播间成单"),
+    AD_CONVERT_TYPE_NOTIFY_DOWNLOAD("AD_CONVERT_TYPE_NOTIFY_DOWNLOAD", 173L, "预约下载"),
+    AD_CONVERT_TYPE_PREMIUM_PAYMENT("AD_CONVERT_TYPE_PREMIUM_PAYMENT", 174L, "保险支付"),
+    AD_CONVERT_TYPE_MESSAGE_CLICK("AD_CONVERT_TYPE_MESSAGE_CLICK", 177L, "私信点击"),
+    AD_CONVERT_TYPE_UG_ROI("AD_CONVERT_TYPE_UG_ROI", 178L, "内广roi"),
+    AD_CONVERT_TYPE_ENTER_HOMEPAGE("AD_CONVERT_TYPE_ENTER_HOMEPAGE", 181L, "进入个人主页"),
+    AD_CONVERT_TYPE_SHOPPING_CART("AD_CONVERT_TYPE_SHOPPING_CART", 182L, "商品购物车点击"),
+    AD_CONVERT_TYPE_WECHAT_REGISTER("AD_CONVERT_TYPE_WECHAT_REGISTER", 183L, "微信内注册"),
+    AD_CONVERT_TYPE_WECHAT_PAY("AD_CONVERT_TYPE_WECHAT_PAY", 184L, "微信内付费"),
+    AD_CONVERT_TYPE_MESSAGE_INTERACTION("AD_CONVERT_TYPE_MESSAGE_INTERACTION", 185L, "沟通互动"),
+    AD_CONVERT_TYPE_LIVE_STAY_TIME("AD_CONVERT_TYPE_LIVE_STAY_TIME", 186L, "直播间停留"),
+    AD_CONVERT_TYPE_NEW_FOLLOW_ACTION("AD_CONVERT_TYPE_NEW_FOLLOW_ACTION", 187L, "粉丝增长"),
+    AD_CONVERT_TYPE_APPLET_CLICK("AD_CONVERT_TYPE_APPLET_CLICK", 189L, "小程序互动"),
+    AD_CONVERT_TYPE_MESSAGE_SERVICE("AD_CONVERT_TYPE_MESSAGE_SERVICE", 190L, "私信服务"),
+    AD_CONVERT_TYPE_MESSAGE_CLUE("AD_CONVERT_TYPE_MESSAGE_CLUE", 192L, "私信留资"),
+    AD_CONVERT_TYPE_LIVE_FANS_ACTION("AD_CONVERT_TYPE_LIVE_FANS_ACTION", 193L, "直播间加入粉丝团"),
+    AD_CONVERT_TYPE_CLUE_CONFIRM("AD_CONVERT_TYPE_CLUE_CONFIRM", 194L, "回访_信息确认"),
+    AD_CONVERT_TYPE_CLUE_INTERFLOW("AD_CONVERT_TYPE_CLUE_INTERFLOW", 195L, "回访_加为好友"),
+    AD_CONVERT_TYPE_CLUE_HIGH_INTENTION("AD_CONVERT_TYPE_CLUE_HIGH_INTENTION", 196L, "回访_高潜成交"),
+    AD_CONVERT_TYPE_LIVE_COMPONENT_CLICK("AD_CONVERT_TYPE_LIVE_COMPONENT_CLICK", 215L, "组件点击");
+
+
+    private String code;
+    private Long num;
+    private String desc;
+
+    public String getCode() {
+        return code;
+    }
+
+    public void setCode(String code) {
+        this.code = code;
+    }
+
+    public Long getNum() {
+        return num;
+    }
+
+    public void setNum(Long num) {
+        this.num = num;
+    }
+
+    public String getDesc() {
+        return desc;
+    }
+
+    public void setDesc(String desc) {
+        this.desc = desc;
+    }
+
+    BytedanceConvertType(String code, Long num, String desc) {
+        this.code = code;
+        this.num = num;
+        this.desc = desc;
+    }
+
+    public static Long getNum(String code) {
+        for (BytedanceConvertType convertType : BytedanceConvertType.values()) {
+            if (convertType.getCode().equals(code.trim())) {
+                return convertType.getNum();
+            }
+        }
+        return null;
+    }
+}

+ 134 - 0
jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/enums/BytedanceCreativeMatTypeEnum.java

@@ -0,0 +1,134 @@
+package ctop.bytedance.ad.advertise.enums;
+
+public enum BytedanceCreativeMatTypeEnum {
+    /**
+     * 创意素材类型
+     * 0 表示当天
+     */
+    BYTEDANCE_CREATIVE_MAT_TYPE_ENUM_NEW("1","上新",0L,0L),
+    BYTEDANCE_CREATIVE_MAT_TYPE_ENUM_HIGH_QUALITY("2","高质量",-4*60*24L,-1*60*24L),
+    BYTEDANCE_CREATIVE_MAT_TYPE_ENUM_MISSING("3","遗漏",-8*60*24L,-1*60*24L),
+    BYTEDANCE_CREATIVE_MAT_TYPE_ENUM_HISTORY("4","打捞",-8*60*24L,-1*60*24L),
+
+
+
+
+    BYTEDANCE_CREATIVE_IMAGE_MODE_LARGE("CREATIVE_IMAGE_MODE_LARGE","1","大图横图"),
+    BYTEDANCE_CREATIVE_IMAGE_MODE_LARGE_VERTICAL("CREATIVE_IMAGE_MODE_LARGE_VERTICAL","2","大图竖图"),
+    BYTEDANCE_CREATIVE_IMAGE_MODE_UNION_SPLASH("CREATIVE_IMAGE_MODE_UNION_SPLASH","3","开屏"),
+    BYTEDANCE_CREATIVE_IMAGE_MODE_VIDEO("CREATIVE_IMAGE_MODE_VIDEO","2","横版视频"),
+    BYTEDANCE_CREATIVE_IMAGE_MODE_VIDEO_VERTICAL("CREATIVE_IMAGE_MODE_VIDEO_VERTICAL","1","竖版视频");
+
+
+
+
+
+    /**
+     * 类型
+     */
+    private String type;
+    /**
+     * 名称
+     */
+    private String name;
+    /**
+     * 素材查询的时间区间
+     */
+    private Long videoGetStartTime;
+    private Long videoGetEndTime;
+
+    private String imageMode;
+
+    BytedanceCreativeMatTypeEnum(String type, String name,Long videoGetStartTime,Long videoGetEndTime) {
+        this.type = type;
+        this.name = name;
+        this.videoGetStartTime = videoGetStartTime;
+        this.videoGetEndTime = videoGetEndTime;
+    }
+
+    public static String getNameByType(String type) {
+        for (BytedanceCreativeMatTypeEnum createTypeEnum : BytedanceCreativeMatTypeEnum.values()) {
+            if (createTypeEnum.getType().equals(type)) {
+                return createTypeEnum.getName();
+            }
+        }
+        return "";
+    }
+
+    public static Long getStartTimeByType(String type) {
+        for (BytedanceCreativeMatTypeEnum createTypeEnum : BytedanceCreativeMatTypeEnum.values()) {
+            if (createTypeEnum.getType().equals(type)) {
+                return createTypeEnum.getVideoGetStartTime();
+            }
+        }
+        return -60*8L;
+    }
+
+    public static Long getEndTimeByType(String type) {
+        for (BytedanceCreativeMatTypeEnum createTypeEnum : BytedanceCreativeMatTypeEnum.values()) {
+            if (createTypeEnum.getType().equals(type)) {
+                return createTypeEnum.getVideoGetEndTime();
+            }
+        }
+        return -5L;
+    }
+
+    public String getType() {
+        return this.type;
+    }
+
+    public String getName() {
+        return this.name;
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
+
+    public void setName(String value) {
+        this.name = value;
+    }
+
+    public Long getVideoGetStartTime() {
+        return videoGetStartTime;
+    }
+
+    public void setVideoGetStartTime(Long videoGetStartTime) {
+        this.videoGetStartTime = videoGetStartTime;
+    }
+
+    public Long getVideoGetEndTime() {
+        return videoGetEndTime;
+    }
+
+    public void setVideoGetEndTime(Long videoGetEndTime) {
+        this.videoGetEndTime = videoGetEndTime;
+    }
+
+
+    public String getImageMode() {
+        return imageMode;
+    }
+
+    public void setImageMode(String imageMode) {
+        this.imageMode = imageMode;
+    }
+
+
+    BytedanceCreativeMatTypeEnum(String type, String name,String imageMode) {
+        this.type = type;
+        this.name = name;
+        this.imageMode = imageMode;
+    }
+
+
+    public static String getImageModeByType(String type) {
+        for (BytedanceCreativeMatTypeEnum createTypeEnum : BytedanceCreativeMatTypeEnum.values()) {
+            if (createTypeEnum.getType().equals(type)) {
+                return createTypeEnum.getImageMode();
+            }
+        }
+        return "";
+    }
+
+}

+ 14 - 0
jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/mapper/AiBytedanceAdDplinkInfoMapper.java

@@ -0,0 +1,14 @@
+package ctop.bytedance.ad.advertise.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import ctop.bytedance.ad.advertise.entity.AiBytedanceAdDplinkInfo;
+
+/**
+ * 头条计划dplink标识创建记录
+ * @author jeecg-boot
+ * 2021-04-26
+ * @version V1.0
+ */
+public interface AiBytedanceAdDplinkInfoMapper extends BaseMapper<AiBytedanceAdDplinkInfo> {
+
+}

+ 25 - 0
jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/mapper/AiBytedanceAdvertiserStrategyMapper.java

@@ -0,0 +1,25 @@
+package ctop.bytedance.ad.advertise.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import io.lettuce.core.dynamic.annotation.Param;
+import ctop.bytedance.ad.advertise.entity.AiBytedanceAdvertiserStrategy;
+import ctop.bytedance.ad.advertise.entity.UpdAdStaOrCpaOrBudget;
+
+/**
+ * 头条智能投放账户配置信息表
+ * @author jeecg-boot
+ * 2021-04-20
+ * @version V1.0
+ */
+public interface AiBytedanceAdvertiserStrategyMapper extends BaseMapper<AiBytedanceAdvertiserStrategy> {
+
+
+    Integer updStaByAccountId(@Param("accountId") String accountId,@Param("creativeImageMode")String creativeImageMode,@Param("state") String state,@Param("id") String id);
+
+    Integer updStaById(@Param("id") String id,@Param("state") String state);
+
+    Integer updCpaById(UpdAdStaOrCpaOrBudget updAdStaOrCpaOrBudget);
+
+    Integer updBudgetById(@Param("id") String id,@Param("budget") String budget,@Param("budgetType") String budgetType);
+
+}

+ 17 - 0
jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/mapper/AiBytedanceAutocreateLogMapper.java

@@ -0,0 +1,17 @@
+package ctop.bytedance.ad.advertise.mapper;
+
+import java.util.List;
+
+import org.apache.ibatis.annotations.Param;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import ctop.bytedance.ad.advertise.entity.AiBytedanceAutocreateLog;
+
+/**
+ * 自动创建计划日志
+ * @author jeecg-boot
+ * 2021-07-05
+ * @version V1.0
+ */
+public interface AiBytedanceAutocreateLogMapper extends BaseMapper<AiBytedanceAutocreateLog> {
+
+}

+ 14 - 0
jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/mapper/AiBytedanceCampaignDplinkInfoMapper.java

@@ -0,0 +1,14 @@
+package ctop.bytedance.ad.advertise.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import ctop.bytedance.ad.advertise.entity.AiBytedanceCampaignDplinkInfo;
+
+/**
+ * 头条组dplink标识创建记录
+ * @author jeecg-boot
+ * 2021-04-26
+ * @version V1.0
+ */
+public interface AiBytedanceCampaignDplinkInfoMapper extends BaseMapper<AiBytedanceCampaignDplinkInfo> {
+
+}

+ 31 - 0
jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/mapper/ByteDanceAdvertisePlanMapper.java

@@ -0,0 +1,31 @@
+package ctop.bytedance.ad.advertise.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import io.lettuce.core.dynamic.annotation.Param;
+import ctop.bytedance.ad.advertise.entity.ByteDanceAdvertisePlan;
+import ctop.bytedance.ad.report.entity.BytedancePlanHourlyReport;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+/**
+ * @Description: 今日头条广告计划信息
+ * @Author: jeecg-boot
+ * @Date: 2019-07-22
+ * @Version: V1.0
+ */
+public interface ByteDanceAdvertisePlanMapper extends BaseMapper<ByteDanceAdvertisePlan> {
+
+    List<String> selectWarningGroup(@Param("accountId") Long accountId, @Param("maxBid") BigDecimal maxBid);
+
+    List<String> selectWarningCpaBid(@Param("accountId") Long accountId, @Param("maxCpaBid") BigDecimal maxCpaBid);
+
+    int queryTodayBuiltCount(Long accountId, String date);
+
+    /**
+     * 更新广告计划 操作状态 或 定向包id
+     * @param byteDanceAdvertisePlan
+     * @return
+     */
+    Integer updateAdvertisePlan (ByteDanceAdvertisePlan byteDanceAdvertisePlan);
+}

+ 14 - 0
jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/mapper/ByteDanceAdvertiserMapper.java

@@ -0,0 +1,14 @@
+package ctop.bytedance.ad.advertise.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import ctop.bytedance.ad.advertise.entity.ByteDanceAdvertiser;
+
+/**
+ * @Description: 今日头条广告主信息
+ * @Author: jeecg-boot
+ * @Date: 2019-07-22
+ * @Version: V1.0
+ */
+public interface ByteDanceAdvertiserMapper extends BaseMapper<ByteDanceAdvertiser> {
+
+}

+ 14 - 0
jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/mapper/ByteDanceAudiencePackageMapper.java

@@ -0,0 +1,14 @@
+package ctop.bytedance.ad.advertise.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import ctop.bytedance.ad.advertise.entity.ByteDanceAudiencePackage;
+
+/**
+ * 头条定向包
+ * @author: jeecg-boot
+ * @date:   2020-07-22
+ * @cersion: V1.0
+ */
+public interface ByteDanceAudiencePackageMapper extends BaseMapper<ByteDanceAudiencePackage> {
+
+}

+ 17 - 0
jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/mapper/ByteDanceCampaignMapper.java

@@ -0,0 +1,17 @@
+package ctop.bytedance.ad.advertise.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Param;
+import ctop.bytedance.ad.advertise.entity.ByteDanceCampaign;
+
+import java.util.List;
+
+/**
+ * @Description: 今日头条广告组信息
+ * @Author: jeecg-boot
+ * @Date: 2019-07-22
+ * @Version: V1.0
+ */
+public interface ByteDanceCampaignMapper extends BaseMapper<ByteDanceCampaign> {
+    void replaceBatch(@Param(value = "campaigns") List<ByteDanceCampaign> campaigns);
+}

+ 18 - 0
jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/mapper/ByteDanceCreativeMapper.java

@@ -0,0 +1,18 @@
+package ctop.bytedance.ad.advertise.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Param;
+import ctop.bytedance.ad.advertise.entity.ByteDanceCreative;
+
+import java.util.List;
+
+/**
+ * @Description: 今日头条创意信息
+ * @Author: jeecg-boot
+ * @Date: 2019-07-22
+ * @Version: V1.0
+ */
+public interface ByteDanceCreativeMapper extends BaseMapper<ByteDanceCreative> {
+
+    void replaceBatch(@Param(value = "creatives") List<ByteDanceCreative> creatives);
+}

+ 14 - 0
jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/mapper/ByteDanceCreativeMaterialMapper.java

@@ -0,0 +1,14 @@
+package ctop.bytedance.ad.advertise.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import ctop.bytedance.ad.advertise.entity.ByteDanceCreativeMaterial;
+
+/**
+ * @Description: 今日头条创意素材信息
+ * @Author: jeecg-boot
+ * @Date: 2019-07-22
+ * @Version: V1.0
+ */
+public interface ByteDanceCreativeMaterialMapper extends BaseMapper<ByteDanceCreativeMaterial> {
+
+}

+ 26 - 0
jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/mapper/ByteDanceGeneralCopywriterMapper.java

@@ -0,0 +1,26 @@
+package ctop.bytedance.ad.advertise.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Param;
+import ctop.bytedance.ad.advertise.entity.ByteDanceCreativeWordPackage;
+import ctop.bytedance.ad.advertise.entity.ByteDanceGeneralCopywriter;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 通用文案库
+ * @author jeecg-boot
+ * 2021-05-28
+ * @version V1.0
+ */
+public interface ByteDanceGeneralCopywriterMapper extends BaseMapper<ByteDanceGeneralCopywriter> {
+    List<Map<String,Object>> selectGeneralCopywriterReport(List<String> accountIds, String keyWord, Integer status, String startTime, String endTime);
+
+    ByteDanceCreativeWordPackage selectCreativeWordPackageByName(String name);
+
+    List<ByteDanceGeneralCopywriter> getRandThree(@Param(value = "accountId") Long accountId);
+    List<ByteDanceGeneralCopywriter> getRandTen(@Param(value = "accountId") Long accountId);
+
+    List<ByteDanceGeneralCopywriter> selectAllDataByTextCopywriter(@Param(value = "textCopywriter") String textCopywriter);
+}

+ 53 - 0
jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/mapper/ByteDanceVideoInfoMapper.java

@@ -0,0 +1,53 @@
+package ctop.bytedance.ad.advertise.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Param;
+import ctop.bytedance.ad.advertise.entity.ByteDanceVideoInfo;
+
+import java.util.List;
+
+/**
+ * @Description: 今日头条视频素材信息
+ * @Author: jeecg-boot
+ * @Date: 2019-07-29
+ * @Version: V1.0
+ */
+public interface ByteDanceVideoInfoMapper extends BaseMapper<ByteDanceVideoInfo> {
+    void replaceBatch(@Param(value = "videoList") List<ByteDanceVideoInfo> videoInfoList);
+    void updateVideoVerticalType();
+    void updateVideoHorizonType();
+
+    /**
+     * 查询规定时间段内尚未创建创意的素材信息
+     * @param accountId
+     * @param startTime
+     * @param endTime
+     * @param videoCnt
+     * @return
+     */
+    List<ByteDanceVideoInfo> getNewVideoByParams(@Param(value = "projectId") Long projectId,@Param(value = "accountId") Long accountId, @Param(value = "imageMode") String imageMode,@Param(value = "startTime")String startTime, @Param(value = "endTime")String endTime, @Param(value = "videoCnt")Long videoCnt,@Param(value = "creativeCnt")Long creativeCnt,@Param(value = "now") String now);
+
+    List<ByteDanceVideoInfo> topMatByParams(@Param(value = "projectId")Long projectId, @Param(value = "accountId")Long accountId, @Param(value = "imageMode") String imageMode,@Param(value = "startTime")String startTime, @Param(value = "endTime")String endTime, @Param(value = "videoCnt")Long videoCnt,@Param(value = "now") String now);
+
+    List<ByteDanceVideoInfo>historyMatByParams(@Param(value = "projectId")Long projectId, @Param(value = "accountId")Long accountId, @Param(value = "imageMode") String imageMode,@Param(value = "startTime")String startTime, @Param(value = "endTime")String endTime, @Param(value = "videoCnt")Long videoCnt,@Param(value = "now") String now);
+
+
+    /**
+     *图片 上新 遗漏
+     */
+    List<ByteDanceVideoInfo> imageListByParams(@Param(value = "projectId") Long projectId,@Param(value = "accountId") Long accountId, @Param(value = "imageMode") String imageMode,@Param(value = "startTime")String startTime, @Param(value = "endTime")String endTime, @Param(value = "videoCnt")Long videoCnt,@Param(value = "creativeCnt")Long creativeCnt,@Param(value = "now") String now);
+
+    /**
+     * 图片 跑量
+     */
+    List<ByteDanceVideoInfo> imageTopMatByParams(@Param(value = "projectId")Long projectId, @Param(value = "accountId")Long accountId, @Param(value = "imageMode") String imageMode,@Param(value = "startTime")String startTime, @Param(value = "endTime")String endTime, @Param(value = "videoCnt")Long videoCnt,@Param(value = "now") String now);
+
+    /**
+     * 图片 打捞
+     */
+    List<ByteDanceVideoInfo>imageHistoryMatByParams(@Param(value = "projectId")Long projectId, @Param(value = "accountId")Long accountId, @Param(value = "imageMode") String imageMode,@Param(value = "startTime")String startTime, @Param(value = "endTime")String endTime, @Param(value = "videoCnt")Long videoCnt,@Param(value = "now") String now);
+
+
+
+
+}

+ 14 - 0
jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/mapper/BytedanceAiVideoCreativeLogMapper.java

@@ -0,0 +1,14 @@
+package ctop.bytedance.ad.advertise.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import ctop.bytedance.ad.advertise.entity.BytedanceAiVideoCreativeLog;
+
+/**
+ * 视频创建创意记录信息
+ * @author jeecg-boot
+ * 2021-05-19
+ * @version V1.0
+ */
+public interface BytedanceAiVideoCreativeLogMapper extends BaseMapper<BytedanceAiVideoCreativeLog> {
+
+}

+ 15 - 0
jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/mapper/BytedanceAreaInfoMapper.java

@@ -0,0 +1,15 @@
+package ctop.bytedance.ad.advertise.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import ctop.bytedance.ad.advertise.entity.AiBytedanceAdDplinkInfo;
+import ctop.bytedance.ad.advertise.entity.BytedanceAreaInfo;
+
+/**
+ * 省市区
+ * @author jeecg-boot
+ * 2021-04-26
+ * @version V1.0
+ */
+public interface BytedanceAreaInfoMapper extends BaseMapper<BytedanceAreaInfo> {
+
+}

+ 22 - 0
jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/mapper/BytedanceImageInfoMapper.java

@@ -0,0 +1,22 @@
+package ctop.bytedance.ad.advertise.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Param;
+import ctop.bytedance.ad.advertise.entity.BytedanceImageInfo;
+
+import java.util.List;
+
+/**
+ * 头条图片素材
+ * @author: jeecg-boot
+ * @date:   2020-08-01
+ * @cersion: V1.0
+ */
+public interface BytedanceImageInfoMapper extends BaseMapper<BytedanceImageInfo> {
+
+    void replaceBatch(@Param(value = "imageInfos")List<BytedanceImageInfo> imageInfos);
+
+    void updateImageVerticalType();
+
+    void updateImageHorizonType();
+}

+ 17 - 0
jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/mapper/BytedanceMaterialRejectReasonMapper.java

@@ -0,0 +1,17 @@
+package ctop.bytedance.ad.advertise.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import ctop.bytedance.ad.advertise.entity.BytedanceMaterialRejectReason;
+
+
+/**
+ * 头条视频文案信息
+ * @author jeecg-boot
+ * 2021-04-19
+ * @version V1.0
+ */
+public interface BytedanceMaterialRejectReasonMapper extends BaseMapper<BytedanceMaterialRejectReason> {
+    int replaceIntoDb(BytedanceMaterialRejectReason bytedanceMaterialRejectReason);
+
+    Integer getIsLowQualityByVideoId(String video);
+}

+ 14 - 0
jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/mapper/BytedancePlanRejectReasonMapper.java

@@ -0,0 +1,14 @@
+package ctop.bytedance.ad.advertise.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import ctop.bytedance.ad.advertise.entity.BytedancePlanRejectReason;
+
+/**
+ * 头条视频文案信息
+ * @author jeecg-boot
+ * 2021-04-19
+ * @version V1.0
+ */
+public interface BytedancePlanRejectReasonMapper extends BaseMapper<BytedancePlanRejectReason> {
+    int replaceIntoDb(BytedancePlanRejectReason bytedancePlanRejectReason);
+}

+ 21 - 0
jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/mapper/BytedanceVideoSlogenInfoMapper.java

@@ -0,0 +1,21 @@
+package ctop.bytedance.ad.advertise.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import io.swagger.models.auth.In;
+import ctop.bytedance.ad.advertise.entity.BytedanceVideoSlogenInfo;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 头条视频文案信息
+ * @author jeecg-boot
+ * 2021-04-19
+ * @version V1.0
+ */
+public interface BytedanceVideoSlogenInfoMapper extends BaseMapper<BytedanceVideoSlogenInfo> {
+    List<Map<String,Object>> selectVideoSlogenReportByAccountIdAndTitle(List<String> projectIds, String keyWord, Integer status, String startTime, String endTime);
+    List<String> getProjectByUserId(String userId);
+
+    List<BytedanceVideoSlogenInfo> getDataBySlogenAndProjectId(String slogan, Long projectId);
+}

+ 15 - 0
jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/mapper/LowQualityRejectReasonMapper.java

@@ -0,0 +1,15 @@
+package ctop.bytedance.ad.advertise.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import ctop.bytedance.ad.advertise.entity.LowQualityRejectReason;
+
+
+/**
+ * 头条视频文案信息
+ * @author jeecg-boot
+ * 2021-04-19
+ * @version V1.0
+ */
+public interface LowQualityRejectReasonMapper extends BaseMapper<LowQualityRejectReason> {
+    LowQualityRejectReason getByRejectReason(String rejectReason);
+}

+ 14 - 0
jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/mapper/RuleDataAccountMapper.java

@@ -0,0 +1,14 @@
+package ctop.bytedance.ad.advertise.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import ctop.bytedance.ad.advertise.entity.RuleDataAccount;
+
+/**
+ * 规则账户清洗数据
+ * @author: jeecg-boot
+ * @date:   2020-11-16
+ * @cersion: V1.0
+ */
+public interface RuleDataAccountMapper extends BaseMapper<RuleDataAccount> {
+
+}

+ 5 - 0
jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/mapper/xml/AiBytedanceAdDplinkInfoMapper.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="ctop.bytedance.ad.advertise.mapper.AiBytedanceAdDplinkInfoMapper">
+
+</mapper>

+ 65 - 0
jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/mapper/xml/AiBytedanceAdvertiserStrategyMapper.xml

@@ -0,0 +1,65 @@
+<?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="ctop.bytedance.ad.advertise.mapper.AiBytedanceAdvertiserStrategyMapper">
+
+    <!-- 账户 修改 头条 配置信息 状态 -->
+    <update id="updStaByAccountId">
+        UPDATE ctop_ai_bytedance_advertiser_strategy
+            SET status = #{state}
+        WHERE 1 = 1
+        <if test="accountId !=null and accountId != ''">
+            AND account_id = #{accountId}
+        </if>
+        <if test="creativeImageMode !=null and creativeImageMode != ''">
+            AND creative_image_mode = #{creativeImageMode}
+        </if>
+        <if test="id !=null and id != ''">
+            AND id != #{id}
+        </if>
+    </update>
+
+    <!--修改 头条 配置信息 状态 -->
+    <update id="updStaById">
+        UPDATE ctop_ai_bytedance_advertiser_strategy
+            SET status = #{state}
+        WHERE
+            id = #{id}
+    </update>
+
+    <!--修改 头条 配置信息 出价  -->
+    <update id="updCpaById">
+        UPDATE ctop_ai_bytedance_advertiser_strategy
+        <set>
+            <if test="adCpaBid != null">
+                ad_cpa_bid = #{adCpaBid},
+            </if>
+            <if test="adMaxBid != null">
+                ad_max_bid = #{adMaxBid},
+            </if>
+            <if test="adMinBid != null">
+                ad_min_bid = #{adMinBid},
+            </if>
+            <if test="adStepBid != null">
+                ad_step_bid = #{adStepBid},
+            </if>
+        </set>
+        WHERE
+            id = #{id}
+    </update>
+
+    <!--修改 头条 配置信息 预算 -->
+    <update id="updBudgetById">
+        UPDATE ctop_ai_bytedance_advertiser_strategy
+        <set>
+            <if test="budget != null">
+                account_budget = #{budget},
+            </if>
+            <if test="budgetType != null">
+                account_budget_mode = #{budgetType},
+            </if>
+        </set>
+        WHERE
+            id = #{id}
+    </update>
+
+</mapper>

+ 5 - 0
jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/mapper/xml/AiBytedanceAutocreateLogMapper.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="ctop.bytedance.ad.advertise.mapper.AiBytedanceAutocreateLogMapper">
+
+</mapper>

+ 5 - 0
jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/mapper/xml/AiBytedanceCampaignDplinkInfoMapper.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="ctop.bytedance.ad.advertise.mapper.AiBytedanceCampaignDplinkInfoMapper">
+
+</mapper>

+ 54 - 0
jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/mapper/xml/ByteDanceAdvertisePlanMapper.xml

@@ -0,0 +1,54 @@
+<?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="ctop.bytedance.ad.advertise.mapper.ByteDanceAdvertisePlanMapper">
+
+    <select id="selectWarningGroup" resultType="java.lang.String">
+   SELECT
+   name
+   FROM ctop_bytedance_advertise_plan
+   WHERE account_id = #{accountId}
+   and (cpa_bid &gt; #{maxBid} or bid &gt; #{maxBid})
+   and toutiao_status = 'AD_STATUS_DELIVERY_OK'
+    </select>
+
+
+    <select id="selectWarningCpaBid" resultType="java.lang.String">
+   SELECT
+   name
+   FROM ctop_bytedance_advertise_plan
+   WHERE account_id = #{accountId}
+   and deep_cpabid &gt; #{maxCpaBid}
+   and toutiao_status = 'AD_STATUS_DELIVERY_OK'
+    </select>
+    <select id="queryTodayBuiltCount" resultType="java.lang.Integer">
+        SELECT count(1) FROM ctop_bytedance_advertise_plan
+        WHERE account_id = #{accountId}
+          AND LOCATE(#{date}, ad_create_time)
+    </select>
+
+
+
+    <!--更新广告计划 操作状态 或 定向包id 或 出价-->
+    <update id="updateAdvertisePlan">
+
+        update ctop_bytedance_advertise_plan
+        <set>
+            <if test="optStatus != null">
+                opt_status = #{optStatus},
+            </if>
+            <if test="audiencePackageId != null">
+                audience_package_id = #{audiencePackageId},
+            </if>
+            <if test="bid != null">
+                bid = #{bid},
+            </if>
+            <if test="cpaBid != null and cpaBid!=''">
+                cpa_bid = #{cpaBid},
+            </if>
+        </set>
+        where id = #{id}
+    </update>
+
+
+
+</mapper>

+ 0 - 0
jeecg-boot-bytedance-ad/src/main/java/ctop/bytedance/ad/advertise/mapper/xml/ByteDanceAdvertiserMapper.xml


Некоторые файлы не были показаны из-за большого количества измененных файлов