Files
go/internal/api/limit_board_handler.go
T
yang d5c053e59d 1、新增二板炸板情况统计;
2、更新项目结构;
2026-05-09 16:59:45 +08:00

153 lines
4.1 KiB
Go

package api
import (
"errors"
"net/http"
"strconv"
"strings"
"github.com/gin-gonic/gin"
"level_go/internal/model"
"level_go/internal/service"
)
type LimitBoardHandler struct {
Service *service.LimitBoardService
}
func NewLimitBoardHandler(s *service.LimitBoardService) *LimitBoardHandler {
return &LimitBoardHandler{Service: s}
}
func (h *LimitBoardHandler) GetOverview(c *gin.Context) {
var req model.LimitBoardRequest
if err := c.ShouldBindQuery(&req); err != nil || req.TradeDate == "" {
c.JSON(http.StatusBadRequest, gin.H{"error": "trade_date 参数不能为空"})
return
}
resp, err := h.Service.GetLimitBoardOverview(req.TradeDate)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, resp)
}
func (h *LimitBoardHandler) GetOpenLowerGroups(c *gin.Context) {
var req model.LimitBoardRequest
if err := c.ShouldBindQuery(&req); err != nil || req.TradeDate == "" {
c.JSON(http.StatusBadRequest, gin.H{"error": "trade_date 参数不能为空"})
return
}
resp, err := h.Service.GetLimitOpenCompareGroups(req.TradeDate)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, resp)
}
func (h *LimitBoardHandler) GetBreakNextPerformance(c *gin.Context) {
req, err := parseLimitBreakNextPerformanceRequest(c, true)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
resp, err := h.Service.GetLimitBreakNextPerformance(req)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, resp)
}
func parseLimitBreakNextPerformanceRequest(c *gin.Context, includePagination bool) (model.LimitBreakNextPerformanceRequest, error) {
req := model.LimitBreakNextPerformanceRequest{
TradeStartDate: strings.TrimSpace(c.DefaultQuery("tradeStartDate", c.Query("start_date"))),
TradeEndDate: strings.TrimSpace(c.DefaultQuery("tradeEndDate", c.Query("end_date"))),
Page: 1,
PageSize: 20,
}
if req.TradeStartDate == "" {
return req, errors.New("tradeStartDate 参数不能为空")
}
if req.TradeEndDate == "" {
return req, errors.New("tradeEndDate 参数不能为空")
}
if err := validateSecondProfitDateRange(req.TradeStartDate, req.TradeEndDate); err != nil {
return req, err
}
if includePagination {
pageText := strings.TrimSpace(c.DefaultQuery("page", "1"))
page, err := strconv.Atoi(pageText)
if err != nil || page <= 0 {
return req, errors.New("page 必须为正整数")
}
req.Page = page
pageSizeText := strings.TrimSpace(c.DefaultQuery("pageSize", "20"))
pageSize, err := strconv.Atoi(pageSizeText)
if err != nil || pageSize <= 0 {
return req, errors.New("pageSize 必须为正整数")
}
req.PageSize = pageSize
}
tOpenGainLt101, err := parseOptionalBoolQuery(c, "tOpenGainLt101", "tOpenLessThan101", "t_open_gain_lt_101")
if err != nil {
return req, errors.New("tOpenGainLt101 必须为布尔值")
}
req.TOpenGainLt101 = tOpenGainLt101
breakTimeBefore1100, err := parseOptionalBoolQuery(c, "breakTimeBefore1100", "tBreakTimeBefore1100", "break_time_before_1100")
if err != nil {
return req, errors.New("breakTimeBefore1100 必须为布尔值")
}
req.BreakTimeBefore1100 = breakTimeBefore1100
return req, nil
}
func parseOptionalBoolQuery(c *gin.Context, keys ...string) (*bool, error) {
for _, key := range keys {
valueText, exists := c.GetQuery(key)
if !exists {
continue
}
valueText = strings.TrimSpace(valueText)
if valueText == "" {
continue
}
value, err := strconv.ParseBool(valueText)
if err != nil {
return nil, err
}
return &value, nil
}
return nil, nil
}
func (h *LimitBoardHandler) GetOpenThresholdGroups(c *gin.Context) {
var req model.LimitBoardRequest
if err := c.ShouldBindQuery(&req); err != nil || req.TradeDate == "" {
c.JSON(http.StatusBadRequest, gin.H{"error": "trade_date 参数不能为空"})
return
}
resp, err := h.Service.GetLimitOpenThresholdGroups(req.TradeDate)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, resp)
}