2026-05-25 19:36:27 +08:00

340 lines
9.7 KiB
Go

package appconfig
import (
"fmt"
"strconv"
"strings"
"hyapp-admin-server/internal/appctx"
"hyapp-admin-server/internal/modules/shared"
"hyapp-admin-server/internal/repository"
"hyapp-admin-server/internal/response"
"github.com/gin-gonic/gin"
)
type Handler struct {
service *AppConfigService
audit shared.OperationLogger
}
func New(store *repository.Store, audit shared.OperationLogger) *Handler {
return &Handler{service: NewService(store), audit: audit}
}
func (h *Handler) ListH5Links(c *gin.Context) {
items, err := h.service.ListH5Links()
if err != nil {
response.ServerError(c, "获取 H5 配置失败")
return
}
response.OK(c, gin.H{"items": items, "total": len(items)})
}
func (h *Handler) UpdateH5Links(c *gin.Context) {
var request updateH5LinksRequest
if err := c.ShouldBindJSON(&request); err != nil {
response.BadRequest(c, "参数不正确")
return
}
items, err := h.service.UpdateH5Links(request)
if err != nil {
response.BadRequest(c, err.Error())
return
}
shared.OperationLog(c, h.audit, "update-app-h5-links", "admin_app_configs", "success", fmt.Sprintf("%d h5 links", len(request.Items)))
response.OK(c, gin.H{"items": items, "total": len(items)})
}
func (h *Handler) CreateH5Link(c *gin.Context) {
var request h5LinkPayload
if err := c.ShouldBindJSON(&request); err != nil {
response.BadRequest(c, "参数不正确")
return
}
item, err := h.service.CreateH5Link(request)
if err != nil {
response.BadRequest(c, err.Error())
return
}
shared.OperationLog(c, h.audit, "create-app-h5-link", "admin_app_configs", "success", fmt.Sprintf("h5_key=%s", item.Key))
response.Created(c, item)
}
func (h *Handler) UpdateH5Link(c *gin.Context) {
key := strings.TrimSpace(c.Param("key"))
if key == "" {
response.BadRequest(c, "h5 config key is invalid")
return
}
var request h5LinkPayload
if err := c.ShouldBindJSON(&request); err != nil {
response.BadRequest(c, "参数不正确")
return
}
item, err := h.service.UpdateH5Link(key, request)
if err != nil {
response.BadRequest(c, err.Error())
return
}
shared.OperationLog(c, h.audit, "update-app-h5-link", "admin_app_configs", "success", fmt.Sprintf("h5_key=%s", item.Key))
response.OK(c, item)
}
func (h *Handler) DeleteH5Link(c *gin.Context) {
key := strings.TrimSpace(c.Param("key"))
if key == "" {
response.BadRequest(c, "h5 config key is invalid")
return
}
if err := h.service.DeleteH5Link(key); err != nil {
response.BadRequest(c, err.Error())
return
}
shared.OperationLog(c, h.audit, "delete-app-h5-link", "admin_app_configs", "success", fmt.Sprintf("h5_key=%s", key))
response.OK(c, gin.H{"deleted": true})
}
func (h *Handler) ListBanners(c *gin.Context) {
options := shared.ListOptions(c)
items, err := h.service.ListBanners(appctx.FromContext(c.Request.Context()), repository.AppBannerListOptions{
Keyword: options.Keyword,
Status: options.Status,
DisplayScope: firstQuery(c, "displayScope", "display_scope"),
Platform: strings.TrimSpace(c.Query("platform")),
RegionID: parseOptionalInt64(c.Query("regionId"), c.Query("region_id")),
Country: firstQuery(c, "countryCode", "country_code", "country"),
})
if err != nil {
response.ServerError(c, "获取 BANNER 配置失败")
return
}
response.OK(c, gin.H{"items": items, "total": len(items)})
}
func (h *Handler) CreateBanner(c *gin.Context) {
var request bannerRequest
if err := c.ShouldBindJSON(&request); err != nil {
response.BadRequest(c, "参数不正确")
return
}
item, err := h.service.CreateBanner(appctx.FromContext(c.Request.Context()), request)
if err != nil {
response.BadRequest(c, err.Error())
return
}
shared.OperationLog(c, h.audit, "create-app-banner", "admin_app_banners", "success", fmt.Sprintf("banner_id=%d", item.ID))
response.Created(c, item)
}
func (h *Handler) UpdateBanner(c *gin.Context) {
id, ok := bannerID(c)
if !ok {
return
}
var request bannerRequest
if err := c.ShouldBindJSON(&request); err != nil {
response.BadRequest(c, "参数不正确")
return
}
item, err := h.service.UpdateBanner(appctx.FromContext(c.Request.Context()), id, request)
if err != nil {
response.BadRequest(c, err.Error())
return
}
shared.OperationLog(c, h.audit, "update-app-banner", "admin_app_banners", "success", fmt.Sprintf("banner_id=%d", item.ID))
response.OK(c, item)
}
func (h *Handler) DeleteBanner(c *gin.Context) {
id, ok := bannerID(c)
if !ok {
return
}
if err := h.service.DeleteBanner(appctx.FromContext(c.Request.Context()), id); err != nil {
response.BadRequest(c, err.Error())
return
}
shared.OperationLog(c, h.audit, "delete-app-banner", "admin_app_banners", "success", fmt.Sprintf("banner_id=%d", id))
response.OK(c, gin.H{"deleted": true})
}
func (h *Handler) ListAppVersions(c *gin.Context) {
items, err := h.service.ListAppVersions(appctx.FromContext(c.Request.Context()), repository.AppVersionListOptions{
Keyword: strings.TrimSpace(c.Query("keyword")),
Platform: strings.TrimSpace(c.Query("platform")),
})
if err != nil {
response.ServerError(c, "获取版本配置失败")
return
}
response.OK(c, gin.H{"items": items, "total": len(items)})
}
func (h *Handler) CreateAppVersion(c *gin.Context) {
var request appVersionRequest
if err := c.ShouldBindJSON(&request); err != nil {
response.BadRequest(c, "参数不正确")
return
}
item, err := h.service.CreateAppVersion(appctx.FromContext(c.Request.Context()), request)
if err != nil {
response.BadRequest(c, err.Error())
return
}
shared.OperationLog(c, h.audit, "create-app-version", "admin_app_versions", "success", fmt.Sprintf("version_id=%d", item.ID))
response.Created(c, item)
}
func (h *Handler) UpdateAppVersion(c *gin.Context) {
id, ok := appVersionID(c)
if !ok {
return
}
var request appVersionRequest
if err := c.ShouldBindJSON(&request); err != nil {
response.BadRequest(c, "参数不正确")
return
}
item, err := h.service.UpdateAppVersion(appctx.FromContext(c.Request.Context()), id, request)
if err != nil {
response.BadRequest(c, err.Error())
return
}
shared.OperationLog(c, h.audit, "update-app-version", "admin_app_versions", "success", fmt.Sprintf("version_id=%d", item.ID))
response.OK(c, item)
}
func (h *Handler) DeleteAppVersion(c *gin.Context) {
id, ok := appVersionID(c)
if !ok {
return
}
if err := h.service.DeleteAppVersion(appctx.FromContext(c.Request.Context()), id); err != nil {
response.BadRequest(c, err.Error())
return
}
shared.OperationLog(c, h.audit, "delete-app-version", "admin_app_versions", "success", fmt.Sprintf("version_id=%d", id))
response.OK(c, gin.H{"deleted": true})
}
func (h *Handler) ListExploreTabs(c *gin.Context) {
var enabled *bool
switch strings.ToLower(strings.TrimSpace(c.Query("enabled"))) {
case "true", "1", "enabled":
value := true
enabled = &value
case "false", "0", "disabled":
value := false
enabled = &value
}
items, err := h.service.ListExploreTabs(appctx.FromContext(c.Request.Context()), repository.AppExploreTabListOptions{
Keyword: strings.TrimSpace(c.Query("keyword")),
Enabled: enabled,
})
if err != nil {
response.ServerError(c, "获取 Explore 配置失败")
return
}
response.OK(c, gin.H{"items": items, "total": len(items)})
}
func (h *Handler) CreateExploreTab(c *gin.Context) {
var request exploreTabRequest
if err := c.ShouldBindJSON(&request); err != nil {
response.BadRequest(c, "参数不正确")
return
}
item, err := h.service.CreateExploreTab(appctx.FromContext(c.Request.Context()), request)
if err != nil {
response.BadRequest(c, err.Error())
return
}
shared.OperationLog(c, h.audit, "create-app-explore-tab", "admin_app_explore_tabs", "success", fmt.Sprintf("explore_tab_id=%d", item.ID))
response.Created(c, item)
}
func (h *Handler) UpdateExploreTab(c *gin.Context) {
id, ok := exploreTabID(c)
if !ok {
return
}
var request exploreTabRequest
if err := c.ShouldBindJSON(&request); err != nil {
response.BadRequest(c, "参数不正确")
return
}
item, err := h.service.UpdateExploreTab(appctx.FromContext(c.Request.Context()), id, request)
if err != nil {
response.BadRequest(c, err.Error())
return
}
shared.OperationLog(c, h.audit, "update-app-explore-tab", "admin_app_explore_tabs", "success", fmt.Sprintf("explore_tab_id=%d", item.ID))
response.OK(c, item)
}
func (h *Handler) DeleteExploreTab(c *gin.Context) {
id, ok := exploreTabID(c)
if !ok {
return
}
if err := h.service.DeleteExploreTab(appctx.FromContext(c.Request.Context()), id); err != nil {
response.BadRequest(c, err.Error())
return
}
shared.OperationLog(c, h.audit, "delete-app-explore-tab", "admin_app_explore_tabs", "success", fmt.Sprintf("explore_tab_id=%d", id))
response.OK(c, gin.H{"deleted": true})
}
func bannerID(c *gin.Context) (uint, bool) {
value, err := strconv.ParseUint(c.Param("banner_id"), 10, 64)
if err != nil || value == 0 {
response.BadRequest(c, "banner id is invalid")
return 0, false
}
return uint(value), true
}
func appVersionID(c *gin.Context) (uint, bool) {
value, err := strconv.ParseUint(c.Param("version_id"), 10, 64)
if err != nil || value == 0 {
response.BadRequest(c, "version id is invalid")
return 0, false
}
return uint(value), true
}
func exploreTabID(c *gin.Context) (uint, bool) {
value, err := strconv.ParseUint(c.Param("tab_id"), 10, 64)
if err != nil || value == 0 {
response.BadRequest(c, "explore tab id is invalid")
return 0, false
}
return uint(value), true
}
func parseOptionalInt64(values ...string) int64 {
for _, value := range values {
value = strings.TrimSpace(value)
if value == "" {
continue
}
parsed, err := strconv.ParseInt(value, 10, 64)
if err == nil && parsed > 0 {
return parsed
}
}
return 0
}
func firstQuery(c *gin.Context, keys ...string) string {
for _, key := range keys {
if value := c.Query(key); value != "" {
return value
}
}
return ""
}