Commit 64e344fa authored by zhangfeng's avatar zhangfeng

feat-508: 分享详情新增点击IP,记录非有效点击

parent 68e948dd
...@@ -2,18 +2,18 @@ package cn.iocoder.yudao.module.member.controller.admin.scoreRule; ...@@ -2,18 +2,18 @@ package cn.iocoder.yudao.module.member.controller.admin.scoreRule;
import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.vo.PageVO;
import cn.iocoder.yudao.module.member.dal.dataobject.ScoreRuleShareRecord.ScoreRuleShareRecordDO;
import cn.iocoder.yudao.module.member.service.ScoreRuleShareRecord.ScoreRuleShareRecordService; import cn.iocoder.yudao.module.member.service.ScoreRuleShareRecord.ScoreRuleShareRecordService;
import cn.iocoder.yudao.module.member.vo.ScoreRuleShareRecord.ScoreRuleShareRecordDetailReqVO; import cn.iocoder.yudao.module.member.vo.ScoreRuleShareRecord.ScoreRuleShareRecordDetailReqVO;
import cn.iocoder.yudao.module.member.vo.ScoreRuleShareRecord.ScoreRuleShareRecordDetailVO; import cn.iocoder.yudao.module.member.vo.ScoreRuleShareRecord.ScoreRuleShareRecordDetailVO;
import cn.iocoder.yudao.module.member.vo.ScoreRuleShareRecord.ScoreRuleShareRecordPageVO; import cn.iocoder.yudao.module.member.vo.ScoreRuleShareRecord.ScoreRuleShareRecordPageVO;
import cn.iocoder.yudao.module.member.vo.ScoreRuleShareRecord.ScoreRuleShareRecordQueryVO; import cn.iocoder.yudao.module.member.vo.ScoreRuleShareRecord.ScoreRuleShareRecordQueryVO;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.validation.Valid; import javax.validation.Valid;
......
...@@ -8,6 +8,7 @@ import cn.iocoder.yudao.module.member.controller.app.scoreRule.vo.AppScoreRuleBa ...@@ -8,6 +8,7 @@ import cn.iocoder.yudao.module.member.controller.app.scoreRule.vo.AppScoreRuleBa
import cn.iocoder.yudao.module.member.controller.app.scoreRule.vo.AppScoreRuleListBackVO; import cn.iocoder.yudao.module.member.controller.app.scoreRule.vo.AppScoreRuleListBackVO;
import cn.iocoder.yudao.module.member.controller.app.scoreRule.vo.AppScoreRuleListReqVO; import cn.iocoder.yudao.module.member.controller.app.scoreRule.vo.AppScoreRuleListReqVO;
import cn.iocoder.yudao.module.member.enums.ScoreRuleTypeEnum; import cn.iocoder.yudao.module.member.enums.ScoreRuleTypeEnum;
import cn.iocoder.yudao.module.member.service.ScoreRuleShareRecord.ScoreRuleShareRecordService;
import cn.iocoder.yudao.module.member.service.scoreRule.ScoreRuleService; import cn.iocoder.yudao.module.member.service.scoreRule.ScoreRuleService;
import cn.iocoder.yudao.module.member.vo.scoreRule.IdReqVo; import cn.iocoder.yudao.module.member.vo.scoreRule.IdReqVo;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
...@@ -36,6 +37,8 @@ public class AppScoreRuleController { ...@@ -36,6 +37,8 @@ public class AppScoreRuleController {
private ApplicationContext applicationContext; private ApplicationContext applicationContext;
@Resource @Resource
private ScoreProducerApi scoreProducerApi; private ScoreProducerApi scoreProducerApi;
@Resource
private ScoreRuleShareRecordService scoreRuleShareRecordService;
@PostMapping("/get") @PostMapping("/get")
...@@ -61,7 +64,11 @@ public class AppScoreRuleController { ...@@ -61,7 +64,11 @@ public class AppScoreRuleController {
if (ruleId == null || userId == null) { if (ruleId == null || userId == null) {
return; return;
} }
scoreProducerApi.sendShareMessage(ScoreRuleTypeEnum.SHARE, userId, ruleId, IPHelper.getIpAddr(request)); String ipAddr = IPHelper.getIpAddr(request);
if (!scoreRuleShareRecordService.verifyTriggerIp(userId, ruleId, ipAddr)) {
return;
}
scoreProducerApi.sendShareMessage(ScoreRuleTypeEnum.SHARE, userId, ruleId, ipAddr);
} }
//@PostMapping("/page") //@PostMapping("/page")
//@ApiOperation("获得积分规则分页") //@ApiOperation("获得积分规则分页")
......
package cn.iocoder.yudao.module.member.dal.dataobject.ScoreRuleShareRecord;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
/**
* 分享规则失败点击记录 DO
*
* @author 系统管理员
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@TableName("score_rule_share_fail_trigger")
public class ScoreRuleShareFailTriggerDO {
/**
* 主键
*/
@TableId
private Long id;
/**
* 分享记录id
*/
private Long shareRecordId;
/**
* 点击时间
*/
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private Date triggerTime;
/**
* 点击ip
*/
private String ipAddress;
}
package cn.iocoder.yudao.module.member.dal.mysql.ScoreRuleShareRecord;
import cn.iocoder.yudao.framework.mybatis.core.mapper.AbstractMapper;
import cn.iocoder.yudao.module.member.dal.dataobject.ScoreRuleShareRecord.ScoreRuleShareFailTriggerDO;
import org.apache.ibatis.annotations.Mapper;
/**
* 分享失败点击记录 Mapper
*
* @author 系统管理员
*/
@Mapper
public interface ScoreRuleShareFailTriggerMapper extends AbstractMapper<ScoreRuleShareFailTriggerDO> {
}
\ No newline at end of file
...@@ -34,4 +34,9 @@ public interface ScoreRuleShareRecordService extends IService<ScoreRuleShareReco ...@@ -34,4 +34,9 @@ public interface ScoreRuleShareRecordService extends IService<ScoreRuleShareReco
* @return 分享记录分页 * @return 分享记录分页
*/ */
PageResult<ScoreRuleShareRecordPageVO> getRuleShareRecordPage(ScoreRuleShareRecordQueryVO query); PageResult<ScoreRuleShareRecordPageVO> getRuleShareRecordPage(ScoreRuleShareRecordQueryVO query);
/**
* 分享规则触发ip校验
*/
boolean verifyTriggerIp(Long userId, Long ruleId, String ipAddr);
} }
...@@ -4,14 +4,21 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; ...@@ -4,14 +4,21 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.dict.core.util.DictFrameworkUtils; import cn.iocoder.yudao.framework.dict.core.util.DictFrameworkUtils;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.mybatis.core.service.AbstractService; import cn.iocoder.yudao.framework.mybatis.core.service.AbstractService;
import cn.iocoder.yudao.module.member.dal.dataobject.ScoreRuleShareRecord.ScoreRuleShareFailTriggerDO;
import cn.iocoder.yudao.module.member.dal.dataobject.ScoreRuleShareRecord.ScoreRuleShareRecordDO; import cn.iocoder.yudao.module.member.dal.dataobject.ScoreRuleShareRecord.ScoreRuleShareRecordDO;
import cn.iocoder.yudao.module.member.dal.dataobject.scoreLog.MemberUserScoreLogDO;
import cn.iocoder.yudao.module.member.dal.mysql.ScoreRuleShareRecord.ScoreRuleShareFailTriggerMapper;
import cn.iocoder.yudao.module.member.dal.mysql.ScoreRuleShareRecord.ScoreRuleShareRecordMapper; import cn.iocoder.yudao.module.member.dal.mysql.ScoreRuleShareRecord.ScoreRuleShareRecordMapper;
import cn.iocoder.yudao.module.member.enums.ScoreSourceTypeEnum;
import cn.iocoder.yudao.module.member.service.scoreLog.MemberUserScoreLogService;
import cn.iocoder.yudao.module.member.util.ScoreRuleGenCodeUtils; import cn.iocoder.yudao.module.member.util.ScoreRuleGenCodeUtils;
import cn.iocoder.yudao.module.member.vo.ScoreRuleShareRecord.*; import cn.iocoder.yudao.module.member.vo.ScoreRuleShareRecord.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.util.Date;
import java.util.List; import java.util.List;
/** /**
...@@ -21,12 +28,17 @@ import java.util.List; ...@@ -21,12 +28,17 @@ import java.util.List;
*/ */
@Service @Service
@Validated @Validated
@Slf4j
public class ScoreRuleShareRecordServiceImpl extends AbstractService<ScoreRuleShareRecordMapper, ScoreRuleShareRecordDO> implements ScoreRuleShareRecordService { public class ScoreRuleShareRecordServiceImpl extends AbstractService<ScoreRuleShareRecordMapper, ScoreRuleShareRecordDO> implements ScoreRuleShareRecordService {
@Resource @Resource
private ScoreRuleShareRecordMapper scoreRuleShareRecordMapper; private ScoreRuleShareRecordMapper scoreRuleShareRecordMapper;
@Resource @Resource
private ScoreRuleGenCodeUtils scoreRuleGenCodeUtils; private ScoreRuleGenCodeUtils scoreRuleGenCodeUtils;
@Resource
private MemberUserScoreLogService logService;
@Resource
private ScoreRuleShareFailTriggerMapper scoreRuleShareFailTriggerMapper;
@Override @Override
public Long createRuleShareRecord(ScoreRuleShareRecordCreateReqVO createReqVO) { public Long createRuleShareRecord(ScoreRuleShareRecordCreateReqVO createReqVO) {
...@@ -55,7 +67,12 @@ public class ScoreRuleShareRecordServiceImpl extends AbstractService<ScoreRuleSh ...@@ -55,7 +67,12 @@ public class ScoreRuleShareRecordServiceImpl extends AbstractService<ScoreRuleSh
if (list.isEmpty()) { if (list.isEmpty()) {
return PageResult.empty(); return PageResult.empty();
} }
list.stream().forEach(item -> { list.forEach(item -> {
// 有效记录中ip取的是积分记录中的幂等key,需要提取出ip
if (item.getIpAddress().contains("SHARE")) {
String[] split = item.getIpAddress().split("_");
item.setIpAddress(split[split.length - 1]);
}
item.setTypeZh(DictFrameworkUtils.getDictDataFromCache("score_rule_type", item.getType().toString()).getLabel()); item.setTypeZh(DictFrameworkUtils.getDictDataFromCache("score_rule_type", item.getType().toString()).getLabel());
item.setTypeEn(DictFrameworkUtils.getDictDataFromCache("score_rule_type", item.getType().toString()).getLabelEn()); item.setTypeEn(DictFrameworkUtils.getDictDataFromCache("score_rule_type", item.getType().toString()).getLabelEn());
}); });
...@@ -78,4 +95,26 @@ public class ScoreRuleShareRecordServiceImpl extends AbstractService<ScoreRuleSh ...@@ -78,4 +95,26 @@ public class ScoreRuleShareRecordServiceImpl extends AbstractService<ScoreRuleSh
int total = scoreRuleShareRecordMapper.countScoreRuleShareRecord(query); int total = scoreRuleShareRecordMapper.countScoreRuleShareRecord(query);
return new PageResult<>(list, total, size, query.getPage(), (total + size - 1) / size); return new PageResult<>(list, total, size, query.getPage(), (total + size - 1) / size);
} }
@Override
public boolean verifyTriggerIp(Long userId, Long ruleId, String ipAddr) {
// 根据分享人和规则id获取分享记录
ScoreRuleShareRecordDO scoreRuleShareRecordDO = selectOne("member_id", userId, "rule_id", ruleId);
if (scoreRuleShareRecordDO == null) {
log.info("Share listener: The user not share the activity,userId:{},ruleId:{}", userId, ruleId);
return false;
}
String uniqueId = userId + "_" + ruleId + "_" + ipAddr;
MemberUserScoreLogDO memberUserScoreLogDO = logService.getByUniqueId(ScoreSourceTypeEnum.SHARE + "_" + uniqueId);
if (memberUserScoreLogDO != null) {
// 增加触发失败记录
ScoreRuleShareFailTriggerDO failTriggerDO = new ScoreRuleShareFailTriggerDO();
failTriggerDO.setShareRecordId(scoreRuleShareRecordDO.getId());
failTriggerDO.setIpAddress(ipAddr);
failTriggerDO.setTriggerTime(new Date());
scoreRuleShareFailTriggerMapper.insert(failTriggerDO);
return false;
}
return true;
}
} }
\ No newline at end of file
...@@ -53,4 +53,7 @@ public class ScoreRuleShareRecordDetailVO { ...@@ -53,4 +53,7 @@ public class ScoreRuleShareRecordDetailVO {
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@ApiModelProperty(value = "点击时间") @ApiModelProperty(value = "点击时间")
private Date triggerTime; private Date triggerTime;
@ApiModelProperty(value = "点击ip")
private String ipAddress;
} }
...@@ -41,6 +41,7 @@ ...@@ -41,6 +41,7 @@
srsr.create_time AS createTime, srsr.create_time AS createTime,
msul.score_count AS score, msul.score_count AS score,
msul.create_time AS triggerTime, msul.create_time AS triggerTime,
msul.unique_id AS ipAddress,
mu.nickname AS memberName, mu.nickname AS memberName,
sr.type, sr.type,
sr.title_zh AS titleZh, sr.title_zh AS titleZh,
...@@ -55,14 +56,38 @@ ...@@ -55,14 +56,38 @@
AND srsr.id = #{query.id} AND srsr.id = #{query.id}
</if> </if>
<include refid="shareRecordDetailCondition"/> <include refid="shareRecordDetailCondition"/>
order by srsr.create_time desc
<if test="query.id == null and query.relationSymbol == null">
UNION
SELECT
srsr.id,
srsr.code,
srsr.create_time AS createTime,
0 AS score,
srsf.trigger_time AS triggerTime,
srsf.ip_address AS ipAddress,
mu.nickname AS memberName,
sr.type,
sr.title_zh AS titleZh,
sr.title_en AS titleEn
FROM
score_rule_share_fail_trigger srsf
LEFT JOIN score_rule_share_record srsr ON srsf.share_record_id = srsr.id
LEFT JOIN member_user mu ON srsr.member_id = mu.id
LEFT JOIN score_rule sr ON srsr.rule_id = sr.id
where srsr.deleted = 0
<include refid="shareRecordDetailCondition"/>
</if>
order by createTime desc, triggerTime desc
limit #{start}, #{size} limit #{start}, #{size}
</select> </select>
<select id="countScoreRuleShareRecordDetail" resultType="java.lang.Integer"> <select id="countScoreRuleShareRecordDetail" resultType="java.lang.Integer">
SELECT SELECT
count(*) count(*)
FROM FROM (
member_user_score_log msul SELECT srsr.id
FROM member_user_score_log msul
LEFT JOIN score_rule_share_record srsr ON msul.member_id = srsr.member_id AND msul.rule_id = srsr.rule_id LEFT JOIN score_rule_share_record srsr ON msul.member_id = srsr.member_id AND msul.rule_id = srsr.rule_id
LEFT JOIN member_user mu ON srsr.member_id = mu.id LEFT JOIN member_user mu ON srsr.member_id = mu.id
LEFT JOIN score_rule sr ON srsr.rule_id = sr.id LEFT JOIN score_rule sr ON srsr.rule_id = sr.id
...@@ -71,6 +96,17 @@ ...@@ -71,6 +96,17 @@
AND srsr.id = #{query.id} AND srsr.id = #{query.id}
</if> </if>
<include refid="shareRecordDetailCondition"/> <include refid="shareRecordDetailCondition"/>
<if test="query.id == null and query.relationSymbol == null">
UNION ALL
SELECT srsr.id
FROM score_rule_share_fail_trigger srsf
LEFT JOIN score_rule_share_record srsr ON srsf.share_record_id = srsr.id
LEFT JOIN member_user mu ON srsr.member_id = mu.id
LEFT JOIN score_rule sr ON srsr.rule_id = sr.id
where srsr.deleted = 0
<include refid="shareRecordDetailCondition"/>
</if>
) subquery
</select> </select>
<select id="getCurrentMaxShareRecordCode" resultType="java.lang.String"> <select id="getCurrentMaxShareRecordCode" resultType="java.lang.String">
SELECT code FROM score_rule_share_record ORDER BY code desc LIMIT 1 SELECT code FROM score_rule_share_record ORDER BY code desc LIMIT 1
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment