144 lines
3.3 KiB
Go
144 lines
3.3 KiB
Go
package commentser
|
|
|
|
import (
|
|
"fmt"
|
|
"net/url"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
"videoweb/app/service/authser"
|
|
"videoweb/app/service/upstream"
|
|
"videoweb/pub/common/log"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
const (
|
|
listPath = "/api/app/comment/list"
|
|
defaultCommentSize = 10
|
|
)
|
|
|
|
// ListQuery 评论列表查询参数。
|
|
type ListQuery struct {
|
|
ObjectID int64
|
|
ObjectType int
|
|
PageNum int
|
|
PageSize int
|
|
SortOrder int
|
|
}
|
|
|
|
// Normalize 校正分页与排序默认值。
|
|
func (q *ListQuery) Normalize() {
|
|
if q.PageNum <= 0 {
|
|
q.PageNum = 1
|
|
}
|
|
if q.PageSize <= 0 {
|
|
q.PageSize = defaultCommentSize
|
|
}
|
|
if q.PageSize > 50 {
|
|
q.PageSize = 50
|
|
}
|
|
q.ObjectType = NormalizeObjectType(q.ObjectType)
|
|
if q.SortOrder != SortLatest {
|
|
q.SortOrder = SortHot
|
|
}
|
|
}
|
|
|
|
// FetchList 分页查询评论。
|
|
func FetchList(c *gin.Context, q ListQuery) (*GetCommentListResp, error) {
|
|
q.Normalize()
|
|
if q.ObjectID <= 0 {
|
|
return nil, fmt.Errorf("comment list invalid objectId")
|
|
}
|
|
params := url.Values{}
|
|
params.Set("objectId", strconv.FormatInt(q.ObjectID, 10))
|
|
params.Set("objectType", strconv.Itoa(q.ObjectType))
|
|
params.Set("pageNum", strconv.Itoa(q.PageNum))
|
|
params.Set("pageSize", strconv.Itoa(q.PageSize))
|
|
params.Set("sortOrder", strconv.Itoa(q.SortOrder))
|
|
|
|
authser.EnsureGuestOnEnter(c)
|
|
requestPath := listPath + "?" + params.Encode()
|
|
env, err := fetchListOnce(c, requestPath)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if env.Code != 200 && authser.IsSessionExpiredCode(env.Code) && authser.RecoverContentSession(c, env.Code) {
|
|
env, err = fetchListOnce(c, requestPath)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
if env.Code != 200 {
|
|
return nil, fmt.Errorf("comment list code=%d msg=%s", env.Code, env.Msg)
|
|
}
|
|
return &env.Data, nil
|
|
}
|
|
|
|
func fetchListOnce(c *gin.Context, path string) (*APIEnvelope[GetCommentListResp], error) {
|
|
var env APIEnvelope[GetCommentListResp]
|
|
if err := upstream.GetJSON(c, path, &env); err != nil {
|
|
return nil, err
|
|
}
|
|
return &env, nil
|
|
}
|
|
|
|
// FetchListOrEmpty 失败时返回空列表。
|
|
func FetchListOrEmpty(c *gin.Context, q ListQuery) *GetCommentListResp {
|
|
data, err := FetchList(c, q)
|
|
if err != nil {
|
|
log.Error("fetch comment list failed", log.E(err))
|
|
return &GetCommentListResp{
|
|
ObjectID: q.ObjectID,
|
|
PageNum: q.PageNum,
|
|
PageSize: q.PageSize,
|
|
}
|
|
}
|
|
if data == nil {
|
|
return &GetCommentListResp{
|
|
ObjectID: q.ObjectID,
|
|
PageNum: q.PageNum,
|
|
PageSize: q.PageSize,
|
|
}
|
|
}
|
|
return data
|
|
}
|
|
|
|
// ParseSortOrder 解析站点评论排序(1 热门 / 2 最新)。
|
|
func ParseSortOrder(s string) int {
|
|
n, err := strconv.Atoi(strings.TrimSpace(s))
|
|
if err != nil || n != SortLatest {
|
|
return SortHot
|
|
}
|
|
return SortLatest
|
|
}
|
|
|
|
// FormatCreatedAt 展示用时间格式化(非字段映射)。
|
|
func FormatCreatedAt(raw string) string {
|
|
raw = strings.TrimSpace(raw)
|
|
if raw == "" {
|
|
return ""
|
|
}
|
|
layouts := []string{
|
|
time.RFC3339Nano,
|
|
time.RFC3339,
|
|
"2006-01-02T15:04:05Z07:00",
|
|
"2006-01-02 15:04:05",
|
|
}
|
|
for _, layout := range layouts {
|
|
if t, err := time.Parse(layout, raw); err == nil {
|
|
return t.Local().Format("2006/1/2 15:04")
|
|
}
|
|
}
|
|
return raw
|
|
}
|
|
|
|
// AvatarOrDefault 头像空时回退默认图。
|
|
func AvatarOrDefault(avatar string) string {
|
|
avatar = strings.TrimSpace(avatar)
|
|
if avatar == "" {
|
|
return "/static/images/profile/avatar.png"
|
|
}
|
|
return avatar
|
|
}
|