group.go 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345
  1. package group
  2. import (
  3. errors2 "errors"
  4. "fmt"
  5. "github.com/Jinnrry/pmail/consts"
  6. "github.com/Jinnrry/pmail/db"
  7. "github.com/Jinnrry/pmail/dto"
  8. "github.com/Jinnrry/pmail/models"
  9. "github.com/Jinnrry/pmail/services/del_email"
  10. "github.com/Jinnrry/pmail/utils/array"
  11. "github.com/Jinnrry/pmail/utils/context"
  12. "github.com/Jinnrry/pmail/utils/errors"
  13. log "github.com/sirupsen/logrus"
  14. "strings"
  15. "xorm.io/builder"
  16. )
  17. type GroupItem struct {
  18. Id int `json:"id"`
  19. Label string `json:"label"`
  20. Tag string `json:"tag"`
  21. Children []*GroupItem `json:"children"`
  22. }
  23. func CreateGroup(ctx *context.Context, name string, parentId int) (*models.Group, error) {
  24. // 先查询是否存在
  25. var group models.Group
  26. db.Instance.Table("group").Where("name = ? and user_id = ?", name, ctx.UserID).Get(&group)
  27. if group.ID > 0 {
  28. return &group, nil
  29. }
  30. group.Name = name
  31. group.ParentId = parentId
  32. group.UserId = ctx.UserID
  33. group.FullPath = getLayerName(ctx, &group, true)
  34. _, err := db.Instance.Insert(&group)
  35. return &group, err
  36. }
  37. func Rename(ctx *context.Context, oldName, newName string) error {
  38. oldGroupInfo, err := GetGroupByName(ctx, oldName)
  39. if err != nil {
  40. return err
  41. }
  42. if oldGroupInfo == nil || oldGroupInfo.ID == 0 {
  43. return errors2.New("group not found")
  44. }
  45. oldGroupInfo.Name = newName
  46. oldGroupInfo.FullPath = getLayerName(ctx, oldGroupInfo, true)
  47. _, err = db.Instance.ID(oldGroupInfo.ID).Update(oldGroupInfo)
  48. return err
  49. }
  50. func GetGroupByName(ctx *context.Context, name string) (*models.Group, error) {
  51. var group models.Group
  52. db.Instance.Table("group").Where("name = ? and user_id = ?", name, ctx.UserID).Get(&group)
  53. return &group, nil
  54. }
  55. func GetGroupByFullPath(ctx *context.Context, fullPath string) (*models.Group, error) {
  56. var group models.Group
  57. _, err := db.Instance.Table("group").Where("full_path = ? and user_id = ?", fullPath, ctx.UserID).Get(&group)
  58. return &group, err
  59. }
  60. func DelGroup(ctx *context.Context, groupId int) (bool, error) {
  61. allGroupIds := getAllChildId(ctx, groupId)
  62. allGroupIds = append(allGroupIds, groupId)
  63. // 开启一个事务
  64. trans := db.Instance.NewSession()
  65. res, err := trans.Exec(db.WithContext(ctx, fmt.Sprintf("delete from `group` where id in (%s) and user_id =?", array.Join(allGroupIds, ","))), ctx.UserID)
  66. if err != nil {
  67. trans.Rollback()
  68. return false, errors.Wrap(err)
  69. }
  70. num, err := res.RowsAffected()
  71. if err != nil {
  72. trans.Rollback()
  73. return false, errors.Wrap(err)
  74. }
  75. _, err = trans.Exec(db.WithContext(ctx, fmt.Sprintf("update user_email set group_id=0 where group_id in (%s)", array.Join(allGroupIds, ","))))
  76. if err != nil {
  77. trans.Rollback()
  78. return false, errors.Wrap(err)
  79. }
  80. trans.Commit()
  81. return num > 0, nil
  82. }
  83. type id struct {
  84. Id int `db:"id"`
  85. }
  86. func getAllChildId(ctx *context.Context, rootId int) []int {
  87. var ids []id
  88. var ret []int
  89. err := db.Instance.Table("group").Where("parent_id=? and user_id=?", rootId, ctx.UserID).Find(&ids)
  90. if err != nil {
  91. log.WithContext(ctx).Errorf("getAllChildId err: %v", err)
  92. }
  93. for _, item := range ids {
  94. ret = array.Merge(ret, getAllChildId(ctx, item.Id))
  95. ret = append(ret, item.Id)
  96. }
  97. return ret
  98. }
  99. // GetGroupInfoList 获取全部的分组
  100. func GetGroupInfoList(ctx *context.Context) []*GroupItem {
  101. return buildChildren(ctx, 0)
  102. }
  103. // MoveMailToGroup 将某封邮件移动到某个分组中
  104. func MoveMailToGroup(ctx *context.Context, mailId []int, groupId int) bool {
  105. res, err := db.Instance.Exec(db.WithContext(ctx,
  106. fmt.Sprintf("update user_email set group_id=? where email_id in (%s) and user_id =?", array.Join(mailId, ","))),
  107. groupId, ctx.UserID)
  108. if err != nil {
  109. log.WithContext(ctx).Errorf("SQL Error:%+v", err)
  110. return false
  111. }
  112. rowNum, err := res.RowsAffected()
  113. if err != nil {
  114. log.WithContext(ctx).Errorf("SQL Error:%+v", err)
  115. return false
  116. }
  117. return rowNum > 0
  118. }
  119. func buildChildren(ctx *context.Context, parentId int) []*GroupItem {
  120. var ret []*GroupItem
  121. var rootGroup []*models.Group
  122. err := db.Instance.Table("group").Where("parent_id=? and user_id=?", parentId, ctx.UserID).Find(&rootGroup)
  123. if err != nil {
  124. log.WithContext(ctx).Errorf("SQL Error:%v", err)
  125. }
  126. for _, group := range rootGroup {
  127. ret = append(ret, &GroupItem{
  128. Id: group.ID,
  129. Label: group.Name,
  130. Tag: dto.SearchTag{GroupId: group.ID, Status: -1, Type: -1}.ToString(),
  131. Children: buildChildren(ctx, group.ID),
  132. })
  133. }
  134. return ret
  135. }
  136. func GetGroupList(ctx *context.Context) []*models.Group {
  137. var ret []*models.Group
  138. db.Instance.Table("group").Where("user_id=?", ctx.UserID).Find(&ret)
  139. return ret
  140. }
  141. func hasChildren(ctx *context.Context, id int) bool {
  142. var parent []*models.Group
  143. db.Instance.Table("group").Where("parent_id=?", id).Find(&parent)
  144. return len(parent) > 0
  145. }
  146. func getLayerName(ctx *context.Context, item *models.Group, allPath bool) string {
  147. if item.ParentId == 0 {
  148. return item.Name
  149. }
  150. var parent models.Group
  151. _, _ = db.Instance.Table("group").Where("id=?", item.ParentId).Get(&parent)
  152. if allPath {
  153. return getLayerName(ctx, &parent, allPath) + "/" + item.Name
  154. }
  155. return getLayerName(ctx, &parent, allPath)
  156. }
  157. func IsDefaultBox(box string) bool {
  158. return array.InArray(box, []string{"INBOX", "Sent Messages", "Drafts", "Deleted Messages", "Junk"})
  159. }
  160. func GetGroupStatus(ctx *context.Context, groupName string, params []string) (string, map[string]int) {
  161. retMap := map[string]int{}
  162. if !IsDefaultBox(groupName) {
  163. groupNames := strings.Split(groupName, "/")
  164. groupName = groupNames[len(groupNames)-1]
  165. var group models.Group
  166. db.Instance.Table("group").Where("user_id=? and name=?", ctx.UserID, groupName).Get(&group)
  167. if group.ID == 0 {
  168. ret := ""
  169. for _, param := range params {
  170. if ret != "" {
  171. ret += " "
  172. }
  173. retMap[param] = 0
  174. ret += fmt.Sprintf("%s %d", param, 0)
  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. db.Instance.Table("user_email").Select("count(1)").Where("group_id=?", group.ID).Get(&value)
  187. case "UIDNEXT":
  188. db.Instance.Table("email").Select("count(1)").Get(&value)
  189. case "UIDVALIDITY":
  190. value = group.ID
  191. case "UNSEEN":
  192. db.Instance.Table("user_email").Select("count(1)").Where("group_id=? and is_read=0", group.ID).Get(&value)
  193. }
  194. retMap[param] = value
  195. ret += fmt.Sprintf("%s %d", param, value)
  196. }
  197. return fmt.Sprintf("(%s)", ret), retMap
  198. }
  199. ret := ""
  200. for _, param := range params {
  201. if ret != "" {
  202. ret += " "
  203. }
  204. var value int
  205. switch param {
  206. case "MESSAGES":
  207. value = getGroupNum(ctx, groupName, false)
  208. case "UIDNEXT":
  209. db.Instance.Table("email").Select("count(1)").Get(&value)
  210. case "UIDVALIDITY":
  211. value = models.GroupNameToCode[groupName]
  212. case "UNSEEN":
  213. value = getGroupNum(ctx, groupName, true)
  214. default:
  215. continue
  216. }
  217. retMap[param] = value
  218. ret += fmt.Sprintf("%s %d", param, value)
  219. }
  220. if ret == "" {
  221. return "", retMap
  222. }
  223. return fmt.Sprintf("(%s)", ret), retMap
  224. }
  225. func getGroupNum(ctx *context.Context, groupName string, mustUnread bool) int {
  226. var count int
  227. switch groupName {
  228. case "INBOX":
  229. if mustUnread {
  230. db.Instance.Table("user_email").Select("count(1)").Where("user_id=? and status=0 and is_read=0", ctx.UserID).Get(&count)
  231. } else {
  232. db.Instance.Table("user_email").Select("count(1)").Where("user_id=? and status=0", ctx.UserID).Get(&count)
  233. }
  234. case "Sent Messages":
  235. if mustUnread {
  236. count = 0
  237. } else {
  238. db.Instance.Table("user_email").Select("count(1)").Where("user_id=? and status=1", ctx.UserID).Get(&count)
  239. }
  240. case "Drafts":
  241. if mustUnread {
  242. db.Instance.Table("user_email").Select("count(1)").Where("user_id=? and status=4 and is_read=0", ctx.UserID).Get(&count)
  243. } else {
  244. db.Instance.Table("user_email").Select("count(1)").Where("user_id=? and status=4", ctx.UserID).Get(&count)
  245. }
  246. case "Deleted Messages":
  247. if mustUnread {
  248. db.Instance.Table("user_email").Select("count(1)").Where("user_id=? and status=3 and is_read=0", ctx.UserID).Get(&count)
  249. } else {
  250. db.Instance.Table("user_email").Select("count(1)").Where("user_id=? and status=3", ctx.UserID).Get(&count)
  251. }
  252. case "Junk":
  253. if mustUnread {
  254. db.Instance.Table("user_email").Select("count(1)").Where("user_id=? and status=5 and is_read=0", ctx.UserID).Get(&count)
  255. } else {
  256. db.Instance.Table("user_email").Select("count(1)").Where("user_id=? and status=5", ctx.UserID).Get(&count)
  257. }
  258. }
  259. return count
  260. }
  261. func Move2DefaultBox(ctx *context.Context, mailIds []int, groupName string) error {
  262. switch groupName {
  263. case "Deleted Messages":
  264. err := del_email.DelEmail(ctx, mailIds, false)
  265. if err != nil {
  266. return err
  267. }
  268. case "INBOX":
  269. _, err := db.Instance.Table(&models.UserEmail{}).Where(builder.Eq{
  270. "user_id": ctx.UserID,
  271. "email_id": mailIds,
  272. }).Update(map[string]interface{}{
  273. "status": consts.EmailTypeReceive,
  274. "group_id": 0,
  275. })
  276. return err
  277. case "Sent Messages":
  278. _, err := db.Instance.Table(&models.UserEmail{}).Where(builder.Eq{
  279. "user_id": ctx.UserID,
  280. "email_id": mailIds,
  281. }).Update(map[string]interface{}{
  282. "status": consts.EmailStatusSent,
  283. "group_id": 0,
  284. })
  285. return err
  286. case "Drafts":
  287. _, err := db.Instance.Table(&models.UserEmail{}).Where(builder.Eq{
  288. "user_id": ctx.UserID,
  289. "email_id": mailIds,
  290. }).Update(map[string]interface{}{
  291. "status": consts.EmailStatusDrafts,
  292. "group_id": 0,
  293. })
  294. return err
  295. case "Junk":
  296. _, err := db.Instance.Table(&models.UserEmail{}).Where(builder.Eq{
  297. "user_id": ctx.UserID,
  298. "email_id": mailIds,
  299. }).Update(map[string]interface{}{
  300. "status": consts.EmailStatusJunk,
  301. "group_id": 0,
  302. })
  303. return err
  304. }
  305. return nil
  306. }