fix(email): fix all incorrect url in email.

This commit is contained in:
LinkinStars 2023-10-08 17:58:52 +08:00
parent a920e5c2c1
commit ee5613099f
8 changed files with 127 additions and 87 deletions

View File

@ -121,7 +121,7 @@ func initApplication(debug bool, serverConf *conf.Server, dbConf *data.Database,
userRankRepo := rank.NewUserRankRepo(dataData, configService)
userActiveActivityRepo := activity.NewUserActiveActivityRepo(dataData, activityRepo, userRankRepo, configService)
emailRepo := export.NewEmailRepo(dataData)
emailService := export2.NewEmailService(configService, emailRepo, siteInfoRepo)
emailService := export2.NewEmailService(configService, emailRepo, siteInfoCommonService)
userRoleRelRepo := role.NewUserRoleRelRepo(dataData)
roleRepo := role.NewRoleRepo(dataData)
roleService := role2.NewRoleService(roleRepo)

View File

@ -9,12 +9,12 @@ const (
)
const (
// PermaLinkQuestionIDAndTitle /questions/10010000000000001/post-title
PermaLinkQuestionIDAndTitle = iota + 1
// PermaLinkQuestionID /questions/10010000000000001
PermaLinkQuestionID
// PermaLinkQuestionIDAndTitleByShortID /questions/11/post-title
PermaLinkQuestionIDAndTitleByShortID
// PermaLinkQuestionIDByShortID /questions/11
PermaLinkQuestionIDByShortID
// PermalinkQuestionIDAndTitle /questions/10010000000000001/post-title
PermalinkQuestionIDAndTitle = iota + 1
// PermalinkQuestionID /questions/10010000000000001
PermalinkQuestionID
// PermalinkQuestionIDAndTitleByShortID /questions/11/post-title
PermalinkQuestionIDAndTitleByShortID
// PermalinkQuestionIDByShortID /questions/11
PermalinkQuestionIDByShortID
)

View File

@ -116,7 +116,7 @@ func (tc *TemplateController) Index(ctx *gin.Context) {
siteInfo.Canonical = siteInfo.General.SiteUrl
UrlUseTitle := false
if siteInfo.SiteSeo.PermaLink == constant.PermaLinkQuestionIDAndTitle {
if siteInfo.SiteSeo.Permalink == constant.PermalinkQuestionIDAndTitle {
UrlUseTitle = true
}
siteInfo.Title = ""
@ -149,7 +149,7 @@ func (tc *TemplateController) QuestionList(ctx *gin.Context) {
}
UrlUseTitle := false
if siteInfo.SiteSeo.PermaLink == constant.PermaLinkQuestionIDAndTitle {
if siteInfo.SiteSeo.Permalink == constant.PermalinkQuestionIDAndTitle {
UrlUseTitle = true
}
siteInfo.Title = fmt.Sprintf("Questions - %s", siteInfo.General.Name)
@ -196,7 +196,7 @@ func (tc *TemplateController) QuestionInfoeRdirect(ctx *gin.Context, siteInfo *s
}
url = fmt.Sprintf("%s/questions/%s", siteInfo.General.SiteUrl, questionID)
if siteInfo.SiteSeo.PermaLink == constant.PermaLinkQuestionID || siteInfo.SiteSeo.PermaLink == constant.PermaLinkQuestionIDByShortID {
if siteInfo.SiteSeo.Permalink == constant.PermalinkQuestionID || siteInfo.SiteSeo.Permalink == constant.PermalinkQuestionIDByShortID {
if len(ctx.Request.URL.Query()) > 0 {
url = fmt.Sprintf("%s?%s", url, ctx.Request.URL.RawQuery)
}
@ -299,7 +299,7 @@ func (tc *TemplateController) QuestionInfo(ctx *gin.Context) {
return
}
siteInfo.Canonical = fmt.Sprintf("%s/questions/%s/%s", siteInfo.General.SiteUrl, id, encodeTitle)
if siteInfo.SiteSeo.PermaLink == constant.PermaLinkQuestionID {
if siteInfo.SiteSeo.Permalink == constant.PermalinkQuestionID {
siteInfo.Canonical = fmt.Sprintf("%s/questions/%s", siteInfo.General.SiteUrl, id)
}
jsonLD := &schema.QAPageJsonLD{}
@ -414,7 +414,7 @@ func (tc *TemplateController) TagInfo(ctx *gin.Context) {
siteInfo.Keywords = taginifo.DisplayName
UrlUseTitle := false
if siteInfo.SiteSeo.PermaLink == constant.PermaLinkQuestionIDAndTitle {
if siteInfo.SiteSeo.Permalink == constant.PermalinkQuestionIDAndTitle {
UrlUseTitle = true
}
siteInfo.Title = fmt.Sprintf("'%s' Questions - %s", taginifo.DisplayName, siteInfo.General.Name)

View File

@ -44,8 +44,8 @@ func (t *TemplateRenderController) Sitemap(ctx *gin.Context) {
"xmlHeader": template.HTML(`<?xml version="1.0" encoding="UTF-8"?>`),
"list": questions,
"general": general,
"hastitle": siteInfo.PermaLink == constant.PermaLinkQuestionIDAndTitle ||
siteInfo.PermaLink == constant.PermaLinkQuestionIDAndTitleByShortID,
"hastitle": siteInfo.Permalink == constant.PermalinkQuestionIDAndTitle ||
siteInfo.Permalink == constant.PermalinkQuestionIDAndTitleByShortID,
},
)
return
@ -93,8 +93,8 @@ func (t *TemplateRenderController) SitemapPage(ctx *gin.Context, page int) error
"xmlHeader": template.HTML(`<?xml version="1.0" encoding="UTF-8"?>`),
"list": questions,
"general": general,
"hastitle": siteInfo.PermaLink == constant.PermaLinkQuestionIDAndTitle ||
siteInfo.PermaLink == constant.PermaLinkQuestionIDAndTitleByShortID,
"hastitle": siteInfo.Permalink == constant.PermalinkQuestionIDAndTitle ||
siteInfo.Permalink == constant.PermalinkQuestionIDAndTitleByShortID,
},
)
return nil

View File

@ -34,6 +34,25 @@ func (r *EmailCodeContent) FromJSONString(data string) error {
return json.Unmarshal([]byte(data), &r)
}
type RegisterTemplateData struct {
SiteName string
RegisterUrl string
}
type PassResetTemplateData struct {
SiteName string
PassResetUrl string
}
type ChangeEmailTemplateData struct {
SiteName string
ChangeEmailUrl string
}
type TestTemplateData struct {
SiteName string
}
type NewAnswerTemplateRawData struct {
AnswerUserDisplayName string
QuestionTitle string

View File

@ -118,13 +118,13 @@ type SiteThemeReq struct {
}
type SiteSeoReq struct {
PermaLink int `validate:"required,lte=4,gte=0" form:"permalink" json:"permalink"`
Permalink int `validate:"required,lte=4,gte=0" form:"permalink" json:"permalink"`
Robots string `validate:"required" form:"robots" json:"robots"`
}
func (s *SiteSeoResp) IsShortLink() bool {
return s.PermaLink == constant.PermaLinkQuestionIDAndTitleByShortID ||
s.PermaLink == constant.PermaLinkQuestionIDByShortID
return s.Permalink == constant.PermalinkQuestionIDAndTitleByShortID ||
s.Permalink == constant.PermalinkQuestionIDByShortID
}
// SiteGeneralResp site general response

View File

@ -4,6 +4,7 @@ import (
"crypto/tls"
"encoding/json"
"fmt"
"github.com/answerdev/answer/pkg/display"
"mime"
"os"
"strings"
@ -13,7 +14,6 @@ import (
"github.com/answerdev/answer/internal/base/handler"
"github.com/answerdev/answer/internal/base/reason"
"github.com/answerdev/answer/internal/base/translator"
"github.com/answerdev/answer/internal/entity"
"github.com/answerdev/answer/internal/schema"
"github.com/answerdev/answer/internal/service/config"
"github.com/answerdev/answer/internal/service/siteinfo_common"
@ -25,9 +25,9 @@ import (
// EmailService kit service
type EmailService struct {
configService *config.ConfigService
emailRepo EmailRepo
siteInfoRepo siteinfo_common.SiteInfoRepo
configService *config.ConfigService
emailRepo EmailRepo
siteInfoService siteinfo_common.SiteInfoCommonService
}
// EmailRepo email repository
@ -37,11 +37,15 @@ type EmailRepo interface {
}
// NewEmailService email service
func NewEmailService(configService *config.ConfigService, emailRepo EmailRepo, siteInfoRepo siteinfo_common.SiteInfoRepo) *EmailService {
func NewEmailService(
configService *config.ConfigService,
emailRepo EmailRepo,
siteInfoService siteinfo_common.SiteInfoCommonService,
) *EmailService {
return &EmailService{
configService: configService,
emailRepo: emailRepo,
siteInfoRepo: siteInfoRepo,
configService: configService,
emailRepo: emailRepo,
siteInfoService: siteInfoService,
}
}
@ -61,25 +65,6 @@ func (e *EmailConfig) IsSSL() bool {
return e.Encryption == "SSL"
}
type RegisterTemplateData struct {
SiteName string
RegisterUrl string
}
type PassResetTemplateData struct {
SiteName string
PassResetUrl string
}
type ChangeEmailTemplateData struct {
SiteName string
ChangeEmailUrl string
}
type TestTemplateData struct {
SiteName string
}
// SaveCode save code
func (es *EmailService) SaveCode(ctx context.Context, code, codeContent string) {
err := es.emailRepo.SetCode(ctx, code, codeContent, 10*time.Minute)
@ -150,29 +135,12 @@ func (es *EmailService) VerifyUrlExpired(ctx context.Context, code string) (cont
return content
}
func (es *EmailService) getSiteGeneral(ctx context.Context) (resp schema.SiteGeneralResp, err error) {
var (
siteType = "general"
siteInfo *entity.SiteInfo
exist bool
)
resp = schema.SiteGeneralResp{}
siteInfo, exist, err = es.siteInfoRepo.GetByType(ctx, siteType)
if !exist {
return
}
_ = json.Unmarshal([]byte(siteInfo.Content), &resp)
return
}
func (es *EmailService) RegisterTemplate(ctx context.Context, registerUrl string) (title, body string, err error) {
siteInfo, err := es.getSiteGeneral(ctx)
siteInfo, err := es.siteInfoService.GetSiteGeneral(ctx)
if err != nil {
return
}
templateData := RegisterTemplateData{
templateData := &schema.RegisterTemplateData{
SiteName: siteInfo.Name,
RegisterUrl: registerUrl,
}
@ -184,12 +152,12 @@ func (es *EmailService) RegisterTemplate(ctx context.Context, registerUrl string
}
func (es *EmailService) PassResetTemplate(ctx context.Context, passResetUrl string) (title, body string, err error) {
siteInfo, err := es.getSiteGeneral(ctx)
siteInfo, err := es.siteInfoService.GetSiteGeneral(ctx)
if err != nil {
return
}
templateData := PassResetTemplateData{SiteName: siteInfo.Name, PassResetUrl: passResetUrl}
templateData := &schema.PassResetTemplateData{SiteName: siteInfo.Name, PassResetUrl: passResetUrl}
lang := handler.GetLangByCtx(ctx)
title = translator.TrWithData(lang, constant.EmailTplKeyPassResetTitle, templateData)
@ -198,11 +166,11 @@ func (es *EmailService) PassResetTemplate(ctx context.Context, passResetUrl stri
}
func (es *EmailService) ChangeEmailTemplate(ctx context.Context, changeEmailUrl string) (title, body string, err error) {
siteInfo, err := es.getSiteGeneral(ctx)
siteInfo, err := es.siteInfoService.GetSiteGeneral(ctx)
if err != nil {
return
}
templateData := ChangeEmailTemplateData{
templateData := &schema.ChangeEmailTemplateData{
SiteName: siteInfo.Name,
ChangeEmailUrl: changeEmailUrl,
}
@ -215,11 +183,11 @@ func (es *EmailService) ChangeEmailTemplate(ctx context.Context, changeEmailUrl
// TestTemplate send test email template parse
func (es *EmailService) TestTemplate(ctx context.Context) (title, body string, err error) {
siteInfo, err := es.getSiteGeneral(ctx)
siteInfo, err := es.siteInfoService.GetSiteGeneral(ctx)
if err != nil {
return
}
templateData := TestTemplateData{SiteName: siteInfo.Name}
templateData := &schema.TestTemplateData{SiteName: siteInfo.Name}
lang := handler.GetLangByCtx(ctx)
title = translator.TrWithData(lang, constant.EmailTplKeyTestTitle, templateData)
@ -230,7 +198,11 @@ func (es *EmailService) TestTemplate(ctx context.Context) (title, body string, e
// NewAnswerTemplate new answer template
func (es *EmailService) NewAnswerTemplate(ctx context.Context, raw *schema.NewAnswerTemplateRawData) (
title, body string, err error) {
siteInfo, err := es.getSiteGeneral(ctx)
siteInfo, err := es.siteInfoService.GetSiteGeneral(ctx)
if err != nil {
return
}
seoInfo, err := es.siteInfoService.GetSiteSeo(ctx)
if err != nil {
return
}
@ -238,7 +210,7 @@ func (es *EmailService) NewAnswerTemplate(ctx context.Context, raw *schema.NewAn
SiteName: siteInfo.Name,
DisplayName: raw.AnswerUserDisplayName,
QuestionTitle: raw.QuestionTitle,
AnswerUrl: fmt.Sprintf("%s/questions/%s/%s", siteInfo.SiteUrl, raw.QuestionID, raw.AnswerID),
AnswerUrl: display.AnswerURL(seoInfo.Permalink, siteInfo.SiteUrl, raw.QuestionID, raw.QuestionTitle, raw.AnswerID),
AnswerSummary: raw.AnswerSummary,
UnsubscribeUrl: fmt.Sprintf("%s/users/unsubscribe?code=%s", siteInfo.SiteUrl, raw.UnsubscribeCode),
}
@ -252,7 +224,11 @@ func (es *EmailService) NewAnswerTemplate(ctx context.Context, raw *schema.NewAn
// NewInviteAnswerTemplate new invite answer template
func (es *EmailService) NewInviteAnswerTemplate(ctx context.Context, raw *schema.NewInviteAnswerTemplateRawData) (
title, body string, err error) {
siteInfo, err := es.getSiteGeneral(ctx)
siteInfo, err := es.siteInfoService.GetSiteGeneral(ctx)
if err != nil {
return
}
seoInfo, err := es.siteInfoService.GetSiteSeo(ctx)
if err != nil {
return
}
@ -260,7 +236,7 @@ func (es *EmailService) NewInviteAnswerTemplate(ctx context.Context, raw *schema
SiteName: siteInfo.Name,
DisplayName: raw.InviterDisplayName,
QuestionTitle: raw.QuestionTitle,
InviteUrl: fmt.Sprintf("%s/questions/%s", siteInfo.SiteUrl, raw.QuestionID),
InviteUrl: display.QuestionURL(seoInfo.Permalink, siteInfo.SiteUrl, raw.QuestionID, raw.QuestionTitle),
UnsubscribeUrl: fmt.Sprintf("%s/users/unsubscribe?code=%s", siteInfo.SiteUrl, raw.UnsubscribeCode),
}
@ -273,7 +249,11 @@ func (es *EmailService) NewInviteAnswerTemplate(ctx context.Context, raw *schema
// NewCommentTemplate new comment template
func (es *EmailService) NewCommentTemplate(ctx context.Context, raw *schema.NewCommentTemplateRawData) (
title, body string, err error) {
siteInfo, err := es.getSiteGeneral(ctx)
siteInfo, err := es.siteInfoService.GetSiteGeneral(ctx)
if err != nil {
return
}
seoInfo, err := es.siteInfoService.GetSiteSeo(ctx)
if err != nil {
return
}
@ -284,13 +264,8 @@ func (es *EmailService) NewCommentTemplate(ctx context.Context, raw *schema.NewC
CommentSummary: raw.CommentSummary,
UnsubscribeUrl: fmt.Sprintf("%s/users/unsubscribe?code=%s", siteInfo.SiteUrl, raw.UnsubscribeCode),
}
if len(raw.AnswerID) > 0 {
templateData.CommentUrl = fmt.Sprintf("%s/questions/%s/%s?commentId=%s", siteInfo.SiteUrl, raw.QuestionID,
raw.AnswerID, raw.CommentID)
} else {
templateData.CommentUrl = fmt.Sprintf("%s/questions/%s?commentId=%s", siteInfo.SiteUrl,
raw.QuestionID, raw.CommentID)
}
templateData.CommentUrl = display.CommentURL(seoInfo.Permalink,
siteInfo.SiteUrl, raw.QuestionID, raw.QuestionTitle, raw.AnswerID, raw.CommentID)
lang := handler.GetLangByCtx(ctx)
title = translator.TrWithData(lang, constant.EmailTplKeyNewCommentTitle, templateData)
@ -301,7 +276,11 @@ func (es *EmailService) NewCommentTemplate(ctx context.Context, raw *schema.NewC
// NewQuestionTemplate new question template
func (es *EmailService) NewQuestionTemplate(ctx context.Context, raw *schema.NewQuestionTemplateRawData) (
title, body string, err error) {
siteInfo, err := es.getSiteGeneral(ctx)
siteInfo, err := es.siteInfoService.GetSiteGeneral(ctx)
if err != nil {
return
}
seoInfo, err := es.siteInfoService.GetSiteSeo(ctx)
if err != nil {
return
}
@ -311,7 +290,8 @@ func (es *EmailService) NewQuestionTemplate(ctx context.Context, raw *schema.New
Tags: strings.Join(raw.Tags, ", "),
UnsubscribeUrl: fmt.Sprintf("%s/users/unsubscribe?code=%s", siteInfo.SiteUrl, raw.UnsubscribeCode),
}
templateData.QuestionUrl = fmt.Sprintf("%s/questions/%s", siteInfo.SiteUrl, raw.QuestionID)
templateData.QuestionUrl = display.QuestionURL(
seoInfo.Permalink, siteInfo.SiteUrl, raw.QuestionID, raw.QuestionTitle)
lang := handler.GetLangByCtx(ctx)
title = translator.TrWithData(lang, constant.EmailTplKeyNewQuestionTitle, templateData)

41
pkg/display/url.go Normal file
View File

@ -0,0 +1,41 @@
package display
import (
"github.com/answerdev/answer/internal/base/constant"
"github.com/answerdev/answer/pkg/htmltext"
"github.com/answerdev/answer/pkg/uid"
)
// QuestionURL get question url
func QuestionURL(permalink int, siteUrl, questionID, title string) string {
u := siteUrl + "/questions"
if permalink == constant.PermalinkQuestionIDAndTitle || permalink == constant.PermalinkQuestionID {
questionID = uid.DeShortID(questionID)
} else {
questionID = uid.EnShortID(questionID)
}
u += "/" + questionID
if permalink == constant.PermalinkQuestionIDAndTitle || permalink == constant.PermalinkQuestionIDAndTitleByShortID {
u += "/" + htmltext.UrlTitle(title)
}
return u
}
// AnswerURL get answer url
func AnswerURL(permalink int, siteUrl, questionID, title, answerID string) string {
if permalink == constant.PermalinkQuestionIDAndTitle ||
permalink == constant.PermalinkQuestionID {
answerID = uid.DeShortID(answerID)
} else {
answerID = uid.EnShortID(answerID)
}
return QuestionURL(permalink, siteUrl, questionID, title) + "/" + answerID
}
// CommentURL get comment url
func CommentURL(permalink int, siteUrl, questionID, title, answerID, commentID string) string {
if len(answerID) > 0 {
return AnswerURL(permalink, siteUrl, questionID, answerID, title) + "?commentId=" + commentID
}
return QuestionURL(permalink, siteUrl, questionID, title) + "?commentId=" + commentID
}