| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258 |
- package list
- import (
- "fmt"
- "github.com/Jinnrry/pmail/db"
- "github.com/Jinnrry/pmail/dto"
- "github.com/Jinnrry/pmail/dto/response"
- "github.com/Jinnrry/pmail/models"
- "github.com/Jinnrry/pmail/utils/array"
- "github.com/Jinnrry/pmail/utils/context"
- log "github.com/sirupsen/logrus"
- "strings"
- )
- import . "xorm.io/builder"
- func GetEmailList(ctx *context.Context, tagInfo dto.SearchTag, keyword string, pop3List bool, offset, limit int) (emailList []*response.EmailResponseData, total int64) {
- return getList(ctx, tagInfo, keyword, pop3List, offset, limit)
- }
- func getList(ctx *context.Context, tagInfo dto.SearchTag, keyword string, pop3List bool, offset, limit int) (emailList []*response.EmailResponseData, total int64) {
- querySQL, queryParams := genSQL(ctx, false, tagInfo, keyword, pop3List, offset, limit)
- err := db.Instance.SQL(querySQL, queryParams...).Find(&emailList)
- if err != nil {
- log.WithContext(ctx).Errorf("SQL ERROR: %s ,Error:%s", querySQL, err)
- }
- totalSQL, totalParams := genSQL(ctx, true, tagInfo, keyword, pop3List, offset, limit)
- _, err = db.Instance.SQL(totalSQL, totalParams...).Get(&total)
- if err != nil {
- log.WithContext(ctx).Errorf("SQL ERROR: %s ,Error:%s", querySQL, err)
- }
- return emailList, total
- }
- func genSQL(ctx *context.Context, count bool, tagInfo dto.SearchTag, keyword string, pop3List bool, offset, limit int) (string, []any) {
- sqlParams := []any{ctx.UserID}
- sql := "select "
- if count {
- sql += `count(1) from email e left join user_email ue on e.id=ue.email_id where ue.user_id = ? `
- } else if pop3List {
- sql += `e.id,e.size from email e left join user_email ue on e.id=ue.email_id where ue.user_id = ? `
- } else {
- sql += `e.*,ue.is_read from email e left join user_email ue on e.id=ue.email_id where ue.user_id = ? `
- }
- if tagInfo.Status != -1 {
- sql += " and ue.status =? "
- sqlParams = append(sqlParams, tagInfo.Status)
- } else if tagInfo.Status == -1 {
- if tagInfo.Type != 1 {
- sql += " and ue.status = 0"
- }
- }
- if tagInfo.Type != -1 {
- sql += " and type =? "
- sqlParams = append(sqlParams, tagInfo.Type)
- }
- if tagInfo.GroupId != -1 {
- sql += " and ue.group_id=? "
- sqlParams = append(sqlParams, tagInfo.GroupId)
- } else {
- sql += " and ue.group_id=0 "
- }
- if keyword != "" {
- sql += " and (subject like ? or text like ? )"
- sqlParams = append(sqlParams, "%"+keyword+"%", "%"+keyword+"%")
- }
- if limit == 0 {
- limit = 10
- }
- sql += " order by e.id desc"
- if limit < 10000 {
- sql += fmt.Sprintf(" LIMIT %d OFFSET %d ", limit, offset)
- }
- return sql, sqlParams
- }
- type statRes struct {
- Total int64
- Size int64
- }
- // Stat 查询邮件总数和大小
- func Stat(ctx *context.Context) (int64, int64) {
- sql := `select count(1) as total,sum(size) as size from email e left join user_email ue on e.id=ue.email_id where ue.user_id = ? and e.type = 0 and ue.status != 3`
- var ret statRes
- _, err := db.Instance.SQL(sql, ctx.UserID).Get(&ret)
- if err != nil {
- log.WithContext(ctx).Errorf("SQL ERROR: %s ,Error:%s", sql, err)
- }
- return ret.Total, ret.Size
- }
- type ImapListReq struct {
- UidList []int
- Star int
- End int
- }
- func GetUEListByUID(ctx *context.Context, groupName string, star, end int, uidList []int) []*response.UserEmailUIDData {
- var ue []*response.UserEmailUIDData
- sql := "SELECT id,email_id, is_read, ROW_NUMBER() OVER (ORDER BY id) AS serial_number FROM `user_email` WHERE user_id = ? "
- params := []any{ctx.UserID}
- if len(uidList) > 0 {
- sql += fmt.Sprintf(" and id in (%s)", array.Join(uidList, ","))
- }
- if star > 0 {
- sql += " and id >=?"
- params = append(params, star)
- }
- if end > 0 {
- sql += " and id <=?"
- params = append(params, end)
- }
- switch groupName {
- case "INBOX":
- sql += " and status =?"
- params = append(params, 0)
- case "Sent Messages":
- sql += " and status =?"
- params = append(params, 1)
- case "Drafts":
- sql += " and status =?"
- params = append(params, 4)
- case "Deleted Messages":
- sql += " and status =?"
- params = append(params, 3)
- case "Junk":
- sql += " and status =?"
- params = append(params, 5)
- default:
- groupNames := strings.Split(groupName, "/")
- groupName = groupNames[len(groupNames)-1]
- var group models.Group
- db.Instance.Table("group").Where("user_id=? and name=?", ctx.UserID, groupName).Get(&group)
- if group.ID == 0 {
- return nil
- }
- sql += " and group_id = ?"
- params = append(params, group.ID)
- }
- db.Instance.SQL(sql, params...).Find(&ue)
- return ue
- }
- func getEmailListByUidList(ctx *context.Context, groupName string, req ImapListReq, uid bool) []*response.EmailResponseData {
- var ret []*response.EmailResponseData
- var ue []*response.UserEmailUIDData
- sql := fmt.Sprintf("SELECT id,email_id, is_read, ROW_NUMBER() OVER (ORDER BY id) AS serial_number FROM `user_email` WHERE (user_id = ? and id in (%s))", array.Join(req.UidList, ","))
- if req.Star > 0 && req.End != 0 {
- sql = fmt.Sprintf("SELECT id,email_id, is_read, ROW_NUMBER() OVER (ORDER BY id) AS serial_number FROM `user_email` WHERE (user_id = ? and id >=%d and id <= %d)", req.Star, req.End)
- }
- if req.Star > 0 && req.End == 0 {
- sql = fmt.Sprintf("SELECT id,email_id, is_read, ROW_NUMBER() OVER (ORDER BY id) AS serial_number FROM `user_email` WHERE (user_id = ? and id >=%d )", req.Star)
- }
- err := db.Instance.SQL(sql, ctx.UserID).Find(&ue)
- if err != nil {
- log.WithContext(ctx).Errorf("SQL ERROR: %s ,Error:%s", sql, err)
- }
- ueMap := map[int]*response.UserEmailUIDData{}
- var emailIds []int
- for _, email := range ue {
- ueMap[email.EmailID] = email
- emailIds = append(emailIds, email.EmailID)
- }
- _ = db.Instance.Table("email").Select("*").Where(Eq{"id": emailIds}).Find(&ret)
- for i, data := range ret {
- ret[i].IsRead = ueMap[data.Id].IsRead
- ret[i].SerialNumber = ueMap[data.Id].SerialNumber
- ret[i].UeId = ueMap[data.Id].ID
- }
- return ret
- }
- func GetEmailListByGroup(ctx *context.Context, groupName string, req ImapListReq, uid bool) []*response.EmailResponseData {
- if len(req.UidList) == 0 && req.Star == 0 && req.End == 0 {
- return nil
- }
- if uid {
- return getEmailListByUidList(ctx, groupName, req, uid)
- }
- var ret []*response.EmailResponseData
- var ue []*response.UserEmailUIDData
- sql := fmt.Sprintf("SELECT * from (SELECT id,email_id, is_read, ROW_NUMBER() OVER (ORDER BY id) AS serial_number FROM `user_email` WHERE (user_id = ? and status = ? and group_id=0 )) a WHERE serial_number in (%s)", array.Join(req.UidList, ","))
- if req.Star > 0 && req.End == 0 {
- sql = fmt.Sprintf("SELECT * from (SELECT id,email_id, is_read, ROW_NUMBER() OVER (ORDER BY id) AS serial_number FROM `user_email` WHERE (user_id = ? and status = ? and group_id=0 )) a WHERE serial_number >= %d", req.Star)
- }
- if req.Star > 0 && req.End > 0 {
- sql = fmt.Sprintf("SELECT * from (SELECT id,email_id, is_read, ROW_NUMBER() OVER (ORDER BY id) AS serial_number FROM `user_email` WHERE (user_id = ? and status = ? and group_id=0 )) a WHERE serial_number >= %d and serial_number <=%d", req.Star, req.End)
- }
- switch groupName {
- case "INBOX":
- db.Instance.SQL(sql, ctx.UserID, 0).Find(&ue)
- case "Sent Messages":
- db.Instance.SQL(sql, ctx.UserID, 1).Find(&ue)
- case "Drafts":
- db.Instance.SQL(sql, ctx.UserID, 4).Find(&ue)
- case "Deleted Messages":
- db.Instance.SQL(sql, ctx.UserID, 3).Find(&ue)
- case "Junk":
- db.Instance.SQL(sql, ctx.UserID, 5).Find(&ue)
- default:
- groupNames := strings.Split(groupName, "/")
- groupName = groupNames[len(groupNames)-1]
- var group models.Group
- db.Instance.Table("group").Where("user_id=? and name=?", ctx.UserID, groupName).Get(&group)
- if group.ID == 0 {
- return ret
- }
- db.Instance.
- SQL(fmt.Sprintf(
- "SELECT * from (SELECT id,email_id, is_read, ROW_NUMBER() OVER (ORDER BY id) AS serial_number FROM `user_email` WHERE (user_id = ? and group_id = ?)) a WHERE serial_number in (%s)",
- array.Join(req.UidList, ","))).
- Find(&ue, ctx.UserID, group.ID)
- }
- ueMap := map[int]*response.UserEmailUIDData{}
- var emailIds []int
- for _, email := range ue {
- ueMap[email.EmailID] = email
- emailIds = append(emailIds, email.EmailID)
- }
- _ = db.Instance.Table("email").Select("*").Where(Eq{"id": emailIds}).Find(&ret)
- for i, data := range ret {
- ret[i].IsRead = ueMap[data.Id].IsRead
- ret[i].SerialNumber = ueMap[data.Id].SerialNumber
- ret[i].UeId = ueMap[data.Id].ID
- }
- return ret
- }
|