package market import ( "encoding/json" "fmt" "mtp2_if/controllers/quote" "mtp2_if/global/app" "mtp2_if/global/e" "mtp2_if/logger" "mtp2_if/models" "net/http" "sort" "time" "github.com/gin-gonic/gin" ) // 通用市场 // QueryMarketRunReq 查询市场运行信息请求参数 type QueryMarketRunReq struct { MarketID int `form:"marketID"` } // QueryMarketRun 查询市场运行信息 // @Summary 查询市场运行信息 // @Produce json // @Param marketID query int false "市场ID,不传返回所有" // @Success 200 {object} models.Marketrun // @Failure 500 {object} app.Response // @Router /Market/QueryMarketRun [get] // @Tags 通用市场 func QueryMarketRun(c *gin.Context) { appG := app.Gin{C: c} // 获取请求参数 var req QueryMarketRunReq if err := appG.C.ShouldBindQuery(&req); err != nil { logger.GetLogger().Errorf("QueryMarketRun failed: %s", err.Error()) appG.Response(http.StatusBadRequest, e.INVALID_PARAMS, nil) return } marketRuns, err := models.GetMarketRuns(req.MarketID) if err != nil { // 查询失败 logger.GetLogger().Errorf("QueryMarketRun failed: %s", err.Error()) appG.Response(http.StatusBadRequest, e.ERROR_QUERY_FAIL, nil) return } // 获取真实开休市时间 for i := range marketRuns { marketRun := &marketRuns[i] quoteTradeDate := marketRun.Tradedate2 // 获取市场 market, err := models.GetMarket(int(marketRun.Marketid)) if err != nil { logger.GetLogger().Errorf("QueryMarketRun failed: %s", err.Error()) appG.Response(http.StatusBadRequest, e.ERROR_QUERY_FAIL, nil) return } if market.Markettype != 2 { continue } if len(quoteTradeDate) == 0 { logger.GetLogger().Errorf("QueryMarketRun failed: %s", err.Error()) appG.Response(http.StatusBadRequest, e.ERROR_GET_MARKETRUN_FAILED, nil) return } // 获取目标品种的开休市计划 // 非外部市场或外部市场没有配置QuoteSourceGroupRunStep表数据的情况下,都从MarketRunStepDetail中获取数据 var runSteps []map[string]interface{} sourceRunSteps, err := models.FindMarketRunStepDetails(int(marketRun.Marketid)) if err != nil { logger.GetLogger().Errorf("QueryMarketRun failed: %s", err.Error()) appG.Response(http.StatusBadRequest, e.ERROR_GET_RUNSTEP_FAILED, nil) return } for _, v := range sourceRunSteps { // struct -> json if jsonBytes, err := json.Marshal(v); err == nil { // json -> struct var runStepMap map[string]interface{} json.Unmarshal(jsonBytes, &runStepMap) runSteps = append(runSteps, runStepMap) } } // 构建分时图可直接使用的开休市数据 // 这里有一个知识点:TRADEWEEKDAY 与 STARTWEEKDAY,以及 TRADEWEEKDAY 与 ENDWEEKDAY 之间相差最多一天(管理端限制), // 所以目前并不支持正真的周五夜盘模式。我们在实现时不用做得太复杂。 // 当前交易日(周几)对应的开休市计划 tradeDate, err := time.ParseInLocation("20060102", quoteTradeDate, time.Local) if err != nil { logger.GetLogger().Errorf("QueryMarketRun failed: %s", err.Error()) appG.Response(http.StatusBadRequest, e.ERROR_QUERY_FAIL, nil) return } // !!!开休市计划明细 curWeekRunSteps := make([]map[string]interface{}, 0) for _, v := range runSteps { tradeWeekDay := int(v["tradeweekday"].(float64)) if tradeWeekDay == int(tradeDate.Weekday()) { curWeekRunSteps = append(curWeekRunSteps, v) } } // 获取不到可用的开休市计划 if len(curWeekRunSteps) == 0 { logger.GetLogger().Errorf("QueryMarketRun failed: %s", err.Error()) appG.Response(http.StatusBadRequest, e.ERROR_GET_RUNSTEP_FAILED, nil) return } // 按 SECTIONID 顺序排序 sort.Slice(curWeekRunSteps, func(i int, j int) bool { return curWeekRunSteps[i]["sectionid"].(float64) < curWeekRunSteps[j]["sectionid"].(float64) }) // 把各开休市时间段转化为真实的时间 // 关于开休市计划的时间顺序:管理端会按时间顺序添加开休市计划,所以交易日开始时间为第一条记录的开始时间,结束时间为最后一条记录的结束时间 // 关于目标商品的交易日问题:目前只能从商品所属市场获取当前交易日,这样有两个问题,一是不能按常规显示最后一个有历史数据的交易日;二是目前所有外部商品的开休市计划都是一样的。 timeFormat := "20060102 15:04" // 开始时间 startInterval := quote.GetTradeDay(int(curWeekRunSteps[0]["tradeweekday"].(float64)), int(curWeekRunSteps[0]["startweekday"].(float64))) marketRun.StartTime, _ = time.ParseInLocation(timeFormat, fmt.Sprintf("%s %s", quoteTradeDate, curWeekRunSteps[0]["starttime"].(string)), time.Local) if startInterval != 0 { duration, _ := time.ParseDuration(fmt.Sprintf("%dh", startInterval*24)) marketRun.StartTime = marketRun.StartTime.Add(duration) } // 结束时间 index := len(curWeekRunSteps) - 1 endInterval := quote.GetTradeDay(int(curWeekRunSteps[index]["tradeweekday"].(float64)), int(curWeekRunSteps[index]["endweekday"].(float64))) marketRun.EndTime, _ = time.ParseInLocation(timeFormat, fmt.Sprintf("%s %s", quoteTradeDate, curWeekRunSteps[index]["endtime"].(string)), time.Local) if endInterval != 0 { duration, _ := time.ParseDuration(fmt.Sprintf("%dh", endInterval*24)) marketRun.EndTime = marketRun.EndTime.Add(duration) } } // 查询成功返回 logger.GetLogger().Debugln("QueryMarketRun successed: %v", marketRuns) appG.Response(http.StatusOK, e.SUCCESS, marketRuns) } // QueryMarketsByLoginIDReq 获取登录账号有权限的市场信息请求参数 type QueryMarketsByLoginIDReq struct { LoginID int `form:"loginID" binding:"required"` } // QueryMarketsByLoginID 获取登录账号有权限的市场信息 // @Summary 获取登录账号有权限的市场信息 // @Produce json // @Security ApiKeyAuth // @Param loginID query int true "登录账号" // @Success 200 {object} models.Market // @Failure 500 {object} app.Response // @Router /Market/QueryMarketsByLoginID [get] // @Tags 通用市场 func QueryMarketsByLoginID(c *gin.Context) { appG := app.Gin{C: c} // 获取请求参数 var req QueryMarketsByLoginIDReq if err := appG.C.ShouldBindQuery(&req); err != nil { logger.GetLogger().Errorf("QueryMarketsByLoginID failed: %s", err.Error()) appG.Response(http.StatusBadRequest, e.INVALID_PARAMS, nil) return } markets, err := models.GetMarketsByLoginID(req.LoginID) if err != nil { // 查询失败 logger.GetLogger().Errorf("QueryMarketsByLoginID failed: %s", err.Error()) appG.Response(http.StatusBadRequest, e.ERROR_QUERY_FAIL, nil) return } // 查询成功返回 logger.GetLogger().Debugln("QueryMarketsByLoginID successed: %v", markets) appG.Response(http.StatusOK, e.SUCCESS, markets) } // QueryGoodsesByLoginIDReq 获取登录账号有权限的商品信息请求参数 type QueryGoodsesByLoginIDReq struct { LoginID int `form:"loginID" binding:"required"` MarketIDs string `form:"marketIDs"` } // QueryGoodsesByLoginID 获取登录账号有权限的商品信息 // @Summary 获取登录账号有权限的商品信息 // @Produce json // @Security ApiKeyAuth // @Param loginID query int true "登录账号" // @Param marketIDs query string false "市场ID列表,格式:1,2,3" // @Success 200 {object} models.Goods // @Failure 500 {object} app.Response // @Router /Market/QueryGoodsesByLoginID [get] // @Tags 通用市场 func QueryGoodsesByLoginID(c *gin.Context) { appG := app.Gin{C: c} // 获取请求参数 var req QueryGoodsesByLoginIDReq if err := appG.C.ShouldBindQuery(&req); err != nil { logger.GetLogger().Errorf("QueryGoodsesByLoginID failed: %s", err.Error()) appG.Response(http.StatusBadRequest, e.INVALID_PARAMS, nil) return } goodses, err := models.GetGoodsByLoginID(req.LoginID, req.MarketIDs) if err != nil { // 查询失败 logger.GetLogger().Errorf("QueryGoodsesByLoginID failed: %s", err.Error()) appG.Response(http.StatusBadRequest, e.ERROR_QUERY_FAIL, nil) return } // 查询成功返回 logger.GetLogger().Debugln("QueryGoodsesByLoginID successed:", goodses) appG.Response(http.StatusOK, e.SUCCESS, goodses) } // GetAllExExchanges 获取所有外部交易所信息 // @Summary 获取所有外部交易所信息 // @Produce json // @Security ApiKeyAuth // @Success 200 {object} models.Goods // @Failure 500 {object} app.Response // @Router /Market/GetAllExExchanges [get] // @Tags 通用市场 func GetAllExExchanges(c *gin.Context) { appG := app.Gin{C: c} rst, err := models.GetAllExExchanges() if err != nil { // 查询失败 logger.GetLogger().Errorf("GetAllExExchanges failed: %s", err.Error()) appG.Response(http.StatusBadRequest, e.ERROR_QUERY_FAIL, nil) return } // 查询成功返回 logger.GetLogger().Debugln("GetAllExExchanges successed: %v", rst) appG.Response(http.StatusOK, e.SUCCESS, rst) } // GetMarketSections 查询新板块设置 // @Summary 查询新板块设置 // @Produce json // @Success 200 {array} models.GetMarketSectionsRsp // @Failure 500 {object} app.Response // @Router /Market/GetMarketSections [get] // @Tags 通用市场 func GetMarketSections(c *gin.Context) { appG := app.Gin{C: c} rst, err := models.GetMarketSections() if err != nil { // 查询失败 logger.GetLogger().Errorf("GetMarketSections failed: %s", err.Error()) appG.Response(http.StatusBadRequest, e.ERROR_QUERY_FAIL, nil) return } // 查询成功返回 logger.GetLogger().Debugln("GetMarketSections successed: %v", rst) appG.Response(http.StatusOK, e.SUCCESS, rst) }