1.新增定时任务,检查历史退订用户(非1小时退订)是否有误判;

2.优化用户留存记录接口;
3.优化历史记录导出excel;
This commit is contained in:
chenlin 2024-11-01 16:30:13 +08:00
parent c262bbd549
commit 967a6c38fd
3 changed files with 110 additions and 35 deletions

View File

@ -443,8 +443,14 @@ func (e MiGuDeployService) HistoricalSummaryList(c *gin.Context) {
return
}
// 执行查询
err = qs.Offset(pageNum * req.PageSize).Limit(req.PageSize).Find(&historicalSummaryList).Error
// 判断是否导出Excel
if req.IsExport == 1 {
// 执行查询
err = qs.Find(&historicalSummaryList).Error
} else {
// 执行查询
err = qs.Offset(pageNum * req.PageSize).Limit(req.PageSize).Find(&historicalSummaryList).Error
}
if err != nil {
logger.Errorf("HistoricalSummaryList query err: %#v", err)
response.Error(c, http.StatusInternalServerError, err, "查询失败")
@ -633,34 +639,25 @@ func (e MiGuDeployService) UserRetentionList(c *gin.Context) {
}
resp.PageSize = req.PageSize
// 获取开始和结束时间
retentionMonth := req.RetentionMonth // 例如 "2024-10"
if retentionMonth == "" {
retentionMonth = time.Now().Format("2006-01")
}
qs := e.Orm.Model(&models.MgOrder{})
// 解析出年和月
year, month, err := models.ParseYearMonth(retentionMonth)
if err != nil {
response.Error(c, http.StatusBadRequest, err, "日期格式错误")
return
}
// 计算该月份的第一天和最后一天
startDate := time.Date(year, month, 1, 0, 0, 0, 0, time.UTC) // 当月第一天
endDate := startDate.AddDate(0, 1, 0).Add(-time.Second) // 当月最后一天的最后一毫秒
// 定义返回的响应结构
var retentionList []models.MgUserRetention
// 查询用户留存数据
qs := e.Orm.Model(&models.MgOrder{}).
Select(`DATE_FORMAT(created_at, '%Y-%m') AS retention_month,
COUNT(DISTINCT phone_number) AS new_user_count,
COUNT(DISTINCT CASE WHEN state != 2 THEN phone_number END) AS retained_user_count,
channel_code, product_id,
IFNULL(FORMAT(COUNT(DISTINCT CASE WHEN state != 2 THEN phone_number END) / NULLIF(COUNT(DISTINCT phone_number), 0) * 100, 2), 0) AS retention_rate`).
Where("created_at >= ? AND created_at <= ?", startDate, endDate)
//// 获取开始和结束时间
//retentionMonth := req.RetentionMonth // 例如 "2024-10"
//if retentionMonth != "" {
// //retentionMonth = time.Now().Format("2006-01")
//
// // 解析出年和月
// year, month, err := models.ParseYearMonth(retentionMonth)
// if err != nil {
// response.Error(c, http.StatusBadRequest, err, "日期格式错误")
// return
// }
//
// // 计算该月份的第一天和最后一天
// startDate := time.Date(year, month, 1, 0, 0, 0, 0, time.UTC) // 当月第一天
// endDate := startDate.AddDate(0, 1, 0).Add(-time.Second) // 当月最后一天的最后一毫秒
// qs = qs.Where("subscribe_time >= ? AND subscribe_time <= ?", startDate, endDate)
//}
// 处理产品编号 (SkuCode) 过滤条件
if req.SkuCode != "" {
@ -672,14 +669,19 @@ func (e MiGuDeployService) UserRetentionList(c *gin.Context) {
qs = qs.Where("channel_code = ?", req.Channel)
}
err = qs.Group("retention_month, channel_code, product_id").
// 定义返回的响应结构
var retentionList []models.MgUserRetention
// 查询用户留存数据
err := qs.
Select(`DATE_FORMAT(subscribe_time, '%Y-%m') AS retention_month,
COUNT(phone_number) AS new_user_count,
COUNT(CASE WHEN state = 1 THEN phone_number END) AS retained_user_count,
channel_code, product_id,
IFNULL(FORMAT(COUNT(CASE WHEN state = 1 THEN phone_number END) / NULLIF(COUNT(phone_number), 0) * 100, 2), 0) AS retention_rate`).
Group("retention_month, channel_code, product_id").
Order("retention_month").
Find(&retentionList).Error
if err != nil {
logger.Errorf("DailyData query err: %#v", err)
response.Error(c, http.StatusInternalServerError, err, "查询失败")
return
}
if err != nil {
e.Logger.Errorf("UserRetentionList query error: %#v", err)
@ -687,6 +689,17 @@ func (e MiGuDeployService) UserRetentionList(c *gin.Context) {
return
}
// 如果传递了月份参数,则在内存中过滤对应月份的数据
if req.RetentionMonth != "" {
var filteredList []models.MgUserRetention
for _, item := range retentionList {
if item.RetentionMonth == req.RetentionMonth {
filteredList = append(filteredList, item)
}
}
retentionList = filteredList
}
for i := range retentionList {
retentionList[i].RetentionRate += "%"
}

View File

@ -1052,6 +1052,63 @@ func CheckAllOrderState() {
}
}
// CheckCancelOrderState 定时任务,检查历史退订阅用户是否有误判
func CheckCancelOrderState() {
if database.Db == nil {
log.Println("Database connection is nil")
fmt.Println("Database connection is nil")
return
}
// 查询订单列表已退订且不是1小时内退订的用户
var orderList []MgOrder
err := database.Db.Where("state = 2 and is_one_hour_cancel != 1").Order("created_at desc").
Find(&orderList).Error
if err != nil {
fmt.Println("query mg_order err:", err.Error())
return
}
for i, _ := range orderList {
for j := 0; j < 5; j++ {
var req QueryRightsInfoReq
req.AppChannelList = append(req.AppChannelList, ChannelCode)
req.Mobile = orderList[i].PhoneNumber
resp, err := MiGuQueryRightsInfo(&req)
if err != nil {
fmt.Println("CheckOrderState MiGuQueryRightsInfo err:", err.Error())
logger.Errorf("CheckOrderState MiGuQueryRightsInfo err:", err.Error())
continue
}
// 有退订数据
if len(resp.ResultData) != 0 {
if resp.ResultData[0].IsUnsub == 1 { // 已退订
break
} else if resp.ResultData[0].IsUnsub == 0 { // 没有退订
fmt.Println("**********CheckCancelOrderState get:", orderList[i].PhoneNumber)
var unsubTime *time.Time = nil
err = database.Db.Table("mg_order").Where("order_serial = ?", orderList[i].OrderSerial).Updates(map[string]interface{}{
"state": SubscribeOK,
"is_one_hour_cancel": 0,
"unsubscribe_time": unsubTime,
"updated_at": time.Now(),
}).Error
break
}
} else {
if j == 1 {
break
}
continue
}
}
}
}
// ExportHistoricalSummaryToExcel 历史汇总数据导出excel
func ExportHistoricalSummaryToExcel(data []MgHistoricalSummary, db *gorm.DB) (string, error) {
// 创建一个新的Excel文件

View File

@ -97,6 +97,11 @@ func run() error {
fmt.Println("err:", err)
}
err = s.Every(1).Day().At("02:30").Do(models.CheckCancelOrderState)
if err != nil {
fmt.Println("err:", err)
}
<-s.Start()
}()