xp-robotaxi-api/src/main/java/com/xiaopeng/api/factory/order/XpOrderClientFallbackFactory.java
@@ -121,6 +121,12 @@ log.error("保存订单轨迹数据失败,原因: {}", cause.getMessage()); return R.fail("保存订单轨迹数据失败"); } @Override public R<Integer> determineUserType(Long userId) { log.error("确定用户类型失败,原因: {}", cause.getMessage()); return R.fail("确定用户类型失败"); } }; } } xp-robotaxi-api/src/main/java/com/xiaopeng/api/feignClient/order/XpOrderClient.java
@@ -153,5 +153,11 @@ /** * 判断用户类型 * @param userId * @return 1=老用户,2=新用户,3=流失用户 */ @PostMapping("/logan/inner/order/determineUserType") R<Integer> determineUserType(@RequestParam Long userId); } xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/operation/XpActicityUser.java
@@ -1,5 +1,6 @@ package com.xiaopeng.api.model.operation; import com.alibaba.fastjson2.JSONArray; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; @@ -41,7 +42,7 @@ private Integer userType; @ApiModelProperty(value = "指定用户json数组") private String userList; private JSONArray userList; @ApiModelProperty(value = "策略组名称") private String strategyName; xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/operation/XpActivity.java
@@ -65,10 +65,57 @@ @ApiModelProperty(value = "邀请启用 1=是 0=否") private Boolean inviteEnable; @ApiModelProperty(value = "图片") private String img; @ApiModelProperty("微信通知(0=否,1=是)") private Integer wechatNotification; @ApiModelProperty(value = "富文本内容") private String richText; @ApiModelProperty("微信通知到账提醒(0=否,1=是)") private Integer wechatReceivedReminder; @ApiModelProperty("微信通知即将过期提醒(0=否,1=是)") private Integer wechatAboutExpireReminder; @ApiModelProperty("微信通知即将过期天数") private Integer wechatAboutExpireDays; @ApiModelProperty("微信通知活动开始提醒(0=否,1=是)") private Integer wechatActicityStart; @ApiModelProperty("微信通知临近券生效前X分钟通知") private Integer wechatActicityStartMinutes; @ApiModelProperty("短信通知(0=否,1=是)") private Integer smsNotification; @ApiModelProperty("短信通知到账提醒(0=否,1=是)") private Integer smsReceivedReminder; @ApiModelProperty("短信通知即将过期提醒(0=否,1=是)") private Integer smsAboutExpireReminder; @ApiModelProperty("短信通知即将过期天数") private Integer smsAboutExpireDays; @ApiModelProperty("短信通知活动开始提醒(0=否,1=是)") private Integer smsActicityStart; @ApiModelProperty("短信通知临近券生效前X分钟通知") private Integer smsActicityStartMinutes; @ApiModelProperty("短信通知屏蔽开始时间") private LocalDateTime smsStartBlockingTime; @ApiModelProperty("短信通知屏蔽结束时间") private LocalDateTime smsEndBlockingTime; @ApiModelProperty("小程序弹窗通知(0=否,1=是)") private Integer miniProgramNotification; @ApiModelProperty("小程序弹窗标题") private String miniProgramPopupTitle; @ApiModelProperty("小程序弹窗按钮文案") private String miniProgramBtnText; @ApiModelProperty("小程序弹窗券到账提醒(0=否,1=是)") private String miniProgramReceivedReminder; @ApiModelProperty("小程序弹窗即将过期提醒(0=否,1=是)") private String miniProgramAboutExpireReminder; @ApiModelProperty("小程序弹窗临近券生效前X分钟") private Integer miniProgramAboutExpireMinutes; @ApiModelProperty("通知内容") private String expireMinutesNotificationContent; @ApiModelProperty("小程序弹窗临近到期时间前X天") private Integer aboutExpireDays; @ApiModelProperty("通知内容") private String expireDaysNotificationContent; @ApiModelProperty("是否开启浮窗(0=否,1=是)") private Integer enableFloatWindow; @ApiModelProperty("浮窗优先级权重") private Integer floatWindowPriority; @ApiModelProperty("浮窗跳转链接") private String floatWindowJumpUrl; } xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpActicityController.java
@@ -15,6 +15,7 @@ import com.xiaopeng.operation.service.IXpActicityCouponService; import com.xiaopeng.operation.service.IXpActicityService; import com.xiaopeng.operation.service.IXpActicityStrategyService; import com.xiaopeng.unifiedverification.interceptor.XpClientCheck; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.RequiredArgsConstructor; @@ -54,6 +55,9 @@ @Resource private IXpActicityStrategyService xpActicityStrategyService; @Resource private IXpActicityCouponService couponService; /** * 获取所有白名单手机号 * @return @@ -77,15 +81,15 @@ * @return 活动信息,id 和 img */ @GetMapping("/api/v1/mini-program/acticity/firstEnter") @ApiOperation(value = "获取是否第一次推送活动", tags = {"管理后台-活动首次进入情况"}) @ApiOperation(value = "获取是否第一次推送活动", tags = {"小程序-首页活动"}) @XpClientCheck(checkToken = false, checkOtpToken = true) public R<XpActivityVo> firstEnter(HttpServletRequest request){ String uid = request.getHeader("XP-Uid"); ValueOperations<String, String> ops = redisTemplate.opsForValue(); XpActivity activity = service.activiting(); List<XpActicityCoupon> cps = couponService.lambdaQuery().eq(XpActicityCoupon::getActivityId, activity.getId()).list(); XpActivity activity = service.activiting(Long.valueOf(uid)); XpActivityVo ret = new XpActivityVo(); if (activity !=null) { List<XpActicityCoupon> cps = couponService.lambdaQuery().eq(XpActicityCoupon::getActivityId, activity.getId()).list(); BeanUtils.copyBeanProp(ret, activity); Duration duration = Duration.between(LocalDateTime.now(), activity.getEndTime()); Boolean isFirst = ops.setIfAbsent(CacheConstants.firstEnterActivity(String.valueOf(activity.getId()), uid),"1", duration); @@ -93,10 +97,23 @@ ret.setCoupons(cps); } return R.ok(ret); } IXpActicityCouponService couponService; /** * 是否第一次进入某活动 * @return 活动信息,id 和 img */ @GetMapping("/api/v1/mini-program/acticity/getFloatActicity") @ApiOperation(value = "获取首页活动悬浮图标数据", tags = {"小程序-首页活动"}) @XpClientCheck(checkToken = false, checkOtpToken = true) public R<XpActivity> getFloatActicity(HttpServletRequest request){ String uid = request.getHeader("XP-Uid"); XpActivity activity = service.getFloatActicity(Long.valueOf(uid)); return R.ok(activity); } @PostMapping("/v1/api/appUserCoupon/pageList") @ApiOperation(value = "活动列表",tags = {"管理后台-活动管理"},response = XpActivity.class) xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/IXpActicityService.java
@@ -22,9 +22,17 @@ List<String> findListToIds(String acticityName); XpActivity activiting(); XpActivity activiting(Long uid); void save(XpActivityDto dto); XpActivityDto detail(Long id); /** * 获取悬浮弹窗活动数据 * @param uid * @return */ XpActivity getFloatActicity(Long uid); } xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpActicityServiceImpl.java
@@ -1,7 +1,9 @@ package com.xiaopeng.operation.service.impl; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.xiaopeng.api.dto.operation.XpActivityDto; import com.xiaopeng.api.feignClient.order.XpOrderClient; import com.xiaopeng.api.model.operation.XpActicityStrategy; import com.xiaopeng.api.model.operation.XpActicityUser; import com.xiaopeng.api.model.operation.XpActivity; @@ -20,6 +22,7 @@ import javax.annotation.Resource; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Random; @@ -46,6 +49,11 @@ @Resource private IXpActivityNoticeService activityNotice; @Resource private XpOrderClient xpOrderClient; @Override public PageInfo<XpActivity> pageList(XpActivityPageListQuery query) { PageInfo<XpActivity> pageInfo = new PageInfo<>(query.getPageNum(),query.getPageSize()); @@ -62,17 +70,27 @@ query.like(XpActivity::getActicityName, acticityName); return listObjs(query, Object::toString); } @Override public XpActivity activiting() { LambdaQueryWrapper<XpActivity> query = new LambdaQueryWrapper<>(); LocalDateTime now = LocalDateTime.now(); query.le(XpActivity::getStartTime, now) .ge(XpActivity::getEndTime, now); List<XpActivity> list = list(query); if(!list.isEmpty()){ return list.get(new Random().nextInt(list.size())); } return null; public XpActivity activiting(Long uid) { //获取当前用户可参与的活动 List<Integer> actitctiyIds = new ArrayList<>(); //全部用户 List<XpActicityUser> list = userService.list(new QueryWrapper<XpActicityUser>().eq("is_deleted", 0).eq("user_type", 1)); actitctiyIds.addAll(list.stream().map(XpActicityUser::getActitcityId).collect(Collectors.toList())); //判断用户类型 2=老用户,3=新用户,4=流失用户 Integer userType = xpOrderClient.determineUserType(uid).getData(); list = userService.list(new QueryWrapper<XpActicityUser>().eq("is_deleted", 0).eq("user_type", userType)); actitctiyIds.addAll(list.stream().map(XpActicityUser::getActitcityId).collect(Collectors.toList())); //指定用户 list = userService.list(new QueryWrapper<XpActicityUser>().eq("is_deleted", 0).eq("user_type", 5) .last(" and JSON_CONTAINS(user_list, '" + uid + "', '$')")); actitctiyIds.addAll(list.stream().map(XpActicityUser::getActitcityId).collect(Collectors.toList())); XpActivity one = this.getOne(new QueryWrapper<XpActivity>().eq("status", 2).eq("is_deleted", 0) .eq("mini_program_notification", 1).in(!actitctiyIds.isEmpty(), "id", actitctiyIds) .last(" and now() between start_time and end_time order by float_window_priority desc limit 1")); return one; } @Override @@ -111,4 +129,31 @@ return ret; } /** * 获取悬浮弹窗活动数据 * @param uid * @return */ @Override public XpActivity getFloatActicity(Long uid) { //获取当前用户可参与的活动 List<Integer> actitctiyIds = new ArrayList<>(); //全部用户 List<XpActicityUser> list = userService.list(new QueryWrapper<XpActicityUser>().eq("is_deleted", 0).eq("user_type", 1)); actitctiyIds.addAll(list.stream().map(XpActicityUser::getActitcityId).collect(Collectors.toList())); //判断用户类型 2=老用户,3=新用户,4=流失用户 Integer userType = xpOrderClient.determineUserType(uid).getData(); list = userService.list(new QueryWrapper<XpActicityUser>().eq("is_deleted", 0).eq("user_type", userType)); actitctiyIds.addAll(list.stream().map(XpActicityUser::getActitcityId).collect(Collectors.toList())); //指定用户 list = userService.list(new QueryWrapper<XpActicityUser>().eq("is_deleted", 0).eq("user_type", 5) .last(" and JSON_CONTAINS(user_list, '" + uid + "', '$')")); actitctiyIds.addAll(list.stream().map(XpActicityUser::getActitcityId).collect(Collectors.toList())); XpActivity one = this.getOne(new QueryWrapper<XpActivity>().eq("status", 2).eq("is_deleted", 0) .eq("enable_float_window", 1).in(!actitctiyIds.isEmpty(), "id", actitctiyIds) .last(" and now() between start_time and end_time order by float_window_priority desc limit 1")); return one; } } xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/controller/XpOrderController.java
@@ -68,6 +68,8 @@ import java.math.BigDecimal; import java.math.RoundingMode; import java.net.URLEncoder; import java.time.LocalDateTime; import java.time.ZoneOffset; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -707,4 +709,25 @@ vo.setSlaveMacList(jsonObject.getList("slaveMacList", String.class)); return R.ok(vo); } /** * 判断用户类型 * @param userId * @return 2=老用户,3=新用户,4=流失用户 */ @PostMapping("/logan/inner/order/determineUserType") public R<Integer> determineUserType(@RequestParam Long userId){ //判断流失用户 XpOrder one = xpOrderService.getOne(new QueryWrapper<XpOrder>().eq("app_user_id", userId).in("status", Arrays.asList(9, 10)).last(" order by create_time desc limit 1")); if(null != one){ long time = LocalDateTime.now().toEpochSecond(ZoneOffset.of("GMT+8")) - one.getCreateTime().toEpochSecond(ZoneOffset.of("GMT+8")); if(time >= 60 * 60 * 24 * 5){ return R.ok(4); } return R.ok(2); }else{ return R.ok(3); } } }