308 lines
6.5 KiB
Go
308 lines
6.5 KiB
Go
package handler
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"net/http"
|
|
|
|
bizlive "kra/internal/biz/live"
|
|
"kra/internal/service/dto"
|
|
liveservice "kra/internal/service/live"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
type Live struct {
|
|
service *liveservice.StreamService
|
|
catalog *liveservice.CatalogService
|
|
follows *liveservice.FollowService
|
|
}
|
|
|
|
func NewLive(service *liveservice.StreamService, catalog *liveservice.CatalogService, follows *liveservice.FollowService) *Live {
|
|
return &Live{service: service, catalog: catalog, follows: follows}
|
|
}
|
|
|
|
func (h *Live) FollowStatus(c *gin.Context) {
|
|
id, ok := businessID(c)
|
|
if !ok {
|
|
return
|
|
}
|
|
claims := Claims(c)
|
|
if claims == nil {
|
|
NoAuth(c, "请登录")
|
|
return
|
|
}
|
|
followed, err := h.follows.Status(c.Request.Context(), claims.ID, id)
|
|
if err != nil {
|
|
businessFail(c, err)
|
|
return
|
|
}
|
|
OKWithData(c, gin.H{"followed": followed})
|
|
}
|
|
|
|
func (h *Live) Follow(c *gin.Context) {
|
|
id, ok := businessID(c)
|
|
if !ok {
|
|
return
|
|
}
|
|
claims := Claims(c)
|
|
if claims == nil {
|
|
NoAuth(c, "请登录")
|
|
return
|
|
}
|
|
followed, err := h.follows.Follow(c.Request.Context(), claims.ID, id)
|
|
if err != nil {
|
|
businessFail(c, err)
|
|
return
|
|
}
|
|
OKWithData(c, gin.H{"followed": followed})
|
|
}
|
|
|
|
func (h *Live) Unfollow(c *gin.Context) {
|
|
id, ok := businessID(c)
|
|
if !ok {
|
|
return
|
|
}
|
|
claims := Claims(c)
|
|
if claims == nil {
|
|
NoAuth(c, "请登录")
|
|
return
|
|
}
|
|
if err := h.follows.Unfollow(c.Request.Context(), claims.ID, id); err != nil {
|
|
businessFail(c, err)
|
|
return
|
|
}
|
|
OKWithData(c, gin.H{"followed": false})
|
|
}
|
|
|
|
func (h *Live) Like(c *gin.Context) {
|
|
id, ok := businessID(c)
|
|
if !ok {
|
|
return
|
|
}
|
|
// Do not create runtime stream state for arbitrary room IDs. The stream
|
|
// repository is process-local, so validating the catalog first also keeps
|
|
// bogus likes from accumulating forever.
|
|
room, err := h.catalog.GetPublicRoom(c.Request.Context(), id)
|
|
if err != nil {
|
|
businessFail(c, err)
|
|
return
|
|
}
|
|
if !room.Enabled || room.Status != bizlive.RoomStatusLive {
|
|
businessFail(c, bizlive.ErrRoomNotLive)
|
|
return
|
|
}
|
|
count, err := h.service.Like(c.Request.Context(), fmt.Sprintf("room-%d", id))
|
|
if err != nil {
|
|
businessFail(c, err)
|
|
return
|
|
}
|
|
OKWithData(c, gin.H{"likeCount": count})
|
|
}
|
|
|
|
func (h *Live) List(c *gin.Context) {
|
|
items, err := h.service.List(c.Request.Context())
|
|
if err != nil {
|
|
Fail(c, "直播列表获取失败")
|
|
return
|
|
}
|
|
Write(c, CodeSuccess, gin.H{"streams": items}, "获取成功")
|
|
}
|
|
|
|
func (h *Live) ListCategories(c *gin.Context) {
|
|
in, ok := bindQuery[dto.LiveCategoryListRequest](c)
|
|
if !ok {
|
|
return
|
|
}
|
|
items, total, e := h.catalog.ListCategories(c.Request.Context(), in)
|
|
if e != nil {
|
|
businessFail(c, e)
|
|
return
|
|
}
|
|
OKWithData(c, gin.H{"list": items, "total": total})
|
|
}
|
|
func (h *Live) PublicCategories(c *gin.Context) {
|
|
enabled := true
|
|
in := &dto.LiveCategoryListRequest{LiveListRequest: dto.LiveListRequest{Page: 1, PageSize: 100, OrderBy: "sort_asc"}, Enabled: &enabled}
|
|
items, _, e := h.catalog.ListCategories(c.Request.Context(), in)
|
|
if e != nil {
|
|
businessFail(c, e)
|
|
return
|
|
}
|
|
OKWithData(c, gin.H{"list": items})
|
|
}
|
|
func (h *Live) CreateCategory(c *gin.Context) {
|
|
in, ok := bindJSON[dto.LiveCategoryRequest](c)
|
|
if !ok {
|
|
return
|
|
}
|
|
v, e := h.catalog.CreateCategory(c.Request.Context(), in)
|
|
if e != nil {
|
|
businessFail(c, e)
|
|
return
|
|
}
|
|
OKWithData(c, v)
|
|
}
|
|
func (h *Live) UpdateCategory(c *gin.Context) {
|
|
id, ok := businessID(c)
|
|
if !ok {
|
|
return
|
|
}
|
|
in, ok := bindJSON[dto.LiveCategoryRequest](c)
|
|
if !ok {
|
|
return
|
|
}
|
|
v, e := h.catalog.UpdateCategory(c.Request.Context(), id, in)
|
|
if e != nil {
|
|
businessFail(c, e)
|
|
return
|
|
}
|
|
OKWithData(c, v)
|
|
}
|
|
func (h *Live) DeleteCategory(c *gin.Context) {
|
|
id, ok := businessID(c)
|
|
if !ok {
|
|
return
|
|
}
|
|
if e := h.catalog.DeleteCategory(c.Request.Context(), id); e != nil {
|
|
businessFail(c, e)
|
|
return
|
|
}
|
|
OK(c)
|
|
}
|
|
func (h *Live) ListRooms(c *gin.Context) {
|
|
in, ok := bindQuery[dto.LiveRoomListRequest](c)
|
|
if !ok {
|
|
return
|
|
}
|
|
items, total, e := h.catalog.ListRooms(c.Request.Context(), in)
|
|
if e != nil {
|
|
businessFail(c, e)
|
|
return
|
|
}
|
|
OKWithData(c, gin.H{"list": items, "total": total})
|
|
}
|
|
func (h *Live) PublicRooms(c *gin.Context) {
|
|
in, ok := bindQuery[dto.LiveRoomListRequest](c)
|
|
if !ok {
|
|
return
|
|
}
|
|
if in.Page < 1 {
|
|
in.Page = 1
|
|
}
|
|
if in.PageSize < 1 {
|
|
in.PageSize = 20
|
|
}
|
|
if in.OrderBy == "" {
|
|
in.OrderBy = "viewer_count_desc"
|
|
}
|
|
items, total, e := h.catalog.ListPublicRooms(c.Request.Context(), in)
|
|
if e != nil {
|
|
businessFail(c, e)
|
|
return
|
|
}
|
|
OKWithData(c, gin.H{"list": items, "total": total, "page": in.Page, "pageSize": in.PageSize})
|
|
}
|
|
func (h *Live) GetPublicRoom(c *gin.Context) {
|
|
id, ok := businessID(c)
|
|
if !ok {
|
|
return
|
|
}
|
|
v, e := h.catalog.GetPublicRoom(c.Request.Context(), id)
|
|
if e != nil {
|
|
businessFail(c, e)
|
|
return
|
|
}
|
|
OKWithData(c, v)
|
|
}
|
|
func (h *Live) GetRoom(c *gin.Context) {
|
|
id, ok := businessID(c)
|
|
if !ok {
|
|
return
|
|
}
|
|
v, e := h.catalog.GetRoom(c.Request.Context(), id)
|
|
if e != nil {
|
|
businessFail(c, e)
|
|
return
|
|
}
|
|
OKWithData(c, v)
|
|
}
|
|
func (h *Live) CreateRoom(c *gin.Context) {
|
|
in, ok := bindJSON[dto.LiveRoomRequest](c)
|
|
if !ok {
|
|
return
|
|
}
|
|
v, e := h.catalog.CreateRoom(c.Request.Context(), in)
|
|
if e != nil {
|
|
businessFail(c, e)
|
|
return
|
|
}
|
|
OKWithData(c, v)
|
|
}
|
|
func (h *Live) UpdateRoom(c *gin.Context) {
|
|
id, ok := businessID(c)
|
|
if !ok {
|
|
return
|
|
}
|
|
in, ok := bindJSON[dto.LiveRoomRequest](c)
|
|
if !ok {
|
|
return
|
|
}
|
|
v, e := h.catalog.UpdateRoom(c.Request.Context(), id, in)
|
|
if e != nil {
|
|
businessFail(c, e)
|
|
return
|
|
}
|
|
OKWithData(c, v)
|
|
}
|
|
func (h *Live) DeleteRoom(c *gin.Context) {
|
|
id, ok := businessID(c)
|
|
if !ok {
|
|
return
|
|
}
|
|
if e := h.catalog.DeleteRoom(c.Request.Context(), id); e != nil {
|
|
businessFail(c, e)
|
|
return
|
|
}
|
|
OK(c)
|
|
}
|
|
func (h *Live) SetRoomStatus(c *gin.Context) {
|
|
id, ok := businessID(c)
|
|
if !ok {
|
|
return
|
|
}
|
|
in, ok := bindJSON[dto.LiveStatusRequest](c)
|
|
if !ok {
|
|
return
|
|
}
|
|
if e := h.catalog.SetRoomEnabled(c.Request.Context(), id, in.Enabled); e != nil {
|
|
businessFail(c, e)
|
|
return
|
|
}
|
|
OK(c)
|
|
}
|
|
func (h *Live) SaveRoomSort(c *gin.Context) {
|
|
in, ok := bindJSON[dto.LiveSortRequest](c)
|
|
if !ok {
|
|
return
|
|
}
|
|
if e := h.catalog.SaveRoomSort(c.Request.Context(), in.Values); e != nil {
|
|
businessFail(c, e)
|
|
return
|
|
}
|
|
OK(c)
|
|
}
|
|
|
|
func (h *Live) Find(c *gin.Context) {
|
|
item, err := h.service.Get(c.Request.Context(), c.Param("streamId"))
|
|
if err != nil {
|
|
if errors.Is(err, bizlive.ErrInvalidStreamID) {
|
|
c.JSON(http.StatusBadRequest, gin.H{"code": http.StatusBadRequest, "data": nil, "msg": "streamId 无效"})
|
|
return
|
|
}
|
|
Fail(c, "直播间获取失败")
|
|
return
|
|
}
|
|
Write(c, CodeSuccess, gin.H{"stream": item}, "获取成功")
|
|
}
|