| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345 |
- package group
- import (
- errors2 "errors"
- "fmt"
- "github.com/Jinnrry/pmail/consts"
- "github.com/Jinnrry/pmail/db"
- "github.com/Jinnrry/pmail/dto"
- "github.com/Jinnrry/pmail/models"
- "github.com/Jinnrry/pmail/services/del_email"
- "github.com/Jinnrry/pmail/utils/array"
- "github.com/Jinnrry/pmail/utils/context"
- "github.com/Jinnrry/pmail/utils/errors"
- log "github.com/sirupsen/logrus"
- "strings"
- "xorm.io/builder"
- )
- type GroupItem struct {
- Id int `json:"id"`
- Label string `json:"label"`
- Tag string `json:"tag"`
- Children []*GroupItem `json:"children"`
- }
- func CreateGroup(ctx *context.Context, name string, parentId int) (*models.Group, error) {
- // 先查询是否存在
- var group models.Group
- db.Instance.Table("group").Where("name = ? and user_id = ?", name, ctx.UserID).Get(&group)
- if group.ID > 0 {
- return &group, nil
- }
- group.Name = name
- group.ParentId = parentId
- group.UserId = ctx.UserID
- group.FullPath = getLayerName(ctx, &group, true)
- _, err := db.Instance.Insert(&group)
- return &group, err
- }
- func Rename(ctx *context.Context, oldName, newName string) error {
- oldGroupInfo, err := GetGroupByName(ctx, oldName)
- if err != nil {
- return err
- }
- if oldGroupInfo == nil || oldGroupInfo.ID == 0 {
- return errors2.New("group not found")
- }
- oldGroupInfo.Name = newName
- oldGroupInfo.FullPath = getLayerName(ctx, oldGroupInfo, true)
- _, err = db.Instance.ID(oldGroupInfo.ID).Update(oldGroupInfo)
- return err
- }
- func GetGroupByName(ctx *context.Context, name string) (*models.Group, error) {
- var group models.Group
- db.Instance.Table("group").Where("name = ? and user_id = ?", name, ctx.UserID).Get(&group)
- return &group, nil
- }
- func GetGroupByFullPath(ctx *context.Context, fullPath string) (*models.Group, error) {
- var group models.Group
- _, err := db.Instance.Table("group").Where("full_path = ? and user_id = ?", fullPath, ctx.UserID).Get(&group)
- return &group, err
- }
- func DelGroup(ctx *context.Context, groupId int) (bool, error) {
- allGroupIds := getAllChildId(ctx, groupId)
- allGroupIds = append(allGroupIds, groupId)
- // 开启一个事务
- trans := db.Instance.NewSession()
- res, err := trans.Exec(db.WithContext(ctx, fmt.Sprintf("delete from `group` where id in (%s) and user_id =?", array.Join(allGroupIds, ","))), ctx.UserID)
- if err != nil {
- trans.Rollback()
- return false, errors.Wrap(err)
- }
- num, err := res.RowsAffected()
- if err != nil {
- trans.Rollback()
- return false, errors.Wrap(err)
- }
- _, err = trans.Exec(db.WithContext(ctx, fmt.Sprintf("update user_email set group_id=0 where group_id in (%s)", array.Join(allGroupIds, ","))))
- if err != nil {
- trans.Rollback()
- return false, errors.Wrap(err)
- }
- trans.Commit()
- return num > 0, nil
- }
- type id struct {
- Id int `db:"id"`
- }
- func getAllChildId(ctx *context.Context, rootId int) []int {
- var ids []id
- var ret []int
- err := db.Instance.Table("group").Where("parent_id=? and user_id=?", rootId, ctx.UserID).Find(&ids)
- if err != nil {
- log.WithContext(ctx).Errorf("getAllChildId err: %v", err)
- }
- for _, item := range ids {
- ret = array.Merge(ret, getAllChildId(ctx, item.Id))
- ret = append(ret, item.Id)
- }
- return ret
- }
- // GetGroupInfoList 获取全部的分组
- func GetGroupInfoList(ctx *context.Context) []*GroupItem {
- return buildChildren(ctx, 0)
- }
- // MoveMailToGroup 将某封邮件移动到某个分组中
- func MoveMailToGroup(ctx *context.Context, mailId []int, groupId int) bool {
- res, err := db.Instance.Exec(db.WithContext(ctx,
- fmt.Sprintf("update user_email set group_id=? where email_id in (%s) and user_id =?", array.Join(mailId, ","))),
- groupId, ctx.UserID)
- if err != nil {
- log.WithContext(ctx).Errorf("SQL Error:%+v", err)
- return false
- }
- rowNum, err := res.RowsAffected()
- if err != nil {
- log.WithContext(ctx).Errorf("SQL Error:%+v", err)
- return false
- }
- return rowNum > 0
- }
- func buildChildren(ctx *context.Context, parentId int) []*GroupItem {
- var ret []*GroupItem
- var rootGroup []*models.Group
- err := db.Instance.Table("group").Where("parent_id=? and user_id=?", parentId, ctx.UserID).Find(&rootGroup)
- if err != nil {
- log.WithContext(ctx).Errorf("SQL Error:%v", err)
- }
- for _, group := range rootGroup {
- ret = append(ret, &GroupItem{
- Id: group.ID,
- Label: group.Name,
- Tag: dto.SearchTag{GroupId: group.ID, Status: -1, Type: -1}.ToString(),
- Children: buildChildren(ctx, group.ID),
- })
- }
- return ret
- }
- func GetGroupList(ctx *context.Context) []*models.Group {
- var ret []*models.Group
- db.Instance.Table("group").Where("user_id=?", ctx.UserID).Find(&ret)
- return ret
- }
- func hasChildren(ctx *context.Context, id int) bool {
- var parent []*models.Group
- db.Instance.Table("group").Where("parent_id=?", id).Find(&parent)
- return len(parent) > 0
- }
- func getLayerName(ctx *context.Context, item *models.Group, allPath bool) string {
- if item.ParentId == 0 {
- return item.Name
- }
- var parent models.Group
- _, _ = db.Instance.Table("group").Where("id=?", item.ParentId).Get(&parent)
- if allPath {
- return getLayerName(ctx, &parent, allPath) + "/" + item.Name
- }
- return getLayerName(ctx, &parent, allPath)
- }
- func IsDefaultBox(box string) bool {
- return array.InArray(box, []string{"INBOX", "Sent Messages", "Drafts", "Deleted Messages", "Junk"})
- }
- func GetGroupStatus(ctx *context.Context, groupName string, params []string) (string, map[string]int) {
- retMap := map[string]int{}
- if !IsDefaultBox(groupName) {
- 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 {
- ret := ""
- for _, param := range params {
- if ret != "" {
- ret += " "
- }
- retMap[param] = 0
- ret += fmt.Sprintf("%s %d", param, 0)
- }
- return fmt.Sprintf("(%s)", ret), retMap
- }
- ret := ""
- for _, param := range params {
- if ret != "" {
- ret += " "
- }
- var value int
- switch param {
- case "MESSAGES":
- db.Instance.Table("user_email").Select("count(1)").Where("group_id=?", group.ID).Get(&value)
- case "UIDNEXT":
- db.Instance.Table("email").Select("count(1)").Get(&value)
- case "UIDVALIDITY":
- value = group.ID
- case "UNSEEN":
- db.Instance.Table("user_email").Select("count(1)").Where("group_id=? and is_read=0", group.ID).Get(&value)
- }
- retMap[param] = value
- ret += fmt.Sprintf("%s %d", param, value)
- }
- return fmt.Sprintf("(%s)", ret), retMap
- }
- ret := ""
- for _, param := range params {
- if ret != "" {
- ret += " "
- }
- var value int
- switch param {
- case "MESSAGES":
- value = getGroupNum(ctx, groupName, false)
- case "UIDNEXT":
- db.Instance.Table("email").Select("count(1)").Get(&value)
- case "UIDVALIDITY":
- value = models.GroupNameToCode[groupName]
- case "UNSEEN":
- value = getGroupNum(ctx, groupName, true)
- default:
- continue
- }
- retMap[param] = value
- ret += fmt.Sprintf("%s %d", param, value)
- }
- if ret == "" {
- return "", retMap
- }
- return fmt.Sprintf("(%s)", ret), retMap
- }
- func getGroupNum(ctx *context.Context, groupName string, mustUnread bool) int {
- var count int
- switch groupName {
- case "INBOX":
- if mustUnread {
- db.Instance.Table("user_email").Select("count(1)").Where("user_id=? and status=0 and is_read=0", ctx.UserID).Get(&count)
- } else {
- db.Instance.Table("user_email").Select("count(1)").Where("user_id=? and status=0", ctx.UserID).Get(&count)
- }
- case "Sent Messages":
- if mustUnread {
- count = 0
- } else {
- db.Instance.Table("user_email").Select("count(1)").Where("user_id=? and status=1", ctx.UserID).Get(&count)
- }
- case "Drafts":
- if mustUnread {
- db.Instance.Table("user_email").Select("count(1)").Where("user_id=? and status=4 and is_read=0", ctx.UserID).Get(&count)
- } else {
- db.Instance.Table("user_email").Select("count(1)").Where("user_id=? and status=4", ctx.UserID).Get(&count)
- }
- case "Deleted Messages":
- if mustUnread {
- db.Instance.Table("user_email").Select("count(1)").Where("user_id=? and status=3 and is_read=0", ctx.UserID).Get(&count)
- } else {
- db.Instance.Table("user_email").Select("count(1)").Where("user_id=? and status=3", ctx.UserID).Get(&count)
- }
- case "Junk":
- if mustUnread {
- db.Instance.Table("user_email").Select("count(1)").Where("user_id=? and status=5 and is_read=0", ctx.UserID).Get(&count)
- } else {
- db.Instance.Table("user_email").Select("count(1)").Where("user_id=? and status=5", ctx.UserID).Get(&count)
- }
- }
- return count
- }
- func Move2DefaultBox(ctx *context.Context, mailIds []int, groupName string) error {
- switch groupName {
- case "Deleted Messages":
- err := del_email.DelEmail(ctx, mailIds, false)
- if err != nil {
- return err
- }
- case "INBOX":
- _, err := db.Instance.Table(&models.UserEmail{}).Where(builder.Eq{
- "user_id": ctx.UserID,
- "email_id": mailIds,
- }).Update(map[string]interface{}{
- "status": consts.EmailTypeReceive,
- "group_id": 0,
- })
- return err
- case "Sent Messages":
- _, err := db.Instance.Table(&models.UserEmail{}).Where(builder.Eq{
- "user_id": ctx.UserID,
- "email_id": mailIds,
- }).Update(map[string]interface{}{
- "status": consts.EmailStatusSent,
- "group_id": 0,
- })
- return err
- case "Drafts":
- _, err := db.Instance.Table(&models.UserEmail{}).Where(builder.Eq{
- "user_id": ctx.UserID,
- "email_id": mailIds,
- }).Update(map[string]interface{}{
- "status": consts.EmailStatusDrafts,
- "group_id": 0,
- })
- return err
- case "Junk":
- _, err := db.Instance.Table(&models.UserEmail{}).Where(builder.Eq{
- "user_id": ctx.UserID,
- "email_id": mailIds,
- }).Update(map[string]interface{}{
- "status": consts.EmailStatusJunk,
- "group_id": 0,
- })
- return err
- }
- return nil
- }
|