group.go 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. package group
  2. import (
  3. "fmt"
  4. "github.com/Jinnrry/pmail/db"
  5. "github.com/Jinnrry/pmail/dto"
  6. "github.com/Jinnrry/pmail/models"
  7. "github.com/Jinnrry/pmail/utils/array"
  8. "github.com/Jinnrry/pmail/utils/context"
  9. "github.com/Jinnrry/pmail/utils/errors"
  10. "github.com/Jinnrry/pmail/utils/utf7"
  11. log "github.com/sirupsen/logrus"
  12. "strings"
  13. )
  14. type GroupItem struct {
  15. Id int `json:"id"`
  16. Label string `json:"label"`
  17. Tag string `json:"tag"`
  18. Children []*GroupItem `json:"children"`
  19. }
  20. func DelGroup(ctx *context.Context, groupId int) (bool, error) {
  21. allGroupIds := getAllChildId(ctx, groupId)
  22. allGroupIds = append(allGroupIds, groupId)
  23. // 开启一个事务
  24. trans := db.Instance.NewSession()
  25. res, err := trans.Exec(db.WithContext(ctx, fmt.Sprintf("delete from `group` where id in (%s) and user_id =?", array.Join(allGroupIds, ","))), ctx.UserID)
  26. if err != nil {
  27. trans.Rollback()
  28. return false, errors.Wrap(err)
  29. }
  30. num, err := res.RowsAffected()
  31. if err != nil {
  32. trans.Rollback()
  33. return false, errors.Wrap(err)
  34. }
  35. _, err = trans.Exec(db.WithContext(ctx, fmt.Sprintf("update email set group_id=0 where group_id in (%s)", array.Join(allGroupIds, ","))))
  36. if err != nil {
  37. trans.Rollback()
  38. return false, errors.Wrap(err)
  39. }
  40. trans.Commit()
  41. return num > 0, nil
  42. }
  43. type id struct {
  44. Id int `db:"id"`
  45. }
  46. func getAllChildId(ctx *context.Context, rootId int) []int {
  47. var ids []id
  48. var ret []int
  49. err := db.Instance.Table("group").Where("parent_id=? and user_id=?", rootId, ctx.UserID).Find(&ids)
  50. if err != nil {
  51. log.WithContext(ctx).Errorf("getAllChildId err: %v", err)
  52. }
  53. for _, item := range ids {
  54. ret = array.Merge(ret, getAllChildId(ctx, item.Id))
  55. ret = append(ret, item.Id)
  56. }
  57. return ret
  58. }
  59. // GetGroupInfoList 获取全部的分组
  60. func GetGroupInfoList(ctx *context.Context) []*GroupItem {
  61. return buildChildren(ctx, 0)
  62. }
  63. // MoveMailToGroup 将某封邮件移动到某个分组中
  64. func MoveMailToGroup(ctx *context.Context, mailId []int, groupId int) bool {
  65. res, err := db.Instance.Exec(db.WithContext(ctx, fmt.Sprintf("update email set group_id=? where id in (%s)", array.Join(mailId, ","))), groupId)
  66. if err != nil {
  67. log.WithContext(ctx).Errorf("SQL Error:%+v", err)
  68. return false
  69. }
  70. rowNum, err := res.RowsAffected()
  71. if err != nil {
  72. log.WithContext(ctx).Errorf("SQL Error:%+v", err)
  73. return false
  74. }
  75. return rowNum > 0
  76. }
  77. func buildChildren(ctx *context.Context, parentId int) []*GroupItem {
  78. var ret []*GroupItem
  79. var rootGroup []*models.Group
  80. err := db.Instance.Table("group").Where("parent_id=? and user_id=?", parentId, ctx.UserID).Find(&rootGroup)
  81. if err != nil {
  82. log.WithContext(ctx).Errorf("SQL Error:%v", err)
  83. }
  84. for _, group := range rootGroup {
  85. ret = append(ret, &GroupItem{
  86. Id: group.ID,
  87. Label: group.Name,
  88. Tag: dto.SearchTag{GroupId: group.ID, Status: -1, Type: -1}.ToString(),
  89. Children: buildChildren(ctx, group.ID),
  90. })
  91. }
  92. return ret
  93. }
  94. func GetGroupList(ctx *context.Context) []*models.Group {
  95. var ret []*models.Group
  96. db.Instance.Table("group").Where("user_id=?", ctx.UserID).Find(&ret)
  97. return ret
  98. }
  99. func hasChildren(ctx *context.Context, id int) bool {
  100. var parent []*models.Group
  101. db.Instance.Table("group").Where("parent_id=?", id).Find(&parent)
  102. return len(parent) > 0
  103. }
  104. func getLayerName(ctx *context.Context, item *models.Group) string {
  105. if item.ParentId == 0 {
  106. return utf7.Encode(item.Name)
  107. }
  108. var parent models.Group
  109. _, _ = db.Instance.Table("group").Where("id=?", item.ParentId).Get(&parent)
  110. return getLayerName(ctx, &parent) + "/" + utf7.Encode(item.Name)
  111. }
  112. func MatchGroup(ctx *context.Context, basePath, template string) []string {
  113. var groups []*models.Group
  114. var ret []string
  115. if basePath == "" {
  116. db.Instance.Table("group").Where("user_id=?", ctx.UserID).Find(&groups)
  117. ret = append(ret, `* LIST (\NoSelect \HasChildren) "/" "[PMail]"`)
  118. ret = append(ret, `* LIST (\HasNoChildren) "/" "INBOX"`)
  119. ret = append(ret, `* LIST (\HasNoChildren) "/" "Sent Messages"`)
  120. ret = append(ret, `* LIST (\HasNoChildren) "/" "Drafts"`)
  121. ret = append(ret, `* LIST (\HasNoChildren) "/" "Deleted Messages"`)
  122. ret = append(ret, `* LIST (\HasNoChildren) "/" "Junk"`)
  123. } else {
  124. var parent *models.Group
  125. db.Instance.Table("group").Where("user_id=? and name=?", ctx.UserID, basePath).Find(&groups)
  126. if parent != nil && parent.ID > 0 {
  127. db.Instance.Table("group").Where("user_id=? and parent_id=?", ctx.UserID, parent.ID).Find(&groups)
  128. }
  129. }
  130. for _, group := range groups {
  131. if hasChildren(ctx, group.ID) {
  132. ret = append(ret, fmt.Sprintf(`* LIST (\HasChildren) "/" "[PMail]/%s"`, getLayerName(ctx, group)))
  133. } else {
  134. ret = append(ret, fmt.Sprintf(`* LIST (\HasNoChildren) "/" "[PMail]/%s"`, getLayerName(ctx, group)))
  135. }
  136. }
  137. return ret
  138. }
  139. func GetGroupStatus(ctx *context.Context, groupName string, params []string) (string, map[string]int) {
  140. retMap := map[string]int{}
  141. if !array.InArray(groupName, []string{"INBOX", "Sent Messages", "Drafts", "Deleted Messages", "Junk"}) {
  142. groupNames := strings.Split(groupName, "/")
  143. groupName = groupNames[len(groupNames)-1]
  144. var group models.Group
  145. db.Instance.Table("group").Where("user_id=? and name=?", ctx.UserID, groupName).Get(&group)
  146. if group.ID == 0 {
  147. ret := ""
  148. for _, param := range params {
  149. if ret != "" {
  150. ret += " "
  151. }
  152. retMap[param] = 0
  153. ret += fmt.Sprintf("%s %d", param, 0)
  154. }
  155. return fmt.Sprintf("(%s)", ret), retMap
  156. }
  157. ret := ""
  158. for _, param := range params {
  159. if ret != "" {
  160. ret += " "
  161. }
  162. var value int
  163. switch param {
  164. case "MESSAGES":
  165. db.Instance.Table("user_email").Select("count(1)").Where("group_id=?", group.ID).Get(&value)
  166. case "UIDNEXT":
  167. db.Instance.Table("email").Select("count(1)").Get(&value)
  168. case "UIDVALIDITY":
  169. value = group.ID
  170. case "UNSEEN":
  171. db.Instance.Table("user_email").Select("count(1)").Where("group_id=? and is_read=0", group.ID).Get(&value)
  172. }
  173. retMap[param] = value
  174. ret += fmt.Sprintf("%s %d", param, value)
  175. }
  176. return fmt.Sprintf("(%s)", ret), retMap
  177. }
  178. ret := ""
  179. for _, param := range params {
  180. if ret != "" {
  181. ret += " "
  182. }
  183. var value int
  184. switch param {
  185. case "MESSAGES":
  186. value = getGroupNum(ctx, groupName, false)
  187. case "UIDNEXT":
  188. db.Instance.Table("email").Select("count(1)").Get(&value)
  189. case "UIDVALIDITY":
  190. value = models.GroupNameToCode[groupName]
  191. case "UNSEEN":
  192. value = getGroupNum(ctx, groupName, true)
  193. default:
  194. continue
  195. }
  196. retMap[param] = value
  197. ret += fmt.Sprintf("%s %d", param, value)
  198. }
  199. if ret == "" {
  200. return "", retMap
  201. }
  202. return fmt.Sprintf("(%s)", ret), retMap
  203. }
  204. func getGroupNum(ctx *context.Context, groupName string, mustUnread bool) int {
  205. var count int
  206. switch groupName {
  207. case "INBOX":
  208. if mustUnread {
  209. db.Instance.Table("user_email").Select("count(1)").Where("user_id=? and status=0 and is_read=0", ctx.UserID).Get(&count)
  210. } else {
  211. db.Instance.Table("user_email").Select("count(1)").Where("user_id=? and status=0", ctx.UserID).Get(&count)
  212. }
  213. case "Sent Messages":
  214. if mustUnread {
  215. count = 0
  216. } else {
  217. db.Instance.Table("user_email").Select("count(1)").Where("user_id=? and status=1", ctx.UserID).Get(&count)
  218. }
  219. case "Drafts":
  220. if mustUnread {
  221. db.Instance.Table("user_email").Select("count(1)").Where("user_id=? and status=4 and is_read=0", ctx.UserID).Get(&count)
  222. } else {
  223. db.Instance.Table("user_email").Select("count(1)").Where("user_id=? and status=4", ctx.UserID).Get(&count)
  224. }
  225. case "Deleted Messages":
  226. if mustUnread {
  227. db.Instance.Table("user_email").Select("count(1)").Where("user_id=? and status=3 and is_read=0", ctx.UserID).Get(&count)
  228. } else {
  229. db.Instance.Table("user_email").Select("count(1)").Where("user_id=? and status=3", ctx.UserID).Get(&count)
  230. }
  231. case "Junk":
  232. if mustUnread {
  233. db.Instance.Table("user_email").Select("count(1)").Where("user_id=? and status=5 and is_read=0", ctx.UserID).Get(&count)
  234. } else {
  235. db.Instance.Table("user_email").Select("count(1)").Where("user_id=? and status=5", ctx.UserID).Get(&count)
  236. }
  237. }
  238. return count
  239. }