package echomeet import ( "yunyan/comm" "yunyan/pb" "time" ) // @Summary 获取用户全部会议记录(骨架) // @Description 获取当前用户的全部会议记录。**只回列表要用的骨架字段**,original/translate/summary 不下发, // @Description 详情由 echomeet_getrecord 单条拉取。 // @Tags Echomeet // @Accept json // @Produce json // @Security BearerAuth // @Param user body pb.EchomeetGetAllRecordsReq true "请求数据" // @Success 200 {object} comm.HttpResult{data=pb.EchomeetGetAllRecordsResp} "响应数据" // @Router /api/home/echomeet_getallrecords [post] func (this *apiComp) GetAllRecords(session comm.IUserSession, req *pb.EchomeetGetAllRecordsReq) (resp *pb.EchomeetGetAllRecordsResp, errdata *pb.ErrorData) { var ( records []*pb.DBEchoMeetRecord err error ) uid, errdata := requireUID(session) if errdata != nil { return } // 骨架查询:列表页只需要 title/rtype/state/seconds/audiourl/creationtime, // 而 original/translate/summary 占了每条 97% 的字节(实测 59 条 ≈ 500KB,其中列表用得上的 15KB)。 // 客户端本地 sqlite 是缓存、服务端是真源,详情进页面时再拉整条(echomeet_getrecord)。 if records, err = this.module.model.getrecordbriefforuid(uid); err != nil { errdata = &pb.ErrorData{ Code: pb.ErrorCode_DBError, Message: err.Error(), } return } now := time.Now().Unix() for _, brief := range records { if brief.State != pb.DBEchoMeetRecordState_Transcribing || brief.Taskid == "" { continue } if brief.Lastquerytime > 0 && now-brief.Lastquerytime < TranscribeQueryMinInterval { continue } // ⚠️ **绝不能拿 brief 去 saverecord / PollTranscribe**。 // // records 是 Omit 掉 original/translate/summary 的骨架,这三个字段在结构体里是空串; // 而 mysql.Save 是**整行 UPDATE**,写回去就等于把这三列清空。 // 触发条件不罕见:StartTask 的闸门是 `state>0 && state<5`,已完成(5)/已阅(6)/ // 失败(10001/10002) 都允许「重新转写」,那期间 state=Transcribing 而旧的纪要 // 还在库里 —— 用户这时候切一下语音纪要列表,旧转写和旧总结就没了; // 如果这次转写又失败,那是永久丢失。 // 列表改成骨架查询(2026-09-18)之前这里拿的是全字段,不会有这个问题。 full, ferr := this.module.model.getrecordforuid(uid, brief.Id) if ferr != nil { this.module.Warnf("GetAllRecords id:%d 取整条失败,本轮不轮询转写: %v", brief.Id, ferr) continue } full.Lastquerytime = now this.module.model.saverecord(full) this.module.tasks.PollTranscribe(full) // 让本次响应里的值也是新的(brief 才是要序列化出去的那个) brief.Lastquerytime = now } // ⚠️ 这里刻意**不**调 hideHalfDoneTranscribe:它的判定是 `state 已完成 && Translate==""`, // 而骨架查询根本不带 Translate,每一条都会被判成「半成品」降级回转写中。 // 那个保护是给「客户端从列表响应里解 translate」加的,列表不再带 translate 就没有半成品可解; // 轮询走的 GetRecords / GetRecord 仍是全字段,保护留在那两处。 resp = &pb.EchomeetGetAllRecordsResp{ Records: records, } return }