159 lines
4.7 KiB
Go
159 lines
4.7 KiB
Go
package email
|
|
|
|
import (
|
|
"encoding/json"
|
|
"net/http"
|
|
"strings"
|
|
"time"
|
|
|
|
"git.pcux.cn/xuans/Smail/db"
|
|
"git.pcux.cn/xuans/Smail/dto/response"
|
|
"git.pcux.cn/xuans/Smail/models"
|
|
"git.pcux.cn/xuans/Smail/utils/context"
|
|
log "github.com/sirupsen/logrus"
|
|
"xorm.io/xorm"
|
|
)
|
|
|
|
type deleteContactRequest struct {
|
|
Email string `json:"email"`
|
|
}
|
|
|
|
type trustSenderRequest struct {
|
|
Email string `json:"email"`
|
|
Trusted bool `json:"trusted"`
|
|
}
|
|
|
|
// ContactsList 查询当前用户的历史写信收件人列表(多租户严格隔离)
|
|
func ContactsList(ctx *context.Context, w http.ResponseWriter, req *http.Request) {
|
|
var contacts []models.UserContact
|
|
err := db.Instance.Table(&models.UserContact{}).
|
|
Where("user_id = ?", ctx.UserID).
|
|
OrderBy("last_used_at DESC").
|
|
Limit(100).
|
|
Find(&contacts)
|
|
if err != nil {
|
|
log.WithContext(ctx).WithError(err).Error("query user contacts failed")
|
|
response.NewErrorResponse(response.ServerError, "获取联系人失败", "").FPrint(w)
|
|
return
|
|
}
|
|
|
|
response.NewSuccessResponse(contacts).FPrint(w)
|
|
}
|
|
|
|
// DeleteContact 删除当前用户的某项历史联系人记录
|
|
func DeleteContact(ctx *context.Context, w http.ResponseWriter, req *http.Request) {
|
|
var reqData deleteContactRequest
|
|
if err := json.NewDecoder(req.Body).Decode(&reqData); err != nil {
|
|
response.NewErrorResponse(response.ParamsError, "参数错误", "").FPrint(w)
|
|
return
|
|
}
|
|
email := strings.ToLower(strings.TrimSpace(reqData.Email))
|
|
if email == "" {
|
|
response.NewErrorResponse(response.ParamsError, "联系人邮箱不能为空", "").FPrint(w)
|
|
return
|
|
}
|
|
|
|
_, err := db.Instance.Table(&models.UserContact{}).
|
|
Where("user_id = ? AND LOWER(email) = ?", ctx.UserID, email).
|
|
Delete(&models.UserContact{})
|
|
if err != nil {
|
|
log.WithContext(ctx).WithError(err).Error("delete user contact failed")
|
|
response.NewErrorResponse(response.ServerError, "删除联系人失败", "").FPrint(w)
|
|
return
|
|
}
|
|
|
|
response.NewSuccessResponse("ok").FPrint(w)
|
|
}
|
|
|
|
// TrustSender 将发件人添加至信任白名单,或从中移除
|
|
func TrustSender(ctx *context.Context, w http.ResponseWriter, req *http.Request) {
|
|
var reqData trustSenderRequest
|
|
if err := json.NewDecoder(req.Body).Decode(&reqData); err != nil {
|
|
response.NewErrorResponse(response.ParamsError, "参数错误", "").FPrint(w)
|
|
return
|
|
}
|
|
email := strings.ToLower(strings.TrimSpace(reqData.Email))
|
|
if email == "" {
|
|
response.NewErrorResponse(response.ParamsError, "发件人邮箱不能为空", "").FPrint(w)
|
|
return
|
|
}
|
|
|
|
if reqData.Trusted {
|
|
var exists bool
|
|
has, err := db.Instance.Table(&models.UserTrustedSender{}).
|
|
Where("user_id = ? AND LOWER(email) = ?", ctx.UserID, email).
|
|
Exist(&models.UserTrustedSender{})
|
|
if err != nil {
|
|
log.WithContext(ctx).WithError(err).Error("check trusted sender failed")
|
|
response.NewErrorResponse(response.ServerError, "操作失败", "").FPrint(w)
|
|
return
|
|
}
|
|
exists = has
|
|
if !exists {
|
|
item := models.UserTrustedSender{
|
|
UserID: ctx.UserID,
|
|
Email: email,
|
|
CreatedAt: time.Now(),
|
|
}
|
|
if _, err := db.Instance.Insert(&item); err != nil {
|
|
log.WithContext(ctx).WithError(err).Error("insert trusted sender failed")
|
|
response.NewErrorResponse(response.ServerError, "添加信任发件人失败", "").FPrint(w)
|
|
return
|
|
}
|
|
}
|
|
} else {
|
|
if _, err := db.Instance.Table(&models.UserTrustedSender{}).
|
|
Where("user_id = ? AND LOWER(email) = ?", ctx.UserID, email).
|
|
Delete(&models.UserTrustedSender{}); err != nil {
|
|
log.WithContext(ctx).WithError(err).Error("remove trusted sender failed")
|
|
response.NewErrorResponse(response.ServerError, "取消信任发件人失败", "").FPrint(w)
|
|
return
|
|
}
|
|
}
|
|
|
|
response.NewSuccessResponse("ok").FPrint(w)
|
|
}
|
|
|
|
// RecordUserContacts 异步批量记录发件成功后的收件人地址
|
|
func RecordUserContacts(userID int, recipients []models.UserContact) {
|
|
if userID <= 0 || len(recipients) == 0 {
|
|
return
|
|
}
|
|
now := time.Now()
|
|
_ = db.Transaction(db.Instance, func(session *xorm.Session) error {
|
|
for _, r := range recipients {
|
|
email := strings.ToLower(strings.TrimSpace(r.Email))
|
|
if email == "" {
|
|
continue
|
|
}
|
|
var existing models.UserContact
|
|
has, err := session.Table(&models.UserContact{}).
|
|
Where("user_id = ? AND LOWER(email) = ?", userID, email).
|
|
Get(&existing)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if has {
|
|
existing.LastUsedAt = now
|
|
if r.Name != "" {
|
|
existing.Name = r.Name
|
|
}
|
|
if _, err := session.ID(existing.ID).Cols("name", "last_used_at").Update(&existing); err != nil {
|
|
return err
|
|
}
|
|
} else {
|
|
item := models.UserContact{
|
|
UserID: userID,
|
|
Email: email,
|
|
Name: r.Name,
|
|
LastUsedAt: now,
|
|
}
|
|
if _, err := session.Insert(&item); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
}
|
|
return nil
|
|
})
|
|
}
|