package english_report import ( "encoding/json" "eta/eta_api/controllers" "eta/eta_api/models" "eta/eta_api/models/company" "eta/eta_api/services" "eta/eta_api/services/alarm_msg" "eta/eta_api/utils" "fmt" "os" "path" "strconv" "strings" "time" "github.com/beego/beego/v2/server/web" "github.com/rdlucklib/rdluck_tools/paging" "github.com/tealeg/xlsx" ) // EnglishReportEmailController 英文研报邮箱/英文客户联系人 type EnglishReportEmailController struct { controllers.BaseAuthController } type EnglishReportEmailCallBackController struct { web.Controller } // List // @Title 英文研报邮箱列表 // @Description 英文研报邮箱列表 // @Param CompanyId query int false "客户ID" // @Param Keywords query string false "关键词:联系人名称/邮箱地址" // @Param SortType query int false "点击量排序方式:1-倒序;2-正序" // @Param SortParam query int false "排序字段:1-点击量;2-点击时间 3-用户状态" // @Param ListParam query int false "筛选字段参数,用来筛选的字段, 枚举值:1:正式 、 2:临时 、 3:终止 、4:正式+临时 " // @Success 200 {object} models.EnglishReportEmailPageListResp // @router /email/list [get] func (this *EnglishReportEmailController) List() { br := new(models.BaseResponse).Init() br.IsSendEmail = false defer func() { this.Data["json"] = br this.ServeJSON() }() sysUser := this.SysUser if sysUser == nil { br.Msg = "请登录" br.ErrMsg = "请登录,SysUser Is Empty" br.Ret = 408 return } companyId, _ := this.GetInt("CompanyId", 0) keywords := this.GetString("Keywords", "") sortType, _ := this.GetInt("SortType", 1) sortParam, _ := this.GetInt("SortParam", 1) listParam, _ := this.GetInt("ListParam", 1) var cond, order string var pars []interface{} if companyId > 0 { cond += ` AND a.company_id = ?` pars = append(pars, companyId) } if keywords != "" { k := "%" + keywords + "%" cond += ` AND (a.name LIKE ? OR a.email LIKE ? OR a.mobile LIKE ?)` pars = append(pars, k, k, k) } sortParamArr := []int{1, 2, 3} sortTypeArr := []int{1, 2} if utils.InArrayByInt(sortParamArr, sortParam) && utils.InArrayByInt(sortTypeArr, sortType) { pMap := map[int]string{1: "a.view_total", 2: "a.last_view_time", 3: "a.enabled"} tMap := map[int]string{1: "DESC", 2: "ASC"} order = fmt.Sprintf(` ORDER BY %s %s`, pMap[sortParam], tMap[sortType]) } if listParam == 1 { cond += ` AND a.status = 1` } if listParam == 2 { cond += ` AND a.status = 2` } if listParam == 3 { cond += ` AND a.status = 3` } if listParam == 4 { cond += ` AND (a.status = 1 OR a.status = 2)` } var startSize int pageSize, _ := this.GetInt("PageSize") currentIndex, _ := this.GetInt("CurrentIndex") if pageSize <= 0 { pageSize = utils.PageSize20 } if currentIndex <= 0 { currentIndex = 1 } startSize = paging.StartIndex(currentIndex, pageSize) total, list, e := models.GetEnglishReportEmailPageList(cond, pars, order, startSize, pageSize) if e != nil { br.Msg = "获取失败" br.ErrMsg = "获取邮箱列表失败, Err: " + e.Error() return } respList := make([]*models.EnglishReportEmailResp, 0) for i := range list { item := &models.EnglishReportEmailResp{ Id: list[i].Id, Name: list[i].Name, Email: list[i].Email, Mobile: list[i].Mobile, CountryCode: list[i].CountryCode, BusinessCardUrl: list[i].BusinessCardUrl, AdminName: list[i].AdminName, CreateTime: list[i].CreateTime.Format(utils.FormatDateTime), ViewTotal: list[i].ViewTotal, Enabled: list[i].Enabled, CompanyName: list[i].CompanyName, RegisterCompanyName: list[i].RegisterCompanyName, RegisterTime: list[i].RegisterTime.Format(utils.FormatDateTime), } if item.RegisterTime == "0001-01-01 00:00:00" { item.RegisterTime = "" } respList = append(respList, item) } page := paging.GetPaging(currentIndex, pageSize, total) resp := &models.EnglishReportEmailPageListResp{ Paging: page, List: respList, } br.Ret = 200 br.Success = true br.Msg = "获取成功" br.Data = resp } // Save // @Title 保存英文研报邮箱 // @Description 保存英文研报邮箱 // @Param request body models.EnglishReportEmailSaveReq true "type json string" // @Success 200 string "操作成功" // @router /email/save [post] func (this *EnglishReportEmailController) Save() { br := new(models.BaseResponse).Init() br.IsSendEmail = false defer func() { this.Data["json"] = br this.ServeJSON() }() sysUser := this.SysUser if sysUser == nil { br.Msg = "请登录" br.ErrMsg = "请登录,SysUser Is Empty" br.Ret = 408 return } var req models.EnglishReportEmailSaveReq if err := json.Unmarshal(this.Ctx.Input.RequestBody, &req); err != nil { br.Msg = "参数解析异常!" br.ErrMsg = "参数解析失败,Err:" + err.Error() return } if req.Name == "" { br.Msg = "请输入客户名称" return } req.Email = strings.Replace(req.Email, " ", "", -1) if req.Email == "" { br.Msg = "请输入邮箱" return } if !utils.ValidateEmailFormatat(req.Email) { br.Msg = "邮箱格式有误" return } // 英文客户以邮箱为主, 邮箱去重, 手机号非必填, 此处不做手机号去重 exist, e := models.GetEnglishReportEmailByEmail(req.Email) if e != nil && e.Error() != utils.ErrNoRow() { br.Msg = "保存失败" br.ErrMsg = "获取同名邮箱失败, Err:" + e.Error() return } opType := 0 now := time.Now().Local() item := new(models.EnglishReportEmail) if req.Id > 0 { // 更新 if exist != nil && exist.Id != req.Id { br.Msg = "该邮箱已存在" return } if exist != nil { createTime, _ := time.Parse(utils.FormatDateTime, exist.CreateTime) modifyTime, _ := time.Parse(utils.FormatDateTime, exist.ModifyTime) item = &models.EnglishReportEmail{ Id: exist.Id, CompanyId: exist.CompanyId, Name: exist.Name, Email: exist.Email, Mobile: exist.Mobile, CountryCode: exist.CountryCode, BusinessCardUrl: exist.BusinessCardUrl, ViewTotal: exist.ViewTotal, LastViewTime: exist.LastViewTime, IsDeleted: exist.IsDeleted, Enabled: exist.Enabled, AdminId: exist.AdminId, AdminName: exist.AdminName, Status: exist.Status, CompanyName: exist.CompanyName, CreateTime: createTime, ModifyTime: modifyTime, } } else { em, e := models.GetEnglishReportEmailById(req.Id) if e != nil { br.Msg = "保存失败" br.ErrMsg = "获取邮箱失败, Err:" + e.Error() return } item = em } item.Name = req.Name item.Email = req.Email item.Mobile = req.Mobile item.CountryCode = req.CountryCode item.BusinessCardUrl = req.BusinessCardUrl item.ModifyTime = now item.Enabled = req.Enabled updateCols := []string{"Name", "Email", "Mobile", "CountryCode", "BusinessCardUrl", "ModifyTime", "Enabled"} if e = item.Update(updateCols); e != nil { br.Msg = "保存失败" br.ErrMsg = "更新邮箱失败, Err:" + e.Error() return } opType = models.EnglishReportEmailOpLogTypeEdit } else { // 新增 if exist != nil { respItem := &models.EnglishReportEmailResp{ Id: exist.Id, Name: exist.Name, Email: exist.Email, Mobile: exist.Mobile, CountryCode: exist.CountryCode, BusinessCardUrl: exist.BusinessCardUrl, AdminName: exist.AdminName, CreateTime: exist.CreateTime, ViewTotal: exist.ViewTotal, Enabled: exist.Enabled, CompanyName: exist.CompanyName, Status: exist.Status, RegisterCompanyName: exist.RegisterCompanyName, RegisterTime: exist.RegisterTime, } if respItem.RegisterTime == "0001-01-01 00:00:00" { respItem.RegisterCompanyName = "" } br.Data = respItem br.Msg = "该邮箱已存在" br.Ret = 1001 return } item = &models.EnglishReportEmail{ CompanyId: req.CompanyId, Name: req.Name, Email: req.Email, Mobile: req.Mobile, CountryCode: req.CountryCode, BusinessCardUrl: req.BusinessCardUrl, AdminId: sysUser.AdminId, AdminName: sysUser.AdminName, CreateTime: now, ModifyTime: now, Enabled: req.Enabled, Status: 1, } if e = item.Create(); e != nil { br.Msg = "保存失败" br.ErrMsg = "新增邮箱失败, Err:" + e.Error() return } opType = models.EnglishReportEmailOpLogTypeAdd } // 更新客户状态 go func() { _ = services.UpdateEnglishCompanyEnabledByCompanyId(item.CompanyId) }() // 记录日志 go func() { opByte, e := json.Marshal(req) if e != nil { return } opData := string(opByte) opLog := &models.EnglishReportEmailOpLog{ CompanyId: item.CompanyId, EmailId: item.Id, AdminId: sysUser.AdminId, OptionData: opData, OptionType: opType, CreateTime: now, } if e = opLog.Create(); e != nil { return } }() br.Ret = 200 br.Success = true br.Msg = "操作成功" //br.Data = item } // Del // @Title 删除英文研报邮箱 // @Description 删除英文研报邮箱 // @Param request body models.EnglishReportEmailDelReq true "type json string" // @Success 200 string "操作成功" // @router /email/del [post] func (this *EnglishReportEmailController) Del() { br := new(models.BaseResponse).Init() br.IsSendEmail = false defer func() { this.Data["json"] = br this.ServeJSON() }() sysUser := this.SysUser if sysUser == nil { br.Msg = "请登录" br.ErrMsg = "请登录,SysUser Is Empty" br.Ret = 408 return } var req models.EnglishReportEmailDelReq if err := json.Unmarshal(this.Ctx.Input.RequestBody, &req); err != nil { br.Msg = "参数解析异常!" br.ErrMsg = "参数解析失败,Err:" + err.Error() return } if req.EmailId <= 0 { br.Msg = "参数有误" return } item, e := models.GetEnglishReportEmailById(req.EmailId) if e != nil { br.Msg = "联系人已被删除, 请勿重复操作" return } nowTime := time.Now().Local() item.IsDeleted = 1 item.ModifyTime = nowTime updateCols := []string{"IsDeleted", "ModifyTime"} if e = item.Update(updateCols); e != nil { br.Msg = "删除失败" br.ErrMsg = "删除英文联系人失败, Err:" + e.Error() return } // 更新客户状态 go func() { _ = services.UpdateEnglishCompanyEnabledByCompanyId(item.CompanyId) }() // 记录日志 go func() { opByte, e := json.Marshal(req) if e != nil { return } opData := string(opByte) opLog := &models.EnglishReportEmailOpLog{ CompanyId: item.CompanyId, EmailId: item.Id, AdminId: sysUser.AdminId, OptionData: opData, OptionType: models.EnglishReportEmailOpLogTypeDel, CreateTime: nowTime, } if e = opLog.Create(); e != nil { return } }() br.Ret = 200 br.Success = true br.Msg = "操作成功" } // EditEnabled // @Title 启用/禁用英文研报邮箱 // @Description 启用/禁用英文研报邮箱 // @Param request body models.EnglishReportEditEnabledReq true "type json string" // @Success 200 string "操作成功" // @router /email/editEnabled [post] func (this *EnglishReportEmailController) EditEnabled() { br := new(models.BaseResponse).Init() br.IsSendEmail = false defer func() { this.Data["json"] = br this.ServeJSON() }() sysUser := this.SysUser if sysUser == nil { br.Msg = "请登录" br.ErrMsg = "请登录,SysUser Is Empty" br.Ret = 408 return } var req models.EnglishReportEditEnabledReq if err := json.Unmarshal(this.Ctx.Input.RequestBody, &req); err != nil { br.Msg = "参数解析异常!" br.ErrMsg = "参数解析失败,Err:" + err.Error() return } if req.EmailId <= 0 { br.Msg = "参数有误" return } if req.Enabled != 0 && req.Enabled != 1 { br.Msg = "参数有误" return } item, e := models.GetEnglishReportEmailById(req.EmailId) if e != nil { br.Msg = "联系人已被删除, 请勿操作" return } if item.Enabled == req.Enabled { br.Ret = 200 br.Success = true br.Msg = "操作成功" return } // 更新联系人 nowTime := time.Now().Local() item.Enabled = req.Enabled item.ModifyTime = nowTime updateCols := []string{"Enabled", "ModifyTime"} if e = item.Update(updateCols); e != nil { br.Msg = "操作失败" br.ErrMsg = "更新英文联系人失败, Err:" + e.Error() return } // 更新所属客户状态 go func() { _ = services.UpdateEnglishCompanyEnabledByCompanyId(item.CompanyId) }() // 记录日志 go func() { opByte, e := json.Marshal(req) if e != nil { return } opData := string(opByte) opLog := &models.EnglishReportEmailOpLog{ CompanyId: item.CompanyId, EmailId: item.Id, AdminId: sysUser.AdminId, OptionData: opData, OptionType: models.EnglishReportEmailOpLogTypeEditEnabled, CreateTime: nowTime, } if e = opLog.Create(); e != nil { return } }() br.Ret = 200 br.Success = true br.Msg = "操作成功" } // Send // @Title 群发推送 // @Description 群发推送 // @Param request body models.EnglishReportEmailSaveReq true "type json string" // @Success 200 string "操作成功" // @router /email/send [post] func (this *EnglishReportEmailController) Send() { br := new(models.BaseResponse).Init() br.IsSendEmail = false defer func() { this.Data["json"] = br this.ServeJSON() }() sysUser := this.SysUser if sysUser == nil { br.Msg = "请登录" br.ErrMsg = "请登录,SysUser Is Empty" br.Ret = 408 return } var req models.EnglishReportEmailSendReq if err := json.Unmarshal(this.Ctx.Input.RequestBody, &req); err != nil { br.Msg = "参数解析异常!" br.ErrMsg = "参数解析失败,Err:" + err.Error() return } if req.ReportId <= 0 { br.Msg = "请选择报告" return } if req.Theme == "" { br.Msg = "请输入邮件主题" return } //prefixTheme := "【HI China Macro and Commodity】" //if !strings.Contains(req.Theme, prefixTheme) { // req.Theme = prefixTheme + req.Theme //} runeThe := []rune(req.Theme) if len(runeThe) > 100 { br.Msg = "邮件主题不可超过100字符" return } // 获取报告信息 reportInfo, e := models.GetEnglishReportItemById(req.ReportId) if e != nil { br.Msg = "报告信息有误" br.ErrMsg = "获取报告信息失败, Err: " + e.Error() return } if reportInfo.EmailState != 0 { br.Msg = "请勿重复发送" br.ErrMsg = fmt.Sprintf("报告群发邮件状态有误, 当前状态: %d", reportInfo.EmailState) return } if reportInfo.State != 2 { br.Msg = "报告未发布" br.ErrMsg = fmt.Sprintf("报告状态有误, 当前状态: %d", reportInfo.State) return } if reportInfo.Title == "" { br.Msg = "报告标题有误" br.ErrMsg = "报告标题为空, 不可推送" return } if reportInfo.Content == `` { br.Msg = "报告内容有误" br.ErrMsg = "报告内容为空, 不可推送" return } // 获取邮件配置 conf := new(models.EnglishReportEmailConf) authKey := "english_report_email_conf" confAuth, e := company.GetConfigDetailByCode(authKey) if e != nil { br.Msg = "无权操作" br.ErrMsg = "获取群发邮件权限失败, Err: " + e.Error() return } if confAuth.ConfigValue == "" { br.Msg = "无权操作" br.ErrMsg = "群发邮件配置为空" return } if e := json.Unmarshal([]byte(confAuth.ConfigValue), &conf); e != nil { br.Msg = "无权操作" br.ErrMsg = "群发邮件配置有误" return } authArr := strings.Split(conf.SendAuthGroup, ",") if !utils.InArrayByStr(authArr, sysUser.RoleTypeCode) { br.Msg = "无权操作" return } noCompanyIdsMap := make(map[int]struct{}) if len(req.NoCompanyIds) > 0 { for _, v := range req.NoCompanyIds { noCompanyIdsMap[v] = struct{}{} } } // 指定品种的客户 sendCompanyIds := make([]int, 0) if len(req.EnPermissions) > 0 { companyIds, e := models.GetEnglishCompanyIdsByEnPermissionIds(req.EnPermissions) if e != nil { br.Msg = "推送失败" br.ErrMsg = "获取指定品种的客户IDs失败, Err: " + e.Error() return } for _, v := range companyIds { if _, ok := noCompanyIdsMap[v]; !ok { sendCompanyIds = append(sendCompanyIds, v) } } } // 指定收件人列表 sendEmailIds := make([]int, 0) if req.EmailIds != "" { emailIdArr := strings.Split(req.EmailIds, ",") if len(emailIdArr) == 0 { br.Msg = "指定收件人列表有误" br.ErrMsg = fmt.Sprintf("收件人列表为空, 收件人IDs: %s", req.EmailIds) return } for _, m := range emailIdArr { v, _ := strconv.Atoi(m) sendEmailIds = append(sendEmailIds, v) } } if len(sendCompanyIds) == 0 && len(sendEmailIds) == 0 { br.Msg = "收件人列表为空(或收件人账号被禁用)" br.ErrMsg = "收件人列表为空, 不可推送" return } // 往正式客户id里面插入0的 目的是为了把临时客户找出来 sendCompanyIds = append(sendCompanyIds, 0) emailCond := " AND enabled = 1 AND status <> 3" emailPars := make([]interface{}, 0) if len(sendCompanyIds) > 0 && len(sendEmailIds) > 0 { emailCond += ` AND (company_id IN (` + utils.GetOrmInReplace(len(sendCompanyIds)) + `) OR id IN (` + utils.GetOrmInReplace(len(sendEmailIds)) + `))` emailPars = append(emailPars, sendCompanyIds) emailPars = append(emailPars, sendEmailIds) } if len(sendCompanyIds) > 0 && len(sendEmailIds) == 0 { emailCond += ` AND company_id IN (` + utils.GetOrmInReplace(len(sendCompanyIds)) + `)` emailPars = append(emailPars, sendCompanyIds) } emails, e := models.GetEnglishReportEmailList(emailCond, emailPars, "") if e != nil { br.Msg = "获取收件人列表失败" br.ErrMsg = "获取收件人列表失败, Err: " + e.Error() return } if len(emails) == 0 { br.Msg = "收件人列表为空(或收件人账号被禁用)" br.ErrMsg = "收件人列表为空, 不可推送" return } // 获取模板 confKey := "english_report_email_tmp" confTmp, e := company.GetConfigDetailByCode(confKey) if e != nil { br.Msg = "获取邮件模板失败" br.ErrMsg = "获取邮件模板失败, Err: " + e.Error() return } if confTmp.ConfigValue == `` { br.Msg = "邮件模板有误" br.ErrMsg = "邮件模板为空, 不可推送" return } // 同一篇报告避免重复推送给同一个邮件 var cond string var pars []interface{} cond += ` AND report_id = ? AND send_status = 1 AND report_type = 0` pars = append(pars, req.ReportId) logs, e := models.GetEnglishReportEmailLogList(cond, pars) if e != nil { br.Msg = "推送失败" br.ErrMsg = "获取邮件发送日志列表失败, Err: " + e.Error() return } repeatMap := make(map[int]bool, 0) for i := range logs { if logs[i].SendStatus == 1 { repeatMap[logs[i].EmailId] = true } } // 推送信息 nowTime := time.Now().Local() sendData := make([]*services.EnglishReportSendEmailRequest, 0) logData := make([]*models.EnglishReportEmailLog, 0) for i := range emails { if repeatMap[emails[i].Id] { continue } r := new(services.EnglishReportSendEmailRequest) r.ReportId = reportInfo.Id r.EmailId = emails[i].Id r.Email = strings.Replace(emails[i].Email, " ", "", -1) r.Subject = req.Theme r.FromAlias = conf.FromAlias // 获取报告Overview部分 if reportInfo.Overview == "" { br.Msg = "报告Overview部分不可为空" return } overview := reportInfo.Overview // 填充模板 t := reportInfo.PublishTime.Format("02/01/2006") l := fmt.Sprintf(utils.EnglishShareUrl+"/report/detail?code=%s", reportInfo.ReportCode) ct := confTmp.ConfigValue ct = strings.Replace(ct, "{{REPORT_TITLE}}", reportInfo.Title, 1) ct = strings.Replace(ct, "{{REPORT_ABSTRACT}}", reportInfo.Abstract, 1) ct = strings.Replace(ct, "{{REPORT_CONTENT}}", overview, 1) ct = strings.Replace(ct, "{{REPORT_SHARE_LINK}}", l, 1) ct = strings.Replace(ct, "{{REPORT_TIME}}", t, 1) r.HtmlBody = ct r.ReportTitle = reportInfo.Title r.ReportAbstract = reportInfo.Abstract r.ReportContent = overview r.ReportShareLink = l r.ReportTime = t logItem := &models.EnglishReportEmailLog{ ReportId: reportInfo.Id, EmailId: emails[i].Id, Email: emails[i].Email, Source: models.EnglishReportEmailLogSourceAli, SendStatus: models.EnglishReportEmailLogStatusIng, CreateTime: nowTime, } r.EmailLog = logItem sendData = append(sendData, r) // 日志 logData = append(logData, logItem) } if len(sendData) == 0 { br.Msg = "无邮件可推送" return } // 写入日志 for _, v := range logData { if e = v.Create(); e != nil { br.Msg = "操作失败" br.ErrMsg = "写入群发邮件日志失败, Err: " + e.Error() return } } //emailLog := new(models.EnglishReportEmailLog) //if e = emailLog.InsertMulti(logData); e != nil { // br.Msg = "操作失败" // br.ErrMsg = "批量写入群发邮件日志失败, Err: " + e.Error() // return //} // 修改推送状态 updateCols := []string{"EmailState", "ModifyTime"} reportInfo.EmailState = 1 reportInfo.ModifyTime = time.Now().Local() if e = reportInfo.Update(updateCols); e != nil { br.Msg = "操作失败" br.ErrMsg = "更新推送状态失败, Err: " + e.Error() return } // 群发邮件 go func() { services.BatchSendAliEnglishReportEmail(sendData) }() br.Ret = 200 br.Success = true br.Msg = "操作成功" } // PvList // @Title 英文研报邮箱PV列表 // @Description 英文研报邮箱PV列表 // @Param ReportId query int false "英文研报ID" // @Param ReportType query int false "类型:0英文研报,1英文线上路演" // @Success 200 {object} models.EnglishReportEmailPvResp // @router /email/pv_list [get] func (this *EnglishReportEmailController) PvList() { br := new(models.BaseResponse).Init() br.IsSendEmail = false defer func() { this.Data["json"] = br this.ServeJSON() }() sysUser := this.SysUser if sysUser == nil { br.Msg = "请登录" br.ErrMsg = "请登录,SysUser Is Empty" br.Ret = 408 return } reportId, e := this.GetInt("ReportId", 0) if reportId == 0 { br.Msg = "参数有误" return } reportType, e := this.GetInt("ReportType", 0) var cond string var pars []interface{} cond += ` AND a.report_id = ? AND a.report_type= ?` pars = append(pars, reportId, reportType) var startSize int pageSize, _ := this.GetInt("PageSize") currentIndex, _ := this.GetInt("CurrentIndex") if pageSize <= 0 { pageSize = utils.PageSize20 } if currentIndex <= 0 { currentIndex = 1 } startSize = paging.StartIndex(currentIndex, pageSize) total, list, e := models.GetEnglishReportEmailPvPageList(cond, pars, startSize, pageSize) if e != nil { br.Msg = "获取失败" br.ErrMsg = "获取英文研报邮箱pv列表失败, Err: " + e.Error() return } page := paging.GetPaging(currentIndex, pageSize, total) resp := &models.EnglishReportEmailPvPageListResp{ Paging: page, List: list, } br.Ret = 200 br.Success = true br.Msg = "获取成功" br.Data = resp } // UvList // @Title 英文研报邮箱UV列表 // @Description 英文研报邮箱UV列表 // @Param ReportId query int false "英文研报ID" // @Param ReportType query int false "类型:0英文研报,1英文线上路演" // @Success 200 {object} models.EnglishReportEmailPvResp // @router /email/uv_list [get] func (this *EnglishReportEmailController) UvList() { br := new(models.BaseResponse).Init() br.IsSendEmail = false defer func() { this.Data["json"] = br this.ServeJSON() }() sysUser := this.SysUser if sysUser == nil { br.Msg = "请登录" br.ErrMsg = "请登录,SysUser Is Empty" br.Ret = 408 return } reportId, e := this.GetInt("ReportId", 0) if reportId == 0 { br.Msg = "参数有误" return } reportType, e := this.GetInt("ReportType", 0) var cond string var pars []interface{} cond += ` AND a.report_id = ? AND a.report_type= ?` pars = append(pars, reportId, reportType) var startSize int pageSize, _ := this.GetInt("PageSize") currentIndex, _ := this.GetInt("CurrentIndex") if pageSize <= 0 { pageSize = utils.PageSize20 } if currentIndex <= 0 { currentIndex = 1 } startSize = paging.StartIndex(currentIndex, pageSize) total, list, e := models.GetEnglishReportEmailUvPageList(cond, pars, startSize, pageSize) if e != nil { br.Msg = "获取失败" br.ErrMsg = "获取英文研报邮箱uv列表失败, Err: " + e.Error() return } page := paging.GetPaging(currentIndex, pageSize, total) resp := &models.EnglishReportEmailUvPageListResp{ Paging: page, List: list, } br.Ret = 200 br.Success = true br.Msg = "获取成功" br.Data = resp } // ImportListMatch // @Title 英文邮箱/联系人批量导入 // @Description 英文邮箱/联系人批量导入 // @Param File query file true "文件" // @Param CompanyId query int true "客户ID" // @Success 200 string "导入成功" // @router /email/import [post] func (this *EnglishReportEmailController) ImportListMatch() { br := new(models.BaseResponse).Init() defer func() { this.Data["json"] = br this.ServeJSON() }() sysUser := this.SysUser if sysUser == nil { br.Msg = "请重新登录" return } companyId, _ := this.GetInt("CompanyId") if companyId <= 0 { br.Msg = "请选择客户" return } companyItem, e := models.GetEnglishCompanyById(companyId) if e != nil { if e.Error() == utils.ErrNoRow() { br.Msg = "客户已被删除, 请刷新页面" return } br.Msg = "操作失败" br.ErrMsg = "获取客户信息失败, Err: " + e.Error() return } file, h, err := this.GetFile("File") if err != nil { br.Msg = "获取文件失败" br.ErrMsg = "获取文件失败,Err:" + err.Error() return } defer func() { _ = file.Close() }() ext := path.Ext(h.Filename) if ext != ".xlsx" && ext != ".xls" { br.Msg = "请上传Excel文件" return } uploadDir := "static/xls" err = os.MkdirAll(uploadDir, utils.DIR_MOD) if err != nil { br.Msg = "存储目录创建失败" br.ErrMsg = "存储目录创建失败,Err:" + err.Error() return } uploadPath := uploadDir + "/" + time.Now().Format(utils.FormatDateTimeUnSpace) + h.Filename err = this.SaveToFile("File", uploadPath) if err != nil { br.Msg = "文件保存失败" br.ErrMsg = "文件保存失败,Err:" + err.Error() return } defer func() { _ = os.Remove(uploadPath) }() xlFile, err := xlsx.OpenFile(uploadPath) if err != nil { br.Msg = "文件导入失败" br.ErrMsg = "文件导入失败,Err:" + err.Error() return } // 重复邮箱校验 var cond string var pars []interface{} emails, e := models.GetEnglishReportEmailList(cond, pars, "") if e != nil { br.Msg = "导入失败" br.ErrMsg = "获取邮箱列表失败, Err:" + e.Error() return } emailArr := make([]string, 0) for i := range emails { emailArr = append(emailArr, emails[i].Email) } importList := make([]*models.EnglishReportEmailSaveReq, 0) // 遍历sheet页读取 titleRow := []string{"联系人姓名", "国际区号", "手机号", "邮箱地址"} for _, sheet := range xlFile.Sheets { // 遍历行读取 maxRow := sheet.MaxRow for i := 0; i < maxRow; i++ { // 首行 if i == 0 { row := sheet.Row(i) cells := row.Cells for k, cell := range cells { text := cell.String() for k2 := range titleRow { if k > k2 { break } if text != titleRow[k] && !strings.Contains(text, titleRow[k]) { br.Msg = fmt.Sprintf("匹配失败, 请按模板导入(%s)", titleRow[k]) br.ErrMsg = "模板格式错误,title:" + text return } } } } // 数据行 if i >= 1 { row := sheet.Row(i) cells := row.Cells var userName, userCountryCode, userMobile, userEmail string for k, cell := range cells { v := utils.TrimStr(cell.String()) if k == 0 { userName = v continue } if k == 1 { userCountryCode = v continue } if k == 2 { userMobile = v continue } if k == 3 { userEmail = v } } // 数据为空则读取下一行 if userName == "" || userEmail == "" { continue } if !utils.ValidateEmailFormatat(userEmail) { br.Msg = "存在错误的邮箱格式, 请检查后重新导入" return } // 重复校验 if utils.InArrayByStr(emailArr, userEmail) { continue } emailArr = append(emailArr, userEmail) importList = append(importList, &models.EnglishReportEmailSaveReq{ CompanyId: companyId, Name: userName, Email: userEmail, Mobile: userMobile, CountryCode: userCountryCode, Enabled: 1, }) } } } if len(importList) == 0 { br.Msg = "无有效数据可导入" return } nowTime := time.Now().Local() newEmails := make([]*models.EnglishReportEmail, 0) newLogs := make([]*models.EnglishReportEmailOpLog, 0) for i := range importList { v := &models.EnglishReportEmail{ CompanyId: importList[i].CompanyId, CompanyName: companyItem.CompanyName, Name: importList[i].Name, Email: importList[i].Email, Mobile: importList[i].Mobile, CountryCode: importList[i].CountryCode, Enabled: importList[i].Enabled, AdminId: sysUser.AdminId, AdminName: sysUser.AdminName, Status: 1, CreateTime: nowTime, ModifyTime: nowTime, } newEmails = append(newEmails, v) newByte, e := json.Marshal(importList[i]) if e != nil { br.Msg = "导入失败" br.ErrMsg = "新邮箱/联系转JSON失败, Err: " + e.Error() return } newLogs = append(newLogs, &models.EnglishReportEmailOpLog{ CompanyId: importList[i].CompanyId, AdminId: sysUser.AdminId, OptionData: string(newByte), OptionType: models.EnglishReportEmailOpLogTypeImport, CreateTime: nowTime, }) } if e = models.MultiCreateEnglishEmail(newEmails, newLogs); e != nil { br.Msg = "导入失败" br.ErrMsg = "批量新增英文邮箱/联系人失败, Err: " + e.Error() return } br.Msg = "导入成功" br.Ret = 200 br.Success = true } // ViewList // @Title 英文研报邮箱/联系人阅读列表 // @Description 英文研报邮箱/联系人阅读列表 // @Param EmailId query int false "英文邮箱/联系人ID" // @Param SortParam query int false "排序字段:1-点击量;2-点击时间" // @Param SortType query int false "排序方式:1-倒序;2-正序" // @Param EnPermissionIds query string false "品种权限IDs(字符串)" // @Success 200 {object} models.EnglishEmailViewPageListResp // @router /email/view_list [get] func (this *EnglishReportEmailController) ViewList() { br := new(models.BaseResponse).Init() br.IsSendEmail = false defer func() { this.Data["json"] = br this.ServeJSON() }() sysUser := this.SysUser if sysUser == nil { br.Msg = "请登录" br.ErrMsg = "请登录,SysUser Is Empty" br.Ret = 408 return } emailId, e := this.GetInt("EmailId", 0) if emailId <= 0 { br.Msg = "参数有误" return } // 默认点击时间降序 sortParam, _ := this.GetInt("SortParam", 2) sortType, _ := this.GetInt("SortType", 1) clickType := this.GetString("ClickType", "") strPermissionIds := this.GetString("EnPermissionIds", "") var cond, order string var pars []interface{} cond += ` AND email_id = ? ` pars = append(pars, emailId) if clickType != "" { cond += ` AND report_type = ? ` pars = append(pars, clickType) } // 品种筛选 if strPermissionIds != "" { permissionIdArr := strings.Split(strPermissionIds, ",") permissionIds := make([]int, 0) for _, s := range permissionIdArr { p, e := strconv.Atoi(s) if e != nil { br.Msg = "品种权限有误" br.ErrMsg = "品种权限筛选有误" return } permissionIds = append(permissionIds, p) } if len(permissionIds) == 0 { br.Msg = "品种权限有误" br.ErrMsg = "品种权限筛选ID为空" return } reportIds, e := models.GetEnglishReportIdsByEnPermissionIds(permissionIds) if e != nil { br.Msg = "获取失败" br.ErrMsg = "获取报告IDs失败, Err: " + e.Error() return } if len(reportIds) > 0 { cond += fmt.Sprintf(` AND report_id IN (%s) `, utils.GetOrmInReplace(len(reportIds))) pars = append(pars, reportIds) } else { cond += ` AND 1=2` } } var startSize int pageSize, _ := this.GetInt("PageSize") currentIndex, _ := this.GetInt("CurrentIndex") if pageSize <= 0 { pageSize = utils.PageSize20 } if currentIndex <= 0 { currentIndex = 1 } startSize = paging.StartIndex(currentIndex, pageSize) sortArr := []int{1, 2} if utils.InArrayByInt(sortArr, sortParam) && utils.InArrayByInt(sortArr, sortType) { pMap := map[int]string{1: "view_total", 2: "last_view_time"} tMap := map[int]string{1: "DESC", 2: "ASC"} order = fmt.Sprintf(` ORDER BY %s %s`, pMap[sortParam], tMap[sortType]) } total, list, e := models.GetEnglishEmailViewPageList(cond, pars, order, startSize, pageSize) if e != nil { br.Msg = "获取失败" br.ErrMsg = "英文研报邮箱/联系人阅读列表失败, Err: " + e.Error() return } // 报告标题,报告类型 reportMap := make(map[int]*models.EnglishReport, 0) videoMap := make(map[int]*models.EnglishVideo, 0) if len(list) > 0 { reportIds := make([]int, 0) videoIds := make([]int, 0) for i := range list { if list[i].ClickType == 0 { reportIds = append(reportIds, list[i].ReportId) } else if list[i].ClickType == 1 { videoIds = append(videoIds, list[i].ReportId) } } fields := []string{"id", "title", "classify_name_first", "classify_name_second"} if len(reportIds) > 0 { reports, e := models.GetEnglishReportByIds(reportIds, fields) if e != nil { br.Msg = "获取失败" br.ErrMsg = "获取英文研报列表失败, Err: " + e.Error() return } for i := range reports { reportMap[reports[i].Id] = reports[i] } } if len(videoIds) > 0 { videos, e := models.GetEnglishVideoByIds(videoIds, fields) if e != nil { br.Msg = "获取失败" br.ErrMsg = "获取英文研报列表失败, Err: " + e.Error() return } for i := range videos { videoMap[videos[i].Id] = videos[i] } } } for i := range list { if r, ok := reportMap[list[i].ReportId]; ok { list[i].ReportTitle = r.Title list[i].ReportType = r.ClassifyNameFirst if r.ClassifyNameSecond != "" { list[i].ReportType += ` / ` + r.ClassifyNameSecond } } else if v, ok1 := videoMap[list[i].ReportId]; ok1 { list[i].ReportTitle = v.Title list[i].ReportType = v.ClassifyNameFirst if v.ClassifyNameSecond != "" { list[i].ReportType += ` / ` + v.ClassifyNameSecond } } } page := paging.GetPaging(currentIndex, pageSize, total) resp := &models.EnglishEmailViewPageListResp{ Paging: page, List: list, } br.Ret = 200 br.Success = true br.Msg = "获取成功" br.Data = resp } // LogList // @Title 邮件群发日志列表 // @Description 邮件群发日志列表 // @Param ReportId query int true "报告ID" // @Param ReportType query int true "类型:0英文研报,1英文线上路演" // @Param SendStatus query int false "发送状态:-1-已发送;0-发送失败;1-发送成功" // @Param Keywords query string false "关键词:邮箱" // @Success 200 {object} models.EnglishReportEmailLogPageListResp // @router /email/log_list [get] func (this *EnglishReportEmailController) LogList() { br := new(models.BaseResponse).Init() br.IsSendEmail = false defer func() { this.Data["json"] = br this.ServeJSON() }() sysUser := this.SysUser if sysUser == nil { br.Msg = "请登录" br.ErrMsg = "请登录,SysUser Is Empty" br.Ret = 408 return } reportId, _ := this.GetInt("ReportId", 0) if reportId <= 0 { br.Msg = "参数有误" return } reportType, _ := this.GetInt("ReportType", 0) keywords := this.GetString("Keywords", "") var startSize int pageSize, _ := this.GetInt("PageSize") currentIndex, _ := this.GetInt("CurrentIndex") if pageSize <= 0 { pageSize = utils.PageSize20 } if currentIndex <= 0 { currentIndex = 1 } startSize = paging.StartIndex(currentIndex, pageSize) var cond string var pars []interface{} cond += ` AND report_id = ? AND report_type = ?` pars = append(pars, reportId, reportType) // 推送状态 status := this.GetString("SendStatus", "") if status != "" { statusInt, e := strconv.Atoi(status) if e != nil { br.Msg = "状态类型有误" return } cond += ` AND send_status = ?` pars = append(pars, statusInt) } // 关键词 if keywords != "" { k := fmt.Sprint("%", keywords, "%") cond += ` AND email LIKE ? ` pars = append(pars, k) } total, list, e := models.GetEnglishReportEmailLogPageList(cond, pars, "", startSize, pageSize) if e != nil { br.Msg = "获取失败" br.ErrMsg = "获取邮箱列表失败, Err: " + e.Error() return } respList := make([]*models.EnglishReportEmailLogPageList, 0) for i := range list { v := new(models.EnglishReportEmailLogPageList) // 推送结果 v.ResultMsg = "发送成功" if list[i].ErrMsg != "" { v.ResultMsg = list[i].ErrMsg } v.SendId = list[i].Id v.ReportId = list[i].ReportId v.EmailId = list[i].EmailId v.Email = list[i].Email v.SendStatus = list[i].SendStatus v.Source = list[i].Source v.CreateTime = list[i].CreateTime.Format(utils.FormatDateTime) respList = append(respList, v) } page := paging.GetPaging(currentIndex, pageSize, total) resp := &models.EnglishReportEmailLogPageListResp{ Paging: page, List: respList, } br.Ret = 200 br.Success = true br.Msg = "获取成功" br.Data = resp } // Resend // @Title 重新推送 // @Description 群发推送 // @Param request body models.EnglishReportEmailResendReq true "type json string" // @Success 200 string "操作成功" // @router /email/resend [post] func (this *EnglishReportEmailController) Resend() { br := new(models.BaseResponse).Init() br.IsSendEmail = false defer func() { this.Data["json"] = br this.ServeJSON() }() sysUser := this.SysUser if sysUser == nil { br.Msg = "请登录" br.ErrMsg = "请登录,SysUser Is Empty" br.Ret = 408 return } var req models.EnglishReportEmailResendReq if err := json.Unmarshal(this.Ctx.Input.RequestBody, &req); err != nil { br.Msg = "参数解析异常!" br.ErrMsg = "参数解析失败,Err:" + err.Error() return } if req.ReportId <= 0 { br.Msg = "请选择报告" return } // 获取报告信息 reportInfo, e := models.GetEnglishReportItemById(req.ReportId) if e != nil { br.Msg = "报告信息有误" br.ErrMsg = "获取报告信息失败, Err: " + e.Error() return } if reportInfo.State != 2 { br.Msg = "报告未发布" br.ErrMsg = fmt.Sprintf("报告状态有误, 当前状态: %d", reportInfo.State) return } if reportInfo.Title == "" { br.Msg = "报告标题有误" br.ErrMsg = "报告标题为空, 不可推送" return } if reportInfo.Content == `` { br.Msg = "报告内容有误" br.ErrMsg = "报告内容为空, 不可推送" return } if reportInfo.Abstract == `` { br.Msg = "报告摘要为空" br.ErrMsg = "报告摘要为空, 不可推送" return } if reportInfo.Overview == "" { br.Msg = "报告Overview部分不可为空" br.ErrMsg = "报告Overview为空, 不可推送" return } // 重新发送超过100字符直接截取 theme := reportInfo.Abstract runeAbs := []rune(reportInfo.Abstract) runeThe := make([]rune, 0) if len(runeAbs) > 100 { runeThe = runeAbs[:100] theme = string(runeThe) } // 获取邮件配置 conf := new(models.EnglishReportEmailConf) authKey := "english_report_email_conf" confAuth, e := company.GetConfigDetailByCode(authKey) if e != nil { br.Msg = "无权操作" br.ErrMsg = "获取群发邮件权限失败, Err: " + e.Error() return } if confAuth.ConfigValue == "" { br.Msg = "无权操作" br.ErrMsg = "群发邮件配置为空" return } if e := json.Unmarshal([]byte(confAuth.ConfigValue), &conf); e != nil { br.Msg = "无权操作" br.ErrMsg = "群发邮件配置有误" return } authArr := strings.Split(conf.SendAuthGroup, ",") if !utils.InArrayByStr(authArr, sysUser.RoleTypeCode) { br.Msg = "无权操作" return } // 获取模板 confKey := "english_report_email_tmp" confTmp, e := company.GetConfigDetailByCode(confKey) if e != nil { br.Msg = "获取邮件模板失败" br.ErrMsg = "获取邮件模板失败, Err: " + e.Error() return } if confTmp.ConfigValue == `` { br.Msg = "邮件模板有误" br.ErrMsg = "邮件模板为空, 不可推送" return } // 获取发送失败的日志 emailIds := make([]int, 0) emails := make([]*models.EnglishReportEmail, 0) logIds := make([]int, 0) if req.SendId > 0 { logItem, e := models.GetEnglishReportEmailLogById(req.SendId) if e != nil { br.Msg = "发送失败" br.ErrMsg = "获取原邮件推送日志失败, Err: " + e.Error() return } emailIds = append(emailIds, logItem.EmailId) logIds = append(logIds, logItem.Id) } else { var logCond string var logPars []interface{} logCond += ` AND report_id = ? AND send_status = 0 AND report_type=0` logPars = append(logPars, req.ReportId) logList, e := models.GetEnglishReportEmailLogList(logCond, logPars) if e != nil { br.Msg = "发送失败" br.ErrMsg = "获取原邮件推送日志列表失败, Err: " + e.Error() return } for i := range logList { emailIds = append(emailIds, logList[i].EmailId) logIds = append(logIds, logList[i].Id) } } // 获取收件人列表 // 注: 此处不从失败日志中取email, 因为有可能是地址有误导致的推送失败 if len(emailIds) > 0 { var emailCond string var emailPars []interface{} emailCond += ` AND id IN (` + utils.GetOrmInReplace(len(emailIds)) + `) and enabled = 1 ` emailPars = append(emailPars, emailIds) em, e := models.GetEnglishReportEmailList(emailCond, emailPars, "") if e != nil { br.Msg = "获取收件人列表失败" br.ErrMsg = "获取收件人列表失败, Err: " + e.Error() return } emails = em } if len(emails) == 0 { br.Msg = "无邮件可推送" return } // 推送信息 nowTime := time.Now().Local() sendData := make([]*services.EnglishReportSendEmailRequest, 0) logData := make([]*models.EnglishReportEmailLog, 0) for i := range emails { r := new(services.EnglishReportSendEmailRequest) r.ReportId = reportInfo.Id r.EmailId = emails[i].Id r.Email = strings.Replace(emails[i].Email, " ", "", -1) r.Subject = theme r.FromAlias = conf.FromAlias // 填充模板 t := reportInfo.PublishTime.Format("02/01/2006") l := fmt.Sprintf(utils.EnglishShareUrl+"/report/detail?code=%s", reportInfo.ReportCode) ct := confTmp.ConfigValue ct = strings.Replace(ct, "{{REPORT_TITLE}}", reportInfo.Title, 1) ct = strings.Replace(ct, "{{REPORT_ABSTRACT}}", reportInfo.Abstract, 1) ct = strings.Replace(ct, "{{REPORT_CONTENT}}", reportInfo.Overview, 1) ct = strings.Replace(ct, "{{REPORT_SHARE_LINK}}", l, 1) ct = strings.Replace(ct, "{{REPORT_TIME}}", t, 1) r.HtmlBody = ct r.ReportTitle = reportInfo.Title r.ReportAbstract = reportInfo.Abstract r.ReportContent = reportInfo.Overview r.ReportShareLink = l r.ReportTime = t logItem := &models.EnglishReportEmailLog{ ReportId: reportInfo.Id, EmailId: emails[i].Id, Email: emails[i].Email, Source: models.EnglishReportEmailLogSourceAli, SendStatus: models.EnglishReportEmailLogStatusIng, CreateTime: nowTime, } r.EmailLog = logItem sendData = append(sendData, r) // 日志 logData = append(logData, logItem) } // 标记原有日志为已删除 if len(logIds) > 0 { if e = models.DeleteEnglishReportEmailLogByIds(logIds); e != nil { br.Msg = "发送失败" br.ErrMsg = "删除原邮件日志失败, Err: " + e.Error() return } } // 写入新的日志 for _, v := range logData { if e = v.Create(); e != nil { br.Msg = "操作失败" br.ErrMsg = "写入群发邮件日志失败, Err: " + e.Error() return } } // 群发邮件 go func() { services.BatchSendAliEnglishReportEmail(sendData) }() br.Ret = 200 br.Success = true br.Msg = "操作成功" } // SendCallBack // @Title 群发邮件回调 // @Description 群发邮件回调 // @Param request body services.TencentEmailCallBack true "type json string" // @Success 200 string "操作成功" // @router /email/send/call_back [post] func (this *EnglishReportEmailCallBackController) SendCallBack() { // 腾讯云后台同一个发信地址只能配置一个回调, 测试环境就不用了, 给正式环境用 if utils.RunMode != "release" { return } var req services.TencentEmailCallBack if err := json.Unmarshal(this.Ctx.Input.RequestBody, &req); err != nil { return } // 仅预警失败的回调事件 alarmTypes := []string{"dropped", "bounce"} if !utils.InArrayByStr(alarmTypes, req.Event) { return } reqByte, e := json.Marshal(req) if e != nil { return } reqStr := string(reqByte) alarm_msg.SendAlarmMsg("腾讯云邮件推送回调信息:"+reqStr, 1) // 存在失败情况则更新日志 var cond string var pars []interface{} cond = ` AND is_deleted = 0 AND email = ? AND source = ? AND result LIKE ? ` pars = append(pars, req.Email, models.EnglishReportEmailLogSourceTencent, fmt.Sprint("%", req.BulkId, "%")) logItem, e := models.GetEnglishReportEmailLog(cond, pars) if e != nil { return } updateCols := []string{"SendStatus", "CallbackData", "ErrMsg"} logItem.SendStatus = models.EnglishReportEmailLogStatusFail logItem.CallbackData = reqStr logItem.ErrMsg = req.Reason if e = logItem.Update(updateCols); e != nil { return } } // VideoSend // @Title 线上路演群发推送 // @Description 线上路演群发推送 // @Param request body models.EnglishReportEmailSaveReq true "type json string" // @Success 200 string "操作成功" // @router /email/video/send [post] func (this *EnglishReportEmailController) VideoSend() { br := new(models.BaseResponse).Init() br.IsSendEmail = false defer func() { this.Data["json"] = br this.ServeJSON() }() sysUser := this.SysUser if sysUser == nil { br.Msg = "请登录" br.ErrMsg = "请登录,SysUser Is Empty" br.Ret = 408 return } var req models.EnglishReportEmailSendReq if err := json.Unmarshal(this.Ctx.Input.RequestBody, &req); err != nil { br.Msg = "参数解析异常!" br.ErrMsg = "参数解析失败,Err:" + err.Error() return } if req.ReportId <= 0 { br.Msg = "请选择路演视频" return } if req.Theme == "" { br.Msg = "请输入邮件主题" return } //prefixTheme := "【HI China Macro and Commodity】" //if !strings.Contains(req.Theme, prefixTheme) { // req.Theme = prefixTheme + req.Theme //} runeThe := []rune(req.Theme) if len(runeThe) > 100 { br.Msg = "邮件主题不可超过100字符" return } // 获取路演视频信息 videoInfo, e := models.GetEnglishVideoItemById(req.ReportId) if e != nil { br.Msg = "路演视频信息有误" br.ErrMsg = "获取路演视频信息失败, Err: " + e.Error() return } if videoInfo.EmailState != 0 { br.Msg = "请勿重复发送" br.ErrMsg = fmt.Sprintf("路演视频群发邮件状态有误, 当前状态: %d", videoInfo.EmailState) return } if videoInfo.State != 2 { br.Msg = "路演视频未发布" br.ErrMsg = fmt.Sprintf("路演视频状态有误, 当前状态: %d", videoInfo.State) return } if videoInfo.Title == "" { br.Msg = "路演视频标题有误" br.ErrMsg = "路演视频标题为空, 不可推送" return } if videoInfo.VideoUrl == `` { br.Msg = "路演视频地址为空, 不可推送" br.ErrMsg = "路演视频内容为空, 不可推送" return } // 获取路演视频Overview部分 if videoInfo.Overview == "" { br.Msg = "路演视频Overview部分不可为空" return } // 获取邮件配置 conf := new(models.EnglishReportEmailConf) authKey := "english_report_email_conf" confAuth, e := company.GetConfigDetailByCode(authKey) if e != nil { br.Msg = "无权操作" br.ErrMsg = "获取群发邮件权限失败, Err: " + e.Error() return } if confAuth.ConfigValue == "" { br.Msg = "无权操作" br.ErrMsg = "群发邮件配置为空" return } if e := json.Unmarshal([]byte(confAuth.ConfigValue), &conf); e != nil { br.Msg = "无权操作" br.ErrMsg = "群发邮件配置有误" return } authArr := strings.Split(conf.SendAuthGroup, ",") if !utils.InArrayByStr(authArr, sysUser.RoleTypeCode) { br.Msg = "无权操作" return } // 指定品种的客户 sendCompanyIds := make([]int, 0) if len(req.EnPermissions) > 0 { companyIds, e := models.GetEnglishCompanyIdsByEnPermissionIds(req.EnPermissions) if e != nil { br.Msg = "推送失败" br.ErrMsg = "获取指定品种的客户IDs失败, Err: " + e.Error() return } sendCompanyIds = companyIds } // 指定收件人列表 sendEmailIds := make([]int, 0) if req.EmailIds != "" { emailIdArr := strings.Split(req.EmailIds, ",") if len(emailIdArr) == 0 { br.Msg = "指定收件人列表有误" br.ErrMsg = fmt.Sprintf("收件人列表为空, 收件人IDs: %s", req.EmailIds) return } for _, m := range emailIdArr { v, _ := strconv.Atoi(m) sendEmailIds = append(sendEmailIds, v) } } if len(sendCompanyIds) == 0 && len(sendEmailIds) == 0 { br.Msg = "收件人列表为空(或收件人账号被禁用)" br.ErrMsg = "收件人列表为空, 不可推送" return } // 往正式客户id里面插入0的 目的是为了把临时客户找出来 sendCompanyIds = append(sendCompanyIds, 0) emailCond := " AND enabled = 1 AND status <> 3" emailPars := make([]interface{}, 0) if len(sendCompanyIds) > 0 && len(sendEmailIds) > 0 { emailCond += ` AND (company_id IN (` + utils.GetOrmInReplace(len(sendCompanyIds)) + `) OR id IN (` + utils.GetOrmInReplace(len(sendEmailIds)) + `))` emailPars = append(emailPars, sendCompanyIds) emailPars = append(emailPars, sendEmailIds) } if len(sendCompanyIds) > 0 && len(sendEmailIds) == 0 { emailCond += ` AND company_id IN (` + utils.GetOrmInReplace(len(sendCompanyIds)) + `)` emailPars = append(emailPars, sendCompanyIds) } emails, e := models.GetEnglishReportEmailList(emailCond, emailPars, "") if e != nil { br.Msg = "获取收件人列表失败" br.ErrMsg = "获取收件人列表失败, Err: " + e.Error() return } if len(emails) == 0 { br.Msg = "收件人列表为空(或收件人账号被禁用)" br.ErrMsg = "收件人列表为空, 不可推送" return } // 获取模板 confKey := "english_video_email_tmp" confTmp, e := company.GetConfigDetailByCode(confKey) if e != nil { br.Msg = "获取邮件模板失败" br.ErrMsg = "获取邮件模板失败, Err: " + e.Error() return } if confTmp.ConfigValue == `` { br.Msg = "邮件模板有误" br.ErrMsg = "邮件模板为空, 不可推送" return } // 同一篇路演视频避免重复推送给同一个邮件 var cond string var pars []interface{} cond += ` AND report_id = ? AND send_status = 1 AND report_type = 1` pars = append(pars, req.ReportId) logs, e := models.GetEnglishReportEmailLogList(cond, pars) if e != nil { br.Msg = "推送失败" br.ErrMsg = "获取邮件发送日志列表失败, Err: " + e.Error() return } repeatMap := make(map[int]bool, 0) for i := range logs { if logs[i].SendStatus == 1 { repeatMap[logs[i].EmailId] = true } } // 推送信息 nowTime := time.Now().Local() sendData := make([]*services.EnglishReportSendEmailRequest, 0) logData := make([]*models.EnglishReportEmailLog, 0) for i := range emails { if repeatMap[emails[i].Id] { continue } r := new(services.EnglishReportSendEmailRequest) r.ReportId = videoInfo.Id r.EmailId = emails[i].Id r.Email = strings.Replace(emails[i].Email, " ", "", -1) r.Subject = req.Theme r.FromAlias = conf.FromAlias overview := videoInfo.Overview // 填充模板 t := videoInfo.PublishTime.Format("02/01/2006") l := fmt.Sprintf(utils.EnglishShareUrl+"/roadshow/detail?code=%s&ShareEmail=%d", videoInfo.VideoCode, emails[i].Id) ct := confTmp.ConfigValue ct = strings.Replace(ct, "{{REPORT_TITLE}}", videoInfo.Title, 1) ct = strings.Replace(ct, "{{REPORT_ABSTRACT}}", videoInfo.Abstract, 1) ct = strings.Replace(ct, "{{REPORT_CONTENT}}", overview, 1) ct = strings.Replace(ct, "{{REPORT_SHARE_LINK}}", l, 1) ct = strings.Replace(ct, "{{REPORT_TIME}}", t, 1) r.HtmlBody = ct r.ReportTitle = videoInfo.Title r.ReportAbstract = videoInfo.Abstract r.ReportContent = overview r.ReportShareLink = l r.ReportTime = t logItem := &models.EnglishReportEmailLog{ ReportId: videoInfo.Id, ReportType: 1, EmailId: emails[i].Id, Email: emails[i].Email, Source: models.EnglishReportEmailLogSourceAli, SendStatus: models.EnglishReportEmailLogStatusIng, CreateTime: nowTime, } r.EmailLog = logItem sendData = append(sendData, r) // 日志 logData = append(logData, logItem) } if len(sendData) == 0 { br.Msg = "无邮件可推送" return } // 写入日志 for _, v := range logData { if e = v.Create(); e != nil { br.Msg = "操作失败" br.ErrMsg = "写入群发邮件日志失败, Err: " + e.Error() return } } // 修改推送状态 updateCols := []string{"EmailState", "ModifyTime"} videoInfo.EmailState = 1 videoInfo.ModifyTime = time.Now().Local() if e = videoInfo.Update(updateCols); e != nil { br.Msg = "操作失败" br.ErrMsg = "更新推送状态失败, Err: " + e.Error() return } // 群发邮件 go func() { services.BatchSendAliEnglishReportEmail(sendData) }() br.Ret = 200 br.Success = true br.Msg = "操作成功" } // VideoResend // @Title 线上路演重新推送 // @Description 线上路演重新推送 // @Param request body models.EnglishReportEmailResendReq true "type json string" // @Success 200 string "操作成功" // @router /email/video/resend [post] func (this *EnglishReportEmailController) VideoResend() { br := new(models.BaseResponse).Init() br.IsSendEmail = false defer func() { this.Data["json"] = br this.ServeJSON() }() sysUser := this.SysUser if sysUser == nil { br.Msg = "请登录" br.ErrMsg = "请登录,SysUser Is Empty" br.Ret = 408 return } var req models.EnglishReportEmailResendReq if err := json.Unmarshal(this.Ctx.Input.RequestBody, &req); err != nil { br.Msg = "参数解析异常!" br.ErrMsg = "参数解析失败,Err:" + err.Error() return } if req.ReportId <= 0 { br.Msg = "请选择路演视频" return } // 获取路演视频信息 reportInfo, e := models.GetEnglishVideoItemById(req.ReportId) if e != nil { br.Msg = "路演视频信息有误" br.ErrMsg = "获取路演视频信息失败, Err: " + e.Error() return } if reportInfo.State != 2 { br.Msg = "路演视频未发布" br.ErrMsg = fmt.Sprintf("路演视频状态有误, 当前状态: %d", reportInfo.State) return } if reportInfo.Title == "" { br.Msg = "路演视频标题有误" br.ErrMsg = "路演视频标题为空, 不可推送" return } if reportInfo.Abstract == `` { br.Msg = "路演视频摘要为空" br.ErrMsg = "路演视频摘要为空, 不可推送" return } if reportInfo.Overview == "" { br.Msg = "路演视频Overview部分不可为空" br.ErrMsg = "路演视频Overview为空, 不可推送" return } // 重新发送超过100字符直接截取 theme := reportInfo.Abstract runeAbs := []rune(reportInfo.Abstract) runeThe := make([]rune, 0) if len(runeAbs) > 100 { runeThe = runeAbs[:100] theme = string(runeThe) } // 获取邮件配置 conf := new(models.EnglishReportEmailConf) authKey := "english_report_email_conf" confAuth, e := company.GetConfigDetailByCode(authKey) if e != nil { br.Msg = "无权操作" br.ErrMsg = "获取群发邮件权限失败, Err: " + e.Error() return } if confAuth.ConfigValue == "" { br.Msg = "无权操作" br.ErrMsg = "群发邮件配置为空" return } if e := json.Unmarshal([]byte(confAuth.ConfigValue), &conf); e != nil { br.Msg = "无权操作" br.ErrMsg = "群发邮件配置有误" return } authArr := strings.Split(conf.SendAuthGroup, ",") if !utils.InArrayByStr(authArr, sysUser.RoleTypeCode) { br.Msg = "无权操作" return } // 获取模板 confKey := "english_video_email_tmp" confTmp, e := company.GetConfigDetailByCode(confKey) if e != nil { br.Msg = "获取邮件模板失败" br.ErrMsg = "获取邮件模板失败, Err: " + e.Error() return } if confTmp.ConfigValue == `` { br.Msg = "邮件模板有误" br.ErrMsg = "邮件模板为空, 不可推送" return } // 获取发送失败的日志 emailIds := make([]int, 0) emails := make([]*models.EnglishReportEmail, 0) logIds := make([]int, 0) if req.SendId > 0 { logItem, e := models.GetEnglishReportEmailLogById(req.SendId) if e != nil { br.Msg = "发送失败" br.ErrMsg = "获取原邮件推送日志失败, Err: " + e.Error() return } emailIds = append(emailIds, logItem.EmailId) logIds = append(logIds, logItem.Id) } else { var logCond string var logPars []interface{} logCond += ` AND report_id = ? AND send_status = 0 AND report_type=1` logPars = append(logPars, req.ReportId) logList, e := models.GetEnglishReportEmailLogList(logCond, logPars) if e != nil { br.Msg = "发送失败" br.ErrMsg = "获取原邮件推送日志列表失败, Err: " + e.Error() return } for i := range logList { emailIds = append(emailIds, logList[i].EmailId) logIds = append(logIds, logList[i].Id) } } // 获取收件人列表 // 注: 此处不从失败日志中取email, 因为有可能是地址有误导致的推送失败 if len(emailIds) > 0 { var emailCond string var emailPars []interface{} emailCond += ` AND id IN (` + utils.GetOrmInReplace(len(emailIds)) + `) and enabled = 1 ` emailPars = append(emailPars, emailIds) em, e := models.GetEnglishReportEmailList(emailCond, emailPars, "") if e != nil { br.Msg = "获取收件人列表失败" br.ErrMsg = "获取收件人列表失败, Err: " + e.Error() return } emails = em } if len(emails) == 0 { br.Msg = "无邮件可推送" return } // 推送信息 nowTime := time.Now().Local() sendData := make([]*services.EnglishReportSendEmailRequest, 0) logData := make([]*models.EnglishReportEmailLog, 0) for i := range emails { r := new(services.EnglishReportSendEmailRequest) r.ReportId = reportInfo.Id r.EmailId = emails[i].Id r.Email = strings.Replace(emails[i].Email, " ", "", -1) r.Subject = theme r.FromAlias = conf.FromAlias // 填充模板 t := reportInfo.PublishTime.Format("02/01/2006") l := fmt.Sprintf(utils.EnglishShareUrl+"/roadshow/detail?code=%s&ShareEmail=%d", reportInfo.VideoCode, emails[i].Id) ct := confTmp.ConfigValue ct = strings.Replace(ct, "{{REPORT_TITLE}}", reportInfo.Title, 1) ct = strings.Replace(ct, "{{REPORT_ABSTRACT}}", reportInfo.Abstract, 1) ct = strings.Replace(ct, "{{REPORT_CONTENT}}", reportInfo.Overview, 1) ct = strings.Replace(ct, "{{REPORT_SHARE_LINK}}", l, 1) ct = strings.Replace(ct, "{{REPORT_TIME}}", t, 1) r.HtmlBody = ct r.ReportTitle = reportInfo.Title r.ReportAbstract = reportInfo.Abstract r.ReportContent = reportInfo.Overview r.ReportShareLink = l r.ReportTime = t logItem := &models.EnglishReportEmailLog{ ReportId: reportInfo.Id, ReportType: 1, EmailId: emails[i].Id, Email: emails[i].Email, Source: models.EnglishReportEmailLogSourceAli, SendStatus: models.EnglishReportEmailLogStatusIng, CreateTime: nowTime, } r.EmailLog = logItem sendData = append(sendData, r) // 日志 logData = append(logData, logItem) } // 标记原有日志为已删除 if len(logIds) > 0 { if e = models.DeleteEnglishReportEmailLogByIds(logIds); e != nil { br.Msg = "发送失败" br.ErrMsg = "删除原邮件日志失败, Err: " + e.Error() return } } // 写入新的日志 for _, v := range logData { if e = v.Create(); e != nil { br.Msg = "操作失败" br.ErrMsg = "写入群发邮件日志失败, Err: " + e.Error() return } } // 群发邮件 go func() { services.BatchSendAliEnglishReportEmail(sendData) }() br.Ret = 200 br.Success = true br.Msg = "操作成功" } // EditEnabled // @Title 移动至当前客户 // @Description 移动至当前客户 // @Param request body models.EnglishReportEditEnabledReq true "type json string" // @Success 200 string "操作成功" // @router /email/moveToCurrent [post] func (this *EnglishReportEmailController) MoveToCurrent() { br := new(models.BaseResponse).Init() br.IsSendEmail = false defer func() { this.Data["json"] = br this.ServeJSON() }() sysUser := this.SysUser if sysUser == nil { br.Msg = "请登录" br.ErrMsg = "请登录,SysUser Is Empty" br.Ret = 408 return } var req models.EnglishReportMoveReq if err := json.Unmarshal(this.Ctx.Input.RequestBody, &req); err != nil { br.Msg = "参数解析异常!" br.ErrMsg = "参数解析失败,Err:" + err.Error() return } if req.EmailId <= 0 { br.Msg = "参数有误" return } if req.CompanyId <= 0 { br.Msg = "参数有误" return } item, e := models.GetEnglishReportEmailById(req.EmailId) if e != nil { br.Msg = "联系人已被删除, 请勿操作" return } // 更新联系人 nowTime := time.Now().Local() item.CompanyId = req.CompanyId item.ModifyTime = nowTime item.Status = 1 updateCols := []string{"CompanyId", "ModifyTime", "Status"} if e = item.Update(updateCols); e != nil { br.Msg = "操作失败" br.ErrMsg = "更新英文联系人失败, Err:" + e.Error() return } // 更新所属客户状态 //go func() { // _ = services.UpdateEnglishCompanyEnabledByCompanyId(item.CompanyId) //}() // 记录日志 go func() { opByte, e := json.Marshal(req) if e != nil { return } opData := string(opByte) opLog := &models.EnglishReportEmailOpLog{ CompanyId: item.CompanyId, EmailId: item.Id, AdminId: sysUser.AdminId, OptionData: opData, OptionType: models.EnglishReportEmailOpLogTypeMoveToCurrent, CreateTime: nowTime, } if e = opLog.Create(); e != nil { return } }() br.Ret = 200 br.Success = true br.Msg = "操作成功" }