This commit is contained in:
2025-06-03 14:33:31 +08:00
parent a9655814ae
commit 1841e43b85
4 changed files with 106 additions and 49 deletions

View File

@ -2,6 +2,7 @@ package com.ycwl.basic.mapper;
import com.ycwl.basic.model.mobile.statistic.req.CommonQueryReq; import com.ycwl.basic.model.mobile.statistic.req.CommonQueryReq;
import com.ycwl.basic.model.mobile.statistic.req.StatisticsRecordAddReq; import com.ycwl.basic.model.mobile.statistic.req.StatisticsRecordAddReq;
import com.ycwl.basic.model.mobile.statistic.resp.AppStatisticsFunnelVO;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
import java.math.BigDecimal; import java.math.BigDecimal;
@ -93,4 +94,7 @@ public interface StatisticsMapper {
List<Long> getBrokerIdListForUser(Long memberId, Date startTime, Date endTime); List<Long> getBrokerIdListForUser(Long memberId, Date startTime, Date endTime);
Long getUserRecentEnterType(Long memberId, Date endTime); Long getUserRecentEnterType(Long memberId, Date endTime);
List<AppStatisticsFunnelVO> listStatByScenic(Long scenicId, Date startTime, Date endTime);
int insertStat(Long scenicId, Date date, AppStatisticsFunnelVO data);
} }

View File

@ -3,6 +3,8 @@ package com.ycwl.basic.model.mobile.statistic.resp;
import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
import java.math.BigDecimal;
import java.math.RoundingMode;
/** /**
* @Authorlongbinbin * @Authorlongbinbin
@ -13,49 +15,106 @@ import lombok.Data;
public class AppStatisticsFunnelVO { public class AppStatisticsFunnelVO {
@ApiModelProperty("镜头检测游客数") @ApiModelProperty("镜头检测游客数")
// private Integer cameraShotOfMemberNum; private int cameraShotOfMemberNum; // cs1
private String cameraShotOfMemberNum;
@ApiModelProperty("镜头检测游客数_扫码访问人数_转化率")
private String csom_scaom;
@ApiModelProperty("扫码访问人数") @ApiModelProperty("扫码访问人数")
private Integer scanCodeVisitorOfMemberNum; private int scanCodeVisitorOfMemberNum; // sv1
@ApiModelProperty("扫码访问人数_上传头像人数_转化率")
private String scaom_ufom;
@ApiModelProperty("上传头像(人脸)人数") @ApiModelProperty("上传头像(人脸)人数")
private Integer uploadFaceOfMemberNum; private int uploadFaceOfMemberNum; // u1
@ApiModelProperty("上传头像人数_推送订阅人数_转化率")
private String ufom_pom;
@ApiModelProperty("推送订阅人数") @ApiModelProperty("推送订阅人数")
private Integer pushOfMemberNum; private int pushOfMemberNum; // m1
@ApiModelProperty("推送订阅人数_生成视频人数_转化率")
private String pom_cvom;
@ApiModelProperty("生成视频人数") @ApiModelProperty("生成视频人数")
private Integer completeVideoOfMemberNum; private int completeVideoOfMemberNum; // gv1
@ApiModelProperty("生成视频人数_预览视频人数_转化率")
private String cvom_pvom;
@ApiModelProperty("预览视频人数") @ApiModelProperty("预览视频人数")
private Integer previewVideoOfMemberNum; private int previewVideoOfMemberNum; // pv1
@ApiModelProperty("预览视频人数_点击购买人数_转化率")
private String pvom_cpom;
@ApiModelProperty("点击购买人数") @ApiModelProperty("点击购买人数")
private Integer clickOnPayOfMemberNum; private int clickOnPayOfMemberNum; // cp1
@ApiModelProperty("点击购买人数_支付订单人数_转化率")
private String cpom_pom;
@ApiModelProperty("支付订单人数") @ApiModelProperty("支付订单人数")
private Integer payOfMemberNum; private int payOfMemberNum; // p1
@ApiModelProperty("总访问人数") @ApiModelProperty("总访问人数")
private Integer totalVisitorOfMemberNum; private int totalVisitorOfMemberNum; // v1
@ApiModelProperty("生成视频条数") @ApiModelProperty("生成视频条数")
private Integer completeOfVideoNum; private int completeOfVideoNum; // gv2
@ApiModelProperty("预览视频条数") @ApiModelProperty("预览视频条数")
private Integer previewOfVideoNum; private int previewOfVideoNum; // pv2
@ApiModelProperty("支付订单数") @ApiModelProperty("支付订单数")
private Integer payOfOrderNum; private int payOfOrderNum; // p2
@ApiModelProperty("支付订单金额") @ApiModelProperty("支付订单金额")
private String payOfOrderAmount; private BigDecimal payOfOrderAmount; // o3
@ApiModelProperty("退款订单数") @ApiModelProperty("退款订单数")
private Integer refundOfOrderNum; private int refundOfOrderNum; // ro2
@ApiModelProperty("退款订单金额") @ApiModelProperty("退款订单金额")
private String refundOfOrderAmount; private BigDecimal refundOfOrderAmount; // ro3
@ApiModelProperty("镜头检测游客数_扫码访问人数_转化率")
public String getCsom_scaom() {
return "-"; // TODO: REAL
}
@ApiModelProperty("扫码访问人数_上传头像人数_转化率")
public String getScaom_ufom() {
if (uploadFaceOfMemberNum == 0 || scanCodeVisitorOfMemberNum == 0) {
return "0.00";
}
return new BigDecimal(uploadFaceOfMemberNum)
.multiply(new BigDecimal(100))
.divide(new BigDecimal(scanCodeVisitorOfMemberNum), 2, RoundingMode.HALF_UP)
.toString();
}
@ApiModelProperty("上传头像人数_推送订阅人数_转化率")
public String getUfom_pom() {
if (pushOfMemberNum == 0 || uploadFaceOfMemberNum == 0) {
return "0.00";
}
return new BigDecimal(uploadFaceOfMemberNum)
.multiply(new BigDecimal(100))
.divide(new BigDecimal(pushOfMemberNum), 2, RoundingMode.HALF_UP)
.toString();
}
@ApiModelProperty("推送订阅人数_生成视频人数_转化率")
public String getPom_cvom() {
if (completeVideoOfMemberNum == 0 || pushOfMemberNum == 0) {
return "0.00";
}
return new BigDecimal(completeVideoOfMemberNum)
.multiply(new BigDecimal(100))
.divide(new BigDecimal(pushOfMemberNum), 2, RoundingMode.HALF_UP)
.toString();
}
@ApiModelProperty("生成视频人数_预览视频人数_转化率")
public String getCvom_pvom() {
if (previewVideoOfMemberNum == 0 || completeVideoOfMemberNum == 0) {
return "0.00";
}
return new BigDecimal(previewVideoOfMemberNum)
.multiply(new BigDecimal(100))
.divide(new BigDecimal(completeVideoOfMemberNum), 2, RoundingMode.HALF_UP)
.toString();
}
@ApiModelProperty("预览视频人数_点击购买人数_转化率")
public String getPvom_cpom() {
if (clickOnPayOfMemberNum == 0 || previewVideoOfMemberNum == 0) {
return "0.00";
}
return new BigDecimal(clickOnPayOfMemberNum)
.multiply(new BigDecimal(100))
.divide(new BigDecimal(previewVideoOfMemberNum), 2, RoundingMode.HALF_UP)
.toString();
}
@ApiModelProperty("点击购买人数_支付订单人数_转化率")
public String getCpom_pom() {
if (payOfMemberNum == 0 || clickOnPayOfMemberNum == 0) {
return "0.00";
}
return new BigDecimal(payOfMemberNum)
.multiply(new BigDecimal(100))
.divide(new BigDecimal(clickOnPayOfMemberNum), 2, RoundingMode.HALF_UP)
.toString();
}
public String getPayOfOrderAmount() {
return payOfOrderAmount.toString();
}
public String getRefundOfOrderAmount() {
return refundOfOrderAmount.toString();
}
} }

View File

@ -141,41 +141,26 @@ public class AppStatisticsServiceImpl implements AppStatisticsService {
//扫码访问人数 //扫码访问人数
// 扫小程序码或景区码进入访问的用户数包括授权用户使用OpenID进行精准统计和未授权用户(使用 UUID统计访问)。但当用户授权时获取OpenID并与UUID关联删除本地UUID避免重复记录。 // 扫小程序码或景区码进入访问的用户数包括授权用户使用OpenID进行精准统计和未授权用户(使用 UUID统计访问)。但当用户授权时获取OpenID并与UUID关联删除本地UUID避免重复记录。
Integer scanCodeVisitorOfMemberNum=statisticsMapper.countScanCodeOfMember(query); Integer scanCodeVisitorOfMemberNum=statisticsMapper.countScanCodeOfMember(query);
//镜头检测游客数_扫码访问人数_转化率
// vo.setCsom_scaom(calculateConversionRate(scanCodeVisitorOfMemberNum,cameraShotOfMemberNum));
vo.setCsom_scaom("-");
//上传头像(人脸)人数 //上传头像(人脸)人数
// 上传了人脸的用户数包括本地临时ID和获取到OpenID的同一设备微信获取到OpenID要覆盖掉之前生成的临时ID上传多张人脸都只算一个人。 // 上传了人脸的用户数包括本地临时ID和获取到OpenID的同一设备微信获取到OpenID要覆盖掉之前生成的临时ID上传多张人脸都只算一个人。
Integer uploadFaceOfMemberNum=statisticsMapper.countUploadFaceOfMember(query); Integer uploadFaceOfMemberNum=statisticsMapper.countUploadFaceOfMember(query);
//扫码访问人数_上传头像人数_转化率
vo.setScaom_ufom(calculateConversionRate(uploadFaceOfMemberNum,scanCodeVisitorOfMemberNum));
//推送订阅人数 //推送订阅人数
// 只要点了允许通知哪怕只勾选1条订阅都算 // 只要点了允许通知哪怕只勾选1条订阅都算
Integer pushOfMemberNum =statisticsMapper.countPushOfMember(query); Integer pushOfMemberNum =statisticsMapper.countPushOfMember(query);
//上传头像人数_推送订阅人数_转化率
vo.setUfom_pom((calculateConversionRate(pushOfMemberNum,uploadFaceOfMemberNum)));
//生成视频人数 //生成视频人数
// 生成过Vlog视频的用户ID数要注意屏蔽掉以前没有片段也能生成的情况 // 生成过Vlog视频的用户ID数要注意屏蔽掉以前没有片段也能生成的情况
Integer completeVideoOfMemberNum =statisticsMapper.countCompleteVideoOfMember(query); Integer completeVideoOfMemberNum =statisticsMapper.countCompleteVideoOfMember(query);
//推送订阅人数_生成视频人数_转化率
vo.setPom_cvom((calculateConversionRate(completeVideoOfMemberNum,pushOfMemberNum)));
//预览视频人数 //预览视频人数
// 购买前播放了5秒的视频条数。 // 购买前播放了5秒的视频条数。
Integer previewVideoOfMemberNum =statisticsMapper.countPreviewVideoOfMember(query); Integer previewVideoOfMemberNum =statisticsMapper.countPreviewVideoOfMember(query);
if (previewVideoOfMemberNum==null){ if (previewVideoOfMemberNum==null){
previewVideoOfMemberNum=0; previewVideoOfMemberNum=0;
} }
//生成视频人数_预览视频人数_转化率
vo.setCvom_pvom((calculateConversionRate(previewVideoOfMemberNum,completeVideoOfMemberNum)));
//点击购买人数 //点击购买人数
// 点了立即购买按钮的用户ID就算包括支付的和未支付的都算只要点击了。 // 点了立即购买按钮的用户ID就算包括支付的和未支付的都算只要点击了。
Integer clickOnPayOfMemberNum =statisticsMapper.countClickPayOfMember(query); Integer clickOnPayOfMemberNum =statisticsMapper.countClickPayOfMember(query);
//预览视频人数_点击购买人数_转化率
vo.setPvom_cpom((calculateConversionRate(clickOnPayOfMemberNum,previewVideoOfMemberNum)));
//支付订单人数 //支付订单人数
Integer payOfMemberNum =statisticsMapper.countPayOfMember(query); Integer payOfMemberNum =statisticsMapper.countPayOfMember(query);
//点击购买人数_支付订单人数_转化率
vo.setCpom_pom((calculateConversionRate(payOfMemberNum,clickOnPayOfMemberNum)));
//总访问人数 //总访问人数
// 通过任何途径访问到小程序的总人数,包括授权用户和未授权用户。 // 通过任何途径访问到小程序的总人数,包括授权用户和未授权用户。
Integer totalVisitorOfMemberNum =statisticsMapper.countTotalVisitorOfMember(query); Integer totalVisitorOfMemberNum =statisticsMapper.countTotalVisitorOfMember(query);
@ -194,8 +179,6 @@ public class AppStatisticsServiceImpl implements AppStatisticsService {
//退款订单金额 //退款订单金额
BigDecimal refundOfOrderAmount =statisticsMapper.countRefundAmount(query); BigDecimal refundOfOrderAmount =statisticsMapper.countRefundAmount(query);
// vo.setCameraShotOfMemberNum(cameraShotOfMemberNum);
vo.setCameraShotOfMemberNum("-");
vo.setScanCodeVisitorOfMemberNum(scanCodeVisitorOfMemberNum); vo.setScanCodeVisitorOfMemberNum(scanCodeVisitorOfMemberNum);
vo.setUploadFaceOfMemberNum(uploadFaceOfMemberNum); vo.setUploadFaceOfMemberNum(uploadFaceOfMemberNum);
vo.setPushOfMemberNum(pushOfMemberNum); vo.setPushOfMemberNum(pushOfMemberNum);
@ -211,9 +194,9 @@ public class AppStatisticsServiceImpl implements AppStatisticsService {
vo.setCompleteOfVideoNum(completeOfVideoNum); vo.setCompleteOfVideoNum(completeOfVideoNum);
vo.setPreviewOfVideoNum(previewOfVideoNum); vo.setPreviewOfVideoNum(previewOfVideoNum);
vo.setPayOfOrderNum(payOfOrderNum); vo.setPayOfOrderNum(payOfOrderNum);
vo.setPayOfOrderAmount(df.format(payOfOrderAmount.setScale(2, RoundingMode.HALF_UP))); vo.setPayOfOrderAmount(payOfOrderAmount.setScale(2, RoundingMode.HALF_UP));
vo.setRefundOfOrderNum(refundOfOrderNum); vo.setRefundOfOrderNum(refundOfOrderNum);
vo.setRefundOfOrderAmount(df.format(refundOfOrderAmount.setScale(2, RoundingMode.HALF_UP))); vo.setRefundOfOrderAmount(refundOfOrderAmount.setScale(2, RoundingMode.HALF_UP));
return ApiResponse.success(vo); return ApiResponse.success(vo);
} }

View File

@ -312,4 +312,15 @@
order by r.create_time desc order by r.create_time desc
limit 1 limit 1
</select> </select>
<select id="listStatByScenic" resultType="com.ycwl.basic.model.mobile.statistic.resp.AppStatisticsFunnelVO">
SELECT cs1 AS cameraShotOfMemberNum, v1 AS totalVisitorOfMemberNum, sv1 AS scanCodeVisitorOfMemberNum, u1 AS uploadFaceOfMemberNum, m1 AS pushOfMemberNum, gv1 AS completeVideoOfMemberNum, gv2 AS completeOfVideoNum, pv1 AS previewVideoOfMemberNum, pv2 AS previewOfVideoNum, cp1 AS clickOnPayOfMemberNum, o1 AS payOfMemberNum, o2 AS totalVisitorOfMemberNum, o3 AS payOfOrderAmount, ro2 AS refundOfOrderNum, ro3 AS refundOfOrderAmount
FROM scenic_stats
WHERE scenic_id = #{scenicId}
AND date BETWEEN #{startTime} AND #{endTime}
</select>
<insert id="insertStat">
REPLACE INTO scenic_stats (scenic_id, date, cs1, v1, sv1, u1, m1, gv1, gv2, pv1, pv2, cp1, o1, o2, o3, ro2, ro3)
VALUES (#{scenicId}, #{date}, #{data.cameraShotOfMemberNum}, #{data.totalVisitorOfMemberNum}, #{data.scanCodeVisitorOfMemberNum}, #{data.uploadFaceOfMemberNum}, #{data.pushOfMemberNum}, #{data.completeVideoOfMemberNum}, #{data.completeOfVideoNum}, #{data.previewVideoOfMemberNum}, #{data.previewOfVideoNum}, #{data.clickOnPayOfMemberNum}, #{data.payOfMemberNum}, #{data.payOfOrderNum}, #{data.payOfOrderAmount}, #{data.refundOfOrderNum}, #{data.refundOfOrderAmount})
</insert>
</mapper> </mapper>