Преглед изворни кода

小程序投流 接入 demand 池过滤、人群包接口、删除鉴权 + 修复列表时间范围

- 新增 VideoSearchPlanType=5(小程序投流),resolveChannelName 路由到 channel_name='小程序投流-稳定'
- VideoContentListParam 加 crowdPackage 字段,demand 池 selectForRecommend 加 crowd_package 精确过滤
- 新增 GET /xcx/getAudiencePackageList:返当前 dt 下 channel='小程序投流-稳定' 的 distinct crowd_package
- xcxPlanSave 显式 setStatus(1) + setUpdateTimestamp;insertXcxPlanReturnId SQL 补 status 列
- xcxPlanDelete 加 type==2 + owner 双校验,跨账号删除返回不存在
- XcxPlanListParam 加 createTimestampStart/End(ms),mapper 由 startDate/endDate 字符串方案改为与 gzh 一致的 ms 直接比较;人群包筛选由 LIKE 改为精确等值,配合前端 Select

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
刘立冬 пре 21 часа
родитељ
комит
818870f1cd

+ 6 - 0
api-module/src/main/java/com/tzld/piaoquan/api/controller/contentplatform/ContentPlatformPlanController.java

@@ -151,6 +151,12 @@ public class ContentPlatformPlanController {
         return CommonResponse.success(planService.getSharePic(pageUrl));
         return CommonResponse.success(planService.getSharePic(pageUrl));
     }
     }
 
 
+    @ApiOperation(value = "小程序投流-人群包列表")
+    @GetMapping("/xcx/getAudiencePackageList")
+    public CommonResponse<List<String>> getXcxAudiencePackageList() {
+        return CommonResponse.success(planService.getXcxAudiencePackageList());
+    }
+
     @ApiOperation(value = "获取分享二维码")
     @ApiOperation(value = "获取分享二维码")
     @GetMapping("/getSharePic")
     @GetMapping("/getSharePic")
     public CommonResponse<String> getSharePic(@RequestParam String pageUrl) {
     public CommonResponse<String> getSharePic(@RequestParam String pageUrl) {

+ 3 - 0
api-module/src/main/java/com/tzld/piaoquan/api/dao/mapper/contentplatform/ext/ContentPlatformDemandVideoMapperExt.java

@@ -49,9 +49,12 @@ public interface ContentPlatformDemandVideoMapperExt {
                                                        @Param("driveDimensionTime") String driveDimensionTime,
                                                        @Param("driveDimensionTime") String driveDimensionTime,
                                                        @Param("category") String category,
                                                        @Param("category") String category,
                                                        @Param("matchMethod") String matchMethod,
                                                        @Param("matchMethod") String matchMethod,
+                                                       @Param("crowdPackage") String crowdPackage,
                                                        @Param("limit") int limit,
                                                        @Param("limit") int limit,
                                                        @Param("excludeSelfTitle") boolean excludeSelfTitle);
                                                        @Param("excludeSelfTitle") boolean excludeSelfTitle);
 
 
+    List<String> selectDistinctCrowdPackages(@Param("dt") String dt, @Param("channelName") String channelName);
+
     List<ContentPlatformDemandVideo> selectActiveVideos(@Param("dt") String dt);
     List<ContentPlatformDemandVideo> selectActiveVideos(@Param("dt") String dt);
 
 
     int updateStatusByVideoId(@Param("videoId") Long videoId, @Param("dt") String dt, @Param("status") Integer status, @Param("updateTimestamp") Long updateTimestamp);
     int updateStatusByVideoId(@Param("videoId") Long videoId, @Param("dt") String dt, @Param("status") Integer status, @Param("updateTimestamp") Long updateTimestamp);

+ 3 - 0
api-module/src/main/java/com/tzld/piaoquan/api/model/param/contentplatform/VideoContentListParam.java

@@ -24,4 +24,7 @@ public class VideoContentListParam extends PageParam {
 
 
     @ApiModelProperty(value = "公众号名称(对应 demand.channel_level3),仅 prior/posterior 路使用,无数据时退化为渠道粒度")
     @ApiModelProperty(value = "公众号名称(对应 demand.channel_level3),仅 prior/posterior 路使用,无数据时退化为渠道粒度")
     private String ghName;
     private String ghName;
+
+    @ApiModelProperty(value = "人群包(对应 demand.crowd_package),小程序投流入口使用,过滤 demand 池候选")
+    private String crowdPackage;
 }
 }

+ 6 - 0
api-module/src/main/java/com/tzld/piaoquan/api/model/param/contentplatform/XcxPlanListParam.java

@@ -13,4 +13,10 @@ public class XcxPlanListParam extends PageParam {
     @ApiModelProperty(value = "标题")
     @ApiModelProperty(value = "标题")
     private String title;
     private String title;
 
 
+    @ApiModelProperty(value = "创建时间开始")
+    private Long createTimestampStart;
+
+    @ApiModelProperty(value = "创建时间截止")
+    private Long createTimestampEnd;
+
 }
 }

+ 2 - 0
api-module/src/main/java/com/tzld/piaoquan/api/service/contentplatform/ContentPlatformPlanService.java

@@ -102,4 +102,6 @@ public interface ContentPlatformPlanService {
     List<XcxPlanItemVO> xcxPlanSave(XcxPlanSaveParam param);
     List<XcxPlanItemVO> xcxPlanSave(XcxPlanSaveParam param);
 
 
     void xcxPlanDelete(Long id);
     void xcxPlanDelete(Long id);
+
+    List<String> getXcxAudiencePackageList();
 }
 }

+ 32 - 12
api-module/src/main/java/com/tzld/piaoquan/api/service/contentplatform/impl/ContentPlatformPlanServiceImpl.java

@@ -646,6 +646,7 @@ public class ContentPlatformPlanServiceImpl implements ContentPlatformPlanServic
     /** 服务号推送 / 公众号推送 走 Daily 人群_渠道,与即转稳定数据隔离 */
     /** 服务号推送 / 公众号推送 走 Daily 人群_渠道,与即转稳定数据隔离 */
     private static final String CHANNEL_NAME_GZH_DAILY = "公众号合作-Daily-自选";
     private static final String CHANNEL_NAME_GZH_DAILY = "公众号合作-Daily-自选";
     private static final String CHANNEL_NAME_QW  = "群/企微合作-稳定";
     private static final String CHANNEL_NAME_QW  = "群/企微合作-稳定";
+    private static final String CHANNEL_NAME_XCX = "小程序投流-稳定";
     private static final double PRIOR_GROUP_KEEP_RATIO = 0.5;
     private static final double PRIOR_GROUP_KEEP_RATIO = 0.5;
     /** posterior 按 demand_content_id 分组后保留 total_rov 排名前 50% 的需求组,
     /** posterior 按 demand_content_id 分组后保留 total_rov 排名前 50% 的需求组,
      * 砍掉群体表现弱的需求,避免低 total_rov 的 demand 带回来的相似变体稀释结果。 */
      * 砍掉群体表现弱的需求,避免低 total_rov 的 demand 带回来的相似变体稀释结果。 */
@@ -657,10 +658,10 @@ public class ContentPlatformPlanServiceImpl implements ContentPlatformPlanServic
     /**
     /**
      * 推导 channel_name(人群_渠道) 作为 demand 池强过滤。
      * 推导 channel_name(人群_渠道) 作为 demand 池强过滤。
      * 信号优先级:
      * 信号优先级:
-     *   1. type 明确时按 type 映射 — 0→公众号合作-即转-稳定;1/4→公众号合作-Daily-自选;2/3→群/企微合作-稳定
+     *   1. type 明确时按 type 映射 — 0→公众号合作-即转-稳定;1/4→公众号合作-Daily-自选;2/3→群/企微合作-稳定;5→小程序投流-稳定
      *   2. type=999/null 但带 ghName(公众号参数)→ 公众号入口,映射即转稳定(与历史一致)
      *   2. type=999/null 但带 ghName(公众号参数)→ 公众号入口,映射即转稳定(与历史一致)
      *   3. 否则 null,不限 channel_name(保留原行为)
      *   3. 否则 null,不限 channel_name(保留原行为)
-     * type 取值: 0-自动回复(公众号入口) / 1-服务号推送 / 2-企微-社群 / 3-企微-自动回复 / 4-公众号推送 / 999-不限。
+     * type 取值: 0-自动回复(公众号入口) / 1-服务号推送 / 2-企微-社群 / 3-企微-自动回复 / 4-公众号推送 / 5-小程序投流 / 999-不限。
      * 作用:解决 crowd_segment 跨渠道客户(如 gzyhc/wxm)在企微/公众号入口下被对侧数据污染的问题。
      * 作用:解决 crowd_segment 跨渠道客户(如 gzyhc/wxm)在企微/公众号入口下被对侧数据污染的问题。
      */
      */
     private String resolveChannelName(VideoContentListParam param) {
     private String resolveChannelName(VideoContentListParam param) {
@@ -669,6 +670,7 @@ public class ContentPlatformPlanServiceImpl implements ContentPlatformPlanServic
             if (type == 2 || type == 3) return CHANNEL_NAME_QW;
             if (type == 2 || type == 3) return CHANNEL_NAME_QW;
             if (type == 1 || type == 4) return CHANNEL_NAME_GZH_DAILY;
             if (type == 1 || type == 4) return CHANNEL_NAME_GZH_DAILY;
             if (type == 0) return CHANNEL_NAME_GZH;
             if (type == 0) return CHANNEL_NAME_GZH;
+            if (type == 5) return CHANNEL_NAME_XCX;
         }
         }
         if (StringUtils.hasText(param.getGhName())) return CHANNEL_NAME_GZH;
         if (StringUtils.hasText(param.getGhName())) return CHANNEL_NAME_GZH;
         return null;
         return null;
@@ -980,17 +982,18 @@ public class ContentPlatformPlanServiceImpl implements ContentPlatformPlanServic
         String ghName = StringUtils.hasText(param.getGhName()) ? param.getGhName() : null;
         String ghName = StringUtils.hasText(param.getGhName()) ? param.getGhName() : null;
 
 
         String category = StringUtils.hasText(param.getCategory()) ? param.getCategory() : null;
         String category = StringUtils.hasText(param.getCategory()) ? param.getCategory() : null;
+        String crowdPackage = StringUtils.hasText(param.getCrowdPackage()) ? param.getCrowdPackage() : null;
         // priorScene 池新识别:demand_strategy='人群需求' AND match_method='场景已看视频'(0519+ 起,旧 demand_strategy='人群需求-场景' 已迁走)
         // priorScene 池新识别:demand_strategy='人群需求' AND match_method='场景已看视频'(0519+ 起,旧 demand_strategy='人群需求-场景' 已迁走)
         List<ContentPlatformDemandVideo> rows = demandVideoMapperExt.selectForRecommend(
         List<ContentPlatformDemandVideo> rows = demandVideoMapperExt.selectForRecommend(
-                dt, channelName, crowdSegment, DEMAND_STRATEGY_PRIOR, null, null, null, ghName, null, category, MATCH_METHOD_PRIOR_SCENE, limit, false);
+                dt, channelName, crowdSegment, DEMAND_STRATEGY_PRIOR, null, null, null, ghName, null, category, MATCH_METHOD_PRIOR_SCENE, crowdPackage, limit, false);
         if (ghName != null && rows.isEmpty()) {
         if (ghName != null && rows.isEmpty()) {
             rows = demandVideoMapperExt.selectForRecommend(
             rows = demandVideoMapperExt.selectForRecommend(
-                    dt, channelName, crowdSegment, DEMAND_STRATEGY_PRIOR, null, null, null, null, null, category, MATCH_METHOD_PRIOR_SCENE, limit, false);
+                    dt, channelName, crowdSegment, DEMAND_STRATEGY_PRIOR, null, null, null, null, null, category, MATCH_METHOD_PRIOR_SCENE, crowdPackage, limit, false);
         }
         }
         // 跨渠道退化:channel_name 命中但 crowd_segment 在对侧渠道下 0 行(如公众号账号切到企微入口)→ 去 crowd_segment,只按 channel_name 拉通用数据
         // 跨渠道退化:channel_name 命中但 crowd_segment 在对侧渠道下 0 行(如公众号账号切到企微入口)→ 去 crowd_segment,只按 channel_name 拉通用数据
         if (channelName != null && rows.isEmpty()) {
         if (channelName != null && rows.isEmpty()) {
             rows = demandVideoMapperExt.selectForRecommend(
             rows = demandVideoMapperExt.selectForRecommend(
-                    dt, channelName, null, DEMAND_STRATEGY_PRIOR, null, null, null, null, null, category, MATCH_METHOD_PRIOR_SCENE, limit, false);
+                    dt, channelName, null, DEMAND_STRATEGY_PRIOR, null, null, null, null, null, category, MATCH_METHOD_PRIOR_SCENE, crowdPackage, limit, false);
         }
         }
         // 1. 同 video_id 取 total_rov 最大的代表行(SQL 已排序,putIfAbsent 保留首次)
         // 1. 同 video_id 取 total_rov 最大的代表行(SQL 已排序,putIfAbsent 保留首次)
         LinkedHashMap<Long, ContentPlatformDemandVideo> bestPerVideo = new LinkedHashMap<>();
         LinkedHashMap<Long, ContentPlatformDemandVideo> bestPerVideo = new LinkedHashMap<>();
@@ -1053,16 +1056,17 @@ public class ContentPlatformPlanServiceImpl implements ContentPlatformPlanServic
         int fetchLimit = Math.max(limit * 3, DEMAND_CANDIDATE_LIMIT);
         int fetchLimit = Math.max(limit * 3, DEMAND_CANDIDATE_LIMIT);
 
 
         String category = StringUtils.hasText(param.getCategory()) ? param.getCategory() : null;
         String category = StringUtils.hasText(param.getCategory()) ? param.getCategory() : null;
+        String crowdPackage = StringUtils.hasText(param.getCrowdPackage()) ? param.getCrowdPackage() : null;
         List<ContentPlatformDemandVideo> rows = demandVideoMapperExt.selectForRecommend(
         List<ContentPlatformDemandVideo> rows = demandVideoMapperExt.selectForRecommend(
-                dt, channelName, crowdSegment, DEMAND_STRATEGY_PRIOR, dimension, null, null, ghName, null, category, MATCH_METHOD_PRIOR, fetchLimit, false);
+                dt, channelName, crowdSegment, DEMAND_STRATEGY_PRIOR, dimension, null, null, ghName, null, category, MATCH_METHOD_PRIOR, crowdPackage, fetchLimit, false);
 
 
         if (ghName != null && rows.isEmpty()) {
         if (ghName != null && rows.isEmpty()) {
             rows = demandVideoMapperExt.selectForRecommend(
             rows = demandVideoMapperExt.selectForRecommend(
-                    dt, channelName, crowdSegment, DEMAND_STRATEGY_PRIOR, dimension, null, null, null, null, category, MATCH_METHOD_PRIOR, fetchLimit, false);
+                    dt, channelName, crowdSegment, DEMAND_STRATEGY_PRIOR, dimension, null, null, null, null, category, MATCH_METHOD_PRIOR, crowdPackage, fetchLimit, false);
         }
         }
         if (channelName != null && rows.isEmpty()) {
         if (channelName != null && rows.isEmpty()) {
             rows = demandVideoMapperExt.selectForRecommend(
             rows = demandVideoMapperExt.selectForRecommend(
-                    dt, channelName, null, DEMAND_STRATEGY_PRIOR, dimension, null, null, null, null, category, MATCH_METHOD_PRIOR, fetchLimit, false);
+                    dt, channelName, null, DEMAND_STRATEGY_PRIOR, dimension, null, null, null, null, category, MATCH_METHOD_PRIOR, crowdPackage, fetchLimit, false);
         }
         }
 
 
         rows = rows.stream()
         rows = rows.stream()
@@ -1131,20 +1135,21 @@ public class ContentPlatformPlanServiceImpl implements ContentPlatformPlanServic
         int fetchLimit = Math.max(limit * 3, DEMAND_CANDIDATE_LIMIT);
         int fetchLimit = Math.max(limit * 3, DEMAND_CANDIDATE_LIMIT);
 
 
         String category = StringUtils.hasText(param.getCategory()) ? param.getCategory() : null;
         String category = StringUtils.hasText(param.getCategory()) ? param.getCategory() : null;
+        String crowdPackage = StringUtils.hasText(param.getCrowdPackage()) ? param.getCrowdPackage() : null;
         // posterior 池加 match_method='票圈推荐库' 兜底,防止未来上游对优质相似分量出别的 match_method 值后污染本池
         // posterior 池加 match_method='票圈推荐库' 兜底,防止未来上游对优质相似分量出别的 match_method 值后污染本池
         // 优质相似池:drive_dimension_time 一律不限制(含主查与退化路径),避免仅「昨日」窗口召回过少。
         // 优质相似池:drive_dimension_time 一律不限制(含主查与退化路径),避免仅「昨日」窗口召回过少。
         List<ContentPlatformDemandVideo> rows = demandVideoMapperExt.selectForRecommend(
         List<ContentPlatformDemandVideo> rows = demandVideoMapperExt.selectForRecommend(
-                dt, channelName, crowdSegment, DEMAND_STRATEGY_POSTERIOR, null, null, null, ghName, null, category, MATCH_METHOD_PRIOR, fetchLimit, true);
+                dt, channelName, crowdSegment, DEMAND_STRATEGY_POSTERIOR, null, null, null, ghName, null, category, MATCH_METHOD_PRIOR, crowdPackage, fetchLimit, true);
 
 
         // 退化:该 ghName 无数据 → 退回渠道粒度
         // 退化:该 ghName 无数据 → 退回渠道粒度
         if (ghName != null && rows.isEmpty()) {
         if (ghName != null && rows.isEmpty()) {
             rows = demandVideoMapperExt.selectForRecommend(
             rows = demandVideoMapperExt.selectForRecommend(
-                    dt, channelName, crowdSegment, DEMAND_STRATEGY_POSTERIOR, null, null, null, null, null, category, MATCH_METHOD_PRIOR, fetchLimit, true);
+                    dt, channelName, crowdSegment, DEMAND_STRATEGY_POSTERIOR, null, null, null, null, null, category, MATCH_METHOD_PRIOR, crowdPackage, fetchLimit, true);
         }
         }
         // 跨渠道退化:channel_name 命中但 crowd_segment 在对侧 0 行 → 去 crowd_segment 拉通用数据
         // 跨渠道退化:channel_name 命中但 crowd_segment 在对侧 0 行 → 去 crowd_segment 拉通用数据
         if (channelName != null && rows.isEmpty()) {
         if (channelName != null && rows.isEmpty()) {
             rows = demandVideoMapperExt.selectForRecommend(
             rows = demandVideoMapperExt.selectForRecommend(
-                    dt, channelName, null, DEMAND_STRATEGY_POSTERIOR, null, null, null, null, null, category, MATCH_METHOD_PRIOR, fetchLimit, true);
+                    dt, channelName, null, DEMAND_STRATEGY_POSTERIOR, null, null, null, null, null, category, MATCH_METHOD_PRIOR, crowdPackage, fetchLimit, true);
         }
         }
 
 
         // 近 7 日 rov 下限,与 prior 池一致(cdjh 0514 验证 ≥0.02 保留 ~54%)
         // 近 7 日 rov 下限,与 prior 池一致(cdjh 0514 验证 ≥0.02 保留 ~54%)
@@ -2079,8 +2084,10 @@ public class ContentPlatformPlanServiceImpl implements ContentPlatformPlanServic
             String rootSourceId = MessageUtil.getRootSourceId(pageUrl);
             String rootSourceId = MessageUtil.getRootSourceId(pageUrl);
             xcxPlan.setPageUrl(pageUrl);
             xcxPlan.setPageUrl(pageUrl);
             xcxPlan.setRootSourceId(rootSourceId);
             xcxPlan.setRootSourceId(rootSourceId);
+            xcxPlan.setStatus(PlanStatusEnum.NORMAL.getVal());
             xcxPlan.setCreateAccountId(loginUser.getId());
             xcxPlan.setCreateAccountId(loginUser.getId());
             xcxPlan.setCreateTimestamp(now);
             xcxPlan.setCreateTimestamp(now);
+            xcxPlan.setUpdateTimestamp(now);
             planMapperExt.insertXcxPlanReturnId(xcxPlan);
             planMapperExt.insertXcxPlanReturnId(xcxPlan);
             list.add(xcxPlan);
             list.add(xcxPlan);
             // 保存视频内容
             // 保存视频内容
@@ -2091,8 +2098,12 @@ public class ContentPlatformPlanServiceImpl implements ContentPlatformPlanServic
 
 
     @Override
     @Override
     public void xcxPlanDelete(Long id) {
     public void xcxPlanDelete(Long id) {
+        ContentPlatformAccount loginUser = LoginUserContext.getUser();
+        if (!Objects.equals(loginUser.getType(), 2)) {
+            throw new CommonException(ExceptionEnum.XCX_PLAN_INTERNAL_ONLY);
+        }
         ContentPlatformXcxPlan plan = xcxPlanMapper.selectByPrimaryKey(id);
         ContentPlatformXcxPlan plan = xcxPlanMapper.selectByPrimaryKey(id);
-        if (Objects.isNull(plan)) {
+        if (Objects.isNull(plan) || !Objects.equals(plan.getCreateAccountId(), loginUser.getId())) {
             throw new CommonException(ExceptionEnum.XCX_PLAN_NOT_EXISTS);
             throw new CommonException(ExceptionEnum.XCX_PLAN_NOT_EXISTS);
         }
         }
         plan.setStatus(PlanStatusEnum.DELETED.getVal());
         plan.setStatus(PlanStatusEnum.DELETED.getVal());
@@ -2100,6 +2111,15 @@ public class ContentPlatformPlanServiceImpl implements ContentPlatformPlanServic
         xcxPlanMapper.updateByPrimaryKeySelective(plan);
         xcxPlanMapper.updateByPrimaryKeySelective(plan);
     }
     }
 
 
+    @Override
+    public List<String> getXcxAudiencePackageList() {
+        String dt = demandVideoMapperExt.getMaxDt(CHANNEL_NAME_XCX);
+        if (!StringUtils.hasText(dt)) {
+            return Collections.emptyList();
+        }
+        return demandVideoMapperExt.selectDistinctCrowdPackages(dt, CHANNEL_NAME_XCX);
+    }
+
     private List<XcxPlanItemVO> buildXcxPlanItemVOList(List<ContentPlatformXcxPlan> planList) {
     private List<XcxPlanItemVO> buildXcxPlanItemVOList(List<ContentPlatformXcxPlan> planList) {
         if (CollectionUtils.isEmpty(planList)) {
         if (CollectionUtils.isEmpty(planList)) {
             return null;
             return null;

+ 13 - 0
api-module/src/main/resources/mapper/contentplatform/ext/ContentPlatformDemandVideoMapperExt.xml

@@ -134,6 +134,9 @@
         <if test="matchMethod != null and matchMethod != ''">
         <if test="matchMethod != null and matchMethod != ''">
             AND match_method = #{matchMethod}
             AND match_method = #{matchMethod}
         </if>
         </if>
+        <if test="crowdPackage != null and crowdPackage != ''">
+            AND crowd_package = #{crowdPackage}
+        </if>
         <if test="excludeSelfTitle">
         <if test="excludeSelfTitle">
             AND (title IS NULL OR demand_content_title IS NULL OR title &lt;&gt; demand_content_title)
             AND (title IS NULL OR demand_content_title IS NULL OR title &lt;&gt; demand_content_title)
         </if>
         </if>
@@ -141,6 +144,16 @@
         LIMIT #{limit}
         LIMIT #{limit}
     </select>
     </select>
 
 
+    <select id="selectDistinctCrowdPackages" resultType="java.lang.String">
+        SELECT DISTINCT crowd_package
+        FROM content_platform_demand_video
+        WHERE dt = #{dt} AND status = 1 AND crowd_package IS NOT NULL AND crowd_package &lt;&gt; ''
+        <if test="channelName != null and channelName != ''">
+            AND channel_name = #{channelName}
+        </if>
+        ORDER BY crowd_package
+    </select>
+
     <select id="selectActiveVideos" resultType="com.tzld.piaoquan.api.model.po.contentplatform.ContentPlatformDemandVideo">
     <select id="selectActiveVideos" resultType="com.tzld.piaoquan.api.model.po.contentplatform.ContentPlatformDemandVideo">
         SELECT DISTINCT video_id
         SELECT DISTINCT video_id
         FROM content_platform_demand_video
         FROM content_platform_demand_video

+ 13 - 13
api-module/src/main/resources/mapper/contentplatform/ext/ContentPlatformPlanMapperExt.xml

@@ -437,17 +437,17 @@
         where create_account_id = #{createAccountId}
         where create_account_id = #{createAccountId}
           and status = 1
           and status = 1
         <if test="param.audiencePackage != null and param.audiencePackage != ''">
         <if test="param.audiencePackage != null and param.audiencePackage != ''">
-            and audience_package like concat('%', #{param.audiencePackage}, '%')
+            and audience_package = #{param.audiencePackage}
         </if>
         </if>
         <if test="param.title != null and param.title != ''">
         <if test="param.title != null and param.title != ''">
             and id in (select plan_id from content_platform_xcx_plan_video where title like concat('%', #{param.title},
             and id in (select plan_id from content_platform_xcx_plan_video where title like concat('%', #{param.title},
             '%'))
             '%'))
         </if>
         </if>
-        <if test="param.startDate != null and param.startDate != ''">
-            and create_timestamp &gt;= UNIX_TIMESTAMP(#{param.startDate}) * 1000
+        <if test="param.createTimestampStart != null">
+            and create_timestamp &gt; #{param.createTimestampStart}
         </if>
         </if>
-        <if test="param.endDate != null and param.endDate != ''">
-            and create_timestamp &lt; UNIX_TIMESTAMP(DATE_ADD(#{param.endDate}, INTERVAL 1 DAY)) * 1000
+        <if test="param.createTimestampEnd != null">
+            and create_timestamp &lt; #{param.createTimestampEnd}
         </if>
         </if>
     </select>
     </select>
 
 
@@ -458,27 +458,27 @@
         where create_account_id = #{createAccountId}
         where create_account_id = #{createAccountId}
         and status = 1
         and status = 1
         <if test="param.audiencePackage != null and param.audiencePackage != ''">
         <if test="param.audiencePackage != null and param.audiencePackage != ''">
-            and audience_package like concat('%', #{param.audiencePackage}, '%')
+            and audience_package = #{param.audiencePackage}
         </if>
         </if>
         <if test="param.title != null and param.title != ''">
         <if test="param.title != null and param.title != ''">
             and id in (select plan_id from content_platform_xcx_plan_video where title like concat('%', #{param.title},
             and id in (select plan_id from content_platform_xcx_plan_video where title like concat('%', #{param.title},
             '%'))
             '%'))
         </if>
         </if>
-        <if test="param.startDate != null and param.startDate != ''">
-            and create_timestamp &gt;= UNIX_TIMESTAMP(#{param.startDate}) * 1000
+        <if test="param.createTimestampStart != null">
+            and create_timestamp &gt; #{param.createTimestampStart}
         </if>
         </if>
-        <if test="param.endDate != null and param.endDate != ''">
-            and create_timestamp &lt; UNIX_TIMESTAMP(DATE_ADD(#{param.endDate}, INTERVAL 1 DAY)) * 1000
+        <if test="param.createTimestampEnd != null">
+            and create_timestamp &lt; #{param.createTimestampEnd}
         </if>
         </if>
         order by create_timestamp desc
         order by create_timestamp desc
         limit #{offset}, #{pageSize}
         limit #{offset}, #{pageSize}
     </select>
     </select>
 
 
     <insert id="insertXcxPlanReturnId" useGeneratedKeys="true" keyProperty="id">
     <insert id="insertXcxPlanReturnId" useGeneratedKeys="true" keyProperty="id">
-        insert into content_platform_xcx_plan (audience_package, page_url, root_source_id, remark, create_account_id,
-                                              create_timestamp, update_timestamp)
+        insert into content_platform_xcx_plan (audience_package, page_url, root_source_id, remark, status,
+                                              create_account_id, create_timestamp, update_timestamp)
         values (#{record.audiencePackage}, #{record.pageUrl}, #{record.rootSourceId}, #{record.remark},
         values (#{record.audiencePackage}, #{record.pageUrl}, #{record.rootSourceId}, #{record.remark},
-                #{record.createAccountId}, #{record.createTimestamp}, #{record.updateTimestamp})
+                #{record.status}, #{record.createAccountId}, #{record.createTimestamp}, #{record.updateTimestamp})
     </insert>
     </insert>
 
 
 </mapper>
 </mapper>