feat: live module and jenkins pipeline to harbor deploy
This commit is contained in:
@@ -2,6 +2,7 @@ package server
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
@@ -97,7 +98,7 @@ func TestGinStartupLogsEveryRegisteredRoute(t *testing.T) {
|
||||
if got, want := strings.Count(text, `"msg":"router registered"`), len(engine.Routes()); got != want {
|
||||
t.Fatalf("registered route log count = %d, want %d", got, want)
|
||||
}
|
||||
if !strings.Contains(text, `"msg":"router register success"`) || !strings.Contains(text, `"route_count":196`) {
|
||||
if !strings.Contains(text, `"msg":"router register success"`) || !strings.Contains(text, fmt.Sprintf(`"route_count":%d`, len(engine.Routes()))) {
|
||||
t.Fatalf("startup route summary is missing: %s", text)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
service "kra/internal/service/analytics"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
type Analytics struct{ s *service.Service }
|
||||
|
||||
func NewAnalytics(s *service.Service) *Analytics { return &Analytics{s: s} }
|
||||
func (h *Analytics) Dashboard(c *gin.Context) {
|
||||
days, _ := strconv.Atoi(c.DefaultQuery("days", "1"))
|
||||
v, e := h.s.Get(c.Request.Context(), days)
|
||||
if e != nil {
|
||||
businessFail(c, e)
|
||||
return
|
||||
}
|
||||
OKWithData(c, v)
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
service "kra/internal/service/asset"
|
||||
"kra/internal/service/dto"
|
||||
)
|
||||
|
||||
type Asset struct{ s *service.Service }
|
||||
|
||||
func NewAsset(s *service.Service) *Asset { return &Asset{s: s} }
|
||||
func (h *Asset) List(c *gin.Context) {
|
||||
in, ok := bindQuery[dto.AssetUserListRequest](c)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
v, total, e := h.s.List(c.Request.Context(), in)
|
||||
if e != nil {
|
||||
businessFail(c, e)
|
||||
return
|
||||
}
|
||||
OKWithData(c, gin.H{"list": v, "total": total})
|
||||
}
|
||||
func (h *Asset) Get(c *gin.Context) {
|
||||
id, ok := businessID(c)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
v, e := h.s.Get(c.Request.Context(), id)
|
||||
if e != nil {
|
||||
businessFail(c, e)
|
||||
return
|
||||
}
|
||||
OKWithData(c, v)
|
||||
}
|
||||
func (h *Asset) Status(c *gin.Context) {
|
||||
id, ok := businessID(c)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
in, ok := bindJSON[dto.LiveStatusRequest](c)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
claims := Claims(c)
|
||||
actor := uint(0)
|
||||
if claims != nil {
|
||||
actor = claims.ID
|
||||
}
|
||||
if e := h.s.SetEnabled(c.Request.Context(), actor, id, in.Enabled); e != nil {
|
||||
businessFail(c, e)
|
||||
return
|
||||
}
|
||||
OK(c)
|
||||
}
|
||||
func (h *Asset) Adjust(c *gin.Context) {
|
||||
id, ok := businessID(c)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
in, ok := bindJSON[dto.AssetAdjustmentRequest](c)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
claims := Claims(c)
|
||||
actor := uint(0)
|
||||
if claims != nil {
|
||||
actor = claims.ID
|
||||
}
|
||||
v, e := h.s.Adjust(c.Request.Context(), actor, id, in)
|
||||
if e != nil {
|
||||
businessFail(c, e)
|
||||
return
|
||||
}
|
||||
OKWithData(c, v)
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
"net/http"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func businessID(c *gin.Context) (uint, bool) {
|
||||
v, e := strconv.ParseUint(c.Param("id"), 10, 64)
|
||||
if e != nil || v == 0 {
|
||||
c.JSON(http.StatusBadRequest, Response{Code: CodeError, Msg: "参数无效"})
|
||||
return 0, false
|
||||
}
|
||||
return uint(v), true
|
||||
}
|
||||
func bindQuery[T any](c *gin.Context) (*T, bool) {
|
||||
var v T
|
||||
if e := c.ShouldBindQuery(&v); e != nil {
|
||||
c.JSON(http.StatusBadRequest, Response{Code: CodeError, Msg: "查询条件无效"})
|
||||
return nil, false
|
||||
}
|
||||
return &v, true
|
||||
}
|
||||
func bindJSON[T any](c *gin.Context) (*T, bool) {
|
||||
var v T
|
||||
if e := c.ShouldBindJSON(&v); e != nil {
|
||||
c.JSON(http.StatusBadRequest, Response{Code: CodeError, Msg: "提交内容无效"})
|
||||
return nil, false
|
||||
}
|
||||
return &v, true
|
||||
}
|
||||
func businessFail(c *gin.Context, e error) {
|
||||
c.JSON(http.StatusBadRequest, Response{Code: CodeError, Msg: e.Error()})
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
"kra/internal/service/dto"
|
||||
service "kra/internal/service/gift"
|
||||
)
|
||||
|
||||
type Gift struct{ s *service.Service }
|
||||
|
||||
func NewGift(s *service.Service) *Gift { return &Gift{s: s} }
|
||||
func (h *Gift) List(c *gin.Context) {
|
||||
in, ok := bindQuery[dto.GiftListRequest](c)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
v, total, e := h.s.List(c.Request.Context(), in)
|
||||
if e != nil {
|
||||
businessFail(c, e)
|
||||
return
|
||||
}
|
||||
OKWithData(c, gin.H{"list": v, "total": total})
|
||||
}
|
||||
func (h *Gift) PublicList(c *gin.Context) {
|
||||
enabled := true
|
||||
in := &dto.GiftListRequest{LiveListRequest: dto.LiveListRequest{Page: 1, PageSize: 100, OrderBy: "sort_asc"}, Enabled: &enabled}
|
||||
v, _, e := h.s.List(c.Request.Context(), in)
|
||||
if e != nil {
|
||||
businessFail(c, e)
|
||||
return
|
||||
}
|
||||
OKWithData(c, gin.H{"list": v})
|
||||
}
|
||||
func (h *Gift) Get(c *gin.Context) {
|
||||
id, ok := businessID(c)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
v, e := h.s.Get(c.Request.Context(), id)
|
||||
if e != nil {
|
||||
businessFail(c, e)
|
||||
return
|
||||
}
|
||||
OKWithData(c, v)
|
||||
}
|
||||
func (h *Gift) Create(c *gin.Context) {
|
||||
in, ok := bindJSON[dto.GiftRequest](c)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
v, e := h.s.Save(c.Request.Context(), 0, in)
|
||||
if e != nil {
|
||||
businessFail(c, e)
|
||||
return
|
||||
}
|
||||
OKWithData(c, v)
|
||||
}
|
||||
func (h *Gift) Update(c *gin.Context) {
|
||||
id, ok := businessID(c)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
in, ok := bindJSON[dto.GiftRequest](c)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
v, e := h.s.Save(c.Request.Context(), id, in)
|
||||
if e != nil {
|
||||
businessFail(c, e)
|
||||
return
|
||||
}
|
||||
OKWithData(c, v)
|
||||
}
|
||||
func (h *Gift) Delete(c *gin.Context) {
|
||||
id, ok := businessID(c)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
if e := h.s.Delete(c.Request.Context(), id); e != nil {
|
||||
businessFail(c, e)
|
||||
return
|
||||
}
|
||||
OK(c)
|
||||
}
|
||||
func (h *Gift) Status(c *gin.Context) {
|
||||
id, ok := businessID(c)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
in, ok := bindJSON[dto.LiveStatusRequest](c)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
if e := h.s.SetEnabled(c.Request.Context(), id, in.Enabled); e != nil {
|
||||
businessFail(c, e)
|
||||
return
|
||||
}
|
||||
OK(c)
|
||||
}
|
||||
func (h *Gift) Sort(c *gin.Context) {
|
||||
in, ok := bindJSON[dto.LiveSortRequest](c)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
if e := h.s.SaveSort(c.Request.Context(), in.Values); e != nil {
|
||||
businessFail(c, e)
|
||||
return
|
||||
}
|
||||
OK(c)
|
||||
}
|
||||
func (h *Gift) Sends(c *gin.Context) {
|
||||
in, ok := bindQuery[dto.GiftSendListRequest](c)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
v, total, sum, e := h.s.ListSends(c.Request.Context(), in)
|
||||
if e != nil {
|
||||
businessFail(c, e)
|
||||
return
|
||||
}
|
||||
OKWithData(c, gin.H{"list": v, "total": total, "summary": sum})
|
||||
}
|
||||
func (h *Gift) Send(c *gin.Context) {
|
||||
id, ok := businessID(c)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
in, ok := bindJSON[dto.GiftSendRequest](c)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
claims := Claims(c)
|
||||
if claims == nil {
|
||||
NoAuth(c, "请登录")
|
||||
return
|
||||
}
|
||||
v, e := h.s.Send(c.Request.Context(), claims.ID, id, in)
|
||||
if e != nil {
|
||||
businessFail(c, e)
|
||||
return
|
||||
}
|
||||
OKWithData(c, v)
|
||||
}
|
||||
@@ -0,0 +1,226 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"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
|
||||
}
|
||||
|
||||
func NewLive(service *liveservice.StreamService, catalog *liveservice.CatalogService) *Live {
|
||||
return &Live{service: service, catalog: catalog}
|
||||
}
|
||||
|
||||
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 = "sort_asc"
|
||||
}
|
||||
enabled := true
|
||||
in.Enabled = &enabled
|
||||
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, "page": in.Page, "pageSize": in.PageSize})
|
||||
}
|
||||
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) LegacyList(c *gin.Context) {
|
||||
items, err := h.service.List(c.Request.Context())
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"ok": false, "error": "直播列表获取失败"})
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, gin.H{"ok": true, "streams": items})
|
||||
}
|
||||
|
||||
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}, "获取成功")
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
"kra/internal/service/dto"
|
||||
service "kra/internal/service/livechat"
|
||||
)
|
||||
|
||||
type LiveChat struct{ service *service.Service }
|
||||
|
||||
func NewLiveChat(service *service.Service) *LiveChat { return &LiveChat{service: service} }
|
||||
|
||||
func (h *LiveChat) History(c *gin.Context) {
|
||||
roomID, ok := businessID(c)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
in, ok := bindQuery[dto.LiveChatHistoryRequest](c)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
items, err := h.service.History(c.Request.Context(), roomID, in.Limit)
|
||||
if err != nil {
|
||||
businessFail(c, err)
|
||||
return
|
||||
}
|
||||
OKWithData(c, gin.H{"list": items})
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
|
||||
"kra/internal/biz/system"
|
||||
"kra/internal/service/dto"
|
||||
service "kra/internal/service/liveclient"
|
||||
)
|
||||
|
||||
type LiveClient struct{ service *service.Service }
|
||||
|
||||
func NewLiveClient(service *service.Service) *LiveClient { return &LiveClient{service: service} }
|
||||
|
||||
func (h *LiveClient) Register(c *gin.Context) {
|
||||
in, ok := bindJSON[dto.LiveClientRegisterRequest](c)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
result, err := h.service.Register(c.Request.Context(), in, c.ClientIP(), c.Request.UserAgent())
|
||||
if err != nil {
|
||||
clientAuthFail(c, err)
|
||||
return
|
||||
}
|
||||
setClientToken(c, result)
|
||||
Write(c, CodeSuccess, result, "注册成功")
|
||||
}
|
||||
|
||||
func (h *LiveClient) Login(c *gin.Context) {
|
||||
in, ok := bindJSON[dto.LiveClientLoginRequest](c)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
result, err := h.service.Login(c.Request.Context(), in, c.ClientIP(), c.Request.UserAgent())
|
||||
if err != nil {
|
||||
clientAuthFail(c, err)
|
||||
return
|
||||
}
|
||||
setClientToken(c, result)
|
||||
Write(c, CodeSuccess, result, "登录成功")
|
||||
}
|
||||
|
||||
func (h *LiveClient) Me(c *gin.Context) {
|
||||
claims := Claims(c)
|
||||
if claims == nil {
|
||||
NoAuth(c, "请登录")
|
||||
return
|
||||
}
|
||||
result, err := h.service.Me(c.Request.Context(), claims.ID)
|
||||
if err != nil {
|
||||
businessFail(c, err)
|
||||
return
|
||||
}
|
||||
OKWithData(c, result)
|
||||
}
|
||||
|
||||
func (h *LiveClient) UpdateProfile(c *gin.Context) {
|
||||
claims := Claims(c)
|
||||
if claims == nil {
|
||||
NoAuth(c, "请登录")
|
||||
return
|
||||
}
|
||||
in, ok := bindJSON[dto.LiveClientProfileRequest](c)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
result, err := h.service.UpdateProfile(c.Request.Context(), claims.ID, in)
|
||||
if err != nil {
|
||||
businessFail(c, err)
|
||||
return
|
||||
}
|
||||
OKWithData(c, result)
|
||||
}
|
||||
|
||||
func (h *LiveClient) ChangePassword(c *gin.Context) {
|
||||
claims := Claims(c)
|
||||
if claims == nil {
|
||||
NoAuth(c, "请登录")
|
||||
return
|
||||
}
|
||||
in, ok := bindJSON[dto.LiveClientPasswordRequest](c)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
result, err := h.service.ChangePassword(c.Request.Context(), claims.ID, in, c.ClientIP(), c.Request.UserAgent())
|
||||
if err != nil {
|
||||
clientAuthFail(c, err)
|
||||
return
|
||||
}
|
||||
setClientToken(c, result)
|
||||
Write(c, CodeSuccess, result, "密码修改成功")
|
||||
}
|
||||
|
||||
func setClientToken(c *gin.Context, result *dto.LiveClientAuthResponse) {
|
||||
maxAge := int(time.UnixMilli(result.ExpiresAt).Unix() - time.Now().Unix())
|
||||
SetTokenCookie(c, result.Token, maxAge)
|
||||
}
|
||||
|
||||
func clientAuthFail(c *gin.Context, err error) {
|
||||
switch {
|
||||
case errors.Is(err, system.ErrAccountLocked):
|
||||
var locked *system.AccountLockedError
|
||||
errors.As(err, &locked)
|
||||
minutes := 0
|
||||
if locked != nil {
|
||||
minutes = locked.Minutes
|
||||
}
|
||||
Fail(c, "账号已锁定,请 "+strconv.Itoa(minutes)+" 分钟后再试")
|
||||
case errors.Is(err, system.ErrInvalidCredentials):
|
||||
Fail(c, "用户名不存在或者密码错误")
|
||||
case errors.Is(err, system.ErrUserDisabled):
|
||||
Fail(c, "用户被禁止登录")
|
||||
default:
|
||||
businessFail(c, err)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
"kra/internal/service/dto"
|
||||
service "kra/internal/service/platformsetting"
|
||||
)
|
||||
|
||||
type PlatformSetting struct{ s *service.Service }
|
||||
|
||||
func NewPlatformSetting(s *service.Service) *PlatformSetting { return &PlatformSetting{s: s} }
|
||||
func (h *PlatformSetting) Get(c *gin.Context) {
|
||||
v, e := h.s.Get(c.Request.Context())
|
||||
if e != nil {
|
||||
businessFail(c, e)
|
||||
return
|
||||
}
|
||||
OKWithData(c, v)
|
||||
}
|
||||
func (h *PlatformSetting) Save(c *gin.Context) {
|
||||
in, ok := bindJSON[dto.PlatformSetting](c)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
if e := h.s.Save(c.Request.Context(), in); e != nil {
|
||||
businessFail(c, e)
|
||||
return
|
||||
}
|
||||
OK(c)
|
||||
}
|
||||
@@ -9,6 +9,7 @@ var ProviderSet = wire.NewSet(
|
||||
NewAnnouncement, NewEmail, NewPayment, NewTask, NewMedia, NewAudit,
|
||||
NewExport, NewVersion, NewDictionary, NewParameter, NewAPIToken,
|
||||
NewSystemConfig, NewPublic, NewUser, NewNavigation, NewSession,
|
||||
NewIntegrationConfig,
|
||||
NewIntegrationConfig, NewLive, NewLiveChat, NewLiveClient,
|
||||
NewGift, NewRecharge, NewAsset, NewPlatformSetting, NewAnalytics,
|
||||
wire.Struct(new(Set), "*"),
|
||||
)
|
||||
|
||||
@@ -138,6 +138,7 @@ func (h *Public) InitializeDatabase(engine *gin.Engine) gin.HandlerFunc {
|
||||
Write(c, CodeSuccess, gin.H{}, "自动创建数据库成功")
|
||||
return
|
||||
}
|
||||
slog.ErrorContext(c.Request.Context(), "数据库初始化失败", "mod", "system", "driver", input.DBType, "host", input.Host, "port", input.Port, "database", input.DBName, "error", err)
|
||||
Fail(c, "自动创建数据库失败,请查看后台日志,检查后在进行初始化")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
"kra/internal/service/dto"
|
||||
service "kra/internal/service/recharge"
|
||||
)
|
||||
|
||||
type Recharge struct{ s *service.Service }
|
||||
|
||||
func NewRecharge(s *service.Service) *Recharge { return &Recharge{s: s} }
|
||||
func (h *Recharge) Plans(c *gin.Context) {
|
||||
v, e := h.s.Plans(c.Request.Context())
|
||||
if e != nil {
|
||||
businessFail(c, e)
|
||||
return
|
||||
}
|
||||
OKWithData(c, gin.H{"list": v})
|
||||
}
|
||||
func (h *Recharge) SavePlans(c *gin.Context) {
|
||||
in, ok := bindJSON[dto.RechargePlansRequest](c)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
if e := h.s.SavePlans(c.Request.Context(), in); e != nil {
|
||||
businessFail(c, e)
|
||||
return
|
||||
}
|
||||
OK(c)
|
||||
}
|
||||
func (h *Recharge) List(c *gin.Context) {
|
||||
in, ok := bindQuery[dto.RechargeOrderListRequest](c)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
v, total, sum, e := h.s.List(c.Request.Context(), in)
|
||||
if e != nil {
|
||||
businessFail(c, e)
|
||||
return
|
||||
}
|
||||
OKWithData(c, gin.H{"list": v, "total": total, "summary": sum})
|
||||
}
|
||||
func (h *Recharge) Get(c *gin.Context) {
|
||||
v, e := h.s.Get(c.Request.Context(), c.Param("orderNo"))
|
||||
if e != nil {
|
||||
businessFail(c, e)
|
||||
return
|
||||
}
|
||||
OKWithData(c, v)
|
||||
}
|
||||
func (h *Recharge) Create(c *gin.Context) {
|
||||
in, ok := bindJSON[dto.RechargeOrderRequest](c)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
claims := Claims(c)
|
||||
if claims == nil {
|
||||
NoAuth(c, "请登录")
|
||||
return
|
||||
}
|
||||
in.ClientIP = c.ClientIP()
|
||||
in.UserAgent = c.Request.UserAgent()
|
||||
in.DeviceID = c.GetHeader("X-Device-Id")
|
||||
v, e := h.s.Create(c.Request.Context(), claims.ID, in)
|
||||
if e != nil {
|
||||
businessFail(c, e)
|
||||
return
|
||||
}
|
||||
OKWithData(c, v)
|
||||
}
|
||||
@@ -23,4 +23,12 @@ type Set struct {
|
||||
Navigation *Navigation
|
||||
Session *Session
|
||||
IntegrationConfig *IntegrationConfig
|
||||
Live *Live
|
||||
LiveChat *LiveChat
|
||||
LiveClient *LiveClient
|
||||
Gift *Gift
|
||||
Recharge *Recharge
|
||||
Asset *Asset
|
||||
PlatformSetting *PlatformSetting
|
||||
Analytics *Analytics
|
||||
}
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
package router
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
"kra/internal/server/handler"
|
||||
)
|
||||
|
||||
func RegisterAnalytics(private *gin.RouterGroup, h *handler.Analytics) {
|
||||
private.GET("/live/admin/dashboard", h.Dashboard)
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package router
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
"kra/internal/server/handler"
|
||||
)
|
||||
|
||||
func RegisterAsset(private *gin.RouterGroup, h *handler.Asset) {
|
||||
private.GET("/live/admin/users", h.List)
|
||||
private.GET("/live/admin/users/:id", h.Get)
|
||||
private.PATCH("/live/admin/users/:id/status", h.Status)
|
||||
private.POST("/live/admin/users/:id/balance", h.Adjust)
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package router
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
"kra/internal/server/handler"
|
||||
)
|
||||
|
||||
func RegisterGift(public, private *gin.RouterGroup, h *handler.Gift) {
|
||||
public.GET("/live/gifts", h.PublicList)
|
||||
private.GET("/live/admin/gifts", h.List)
|
||||
private.GET("/live/admin/gifts/:id", h.Get)
|
||||
private.POST("/live/admin/gifts", h.Create)
|
||||
private.PUT("/live/admin/gifts/:id", h.Update)
|
||||
private.DELETE("/live/admin/gifts/:id", h.Delete)
|
||||
private.PATCH("/live/admin/gifts/:id/status", h.Status)
|
||||
private.PUT("/live/admin/gifts/sort", h.Sort)
|
||||
private.GET("/live/admin/sends", h.Sends)
|
||||
private.POST("/live/rooms/:id/gifts", h.Send)
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package router
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
"kra/internal/server/handler"
|
||||
)
|
||||
|
||||
func RegisterLive(public, private *gin.RouterGroup, h *handler.Live) {
|
||||
public.GET("/live/streams", h.List)
|
||||
public.GET("/live/streams/:streamId", h.Find)
|
||||
// Keep the old list endpoint as a compatibility alias for existing clients.
|
||||
public.GET("/api/streams", h.LegacyList)
|
||||
public.GET("/live/categories", h.PublicCategories)
|
||||
public.GET("/live/rooms", h.PublicRooms)
|
||||
public.GET("/live/rooms/:id", h.GetRoom)
|
||||
private.GET("/live/admin/categories", h.ListCategories)
|
||||
private.POST("/live/admin/categories", h.CreateCategory)
|
||||
private.PUT("/live/admin/categories/:id", h.UpdateCategory)
|
||||
private.DELETE("/live/admin/categories/:id", h.DeleteCategory)
|
||||
private.GET("/live/admin/rooms", h.ListRooms)
|
||||
private.GET("/live/admin/rooms/:id", h.GetRoom)
|
||||
private.POST("/live/admin/rooms", h.CreateRoom)
|
||||
private.PUT("/live/admin/rooms/:id", h.UpdateRoom)
|
||||
private.DELETE("/live/admin/rooms/:id", h.DeleteRoom)
|
||||
private.PATCH("/live/admin/rooms/:id/status", h.SetRoomStatus)
|
||||
private.PUT("/live/admin/rooms/sort", h.SaveRoomSort)
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package router
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
"kra/internal/server/handler"
|
||||
)
|
||||
|
||||
func RegisterLiveChat(public *gin.RouterGroup, h *handler.LiveChat) {
|
||||
public.GET("/live/rooms/:id/messages", h.History)
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package router
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
"kra/internal/server/handler"
|
||||
)
|
||||
|
||||
func RegisterLiveClient(public, private *gin.RouterGroup, h *handler.LiveClient) {
|
||||
public.POST("/live/client/auth/login", h.Login)
|
||||
public.POST("/live/client/auth/register", h.Register)
|
||||
private.GET("/live/client/me", h.Me)
|
||||
private.PUT("/live/client/me", h.UpdateProfile)
|
||||
private.PUT("/live/client/me/password", h.ChangePassword)
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package router
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
"kra/internal/server/handler"
|
||||
)
|
||||
|
||||
func RegisterPlatformSetting(public, private *gin.RouterGroup, h *handler.PlatformSetting) {
|
||||
public.GET("/live/settings", h.Get)
|
||||
private.PUT("/live/admin/settings", h.Save)
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package router
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
"kra/internal/server/handler"
|
||||
)
|
||||
|
||||
func RegisterRecharge(public, private *gin.RouterGroup, h *handler.Recharge) {
|
||||
public.GET("/live/recharge/plans", h.Plans)
|
||||
private.PUT("/live/admin/recharge/plans", h.SavePlans)
|
||||
private.GET("/live/admin/orders", h.List)
|
||||
private.GET("/live/admin/orders/:orderNo", h.Get)
|
||||
private.POST("/live/recharge/orders", h.Create)
|
||||
}
|
||||
@@ -42,6 +42,14 @@ func (r *Routes) RegisterRoutes(public, private *gin.RouterGroup, engine *gin.En
|
||||
func() { RegisterEmail(private, r.handlers.Email) },
|
||||
func() { RegisterIntegrationConfig(private, r.handlers.IntegrationConfig) },
|
||||
func() { RegisterPayment(private, public, r.handlers.Payment) },
|
||||
func() { RegisterLive(public, private, r.handlers.Live) },
|
||||
func() { RegisterLiveChat(public, r.handlers.LiveChat) },
|
||||
func() { RegisterLiveClient(public, private, r.handlers.LiveClient) },
|
||||
func() { RegisterGift(public, private, r.handlers.Gift) },
|
||||
func() { RegisterRecharge(public, private, r.handlers.Recharge) },
|
||||
func() { RegisterAsset(private, r.handlers.Asset) },
|
||||
func() { RegisterPlatformSetting(public, private, r.handlers.PlatformSetting) },
|
||||
func() { RegisterAnalytics(private, r.handlers.Analytics) },
|
||||
}
|
||||
for _, register := range registrations {
|
||||
register()
|
||||
|
||||
Reference in New Issue
Block a user