支持 square/squarenovel/squaresteps/squarehealth 实例与 category 筛选;音乐增加免登录 grouped/track;订阅套餐按 package_name 区分;补 migration 0030/0031 与 OpenAPI。 Co-authored-by: Cursor <cursoragent@cursor.com>
193 lines
4.6 KiB
Go
193 lines
4.6 KiB
Go
package adminhandler
|
|
|
|
import (
|
|
"net/http"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
|
|
"spark-server/internal/module/client/entity"
|
|
clientlogic "spark-server/internal/module/client/logic"
|
|
)
|
|
|
|
// ClientHandler serves popadmin legal / subscription / feedback / developer-apps ops.
|
|
type ClientHandler struct {
|
|
svc *clientlogic.Service
|
|
}
|
|
|
|
func NewClient(svc *clientlogic.Service) *ClientHandler {
|
|
return &ClientHandler{svc: svc}
|
|
}
|
|
|
|
func (h *ClientHandler) ready(c *gin.Context) bool {
|
|
if h == nil || h.svc == nil || !h.svc.Ready() {
|
|
Fail(c, http.StatusServiceUnavailable, "client 服务未就绪")
|
|
return false
|
|
}
|
|
return true
|
|
}
|
|
|
|
func (h *ClientHandler) GetLegal(c *gin.Context) {
|
|
if !h.ready(c) {
|
|
return
|
|
}
|
|
out, err := h.svc.LegalAgreements(c.Request.Context())
|
|
if err != nil {
|
|
Fail(c, http.StatusInternalServerError, err.Error())
|
|
return
|
|
}
|
|
OK(c, out)
|
|
}
|
|
|
|
func (h *ClientHandler) PutLegal(c *gin.Context) {
|
|
if !h.ready(c) {
|
|
return
|
|
}
|
|
var body entity.LegalDocument
|
|
if err := c.ShouldBindJSON(&body); err != nil {
|
|
Fail(c, http.StatusBadRequest, "无效 JSON")
|
|
return
|
|
}
|
|
if err := h.svc.UpsertLegalAdmin(c.Request.Context(), &body); err != nil {
|
|
Fail(c, http.StatusBadRequest, err.Error())
|
|
return
|
|
}
|
|
OKMsg(c, "已保存", body)
|
|
}
|
|
|
|
func (h *ClientHandler) ListPlans(c *gin.Context) {
|
|
if !h.ready(c) {
|
|
return
|
|
}
|
|
lang := c.Query("lang")
|
|
pkg := strings.TrimSpace(c.Query("packageName"))
|
|
if pkg == "" {
|
|
pkg = strings.TrimSpace(c.Query("package_name"))
|
|
}
|
|
list, err := h.svc.ListPlansAdmin(c.Request.Context(), lang, pkg)
|
|
if err != nil {
|
|
Fail(c, http.StatusInternalServerError, err.Error())
|
|
return
|
|
}
|
|
OK(c, gin.H{"items": list})
|
|
}
|
|
|
|
func (h *ClientHandler) PutPlan(c *gin.Context) {
|
|
if !h.ready(c) {
|
|
return
|
|
}
|
|
var body entity.SubscriptionPlan
|
|
if err := c.ShouldBindJSON(&body); err != nil {
|
|
Fail(c, http.StatusBadRequest, "无效 JSON")
|
|
return
|
|
}
|
|
if err := h.svc.UpsertPlanAdmin(c.Request.Context(), &body); err != nil {
|
|
Fail(c, http.StatusBadRequest, err.Error())
|
|
return
|
|
}
|
|
OKMsg(c, "已保存", body)
|
|
}
|
|
|
|
func (h *ClientHandler) ListFeedback(c *gin.Context) {
|
|
if !h.ready(c) {
|
|
return
|
|
}
|
|
page, _ := strconv.Atoi(c.DefaultQuery("page", "0"))
|
|
size, _ := strconv.Atoi(c.DefaultQuery("size", "50"))
|
|
authType := strings.TrimSpace(c.Query("auth_type"))
|
|
list, total, err := h.svc.ListFeedbackAdmin(c.Request.Context(), page, size, authType)
|
|
if err != nil {
|
|
Fail(c, http.StatusInternalServerError, err.Error())
|
|
return
|
|
}
|
|
OK(c, gin.H{"list": list, "total": total, "page": page, "size": size, "auth_type": authType})
|
|
}
|
|
|
|
func (h *ClientHandler) PatchFeedback(c *gin.Context) {
|
|
if !h.ready(c) {
|
|
return
|
|
}
|
|
id, err := strconv.ParseInt(c.Param("id"), 10, 64)
|
|
if err != nil || id <= 0 {
|
|
Fail(c, http.StatusBadRequest, "无效 id")
|
|
return
|
|
}
|
|
var body struct {
|
|
Status string `json:"status"`
|
|
}
|
|
if err := c.ShouldBindJSON(&body); err != nil || body.Status == "" {
|
|
Fail(c, http.StatusBadRequest, "status 必填")
|
|
return
|
|
}
|
|
if err := h.svc.UpdateFeedbackStatus(c.Request.Context(), id, body.Status); err != nil {
|
|
Fail(c, http.StatusBadRequest, err.Error())
|
|
return
|
|
}
|
|
OKMsg(c, "已更新", gin.H{"id": id, "status": body.Status})
|
|
}
|
|
|
|
func (h *ClientHandler) ListDeveloperApps(c *gin.Context) {
|
|
if !h.ready(c) {
|
|
return
|
|
}
|
|
appCode := c.Query("appCode")
|
|
if appCode == "" {
|
|
appCode = c.Query("sourceAppCode")
|
|
}
|
|
if appCode == "" {
|
|
appCode = "spark"
|
|
}
|
|
list, err := h.svc.ListDeveloperAppsAdmin(c.Request.Context(), appCode)
|
|
if err != nil {
|
|
Fail(c, http.StatusInternalServerError, err.Error())
|
|
return
|
|
}
|
|
OK(c, list)
|
|
}
|
|
|
|
func (h *ClientHandler) CreateDeveloperApp(c *gin.Context) {
|
|
if !h.ready(c) {
|
|
return
|
|
}
|
|
var body entity.DeveloperApp
|
|
if err := c.ShouldBindJSON(&body); err != nil {
|
|
Fail(c, http.StatusBadRequest, "无效 JSON")
|
|
return
|
|
}
|
|
out, err := h.svc.CreateDeveloperAppAdmin(c.Request.Context(), &body)
|
|
if err != nil {
|
|
Fail(c, http.StatusBadRequest, err.Error())
|
|
return
|
|
}
|
|
OKMsg(c, "已保存", out)
|
|
}
|
|
|
|
func (h *ClientHandler) DeleteDeveloperApp(c *gin.Context) {
|
|
if !h.ready(c) {
|
|
return
|
|
}
|
|
id, err := strconv.ParseInt(c.Param("id"), 10, 64)
|
|
if err != nil || id <= 0 {
|
|
Fail(c, http.StatusBadRequest, "无效 id")
|
|
return
|
|
}
|
|
if err := h.svc.DeleteDeveloperAppAdmin(c.Request.Context(), id); err != nil {
|
|
Fail(c, http.StatusBadRequest, err.Error())
|
|
return
|
|
}
|
|
OKMsg(c, "已删除", gin.H{"id": id})
|
|
}
|
|
|
|
func (h *ClientHandler) SyncDeveloperAppIcons(c *gin.Context) {
|
|
if !h.ready(c) {
|
|
return
|
|
}
|
|
n, err := h.svc.SyncWebsiteIconsAdmin(c.Request.Context())
|
|
if err != nil {
|
|
Fail(c, http.StatusBadRequest, err.Error())
|
|
return
|
|
}
|
|
OKMsg(c, "已同步", gin.H{"count": n})
|
|
}
|