Enhance smoking tracking API and documentation

- Updated the main.go file to set the local time zone to Asia/Shanghai.
- Changed API endpoints from `PUT` to `POST` for user profile and logs management in multiple documentation files to reflect the correct usage.
- Added new fields in the API response for home summary, including `last_smoke_at`, `today_count`, `resisted_count`, and `reduced_from_yesterday`.
- Enhanced documentation across various files to accurately describe the updated API endpoints and their expected behaviors.
This commit is contained in:
nepiedg
2026-01-25 07:55:32 +00:00
parent be6d579d41
commit b67dc32369
12 changed files with 758 additions and 37 deletions
@@ -117,6 +117,14 @@ type SmokeDashboardResult struct {
Weekly []DashboardWeeklyStat `json:"weekly"`
}
// SmokeHomeSummary 汇总首页所需的关键指标。
type SmokeHomeSummary struct {
LastSmokeAt *time.Time
TodayCount int
ResistedCount int
ReducedFromYesterday int
}
// DashboardWeeklyStat 表示某一天的抽烟支数以及是否为今天。
type DashboardWeeklyStat struct {
Date string `json:"date"`
@@ -248,6 +256,68 @@ func (s *SmokeLogService) Dashboard(ctx context.Context, uid int, req SmokeDashb
}, nil
}
// HomeSummary 返回首页所需的汇总数据(不包含时间范围的周统计)。
func (s *SmokeLogService) HomeSummary(ctx context.Context, uid int, asOf time.Time) (SmokeHomeSummary, error) {
today := dateOnly(asOf)
todayKey := today.Format("2006-01-02")
yesterdayKey := today.AddDate(0, 0, -1).Format("2006-01-02")
var todayCount int64
if err := s.db.WithContext(ctx).
Model(&smokemodel.SmokeLog{}).
Where("uid = ? AND (deletetime IS NULL OR deletetime = 0) AND smoke_time = ?", uid, todayKey).
Select("COALESCE(SUM(num), 0)").
Scan(&todayCount).Error; err != nil {
return SmokeHomeSummary{}, fmt.Errorf("count today smoke logs: %w", err)
}
var resistedCount int64
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).
Count(&resistedCount).Error; err != nil {
return SmokeHomeSummary{}, fmt.Errorf("count resisted logs: %w", err)
}
var yesterdayCount int64
if err := s.db.WithContext(ctx).
Model(&smokemodel.SmokeLog{}).
Where("uid = ? AND (deletetime IS NULL OR deletetime = 0) AND smoke_time = ?", uid, yesterdayKey).
Select("COALESCE(SUM(num), 0)").
Scan(&yesterdayCount).Error; err != nil {
return SmokeHomeSummary{}, fmt.Errorf("count yesterday smoke logs: %w", err)
}
reduced := int(yesterdayCount - todayCount)
if reduced < 0 {
reduced = 0
}
var lastSmokeAt *time.Time
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)").
Order("COALESCE(smoke_at, FROM_UNIXTIME(createtime), smoke_time) DESC").
Order("id DESC").
Limit(1).
Take(&last).Error; err != nil {
if !errors.Is(err, gorm.ErrRecordNotFound) {
return SmokeHomeSummary{}, fmt.Errorf("load last smoke log: %w", err)
}
} else if t, ok := lastEventTime(last); ok {
lastSmokeAt = &t
}
return SmokeHomeSummary{
LastSmokeAt: lastSmokeAt,
TodayCount: int(todayCount),
ResistedCount: int(resistedCount),
ReducedFromYesterday: reduced,
}, nil
}
func (s *SmokeLogService) ListLatest(ctx context.Context, uid int, limit int) ([]smokemodel.SmokeLog, error) {
if limit <= 0 {
limit = 20