func()

in internal/controller/template_controller.go [303:449]


func (tc *TemplateController) QuestionInfo(ctx *gin.Context) {
	id := ctx.Param("id")
	title := ctx.Param("title")
	answerid := ctx.Param("answerid")
	shareUsername := ctx.Query("share")
	if checker.IsQuestionsIgnorePath(id) {
		// if id == "ask" {
		file, err := ui.Build.ReadFile("build/index.html")
		if err != nil {
			log.Error(err)
			tc.Page404(ctx)
			return
		}
		ctx.Header("content-type", "text/html;charset=utf-8")
		ctx.String(http.StatusOK, string(file))
		return
	}

	correctTitle := false

	detail, err := tc.templateRenderController.QuestionDetail(ctx, id)
	if err != nil {
		tc.Page404(ctx)
		return
	}
	if len(shareUsername) > 0 {
		userInfo, err := tc.userService.GetOtherUserInfoByUsername(
			ctx, &schema.GetOtherUserInfoByUsernameReq{Username: shareUsername})
		if err == nil {
			tc.eventQueueService.Send(ctx, schema.NewEvent(constant.EventUserShare, userInfo.ID).
				QID(id, detail.UserID).AID(answerid, ""))
		}
	}
	encodeTitle := htmltext.UrlTitle(detail.Title)
	if encodeTitle == title {
		correctTitle = true
	}

	siteInfo := tc.SiteInfo(ctx)
	jump, jumpurl := tc.QuestionInfoRedirect(ctx, siteInfo, correctTitle)
	if jump {
		ctx.Redirect(http.StatusFound, jumpurl)
		return
	}

	// answers
	answerReq := &schema.AnswerListReq{
		QuestionID: id,
		Order:      "",
		Page:       1,
		PageSize:   999,
		UserID:     "",
	}
	answers, answerCount, err := tc.templateRenderController.AnswerList(ctx, answerReq)
	if err != nil {
		tc.Page404(ctx)
		return
	}

	// comments
	objectIDs := []string{uid.DeShortID(id)}
	for _, answer := range answers {
		answerID := uid.DeShortID(answer.ID)
		objectIDs = append(objectIDs, answerID)
	}
	comments, err := tc.templateRenderController.CommentList(ctx, objectIDs)
	if err != nil {
		tc.Page404(ctx)
		return
	}

	UrlUseTitle := false
	if siteInfo.SiteSeo.Permalink == constant.PermalinkQuestionIDAndTitle ||
		siteInfo.SiteSeo.Permalink == constant.PermalinkQuestionIDAndTitleByShortID {
		UrlUseTitle = true
	}

	//related question
	userID := middleware.GetLoginUserIDFromContext(ctx)
	relatedQuestion, _, _ := tc.questionService.SimilarQuestion(ctx, id, userID)

	siteInfo.Canonical = fmt.Sprintf("%s/questions/%s/%s", siteInfo.General.SiteUrl, id, encodeTitle)
	if siteInfo.SiteSeo.Permalink == constant.PermalinkQuestionID || siteInfo.SiteSeo.Permalink == constant.PermalinkQuestionIDByShortID {
		siteInfo.Canonical = fmt.Sprintf("%s/questions/%s", siteInfo.General.SiteUrl, id)
	}
	jsonLD := &schema.QAPageJsonLD{}
	jsonLD.Context = "https://schema.org"
	jsonLD.Type = "QAPage"
	jsonLD.MainEntity.Type = "Question"
	jsonLD.MainEntity.Name = detail.Title
	jsonLD.MainEntity.Text = detail.HTML
	jsonLD.MainEntity.AnswerCount = int(answerCount)
	jsonLD.MainEntity.UpvoteCount = detail.VoteCount
	jsonLD.MainEntity.DateCreated = time.Unix(detail.CreateTime, 0)
	jsonLD.MainEntity.Author.Type = "Person"
	jsonLD.MainEntity.Author.Name = detail.UserInfo.DisplayName
	jsonLD.MainEntity.Author.URL = fmt.Sprintf("%s/users/%s", siteInfo.General.SiteUrl, detail.UserInfo.Username)
	answerList := make([]*schema.SuggestedAnswerItem, 0)
	for _, answer := range answers {
		if answer.Accepted == schema.AnswerAcceptedEnable {
			acceptedAnswerItem := &schema.AcceptedAnswerItem{}
			acceptedAnswerItem.Type = "Answer"
			acceptedAnswerItem.Text = answer.HTML
			acceptedAnswerItem.DateCreated = time.Unix(answer.CreateTime, 0)
			acceptedAnswerItem.UpvoteCount = answer.VoteCount
			acceptedAnswerItem.URL = fmt.Sprintf("%s/%s", siteInfo.Canonical, answer.ID)
			acceptedAnswerItem.Author.Type = "Person"
			acceptedAnswerItem.Author.Name = answer.UserInfo.DisplayName
			acceptedAnswerItem.Author.URL = fmt.Sprintf("%s/users/%s", siteInfo.General.SiteUrl, answer.UserInfo.Username)
			jsonLD.MainEntity.AcceptedAnswer = acceptedAnswerItem
		} else {
			item := &schema.SuggestedAnswerItem{}
			item.Type = "Answer"
			item.Text = answer.HTML
			item.DateCreated = time.Unix(answer.CreateTime, 0)
			item.UpvoteCount = answer.VoteCount
			item.URL = fmt.Sprintf("%s/%s", siteInfo.Canonical, answer.ID)
			item.Author.Type = "Person"
			item.Author.Name = answer.UserInfo.DisplayName
			item.Author.URL = fmt.Sprintf("%s/users/%s", siteInfo.General.SiteUrl, answer.UserInfo.Username)
			answerList = append(answerList, item)
		}
	}
	jsonLD.MainEntity.SuggestedAnswer = answerList
	jsonLDStr, err := json.Marshal(jsonLD)
	if err == nil {
		siteInfo.JsonLD = `<script data-react-helmet="true" type="application/ld+json">` + string(jsonLDStr) + ` </script>`
	}

	siteInfo.Description = htmltext.FetchExcerpt(detail.HTML, "...", 240)
	tags := make([]string, 0)
	for _, tag := range detail.Tags {
		tags = append(tags, tag.DisplayName)
	}
	siteInfo.Keywords = strings.Replace(strings.Trim(fmt.Sprint(tags), "[]"), " ", ",", -1)
	siteInfo.Title = fmt.Sprintf("%s - %s", detail.Title, siteInfo.General.Name)
	tc.html(ctx, http.StatusOK, "question-detail.html", siteInfo, gin.H{
		"id":              id,
		"answerid":        answerid,
		"detail":          detail,
		"answers":         answers,
		"comments":        comments,
		"noindex":         detail.Show == entity.QuestionHide,
		"useTitle":        UrlUseTitle,
		"relatedQuestion": relatedQuestion,
	})
}