package processor import ( "encoding/json" "fmt" "github.com/gin-gonic/gin" "github.com/shopspring/decimal" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" "net/http" "strconv" "strings" "time" "wss-pool/cmd/common" "wss-pool/config" "wss-pool/dictionary" "wss-pool/internal" "wss-pool/internal/data" "wss-pool/internal/data/business" red "wss-pool/internal/redis" "wss-pool/logging/applogger" "wss-pool/pkg/model" "wss-pool/pkg/model/stock" ) var Token = "asdfsnl123jlknl3nksdf32345ln98sdfsfs8891232nsdfsdfsdfsdxcfvbhnfgh" var TapsMap = map[string]int{ "NYSE": 1, "NYSEARCA": 2, "NASDAQ": 3, } func UsMessage(c *gin.Context) { param := model.ClientMessageParam{} err := c.BindJSON(¶m) if err != nil { applogger.Error("BindJSON", err.Error()) c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, "param error", internal.QueryError)) return } else if param.Token != Token { c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, "token error", internal.QueryError)) return } for _, message := range param.Data { msgStr, _ := json.Marshal(message) business.JudgeHsetMap("US", business.StockClosingPrice[fmt.Sprintf("%sNew", "US")], message.S, message.Cl.String()) business.JudgePublishMap("US", message.S, fmt.Sprintf("%s.%s", message.S, "US"), string(msgStr)) } c.JSON(http.StatusOK, internal.GinResult(http.StatusOK, "", "ok")) } func StockInfoAdd(c *gin.Context) { param := make([]model.StockParam, 0) err := c.BindJSON(¶m) total := len(param) if err != nil { applogger.Error("BindJSON", err.Error()) c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, "param error", internal.QueryError)) return } else if total <= 0 { c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, "param null", internal.QueryError)) return } else if param[0].Token != Token { c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, "token error", internal.QueryError)) return } else if param[0].Country == "" { c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, "country error", internal.QueryError)) return } country := common.CapitalizeFirstLetter(param[0].Country) var dataList []mongo.WriteModel applogger.Debug("stock info add param total: %d", total) for _, v := range param { var price string //if v.Country == "indonesia" { // price = strconv.FormatFloat(v.Price, 'f', -1, 64) //} else { //price = strconv.FormatFloat(v.Price, 'f', 2, 64) price = strconv.FormatFloat(v.Price, 'f', -1, 64) //v.Price, err = strconv.ParseFloat(price, 64) //if err != nil { // applogger.Error(v.Country, v.StockCode, err) //} // } //if !common.GetIndiaStockBool(v.Symbol,country) { // applogger.Error("not india stock :%v", v.Symbol) // continue //} if !business.IsPriceTime(v.Symbol, price, country) { continue } business.StockWs(v, country) //更新最新价格 //business.UpdateStockBeforeClose(v.Symbol, price, country) business.JudgeHsetMap(country, business.StockClosingPrice[fmt.Sprintf("%sNew", country)], v.Symbol, price) filter := bson.M{"timestamp": bson.M{"$eq": v.Ts}, "symbol": bson.M{"$eq": v.Symbol}} update := bson.D{{"$set", bson.D{ {"symbol", v.Symbol}, {"stock_code", v.StockCode}, {"stock_name", v.StockName}, {"price", v.Price}, {"up_down_rate", v.UpDownRate.String()}, {"up_down", v.UpDown.String()}, {"trade_v", v.TradeV.String()}, {"trade_k", v.TradeK}, {"vol", v.Vol}, {"turnover_price_total", v.TurnoverPriceTotal.String()}, {"price_total", v.PriceTotal}, {"p_e", v.PE}, {"eps", v.Eps}, {"employees_number", v.EmployeesNumber}, {"plate", v.Plate}, {"desc", v.Desc}, {"price_code", v.PriceCode}, {"country", v.Country}, {"timestamp", v.Ts}, }}} models := mongo.NewUpdateOneModel().SetFilter(filter).SetUpdate(update).SetUpsert(true) dataList = append(dataList, models) } if len(dataList) > 0 { if err := data.MgoBulkWrite(data.GetStockTableName(country), dataList); err != nil { applogger.Error("stock MgoInsertMany err:%v", err) } } c.JSON(http.StatusOK, internal.GinResult(http.StatusOK, "", "ok")) } func UpdateImg(c *gin.Context) { // 获取上传文件 file, err := c.FormFile("image") if err != nil { c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, fmt.Sprintf("file error %s", err.Error()), internal.QueryError)) return } //不能大于10M if file.Size > 10*1024*1024 { c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, fmt.Sprintf("file too big"), internal.QueryError)) return } // 打开上传文件 src, err := file.Open() if err != nil { c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, fmt.Sprintf("file error %s", err.Error()), internal.QueryError)) return } defer src.Close() name := fmt.Sprintf("%d-%s", time.Now().Unix(), file.Filename) if err := common.UpdateImage(name, src); err != nil { c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, fmt.Sprintf("file error %s", err.Error()), internal.QueryError)) return } c.JSON(http.StatusOK, internal.GinResult(http.StatusOK, common.Path+name, "ok")) } func Visit(c *gin.Context) { fileName := internal.ReplaceStr(c.Query("fileName")) if fileName == "" { c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, fmt.Sprintf("fileName error "), internal.QueryError)) return } url, err := common.VisitImage(fileName) if err != nil { c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, fmt.Sprintf("file error %s", err.Error()), internal.QueryError)) return } c.JSON(http.StatusOK, internal.GinResult(http.StatusOK, url, "ok")) } func StockListAdd(c *gin.Context) { param := stock.StockList{} err := c.BindJSON(¶m) fmt.Println(param) if err != nil { applogger.Error("BindJSON", err.Error()) c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, "param error", internal.QueryError)) return } else if len(param.Results) <= 0 { c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, "param null", internal.QueryError)) return } else if param.Token != Token { c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, "token error", internal.QueryError)) return } else if param.Results[0].Code == "" { c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, "ticker error", internal.QueryError)) return } else if param.Results[0].Locale == "" { c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, "locale error", internal.QueryError)) return } else if param.Results[0].PrimaryExchange == "" { c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, "primary exchange error", internal.QueryError)) return } ////遇到排重 直接返回 //if len(param.Results) == 1 { // value := param.Results[0] // if !common.GetIndiaStockBool(fmt.Sprintf("%s:%s", value.PrimaryExchange, value.Code),common.CapitalizeFirstLetter(value.Locale)) { // c.JSON(http.StatusOK, internal.GinResult(http.StatusOK, "", "ok")) // return // } //} var dataList []mongo.WriteModel for _, value := range param.Results { //if !common.IsLetter(value.Code) { // applogger.Debug(value.Code, "包含其他符号") // continue //} locale := common.CapitalizeFirstLetter(value.Locale) value.Code = common.GetNewCode(value.PrimaryExchange, value.Code, locale) filter := bson.D{{"Code", bson.M{ "$eq": value.Code, }}, {"Country", bson.M{ "$eq": locale, }}} update := bson.D{{"$set", bson.D{ {"Code", value.Code}, {"Name", value.Name}, {"Country", locale}, {"Exchange", value.PrimaryExchange}, {"Symbol", common.GetOldCode(value.Code)}, {"Currency", value.Currency}, {"Intro", value.Intro}, {"LogoUrl", value.LogoUrl}}}} //第二次 if value.Currency == "" && value.YesterdayClose != "" { _, err := decimal.NewFromString(value.YesterdayClose) if err != nil { applogger.Debug(value.Code, value.YesterdayClose, err.Error()) continue } value.DateStr = strings.TrimSpace(value.DateStr) //if common.TimeToNows().Format("2006-01-02") != value.DateStr { // applogger.Error(value.Code, "不是今日的闭盘价") // continue //} update = bson.D{{"$set", bson.D{ {"YesterdayClose", value.YesterdayClose}, //上一次 闭盘价 {"Vol", value.Vol}, //当天的交易量 {"BeforeClose", value.BeforeClose}, {"ClosePrice", "0"}, {"Symbol", common.GetOldCode(value.Code)}, {"Exchange", value.PrimaryExchange}, {"IsSharia", value.IsSharia}, //是否符合伊斯兰股票 只针对 马来、印尼市场 其他市场不需要 {"DateStr", value.DateStr}, }}} red.HsetMap(business.StockClosingPrice[locale], value.Code, value.YesterdayClose) red.HsetMap(business.StockClosingPrice[fmt.Sprintf("%sBeforeClose", locale)], value.Code, value.BeforeClose) red.HsetMap(business.StockClosingPrice[fmt.Sprintf("%sNew", locale)], value.Code, "0") } models := mongo.NewUpdateOneModel().SetFilter(filter).SetUpdate(update).SetUpsert(true) dataList = append(dataList, models) } if len(dataList) > 0 { if err := data.MgoBulkWrite(data.StockList, dataList); err != nil { applogger.Error("MgoInsertMany err:%v", err) c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, "operation failure", internal.QueryError)) return } // TODO: 更改副表 没有公用数据的服务不需要 暂用redis 参数 dbs := common.GetRedisDBMore(config.Config.Redis.DbMore) if len(dbs) > 1 { applogger.Info("StockListAdd update table db", dbs[1]) data.MgoBulkWrite(fmt.Sprintf("%s%s", data.StockList, dbs[1]), dataList) } } else { c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, "error operation repetition", internal.QueryError)) return } c.JSON(http.StatusOK, internal.GinResult(http.StatusOK, "", "ok")) } func StockListUpdate(c *gin.Context) { param := stock.StockList{} err := c.BindJSON(¶m) if err != nil { applogger.Error("BindJSON", err.Error()) c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, "param error", internal.QueryError)) return } else if len(param.Results) <= 0 { c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, "param null", internal.QueryError)) return } else if param.Token != Token { c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, "token error", internal.QueryError)) return } else if param.Results[0].Code == "" { c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, "ticker error", internal.QueryError)) return } else if param.Results[0].Locale == "" { c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, "locale error", internal.QueryError)) return } for _, value := range param.Results { locale := common.CapitalizeFirstLetter(value.Locale) value.Code = common.GetNewCode(value.PrimaryExchange, value.Code, locale) filter := bson.D{{"Code", bson.M{ "$eq": value.Code, }}, {"Country", bson.M{ "$eq": common.CapitalizeFirstLetter(value.Locale), }}} updateData := bson.D{{"$set", bson.D{ {"Name", value.Name}, {"Country", common.CapitalizeFirstLetter(value.Locale)}, {"Exchange", value.PrimaryExchange}, {"Currency", value.Currency}, {"Intro", value.Intro}, {"LogoUrl", value.LogoUrl}}}} if err := data.MgoUpdateOne(data.StockList, filter, updateData); err != nil { applogger.Error("MgoInsertMany info err: %v", err) //return } postData := make(map[string]string) postData["stock_code"] = value.Code postData["stock_name"] = value.Name postData["tape"] = value.PrimaryExchange postData["country"] = fmt.Sprintf("%d", business.StockClosedDataList[common.CapitalizeFirstLetter(value.Locale)]) applogger.Info("php ", postData) bodyStr, err := internal.HttpPostFrom(config.Config.PhpHost.URL, postData) if err != nil { applogger.Error("Failed to query data:%v", err) } applogger.Info(bodyStr) } c.JSON(http.StatusOK, internal.GinResult(http.StatusOK, "", "ok")) } func StockListGet(c *gin.Context) { country := strings.TrimSpace(c.Query("country")) isDeficiency := strings.TrimSpace(c.Query("is_deficiency")) // true 查找缺失数据股票 false 查找全部 sourceVal := strings.TrimSpace(c.Query("source")) // 1 tradingview 2 其他 source, _ := strconv.Atoi(sourceVal) token := internal.ReplaceStr(c.Query("token")) fmt.Println("source : ", source) if token != Token { c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, "token error", internal.QueryError)) return } else if country == "" { c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, "country error", internal.QueryError)) return } country = common.CapitalizeFirstLetter(internal.ReplaceStr(country)) filter := bson.M{"Country": country} if isDeficiency == "true" { filter = bson.M{"Country": country, "Name": bson.M{"$exists": false}, "YesterdayClose": bson.M{"$ne": ""}} } if source != 0 { filter = bson.M{"Country": country, "Source": source} } projection := bson.M{"Code": 1, "Country": 1, "Symbol": 1, "Exchange": 1, "Source": 1, "Name": 1} sort := bson.M{} var md stock.MgoPageSize md.Total, _ = data.MgoFindTotal(data.StockList, filter) md.Data, _ = data.MgoFindProjection(data.StockList, filter, projection, sort, 0) c.JSON(http.StatusOK, internal.GinResult(http.StatusOK, md, "ok")) } func StockInfoMon(c *gin.Context) { param := model.StockMonRes{} err := c.BindJSON(¶m) fmt.Println(param) if err != nil { applogger.Error("BindJSON", err.Error()) c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, "param error", internal.QueryError)) return } else if len(param.Result) <= 0 { c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, "param null", internal.QueryError)) return } else if param.Token != Token { c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, "token error", internal.QueryError)) return } else if param.Country == "" { c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, "country error", internal.QueryError)) return } else if param.Status == "" { c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, "status error", internal.QueryError)) return } var dataList []mongo.WriteModel for _, v := range param.Result { filter := bson.M{"timestamp": bson.M{"$eq": v.Ts}, "symbol": bson.M{"$eq": v.Symbol}} update := bson.D{{"$set", bson.D{ {"symbol", v.Symbol}, {"stock_code", v.StockCode}, {"stock_name", v.StockName}, {"open_price", v.OpenPrice.String()}, {"high_price", v.HighPrice.String()}, {"low_price", v.LowPrice.String()}, {"close_price", v.ClosePrice.String()}, {"desc", v.Desc}, {"price_code", v.PriceCode}, {"country", v.Country}, {"vol", v.Vol}, {"timestamp", v.Ts}, }}} models := mongo.NewUpdateOneModel().SetFilter(filter).SetUpdate(update).SetUpsert(true) dataList = append(dataList, models) } if err := data.MgoBulkWrite(data.GetStockSouthAsiaTableName(common.CapitalizeFirstLetter(param.Country), param.Status), dataList); err != nil { applogger.Error("stock MgoInsertMany err:%v", err) } c.JSON(http.StatusOK, internal.GinResult(http.StatusOK, "", "ok")) } func StockKLineList(c *gin.Context) { symbol := internal.ReplaceStr(c.Query("symbol")) country := internal.ReplaceStr(c.Query("country")) from := internal.IntegerInit(internal.ReplaceStr(c.Query("from"))) // 开始时间 to := internal.IntegerInit(internal.ReplaceStr(c.Query("to"))) // 结束时间 period := internal.ReplaceStr(c.Query("period")) // 时间颗粒度 size := internal.IntegerInit(internal.ReplaceStr(c.Query("size"))) // 结束时间 if period == "60min" { period = "1hour" } if symbol == "" { c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, "symbol error", internal.QueryError)) return } else if period == "" { c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, "period error", internal.QueryError)) return } filter := bson.M{"symbol": symbol, "timestamp": bson.M{"$gte": from, "$lte": to}} if size > 0 { filter = bson.M{"symbol": symbol} } tableName := data.GetStockSouthAsiaTableName(common.CapitalizeFirstLetter(country), period) pagedData, err := data.MgoFinds(tableName, filter, int64(size)) if err != nil { c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, err, internal.QueryError)) return } var md stock.MgoPageSize md.Data = pagedData c.JSON(http.StatusOK, internal.GinResult(http.StatusOK, md, internal.QuerySuccess)) } func StockKLineUsList(c *gin.Context) { symbol := internal.ReplaceStr(c.Query("symbol")) from := internal.IntegerInit(internal.ReplaceStr(c.Query("from"))) // 开始时间 to := internal.IntegerInit(internal.ReplaceStr(c.Query("to"))) // 结束时间 period := internal.ReplaceStr(c.Query("period")) // 时间颗粒度 size := internal.IntegerInit(internal.ReplaceStr(c.Query("size"))) // 结束时间 if period == "60min" { period = "1hour" } if symbol == "" { c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, "symbol error", internal.QueryError)) return } else if period == "" { c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, "period error", internal.QueryError)) return } filter := bson.M{"code": symbol, "timestamp": bson.M{"$gte": from, "$lte": to}} if size > 0 { filter = bson.M{"code": symbol} } tableName := data.GetStockUsTableName(period) pagedData, err := data.MgoFinds(tableName, filter, int64(size)) if err != nil { c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, err, internal.QueryError)) return } var md stock.MgoPageSize md.Data = pagedData c.JSON(http.StatusOK, internal.GinResult(http.StatusOK, md, internal.QuerySuccess)) } func StockNewAdd(c *gin.Context) { param := model.StockNewsRes{} err := c.BindJSON(¶m) if err != nil { applogger.Error("BindJSON", err.Error()) c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, "param error", internal.QueryError)) return } else if len(param.Result) <= 0 { c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, "param null", internal.QueryError)) return } else if param.Token != Token { c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, "token error", internal.QueryError)) return } else if param.Country == "" { c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, "country error", internal.QueryError)) return } var bsonEod []interface{} for _, v := range param.Result { bsonEod = append(bsonEod, bson.D{ {"country", v.Country}, {"pubdate", v.Pubdate}, {"title", v.Title}, {"link", v.Link}, {"source", v.Source}, {"code", common.TimeToNow()}, }) } if len(bsonEod) > 0 { if err := data.MgoInsertMany(data.StockNews, bsonEod); err != nil { applogger.Error("MgoInsertMany info err: %v", err) return } } c.JSON(http.StatusOK, internal.GinResult(http.StatusOK, "", "ok")) } func StockNewsList(c *gin.Context) { country := internal.ReplaceStr(c.Query("country")) size := internal.IntegerInit(internal.ReplaceStr(c.Query("size"))) if country == "" { c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, "country error", internal.QueryError)) return } switch country { case "Forex": country = country case "Encryption": country = country case "UK": country = country default: country = strings.ToLower(country) } if size == 0 { size = TotalSize } var filter = bson.M{} if country != "" { filter = bson.M{"country": country} } applogger.Debug("StockNewsList filter: %v", filter) pagedData, err := data.MgoFindsCode(data.StockNews, filter, int64(size)) if err != nil { c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, err, internal.QueryError)) return } var md stock.MgoPageSize md.Data = pagedData c.JSON(http.StatusOK, internal.GinResult(http.StatusOK, md, internal.QuerySuccess)) } func StockSouthAsiaInfo(c *gin.Context) { symbol := internal.ReplaceStr(c.Query("symbol")) country := internal.ReplaceStr(c.Query("country")) if symbol == "" { c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, "symbol error", internal.QueryError)) return } else if country == "" { c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, "country error", internal.QueryError)) return } country = common.CapitalizeFirstLetter(country) var pageData = model.StockMogoParam{} filter := bson.M{"symbol": symbol} res, _ := data.MgoFinds(data.GetStockSouthAsiaTableName(country, "1day"), filter, int64(1)) pageData.StockCode = symbol if len(res) > 0 { pageData.HighPrice = business.TypeCheck(res[0]["high_price"]) pageData.LowPrice = business.TypeCheck(res[0]["low_price"]) pageData.Vol = res[0]["vol"] pageData.PriceTotal = business.TypeCheck(res[0]["price_total"]) pageData.TurnoverPriceTotal = business.TypeCheck(res[0]["turnover_price_total"]) } pageData.OpenPrice, _ = red.Hget(business.StockClosingPrice[country], symbol) pageData.ClosePrice, _ = red.Hget(business.StockClosingPrice[fmt.Sprintf("%sNew", country)], symbol) if pageData.ClosePrice == "" || pageData.ClosePrice == "0" { //闭盘期间 pageData.ClosePrice = pageData.OpenPrice pageData.OpenPrice, _ = red.Hget(business.StockClosingPrice[fmt.Sprintf("%sBeforeClose", country)], symbol) } //if country == "India" { filter = bson.M{"Country": country, "Code": symbol} projection := bson.M{"Exchange": 1, "Symbol": 1, "NumericCode": 1} sort := bson.M{} result, _ := data.MgoFindProjection(data.StockList, filter, projection, sort, 0) if len(result) > 0 { pageData.PrimaryExchange = business.TypeCheck(result[0]["Exchange"]) pageData.Symbol = business.TypeCheck(result[0]["Symbol"]) pageData.NumericCode = business.TypeCheck(result[0]["NumericCode"]) } // } var md stock.MgoPageSize md.Data = pageData c.JSON(http.StatusOK, internal.GinResult(http.StatusOK, md, internal.QuerySuccess)) } func StockUsInfo(c *gin.Context) { symbol := internal.ReplaceStr(c.Query("symbol")) if symbol == "" { c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, "symbol error", internal.QueryError)) return } var pageData = model.StockMogoParam{} res := business.GetFinnhubBeforClose(symbol) if res.C.GreaterThan(decimal.Zero) { pageData.OpenPrice = res.O.String() pageData.HighPrice = res.H.String() pageData.LowPrice = res.L.String() pageData.ClosePrice = res.C.String() //pageData.Vol = res.Results[0].V.String() //pageData.Vw = res.Results[0].VW.String() pageData.Symbol = symbol } filter := bson.M{"Country": "US", "Code": symbol} projection := bson.M{"Exchange": 1} usData, _ := data.MgoFindProjection(data.StockList, filter, projection, bson.M{}, 1) if len(usData) > 0 { pageData.PrimaryExchange = usData[0]["Exchange"].(string) } pageData.PreviousPrice, _ = red.Hget(business.StockClosingPrice[fmt.Sprintf("US")], symbol) pageData.ClosePrice, _ = red.Hget(business.StockClosingPrice[fmt.Sprintf("USNew")], symbol) //市价 if pageData.ClosePrice == "" || pageData.ClosePrice == "0" { //闭盘期间 pageData.ClosePrice = pageData.PreviousPrice pageData.PreviousPrice, _ = red.Hget(business.StockClosingPrice[fmt.Sprintf("USBeforeClose")], symbol) } var md stock.MgoPageSize md.Data = pageData c.JSON(http.StatusOK, internal.GinResult(http.StatusOK, md, internal.QuerySuccess)) } func getCodePrice(code, country string) (string, string) { if country != "US" { return "", "" } eodModel, _ := business.PreviousClose(code) if len(eodModel.Results) <= 0 { return "", "" } dateStrs := common.ConvertToTimezones(eodModel.Results[0].T) yesterday := dateStrs var i int Loop: yesterday = yesterday.AddDate(0, 0, -1) yesterdayClose, _ := business.UsData(code, yesterday.Format("2006-01-02")) if yesterdayClose == "" { if i <= 2 { time.Sleep(1 * time.Second) i++ goto Loop } } if yesterdayClose == "" { return "", "" } return eodModel.Results[0].C.String(), yesterdayClose } func StockListUpdateToPHP(c *gin.Context) { param := stock.StockUpdatePolygon{} err := c.BindJSON(¶m) fmt.Printf("%+v", param) if err != nil { applogger.Error("BindJSON", err.Error()) c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, "param error", internal.QueryError)) return } else if param.NewCode == "" { c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, "new ticker error", internal.QueryError)) return } else if param.Locale == "" { c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, "locale error", internal.QueryError)) return } else if param.Token != Token { c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, "token error", internal.QueryError)) return } else if param.Source == 0 { c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, "source error", internal.QueryError)) return } param.Locale = common.CapitalizeFirstLetter(param.Locale) filter := bson.M{"Code": param.NewCode, "Country": param.Locale, } updateData := bson.D{{"$set", bson.D{ {"Source", param.Source}}}} if err := data.MgoUpdateOne(data.StockList, filter, updateData); err != nil { applogger.Error("php update err:%v", err) c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, "operation failure", internal.QueryError)) return } c.JSON(http.StatusOK, internal.GinResult(http.StatusOK, "", "ok")) } func StockListAddToPHP(c *gin.Context) { param := stock.StockUpdatePolygon{} err := c.BindJSON(¶m) fmt.Printf("%+v", param) if err != nil { applogger.Error("BindJSON", err.Error()) c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, "param error", internal.QueryError)) return } else if param.NewCode == "" { c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, "new ticker error", internal.QueryError)) return } else if param.OldCode == "" { c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, "old ticker error", internal.QueryError)) return } else if param.Locale == "" { c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, "locale error", internal.QueryError)) return } else if param.Token != Token { c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, "token error", internal.QueryError)) return } else if param.PrimaryExchange == "" { c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, "primary exchange error", internal.QueryError)) return } //转换股票code类型 param.Locale = common.CapitalizeFirstLetter(param.Locale) param.OldCode = common.GetNewCode(param.PrimaryExchange, param.OldCode, param.Locale) param.NewCode = common.GetNewCode(param.PrimaryExchange, param.NewCode, param.Locale) var dataList []mongo.WriteModel filter := bson.M{"Code": param.OldCode, "Country": param.Locale, } yesterdayClose, beforeClose := getCodePrice(param.OldCode, param.Locale) if yesterdayClose != "" { param.YesterdayClose = yesterdayClose } else { beforeClose = param.YesterdayClose } updateData := bson.M{} updateData["Code"] = param.NewCode updateData["Country"] = param.Locale if param.Name != "" { updateData["Name"] = param.Name } if param.NumericCode != "" { updateData["NumericCode"] = param.NumericCode } if param.PrimaryExchange != "" { updateData["Exchange"] = param.PrimaryExchange updateData["Tape"] = TapsMap[strings.ReplaceAll(param.PrimaryExchange, " ", "")] } if param.YesterdayClose != "" { updateData["YesterdayClose"] = param.YesterdayClose } if beforeClose != "" { updateData["BeforeClose"] = beforeClose } if param.IsReal != 0 { updateData["IsReal"] = param.IsReal } if param.Intro != "" { updateData["Intro"] = param.Intro } if param.Currency != "" { updateData["Currency"] = param.Currency } if param.Source != 0 { updateData["Source"] = param.Source } updateData["Symbol"] = common.GetOldCode(param.NewCode) update := bson.M{"$set": updateData} //修改股票CODE if param.OldCode != param.NewCode { //判断修改原数据是否存在 total, _ := data.MgoFindTotal(data.StockList, filter) if total == 0 { c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, "stock code not exist", internal.QueryError)) return } if param.Locale != "US" { go func(param stock.StockUpdatePolygon) { for _, v := range dictionary.StockSouthAsiaListTime { tableName := data.GetStockSouthAsiaTableName(param.Locale, v) if err := data.MgoUpdateMany(tableName, bson.D{{"symbol", bson.M{ "$eq": param.OldCode, }}}, bson.D{{"$set", bson.D{ {"stock_code", common.GetOldCode(param.NewCode)}, {"symbol", param.NewCode}}}}); err != nil { applogger.Error("Mgo update Many err:%v", err) } } }(param) } param.YesterdayClose, _ = red.Hget(business.StockClosingPrice[param.Locale], param.OldCode) beforeClose, _ = red.Hget(business.StockClosingPrice[fmt.Sprintf("%sBeforeClose", param.Locale)], param.OldCode) } models := mongo.NewUpdateOneModel().SetFilter(filter).SetUpdate(update).SetUpsert(true) dataList = append(dataList, models) red.Hset(business.StockClosingPrice[param.Locale], param.NewCode, param.YesterdayClose) red.Hset(business.StockClosingPrice[fmt.Sprintf("%sBeforeClose", param.Locale)], param.NewCode, beforeClose) red.Hset(business.StockClosingPrice[fmt.Sprintf("%sNew", param.Locale)], param.NewCode, "0") if len(dataList) > 0 { if err := data.MgoBulkWrite(data.StockList, dataList); err != nil { applogger.Error("MgoInsertMany err:%v", err) c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, "operation failure", internal.QueryError)) return } } else { c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, "error operation repetition", internal.QueryError)) return } // 新增美股行情分发股票代码列表 WriteShareUs(param.NewCode) c.JSON(http.StatusOK, internal.GinResult(http.StatusOK, "", "ok")) } // WriteShareUs // // @Description: 新增美股行情分发股票代码列表 // @param code func WriteShareUs(code string) { url := fmt.Sprintf("http://%v/usWss/add/code?code=%v", config.Config.FinnhubUs.DispenseWss, code) applogger.Debug("url data info:%v", url) bodyStr, err := internal.HttpGet(url) if err != nil { applogger.Error("WriteShareUs err info:%v", err) return } applogger.Debug("new add shareUs code info:%v", bodyStr) }