package biz import ( "context" "fmt" "io" "net/http" "os" "strings" "sync" "bkb-notify/internal/conf" "crypto/tls" "net/smtp" "github.com/go-kratos/kratos/v2/log" "github.com/jordan-wright/email" ) // ErrUserNotFound is user not found. // GreeterRepo is a Greater repo. type EmailRepo interface { Send(context.Context, *Greeter) (*Greeter, error) FindByID(context.Context, int64) (*Greeter, error) ListByName(context.Context, string) ([]*Greeter, error) ListAll(context.Context) ([]*Greeter, error) } // EmailUsecase is a Greeter usecase. type EmailUsecase struct { repo GreeterRepo log *log.Helper c *conf.App_Email wg *sync.WaitGroup ch chan int } // NewGreeterUsecase new a Greeter usecase. func NewEmailUsecase(repo GreeterRepo, logger log.Logger, c *conf.App) *EmailUsecase { return &EmailUsecase{repo: repo, log: log.NewHelper(logger), c: c.Email, wg: &sync.WaitGroup{}, ch: make(chan int, 2)} } func (uc *EmailUsecase) SendEmail(to []string, subject string, body string, files []string) (err error) { from := uc.c.Account nickname := uc.c.Sender secret := uc.c.Password host := uc.c.Host port := uc.c.Port //port := 587 isSSL := uc.c.IsSSL auth := smtp.PlainAuth("", from, secret, host) e := email.NewEmail() if nickname != "" { e.From = fmt.Sprintf("%s <%s>", nickname, from) } else { e.From = from } e.Subject = subject e.HTML = []byte(body) hostAddr := fmt.Sprintf("%s:%d", host, port) e.To = to // 创建../docs目录 os.Mkdir("docs", os.ModePerm) // 添加附件 for _, obsUrl := range files { // 下载素材 resp, err := http.Get(obsUrl) if err != nil { log.Log(log.LevelError, "email", err) } defer resp.Body.Close() // 获取URL中的文件名 segments := strings.Split(obsUrl, "/") filename := segments[len(segments)-1] // 创建一个文件用于保存下载的内容 out, err := os.Create("docs/" + filename) if err != nil { log.Log(log.LevelError, "email", err) } defer out.Close() // 将响应流和文件流连接起来 _, err = io.Copy(out, resp.Body) if err != nil { log.Log(log.LevelError, "email", err) } // Attach the file _, err = e.AttachFile("docs/" + filename) if err != nil { log.Log(log.LevelError, "email", err) } // 删除临时文件 err = os.Remove("docs/" + filename) if err != nil { log.Log(log.LevelError, "email", err) } } if isSSL { err = e.SendWithTLS(hostAddr, auth, &tls.Config{ServerName: host}) } else { err = e.Send(hostAddr, auth) } return err } func (uc *EmailUsecase) BulkSendEmail(to []string, subject string, body string) error { from := uc.c.Account nickname := uc.c.Sender secret := uc.c.Password host := uc.c.Host port := uc.c.Port //port := 587 isSSL := uc.c.IsSSL auth := smtp.PlainAuth("", from, secret, host) e := email.NewEmail() if nickname != "" { e.From = fmt.Sprintf("%s <%s>", nickname, from) } else { e.From = from } e.Subject = subject e.HTML = []byte(body) hostAddr := fmt.Sprintf("%s:%d", host, port) var err error var errList []string for _, vTo := range to { e.To = []string{vTo} uc.ch <- 1 uc.wg.Add(1) go func(ve *email.Email) { defer uc.wg.Done() if isSSL { err = e.SendWithTLS(hostAddr, auth, &tls.Config{ServerName: host}) } else { err = e.Send(hostAddr, auth) } if err != nil { errList = append(errList, e.To...) } <-uc.ch }(e) } uc.wg.Wait() if len(errList) > 0 { return fmt.Errorf(fmt.Sprintf("发送失败%d条:%s", len(errList), strings.Join(errList[:3], ","))) } return err }