package memory import ( "time" "yunyan/comm" "yunyan/pb" ) // GetReport 取周报/月报 // // period_type 与 period_key 都为空时返回「最近一份未确认的」——用户一个月不开 App // 会攒下 4 份周报 + 1 份月报,一次弹 5 次没人受得了,其余去 memory_listreports 里翻。 // // 顺带承担补偿职责:发现报告卡在 pending/processing 超时就重新入队(容器在 00:30 // 重启一次就够让那一周的报告永远停住,而且不报任何错)。 // // @Summary 取周期报告 // @Description 取指定周期的报告;不指定则返回最近一份未确认的 // @Tags Memory // @Accept json // @Produce json // @Security BearerAuth // @Param data body pb.MemoryGetReportReq true "请求数据" // @Success 200 {object} comm.HttpResult{data=pb.MemoryGetReportResp} "响应数据" // @Router /api/home/memory_getreport [post] func (this *apiComp) GetReport(session comm.IUserSession, req *pb.MemoryGetReportReq) (resp *pb.MemoryGetReportResp, errdata *pb.ErrorData) { uid, errdata := requireUID(session) if errdata != nil { return } var ( rec *pb.DBMemoryReport err error ) if req.PeriodType != "" && req.PeriodKey != "" { rec, err = this.module.model.getReportByPeriod(uid, req.PeriodType, req.PeriodKey) } else { rec, err = this.module.model.latestUnconfirmedReport(uid) } if err != nil { this.module.Errorf("memory_getreport uid:%s err:%v", uid, err) errdata = &pb.ErrorData{Code: pb.ErrorCode_DBError, Message: "查询失败"} return } if rec != nil { // 补偿:卡住的重新入队。重新入队后按「还在生成中」回复,客户端转圈重试即可。 this.module.report.requeueIfStale(rec) switch rec.State { case pb.MemoryReportState_MemoryReportState_Pending, pb.MemoryReportState_MemoryReportState_Processing: errdata = &pb.ErrorData{Code: pb.ErrorCode_MemoryReportNotReady, Message: "报告生成中"} return case pb.MemoryReportState_MemoryReportState_Failed: errdata = &pb.ErrorData{Code: pb.ErrorCode_MemoryReportFailed, Message: rec.ErrorMsg} return } } resp = &pb.MemoryGetReportResp{Report: rec} return } // ConfirmReport 用户确认报告 // @Summary 确认周期报告 // @Description 标记报告为已确认,之后不再主动弹窗 // @Tags Memory // @Accept json // @Produce json // @Security BearerAuth // @Param data body pb.MemoryConfirmReportReq true "请求数据" // @Success 200 {object} comm.HttpResult{data=pb.MemoryConfirmReportResp} "响应数据" // @Router /api/home/memory_confirmreport [post] func (this *apiComp) ConfirmReport(session comm.IUserSession, req *pb.MemoryConfirmReportReq) (resp *pb.MemoryConfirmReportResp, errdata *pb.ErrorData) { uid, errdata := requireUID(session) if errdata != nil { return } rec, err := this.module.model.getReport(req.ReportId) if err != nil { this.module.Errorf("memory_confirmreport uid:%s id:%d err:%v", uid, req.ReportId, err) errdata = &pb.ErrorData{Code: pb.ErrorCode_DBError, Message: "查询失败"} return } // 归属校验:报告 id 是自增的,不校验 uid 等于任何人都能确认别人的报告 if rec == nil || rec.Uid != uid { errdata = &pb.ErrorData{Code: pb.ErrorCode_MemoryReportNotFound, Message: "报告不存在"} return } if !rec.Confirmed { rec.Confirmed = true rec.ConfirmTime = time.Now().Unix() if err := this.module.model.saveReport(rec); err != nil { this.module.Errorf("memory_confirmreport uid:%s id:%d 保存失败 err:%v", uid, req.ReportId, err) errdata = &pb.ErrorData{Code: pb.ErrorCode_DBError, Message: "保存失败"} return } } resp = &pb.MemoryConfirmReportResp{Report: rec} return } // ListReports 历史报告列表 // @Summary 历史报告列表 // @Description 分页列出用户的周报/月报 // @Tags Memory // @Accept json // @Produce json // @Security BearerAuth // @Param data body pb.MemoryListReportsReq true "请求数据" // @Success 200 {object} comm.HttpResult{data=pb.MemoryListReportsResp} "响应数据" // @Router /api/home/memory_listreports [post] func (this *apiComp) ListReports(session comm.IUserSession, req *pb.MemoryListReportsReq) (resp *pb.MemoryListReportsResp, errdata *pb.ErrorData) { uid, errdata := requireUID(session) if errdata != nil { return } recs, total, err := this.module.model.listReports(uid, req.PeriodType, req.Page, req.Size) if err != nil { this.module.Errorf("memory_listreports uid:%s err:%v", uid, err) errdata = &pb.ErrorData{Code: pb.ErrorCode_DBError, Message: "查询失败"} return } resp = &pb.MemoryListReportsResp{Reports: recs, Total: total} return }