Enhance smoking tracking API with new features and improvements
- Added a new API endpoint `GET /api/v1/smoke/home` to consolidate core modules for the home dashboard, reducing the need for multiple requests. - Updated the `smoke` routes to include the new home endpoint and improved user profile management with the addition of a `quit_date` field. - Enhanced the algorithm for calculating daily targets and next smoke suggestions, ensuring accurate future time handling and user-specific recommendations. - Improved API documentation to reflect new endpoints, response formats, and detailed field descriptions for better clarity and usability. - Refactored user authentication handling in various handlers to streamline the process and ensure consistent error responses.
This commit is contained in:
@@ -95,6 +95,7 @@ type ListSmokeLogsRequest struct {
|
||||
PageSize int
|
||||
Start *time.Time
|
||||
End *time.Time
|
||||
Type string
|
||||
}
|
||||
|
||||
type ListSmokeLogsResult struct {
|
||||
@@ -124,6 +125,7 @@ type SmokeHomeSummary struct {
|
||||
ResistedCount int
|
||||
ReducedFromYesterday int
|
||||
ExceededYesterday bool
|
||||
SecondsSinceLast int
|
||||
}
|
||||
|
||||
// DashboardWeeklyStat 表示某一天的抽烟支数以及是否为今天。
|
||||
@@ -155,6 +157,14 @@ func (s *SmokeLogService) List(ctx context.Context, uid int, req ListSmokeLogsRe
|
||||
if req.End != nil {
|
||||
tx = tx.Where("smoke_time <= ?", req.End.Format("2006-01-02"))
|
||||
}
|
||||
switch req.Type {
|
||||
case "", "all":
|
||||
// no-op
|
||||
case "smoke":
|
||||
tx = tx.Where("num > 0")
|
||||
case "resisted":
|
||||
tx = tx.Where("num = 0")
|
||||
}
|
||||
|
||||
var total int64
|
||||
if err := tx.Count(&total).Error; err != nil {
|
||||
@@ -164,7 +174,7 @@ func (s *SmokeLogService) List(ctx context.Context, uid int, req ListSmokeLogsRe
|
||||
var items []smokemodel.SmokeLog
|
||||
offset := (page - 1) * pageSize
|
||||
if err := tx.
|
||||
Order("smoke_time DESC").
|
||||
Order("COALESCE(smoke_at, FROM_UNIXTIME(createtime), smoke_time) DESC").
|
||||
Order("id DESC").
|
||||
Limit(pageSize).
|
||||
Offset(offset).
|
||||
@@ -221,7 +231,7 @@ func (s *SmokeLogService) Dashboard(ctx context.Context, uid int, req SmokeDashb
|
||||
var last smokemodel.SmokeLog
|
||||
if err := s.db.WithContext(ctx).
|
||||
Where("uid = ? AND (deletetime IS NULL OR deletetime = 0)", uid).
|
||||
Where("NOT (level = 0 AND num = 0)").
|
||||
Where("num > 0").
|
||||
Order("COALESCE(smoke_at, FROM_UNIXTIME(createtime), smoke_time) DESC").
|
||||
Order("id DESC").
|
||||
Limit(1).
|
||||
@@ -259,6 +269,7 @@ func (s *SmokeLogService) Dashboard(ctx context.Context, uid int, req SmokeDashb
|
||||
|
||||
// HomeSummary 返回首页所需的汇总数据(不包含时间范围的周统计)。
|
||||
func (s *SmokeLogService) HomeSummary(ctx context.Context, uid int, asOf time.Time) (SmokeHomeSummary, error) {
|
||||
localAsOf := asOf.In(time.Local)
|
||||
today := dateOnly(asOf)
|
||||
todayKey := today.Format("2006-01-02")
|
||||
yesterdayKey := today.AddDate(0, 0, -1).Format("2006-01-02")
|
||||
@@ -276,7 +287,7 @@ func (s *SmokeLogService) HomeSummary(ctx context.Context, uid int, asOf time.Ti
|
||||
if err := s.db.WithContext(ctx).
|
||||
Model(&smokemodel.SmokeLog{}).
|
||||
Where("uid = ? AND (deletetime IS NULL OR deletetime = 0)", uid).
|
||||
Where("level = 0 AND num = 0 AND smoke_time = ?", todayKey).
|
||||
Where("num = 0 AND smoke_time = ?", todayKey).
|
||||
Count(&resistedCount).Error; err != nil {
|
||||
return SmokeHomeSummary{}, fmt.Errorf("count resisted logs: %w", err)
|
||||
}
|
||||
@@ -290,14 +301,22 @@ func (s *SmokeLogService) HomeSummary(ctx context.Context, uid int, asOf time.Ti
|
||||
return SmokeHomeSummary{}, fmt.Errorf("count yesterday smoke logs: %w", err)
|
||||
}
|
||||
|
||||
reduced := int(yesterdayCount - todayCount)
|
||||
exceeded := reduced < 0
|
||||
diffFromYesterday := int(yesterdayCount - todayCount)
|
||||
reduced := 0
|
||||
exceeded := false
|
||||
if diffFromYesterday > 0 {
|
||||
reduced = diffFromYesterday
|
||||
} else if diffFromYesterday < 0 {
|
||||
reduced = -diffFromYesterday
|
||||
exceeded = true
|
||||
}
|
||||
|
||||
var lastSmokeAt *time.Time
|
||||
secondsSinceLast := -1
|
||||
var last smokemodel.SmokeLog
|
||||
if err := s.db.WithContext(ctx).
|
||||
Where("uid = ? AND (deletetime IS NULL OR deletetime = 0)", uid).
|
||||
Where("NOT (level = 0 AND num = 0)").
|
||||
Where("num > 0").
|
||||
Order("COALESCE(smoke_at, FROM_UNIXTIME(createtime), smoke_time) DESC").
|
||||
Order("id DESC").
|
||||
Limit(1).
|
||||
@@ -306,7 +325,15 @@ func (s *SmokeLogService) HomeSummary(ctx context.Context, uid int, asOf time.Ti
|
||||
return SmokeHomeSummary{}, fmt.Errorf("load last smoke log: %w", err)
|
||||
}
|
||||
} else if t, ok := lastEventTime(last); ok {
|
||||
if t.After(localAsOf) {
|
||||
t = localAsOf
|
||||
}
|
||||
lastSmokeAt = &t
|
||||
diff := int(localAsOf.Sub(t).Seconds())
|
||||
if diff < 0 {
|
||||
diff = 0
|
||||
}
|
||||
secondsSinceLast = diff
|
||||
}
|
||||
|
||||
return SmokeHomeSummary{
|
||||
@@ -315,6 +342,7 @@ func (s *SmokeLogService) HomeSummary(ctx context.Context, uid int, asOf time.Ti
|
||||
ResistedCount: int(resistedCount),
|
||||
ReducedFromYesterday: reduced,
|
||||
ExceededYesterday: exceeded,
|
||||
SecondsSinceLast: secondsSinceLast,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user