修复IMAP邮箱序号计算范围
Some checks are pending
Security Checks / security (push) Waiting to run

This commit is contained in:
smail 2026-09-06 08:10:26 +08:00
parent 1c8a600d79
commit f593c99bbc
2 changed files with 8 additions and 20 deletions

View File

@ -147,7 +147,6 @@ func (s *serverSession) Fetch(w *imapserver.FetchWriter, numSet imap.NumSet, opt
if uidSet.Dynamic() {
var err error
maxUID, err = list.GetMaxUIDByMailbox(s.ctx, s.currentMailbox)
log.WithContext(s.ctx).Infof("IMAP FETCH UID set=%s dynamic=%t max_uid=%d", uidSet.String(), uidSet.Dynamic(), maxUID)
if err != nil {
log.WithContext(s.ctx).WithError(err).Error("query IMAP maximum UID for fetch failed")
return &imap.Error{Type: imap.StatusResponseTypeNo, Text: "Fetch failed"}
@ -166,7 +165,6 @@ func (s *serverSession) Fetch(w *imapserver.FetchWriter, numSet imap.NumSet, opt
end = maxUID
}
}
log.WithContext(s.ctx).Infof("IMAP FETCH UID range start=%d end=%d mailbox=%s", start, end, s.currentMailbox)
emailList, err := list.GetEmailListByGroup(s.ctx, s.currentMailbox, list.ImapListReq{
Star: start,
End: end,
@ -175,7 +173,6 @@ func (s *serverSession) Fetch(w *imapserver.FetchWriter, numSet imap.NumSet, opt
log.WithContext(s.ctx).WithError(err).Error("query IMAP messages for UID fetch failed")
return &imap.Error{Type: imap.StatusResponseTypeNo, Text: "Fetch failed"}
}
log.WithContext(s.ctx).Infof("IMAP FETCH UID result count=%d", len(emailList))
if err := write(s.ctx, w, emailList, options); err != nil {
return err
}
@ -321,7 +318,6 @@ func write(ctx *context.Context, w *imapserver.FetchWriter, emailList []*respons
if options.UID {
writer.WriteUID(uid)
}
log.WithContext(ctx).Infof("IMAP FETCH write sequence=%d uid=%d ue_id=%d", sequence, uid, email.UeId)
if options.Envelope {
env := buildEnvelope(email, traEmail)
writer.WriteEnvelope(env)

View File

@ -140,23 +140,23 @@ func buildIMAPMailboxRelationQuery(ctx *context.Context, groupName string) (stri
if ctx == nil || ctx.UserID <= 0 {
return "", nil, fmt.Errorf("invalid mailbox user")
}
inner := "SELECT id,email_id,is_read,is_deleted,status,ROW_NUMBER() OVER (ORDER BY id) AS serial_number FROM user_email WHERE user_id = ? AND email_id > 0"
relations := "SELECT * FROM user_email WHERE user_id = ? AND email_id > 0"
params := []any{ctx.UserID}
switch groupName {
case "INBOX":
inner += " and status = ? and group_id = 0"
relations += " and status = ? and group_id = 0"
params = append(params, 0)
case "Sent Messages":
inner += " and status = ? and group_id = 0"
relations += " and status = ? and group_id = 0"
params = append(params, 1)
case "Drafts":
inner += " and status = ? and group_id = 0"
relations += " and status = ? and group_id = 0"
params = append(params, 4)
case "Deleted Messages":
inner += " and status = ? and group_id = 0"
relations += " and status = ? and group_id = 0"
params = append(params, 3)
case "Junk":
inner += " and status = ? and group_id = 0"
relations += " and status = ? and group_id = 0"
params = append(params, 5)
default:
var mailbox models.Group
@ -167,10 +167,10 @@ func buildIMAPMailboxRelationQuery(ctx *context.Context, groupName string) (stri
if !found || mailbox.ID == 0 {
return "", nil, fmt.Errorf("mailbox not found")
}
inner += " and group_id = ?"
relations += " and group_id = ?"
params = append(params, mailbox.ID)
}
return inner, params, nil
return "SELECT mailbox_rel.*, ROW_NUMBER() OVER (ORDER BY mailbox_rel.id) AS serial_number FROM (" + relations + ") mailbox_rel", params, nil
}
func GetUEListByUID(ctx *context.Context, groupName string, star, end int, uidList []int) ([]*response.UserEmailUIDData, error) {
@ -270,13 +270,6 @@ func getEmailListByUidList(ctx *context.Context, groupName string, req ImapListR
if err := db.Instance.SQL(sql, params...).Find(&relations); err != nil {
return nil, fmt.Errorf("query mailbox UID list: %w", err)
}
if len(relations) > 0 {
for _, relation := range relations {
if relation != nil {
fmt.Printf("IMAP UID relation id=%d email_id=%d status=%d group_id=%d\n", relation.ID, relation.EmailID, relation.Status, relation.GroupId)
}
}
}
return hydrateIMAPEmailResponses(relations)
}
@ -337,7 +330,6 @@ func hydrateIMAPEmailResponses(relations []*response.UserEmailUIDData) ([]*respo
if err := db.Instance.Table("email").Select("*").Where(Eq{"id": emailIDs}).Find(&stored); err != nil {
return nil, fmt.Errorf("query mailbox messages: %w", err)
}
fmt.Printf("IMAP hydrate email_ids=%v stored=%d\n", emailIDs, len(stored))
messageByID := make(map[int]*response.EmailResponseData, len(stored))
for _, message := range stored {
if message != nil {