Browse Source

增加“定制【海商报业】- 查询热门商品列表”接口

zhou.xiaoning 5 years ago
parent
commit
af15541140
15 changed files with 896 additions and 62 deletions
  1. 5 21
      config/cfg.json
  2. 77 5
      config/config.go
  3. 11 3
      config/config.xml
  4. 91 0
      controllers/hsby/hsby.go
  5. 0 1
      db/db.go
  6. 50 0
      db/mysqldb.go
  7. 114 1
      docs/docs.go
  8. 114 1
      docs/swagger.json
  9. 138 20
      docs/swagger.yaml
  10. 1 0
      go.mod
  11. 18 10
      main.go
  12. 108 0
      models/hsby.go
  13. 149 0
      models/quote.go
  14. 8 0
      routers/router.go
  15. 12 0
      utils/mathUtils.go

+ 5 - 21
config/cfg.json

@@ -7,26 +7,10 @@
         "goCommonSearchUrl": "http://192.168.31.104:8080/api",
         "openApiUrl": "http://192.168.31.104:5015/mtp2-onlineopen",
         "mobileOpenUrl": "http://192.168.31.104:5055",
-        "mobileAuthUrl": "http://192.168.31.104:5056"
-    },
-    "dev_182": {
-        "quoteUrl": "ws://192.168.30.182:18891",
-        "tradeUrl": "ws://192.168.30.182:18892",
-        "uploadUrl": "http://192.168.30.182:5015/mtp2-onlineopen/upload",
-        "commSearchUrl": "http://192.168.30.182:5019/mtp2-search",
-        "goCommonSearchUrl": "http://192.168.30.182:8080/api",
-        "openApiUrl": "http://192.168.30.182:5015/mtp2-onlineopen",
-        "mobileOpenUrl": "http://192.168.30.182:5035",
-        "mobileAuthUrl": "http://192.168.30.182:5035/szWebRegister"
-    },
-    "test_181": {
-        "quoteUrl": "ws://192.168.31.181:18891",
-        "tradeUrl": "ws://192.168.31.181:18892",
-        "uploadUrl": "http://192.168.31.181:5015/mtp2-onlineopen/upload",
-        "commSearchUrl": "http://192.168.31.181:5019/mtp2-search",
-        "openApiUrl": "http://192.168.31.181:5015/mtp2-onlineopen",
-        "goCommonSearchUrl": "http://192.168.31.181:8080/api",
-        "mobileOpenUrl": "http://192.168.31.181:5055",
-        "mobileAuthUrl": "http://192.168.31.181:5056"
+        "mobileAuthUrl": "http://192.168.31.104:5056",
+        "quoteHost": "192.168.31.109",
+        "quotePort": "5002",
+        "tradeHost": "192.168.31.109",
+        "tradePort": "5001"
     }
 }

+ 77 - 5
config/config.go

@@ -44,7 +44,15 @@ type MqConfig struct {
 }
 
 type MongoDBConfig struct {
-	Hostname string
+	HostName string
+	Port     int
+	DBName   string
+	Username string
+	Password string
+}
+
+type MySQLConfig struct {
+	Host     string
 	Port     int
 	DBName   string
 	Username string
@@ -58,6 +66,7 @@ type ServiceConfig struct {
 	RedisCfg   RedisConfig
 	MqCfg      MqConfig
 	MongoDBCfg MongoDBConfig
+	MySQLCfg   MySQLConfig
 }
 
 func (c *ServiceConfig) Init(path string) error {
@@ -248,11 +257,11 @@ func (c *ServiceConfig) Init(path string) error {
 	mongodbsettings := root.SelectElements("MongoDBSetting")
 	for _, setting := range mongodbsettings {
 		// 主机地址
-		hostname := setting.SelectElement("Hostname")
-		if hostname == nil {
+		hostName := setting.SelectElement("HostName")
+		if hostName == nil {
 			return errors.New("read mongondb hostname failed")
 		}
-		SerCfg.MongoDBCfg.Hostname = hostname.SelectAttrValue("value", "")
+		SerCfg.MongoDBCfg.HostName = hostName.SelectAttrValue("value", "")
 
 		// 端口
 		port := setting.SelectElement("Port")
@@ -287,6 +296,49 @@ func (c *ServiceConfig) Init(path string) error {
 		SerCfg.MongoDBCfg.Password = password.SelectAttrValue("value", "")
 	}
 
+	// MySQL配置
+	mysqlsettings := root.SelectElements("MySQLSetting")
+	for _, setting := range mysqlsettings {
+		// 主机地址
+		host := setting.SelectElement("Host")
+		if host == nil {
+			return errors.New("read mysql host failed")
+		}
+		SerCfg.MySQLCfg.Host = host.SelectAttrValue("value", "")
+
+		// 端口
+		port := setting.SelectElement("Port")
+		if port == nil {
+			return errors.New("read mysql port failed")
+		}
+		ret, err := strconv.ParseUint(port.SelectAttrValue("value", "3306"), 10, 32)
+		if err != nil {
+			return errors.New("read mysql port failed")
+		}
+		SerCfg.MySQLCfg.Port = int(ret)
+
+		// 数据库名
+		dbname := setting.SelectElement("DBName")
+		if dbname == nil {
+			return errors.New("read mysql dbname failed")
+		}
+		SerCfg.MySQLCfg.DBName = dbname.SelectAttrValue("value", "")
+
+		// 用户名
+		username := setting.SelectElement("Username")
+		if username == nil {
+			return errors.New("read mysql username failed")
+		}
+		SerCfg.MySQLCfg.Username = username.SelectAttrValue("value", "")
+
+		// 密码
+		password := setting.SelectElement("Password")
+		if password == nil {
+			return errors.New("read mysql password failed")
+		}
+		SerCfg.MySQLCfg.Password = password.SelectAttrValue("value", "")
+	}
+
 	return nil
 }
 
@@ -342,7 +394,7 @@ func (c *ServiceConfig) GetRedisTimeout() int {
 }
 
 func (c *ServiceConfig) GetMongoDBHostname() string {
-	return SerCfg.MongoDBCfg.Hostname
+	return SerCfg.MongoDBCfg.HostName
 }
 
 func (c *ServiceConfig) GetMongoDBPort() int {
@@ -360,3 +412,23 @@ func (c *ServiceConfig) GetMongoDBUsername() string {
 func (c *ServiceConfig) GetMongoDBPassword() string {
 	return SerCfg.MongoDBCfg.Password
 }
+
+func (c *ServiceConfig) GetMySQLHost() string {
+	return SerCfg.MySQLCfg.Host
+}
+
+func (c *ServiceConfig) GetMySQLPort() int {
+	return SerCfg.MySQLCfg.Port
+}
+
+func (c *ServiceConfig) GetMySQLDBName() string {
+	return SerCfg.MySQLCfg.DBName
+}
+
+func (c *ServiceConfig) GetMySQLUsername() string {
+	return SerCfg.MySQLCfg.Username
+}
+
+func (c *ServiceConfig) GetMySQLPassword() string {
+	return SerCfg.MySQLCfg.Password
+}

+ 11 - 3
config/config.xml

@@ -16,12 +16,12 @@
         <DbAddress value="192.168.31.117"/>
         <DbName    value="orcl"/>
         <DbPort    value="1521"/>
-        <DbUser    value="mtp2_test181"/>
+        <DbUser    value="mtp2_test82"/>
         <DbPwd     value="muchinfo"/>
     </DbSetting>
 
     <RedisSetting>
-        <Address   value="192.168.31.181"/>
+        <Address   value="192.168.30.182"/>
         <Port      value="5007"/>
         <Timeout   value="3"/>
         <ConnNum   value="1"/>
@@ -35,10 +35,18 @@
     </MqSetting>
 
     <MongoDBSetting>
-        <Hostname   value="192.168.30.182"/>
+        <HostName   value="192.168.30.182"/>
         <Port       value="5025"/>
         <DBName     value="HistoryQuote"/>
         <Username   value="quote_test01"/>
         <Password   value="123456"/>
     </MongoDBSetting>
+
+    <MySQLSetting>
+        <Host       value="192.168.30.113"/>
+        <Port       value="3306"/>
+        <DBName     value="historyquote_test82"/>
+        <Username   value="quote_test82"/>
+        <Password   value="123456"/>
+    </MySQLSetting>
 </Configuration>

+ 91 - 0
controllers/hsby/hsby.go

@@ -0,0 +1,91 @@
+package hsby
+
+import (
+	"mtp2_if/global/app"
+	"mtp2_if/global/e"
+	"mtp2_if/logger"
+	"mtp2_if/models"
+	"net/http"
+	"sort"
+
+	"github.com/gin-gonic/gin"
+)
+
+// QueryTopGoodsReq 查询热门商品列表请求参数
+type QueryTopGoodsReq struct {
+	app.PageInfo
+	MarketID       int `form:"marketID" binding:"required"`
+	DescProvinceID int `form:"descProvinceID"`
+	DescCityID     int `form:"descCityID"`
+}
+
+// QueryTopGoods 查询热门商品列表
+// @Summary 查询热门商品列表
+// @Description 说明:查询结果已按Hotindex(景点热度)从大到小排序
+// @Produce json
+// @Security ApiKeyAuth
+// @Param page query int false "页码"
+// @Param pagesize query int false "每页条数"
+// @Param marketID query int true "市场ID"
+// @Param DescProvinceID query int false "目的地(省)ID"
+// @Param DescCityID query int false "目的地(市)ID"
+// @Success 200 {object} models.TopGoods
+// @Failure 500 {object} app.Response
+// @Router /HSBY/QueryTopGoods [get]
+// @Tags 定制【海商报业】
+func QueryTopGoods(c *gin.Context) {
+	appG := app.Gin{C: c}
+
+	// 获取请求参数
+	var req QueryTopGoodsReq
+	if err := appG.C.ShouldBindQuery(&req); err != nil {
+		logger.GetLogger().Errorf("QueryTopGoods failed: %s", err.Error())
+		appG.Response(http.StatusBadRequest, e.INVALID_PARAMS, nil)
+		return
+	}
+
+	// 获取数据
+	topGoodses, err := models.GetHsbyTopGoods(req.MarketID, req.DescProvinceID, req.DescCityID)
+	if err != nil {
+		// 查询失败
+		logger.GetLogger().Errorf("QueryTopGoods failed: %s", err.Error())
+		appG.Response(http.StatusBadRequest, e.ERROR_QUERY_FAIL, nil)
+		return
+	}
+
+	// 排序
+	sort.Slice(topGoodses, func(i int, j int) bool {
+		return topGoodses[i].Hotindex > topGoodses[j].Hotindex
+	})
+
+	// 分页
+	total := len(topGoodses)
+	if req.PageSize > 0 {
+		rstByPage := make([]models.TopGoods, 0)
+		// 开始上标
+		start := req.Page * req.PageSize
+		// 结束下标
+		end := start + req.PageSize
+
+		if start <= len(topGoodses) {
+			// 判断结束下标是否越界
+			if end > len(topGoodses) {
+				end = len(topGoodses)
+			}
+			rstByPage = topGoodses[start:end]
+		} else {
+			rstByPage = topGoodses[0:0]
+		}
+
+		topGoodses = rstByPage
+	}
+
+	// 查询成功返回
+	if req.PageSize > 0 {
+		logger.GetLogger().Debugln("QueryTopGoods successed: %v", topGoodses)
+		appG.ResponseByPage(http.StatusOK, e.SUCCESS, topGoodses, app.PageInfo{Page: req.Page, PageSize: req.PageSize, Total: total})
+	} else {
+		logger.GetLogger().Debugln("QueryTopGoods successed: %v", topGoodses)
+		appG.Response(http.StatusOK, e.SUCCESS, topGoodses)
+	}
+}

+ 0 - 1
db/db.go

@@ -37,7 +37,6 @@ func InitDbEngine() error {
 	Engine.SetLogger(logger)
 	// 将SQL打印到Console
 	Engine.ShowSQL(true)
-
 	Engine.SetTableMapper(core.SameMapper{})
 
 	return nil

+ 50 - 0
db/mysqldb.go

@@ -0,0 +1,50 @@
+package db
+
+import (
+	"fmt"
+	"mtp2_if/config"
+	"mtp2_if/logger"
+
+	"github.com/xormplus/core"
+	"github.com/xormplus/xorm"
+	"github.com/xormplus/xorm/log"
+)
+
+// MySQLEngine MySQL Engine
+var MySQLEngine *xorm.Engine
+
+// InitMySQLDbEngine 创建数据库驱动
+func InitMySQLDbEngine() error {
+	host := config.SerCfg.GetMySQLHost()
+	port := config.SerCfg.GetMySQLPort()
+	dbname := config.SerCfg.GetMySQLDBName()
+	username := config.SerCfg.GetMySQLUsername()
+	password := config.SerCfg.GetMySQLPassword()
+	dataSourceName := fmt.Sprintf("%s:%s@(%s:%d)/%s?charset=utf8", username, password, host, port, dbname)
+
+	var err error
+	MySQLEngine, err = xorm.NewEngine("mysql", dataSourceName)
+	if err != nil {
+		fmt.Println("create mysql engine failed:", err)
+		return err
+	}
+
+	// 将SQL写到日志文件
+	logger := log.NewSimpleLogger(logger.GetLogWriter())
+	Engine.SetLogger(logger)
+	// 将SQL打印到Console
+	Engine.ShowSQL(true)
+	Engine.SetTableMapper(core.SameMapper{})
+
+	return nil
+}
+
+// GetMySQLEngine GetMySQLEngine
+func GetMySQLEngine() *xorm.Engine {
+	return MySQLEngine
+}
+
+// CloseMySQL CloseMySQL
+func CloseMySQL() {
+	MySQLEngine.Close()
+}

+ 114 - 1
docs/docs.go

@@ -20,7 +20,6 @@ var doc = `{
         "title": "{{.Title}}",
         "termsOfService": "http://muchinfo.cn",
         "contact": {},
-        "license": {},
         "version": "{{.Version}}"
     },
     "host": "{{.Host}}",
@@ -724,6 +723,70 @@ var doc = `{
                 }
             }
         },
+        "/HSBY/QueryTopGoods": {
+            "get": {
+                "security": [
+                    {
+                        "ApiKeyAuth": []
+                    }
+                ],
+                "description": "说明:查询结果已按Hotindex(景点热度)从大到小排序",
+                "produces": [
+                    "application/json"
+                ],
+                "tags": [
+                    "定制【海商报业】"
+                ],
+                "summary": "查询热门商品列表",
+                "parameters": [
+                    {
+                        "type": "integer",
+                        "description": "页码",
+                        "name": "page",
+                        "in": "query"
+                    },
+                    {
+                        "type": "integer",
+                        "description": "每页条数",
+                        "name": "pagesize",
+                        "in": "query"
+                    },
+                    {
+                        "type": "integer",
+                        "description": "市场ID",
+                        "name": "marketID",
+                        "in": "query",
+                        "required": true
+                    },
+                    {
+                        "type": "integer",
+                        "description": "目的地(省)ID",
+                        "name": "DescProvinceID",
+                        "in": "query"
+                    },
+                    {
+                        "type": "integer",
+                        "description": "目的地(市)ID",
+                        "name": "DescCityID",
+                        "in": "query"
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "OK",
+                        "schema": {
+                            "$ref": "#/definitions/models.TopGoods"
+                        }
+                    },
+                    "500": {
+                        "description": "Internal Server Error",
+                        "schema": {
+                            "$ref": "#/definitions/app.Response"
+                        }
+                    }
+                }
+            }
+        },
         "/History/QueryTSData": {
             "get": {
                 "produces": [
@@ -3553,6 +3616,56 @@ var doc = `{
                 }
             }
         },
+        "models.TopGoods": {
+            "type": "object",
+            "required": [
+                "goodscode",
+                "goodsid",
+                "goodsname"
+            ],
+            "properties": {
+                "currency": {
+                    "description": "货币",
+                    "type": "string"
+                },
+                "currencysign": {
+                    "description": "货币符号",
+                    "type": "string"
+                },
+                "decimalplace": {
+                    "description": "报价小数位",
+                    "type": "integer"
+                },
+                "goodscode": {
+                    "description": "商品代码(内部)",
+                    "type": "string"
+                },
+                "goodsid": {
+                    "description": "商品ID(自增ID SEQ_GOODS)",
+                    "type": "integer"
+                },
+                "goodsname": {
+                    "description": "商品名称",
+                    "type": "string"
+                },
+                "hotindex": {
+                    "description": "景点热度",
+                    "type": "integer"
+                },
+                "last": {
+                    "description": "现价",
+                    "type": "number"
+                },
+                "picurls": {
+                    "description": "介绍图片[多张用逗号分隔]",
+                    "type": "string"
+                },
+                "videourls": {
+                    "description": "介绍视频[多张用逗号分隔]",
+                    "type": "string"
+                }
+            }
+        },
         "models.Userinfo": {
             "type": "object",
             "required": [

+ 114 - 1
docs/swagger.json

@@ -5,7 +5,6 @@
         "title": "MTP2.0 查询服务 API",
         "termsOfService": "http://muchinfo.cn",
         "contact": {},
-        "license": {},
         "version": "1.0"
     },
     "basePath": "/api",
@@ -708,6 +707,70 @@
                 }
             }
         },
+        "/HSBY/QueryTopGoods": {
+            "get": {
+                "security": [
+                    {
+                        "ApiKeyAuth": []
+                    }
+                ],
+                "description": "说明:查询结果已按Hotindex(景点热度)从大到小排序",
+                "produces": [
+                    "application/json"
+                ],
+                "tags": [
+                    "定制【海商报业】"
+                ],
+                "summary": "查询热门商品列表",
+                "parameters": [
+                    {
+                        "type": "integer",
+                        "description": "页码",
+                        "name": "page",
+                        "in": "query"
+                    },
+                    {
+                        "type": "integer",
+                        "description": "每页条数",
+                        "name": "pagesize",
+                        "in": "query"
+                    },
+                    {
+                        "type": "integer",
+                        "description": "市场ID",
+                        "name": "marketID",
+                        "in": "query",
+                        "required": true
+                    },
+                    {
+                        "type": "integer",
+                        "description": "目的地(省)ID",
+                        "name": "DescProvinceID",
+                        "in": "query"
+                    },
+                    {
+                        "type": "integer",
+                        "description": "目的地(市)ID",
+                        "name": "DescCityID",
+                        "in": "query"
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "OK",
+                        "schema": {
+                            "$ref": "#/definitions/models.TopGoods"
+                        }
+                    },
+                    "500": {
+                        "description": "Internal Server Error",
+                        "schema": {
+                            "$ref": "#/definitions/app.Response"
+                        }
+                    }
+                }
+            }
+        },
         "/History/QueryTSData": {
             "get": {
                 "produces": [
@@ -3537,6 +3600,56 @@
                 }
             }
         },
+        "models.TopGoods": {
+            "type": "object",
+            "required": [
+                "goodscode",
+                "goodsid",
+                "goodsname"
+            ],
+            "properties": {
+                "currency": {
+                    "description": "货币",
+                    "type": "string"
+                },
+                "currencysign": {
+                    "description": "货币符号",
+                    "type": "string"
+                },
+                "decimalplace": {
+                    "description": "报价小数位",
+                    "type": "integer"
+                },
+                "goodscode": {
+                    "description": "商品代码(内部)",
+                    "type": "string"
+                },
+                "goodsid": {
+                    "description": "商品ID(自增ID SEQ_GOODS)",
+                    "type": "integer"
+                },
+                "goodsname": {
+                    "description": "商品名称",
+                    "type": "string"
+                },
+                "hotindex": {
+                    "description": "景点热度",
+                    "type": "integer"
+                },
+                "last": {
+                    "description": "现价",
+                    "type": "number"
+                },
+                "picurls": {
+                    "description": "介绍图片[多张用逗号分隔]",
+                    "type": "string"
+                },
+                "videourls": {
+                    "description": "介绍视频[多张用逗号分隔]",
+                    "type": "string"
+                }
+            }
+        },
         "models.Userinfo": {
             "type": "object",
             "required": [

+ 138 - 20
docs/swagger.yaml

@@ -377,7 +377,8 @@ definitions:
         description: 客户端流水号
         type: string
       clienttype:
-        description: 客户端类型 - 0:保留为未填终端类型 1:PC管理端 2:PC交易端 3:手机客户端_安卓 4:网页客户端 5:微信客户端 6:手机客户端_苹果 7:网上开户客户端 8:无效终端编号 9:报价终端(中江)
+        description: 客户端类型 - 0:保留为未填终端类型 1:PC管理端 2:PC交易端 3:手机客户端_安卓 4:网页客户端 5:微信客户端
+          6:手机客户端_苹果 7:网上开户客户端 8:无效终端编号 9:报价终端(中江)
         type: integer
       closeexchagechargevalue:
         description: 平仓交易所手续费设置值
@@ -461,7 +462,9 @@ definitions:
         description: 开仓解冻手续费(先建后平操作,需要记录)
         type: number
       operatetype:
-        description: 操作类型 - 1:正常下单 2:斩仓 3:转单 4:结算撤单 5:系统卖出(适用于先平后建的卖出) 6:行情源报价 7:(结算)到期强平 8:(结算)协议转让 9:系统对冲单 10:(结算)到期无效 11:交割协议转让 12:交割协议平仓 13:交割成交(所有权) 14:管理端强行平仓 15:管理端协议转让
+        description: 操作类型 - 1:正常下单 2:斩仓 3:转单 4:结算撤单 5:系统卖出(适用于先平后建的卖出) 6:行情源报价 7:(结算)到期强平
+          8:(结算)协议转让 9:系统对冲单 10:(结算)到期无效 11:交割协议转让 12:交割协议平仓 13:交割成交(所有权) 14:管理端强行平仓
+          15:管理端协议转让
         type: integer
       operatorid:
         description: 登录账号(LoginID)
@@ -476,10 +479,13 @@ definitions:
         description: 委托数量
         type: integer
       ordersrc:
-        description: 委托来源 -  1:客户端 2:管理端 3:风控服务 4:交割服务 5:交易服务 6:交易日结 7:商品强平 8:管理端商品退市强平 9:交易接口 10:交割服务商被动(受托竞价) 11:预埋触发
+        description: 委托来源 -  1:客户端 2:管理端 3:风控服务 4:交割服务 5:交易服务 6:交易日结 7:商品强平 8:管理端商品退市强平
+          9:交易接口 10:交割服务商被动(受托竞价) 11:预埋触发
         type: integer
       orderstatus:
-        description: 委托状态 - 1: 委托请求 2:待冻结 3:委托成功 4: 委托失败 5:配对成功 6: 已撤销 7:部分成交 8:已成交 9:部成部撤 10:成交失败 11:已拒绝 12:经过摘牌(先摘后挂专用-先摘后挂已摘过) 13:冻结成功(通道交易专用) 14:通道已撤 15:通道部成部撤 16:成交失败违约(荷兰式竞拍专用)
+        description: 委托状态 - 1: 委托请求 2:待冻结 3:委托成功 4: 委托失败 5:配对成功 6: 已撤销 7:部分成交 8:已成交
+          9:部成部撤 10:成交失败 11:已拒绝 12:经过摘牌(先摘后挂专用-先摘后挂已摘过) 13:冻结成功(通道交易专用) 14:通道已撤 15:通道部成部撤
+          16:成交失败违约(荷兰式竞拍专用)
         type: integer
       ordertime:
         description: 委托时间
@@ -1278,7 +1284,8 @@ definitions:
         description: 是否可转出 - 0:不可 1:可 [5:花生米转交易]
         type: integer
       converttype:
-        description: 转换类型 - 1:金点赞转交易 2:金点拍转交易 3:交易转金点赞(不设置) 4:交易转金点拍(不设置) 5:花生米转交易 6:交易转花生米(不设置)
+        description: 转换类型 - 1:金点赞转交易 2:金点拍转交易 3:交易转金点赞(不设置) 4:交易转金点拍(不设置) 5:花生米转交易
+          6:交易转花生米(不设置)
         type: integer
       createtime:
         description: 创建时间
@@ -1391,6 +1398,43 @@ definitions:
     required:
     - autoid
     type: object
+  models.TopGoods:
+    properties:
+      currency:
+        description: 货币
+        type: string
+      currencysign:
+        description: 货币符号
+        type: string
+      decimalplace:
+        description: 报价小数位
+        type: integer
+      goodscode:
+        description: 商品代码(内部)
+        type: string
+      goodsid:
+        description: 商品ID(自增ID SEQ_GOODS)
+        type: integer
+      goodsname:
+        description: 商品名称
+        type: string
+      hotindex:
+        description: 景点热度
+        type: integer
+      last:
+        description: 现价
+        type: number
+      picurls:
+        description: 介绍图片[多张用逗号分隔]
+        type: string
+      videourls:
+        description: 介绍视频[多张用逗号分隔]
+        type: string
+    required:
+    - goodscode
+    - goodsid
+    - goodsname
+    type: object
   models.Userinfo:
     properties:
       address:
@@ -1502,7 +1546,8 @@ definitions:
         description: 昵称:默认为名称脱敏(张**) 或 手机号脱敏(139****9999)
         type: string
       openmode:
-        description: 开户方式 -  1:管理端开户 2:网上开户注册(会员官网) 3:微信开户 4:网页交易端注册 5:安卓手机端注册 6:苹果手机端注册 7:PC交易端注册 8:微信快速开户 9:支付宝快速开户 10:手机号快速开户
+        description: 开户方式 -  1:管理端开户 2:网上开户注册(会员官网) 3:微信开户 4:网页交易端注册 5:安卓手机端注册 6:苹果手机端注册
+          7:PC交易端注册 8:微信快速开户 9:支付宝快速开户 10:手机号快速开户
         type: integer
       otherurl:
         description: 其它图片地址[使用分号分隔]
@@ -1699,7 +1744,8 @@ definitions:
         description: 成交时间
         type: string
       tradetype:
-        description: '成交类别 - 1:正常委托成交 2:定向做市成交(接单) 3:交割协议平仓成交 4:交割减仓成交 5:到期强平成交 6:风控斩仓成交 7:协议平仓(管理端)成交 8:仓单转持仓成交 9: 交割协议转让成交 10:受托竞价成交(接单) 11:协议转让成交 12:系统强行平仓 13:期权违约平仓'
+        description: '成交类别 - 1:正常委托成交 2:定向做市成交(接单) 3:交割协议平仓成交 4:交割减仓成交 5:到期强平成交 6:风控斩仓成交
+          7:协议平仓(管理端)成交 8:仓单转持仓成交 9: 交割协议转让成交 10:受托竞价成交(接单) 11:协议转让成交 12:系统强行平仓 13:期权违约平仓'
         type: integer
     required:
     - accountid
@@ -1740,7 +1786,8 @@ definitions:
         description: 客户端流水号
         type: string
       clienttype:
-        description: 客户端类型 - 0:保留为未填终端类型 1:PC管理端 2:PC交易端 3:手机客户端_安卓 4:网页客户端 5:微信客户端 6:手机客户端_苹果 7:网上开户客户端 8:无效终端编号 9:报价终端(中江)
+        description: 客户端类型 - 0:保留为未填终端类型 1:PC管理端 2:PC交易端 3:手机客户端_安卓 4:网页客户端 5:微信客户端
+          6:手机客户端_苹果 7:网上开户客户端 8:无效终端编号 9:报价终端(中江)
         type: integer
       closeexchagechargevalue:
         description: 平仓交易所手续费设置值
@@ -1839,7 +1886,9 @@ definitions:
         description: 开仓解冻手续费(先建后平操作,需要记录)
         type: number
       operatetype:
-        description: 操作类型 - 1:正常下单 2:斩仓 3:转单 4:结算撤单 5:系统卖出(适用于先平后建的卖出) 6:行情源报价 7:(结算)到期强平 8:(结算)协议转让 9:系统对冲单 10:(结算)到期无效 11:交割协议转让 12:交割协议平仓 13:交割成交(所有权) 14:管理端强行平仓 15:管理端协议转让
+        description: 操作类型 - 1:正常下单 2:斩仓 3:转单 4:结算撤单 5:系统卖出(适用于先平后建的卖出) 6:行情源报价 7:(结算)到期强平
+          8:(结算)协议转让 9:系统对冲单 10:(结算)到期无效 11:交割协议转让 12:交割协议平仓 13:交割成交(所有权) 14:管理端强行平仓
+          15:管理端协议转让
         type: integer
       operatorid:
         description: 登录账号(LoginID)
@@ -1857,10 +1906,13 @@ definitions:
         description: 委托数量
         type: integer
       ordersrc:
-        description: 委托来源 -  1:客户端 2:管理端 3:风控服务 4:交割服务 5:交易服务 6:交易日结 7:商品强平 8:管理端商品退市强平 9:交易接口 10:交割服务商被动(受托竞价) 11:预埋触发
+        description: 委托来源 -  1:客户端 2:管理端 3:风控服务 4:交割服务 5:交易服务 6:交易日结 7:商品强平 8:管理端商品退市强平
+          9:交易接口 10:交割服务商被动(受托竞价) 11:预埋触发
         type: integer
       orderstatus:
-        description: 委托状态 - 1: 委托请求 2:待冻结 3:委托成功 4: 委托失败 5:配对成功 6: 已撤销 7:部分成交 8:已成交 9:部成部撤 10:成交失败 11:已拒绝 12:经过摘牌(先摘后挂专用-先摘后挂已摘过) 13:冻结成功(通道交易专用) 14:通道已撤 15:通道部成部撤 16:成交失败违约(荷兰式竞拍专用)
+        description: 委托状态 - 1: 委托请求 2:待冻结 3:委托成功 4: 委托失败 5:配对成功 6: 已撤销 7:部分成交 8:已成交
+          9:部成部撤 10:成交失败 11:已拒绝 12:经过摘牌(先摘后挂专用-先摘后挂已摘过) 13:冻结成功(通道交易专用) 14:通道已撤 15:通道部成部撤
+          16:成交失败违约(荷兰式竞拍专用)
         type: integer
       ordertime:
         description: 委托时间
@@ -2082,7 +2134,8 @@ definitions:
         description: 成交时间
         type: string
       tradetype:
-        description: '成交类别 - 1:正常委托成交 2:定向做市成交(接单) 3:交割协议平仓成交 4:交割减仓成交 5:到期强平成交 6:风控斩仓成交 7:协议平仓(管理端)成交 8:仓单转持仓成交 9: 交割协议转让成交 10:受托竞价成交(接单) 11:协议转让成交 12:系统强行平仓 13:期权违约平仓'
+        description: '成交类别 - 1:正常委托成交 2:定向做市成交(接单) 3:交割协议平仓成交 4:交割减仓成交 5:到期强平成交 6:风控斩仓成交
+          7:协议平仓(管理端)成交 8:仓单转持仓成交 9: 交割协议转让成交 10:受托竞价成交(接单) 11:协议转让成交 12:系统强行平仓 13:期权违约平仓'
         type: integer
     required:
     - accountid
@@ -2116,7 +2169,8 @@ definitions:
         description: 撤单数量
         type: integer
       clienttype:
-        description: 客户端类型 - 0:保留为未填终端类型 1:PC管理端 2:PC交易端 3:手机客户端_安卓 4:网页客户端 5:微信客户端 6:手机客户端_苹果 7:网上开户客户端 8:无效终端编号 9:报价终端(中江)
+        description: 客户端类型 - 0:保留为未填终端类型 1:PC管理端 2:PC交易端 3:手机客户端_安卓 4:网页客户端 5:微信客户端
+          6:手机客户端_苹果 7:网上开户客户端 8:无效终端编号 9:报价终端(中江)
         type: integer
       closefreezecharge:
         description: 平仓冻结手续费(先建后平操作,需要记录)
@@ -2173,7 +2227,9 @@ definitions:
         description: 开仓解冻手续费(先建后平操作,需要记录)
         type: number
       operatetype:
-        description: 操作类型 - 1:正常下单 2:斩仓 3:转单 4:结算撤单 5:系统卖出(适用于先平后建的卖出) 6:行情源报价 7:(结算)到期强平 8:(结算)协议转让 9:系统对冲单 10:(结算)到期无效 11:交割协议转让 12:交割协议平仓 13:交割成交(所有权) 14:管理端强行平仓 15:管理端协议转让
+        description: 操作类型 - 1:正常下单 2:斩仓 3:转单 4:结算撤单 5:系统卖出(适用于先平后建的卖出) 6:行情源报价 7:(结算)到期强平
+          8:(结算)协议转让 9:系统对冲单 10:(结算)到期无效 11:交割协议转让 12:交割协议平仓 13:交割成交(所有权) 14:管理端强行平仓
+          15:管理端协议转让
         type: integer
       operatorid:
         description: 登录账号(LoginID)
@@ -2188,10 +2244,13 @@ definitions:
         description: 委托数量
         type: integer
       ordersrc:
-        description: 委托来源 -  1:客户端 2:管理端 3:风控服务 4:交割服务 5:交易服务 6:交易日结 7:商品强平 8:管理端商品退市强平 9:交易接口 10:交割服务商被动(受托竞价) 11:预埋触发
+        description: 委托来源 -  1:客户端 2:管理端 3:风控服务 4:交割服务 5:交易服务 6:交易日结 7:商品强平 8:管理端商品退市强平
+          9:交易接口 10:交割服务商被动(受托竞价) 11:预埋触发
         type: integer
       orderstatus:
-        description: 委托状态 - 1: 委托请求 2:待冻结 3:委托成功 4: 委托失败 5:配对成功 6: 已撤销 7:部分成交 8:已成交 9:部成部撤 10:成交失败 11:已拒绝 12:经过摘牌(先摘后挂专用-先摘后挂已摘过) 13:冻结成功(通道交易专用) 14:通道已撤 15:通道部成部撤 16:成交失败违约(荷兰式竞拍专用)
+        description: 委托状态 - 1: 委托请求 2:待冻结 3:委托成功 4: 委托失败 5:配对成功 6: 已撤销 7:部分成交 8:已成交
+          9:部成部撤 10:成交失败 11:已拒绝 12:经过摘牌(先摘后挂专用-先摘后挂已摘过) 13:冻结成功(通道交易专用) 14:通道已撤 15:通道部成部撤
+          16:成交失败违约(荷兰式竞拍专用)
         type: integer
       ordertime:
         description: 委托时间
@@ -2727,7 +2786,16 @@ definitions:
         description: 资金流水号:银行端流水号
         type: integer
       operatetype:
-        description: 资金操作类型 (AccountFundCmdOp)- 101:入金 102:入金手续费 103:出金 104:出金冻结 105:出金解冻 106:出金手续费 107:出金手续费冻结 108:出金手续费解冻 201:交易冻结 202:交易解冻 203:交易占用 204:交易解占用 205:交易手续费冻结 206:交易手续费解冻 207:交易手续费 208:交易货款 209:交易盈亏 301:交割冻结 302:交割解冻 303:交割手续费 304:交割手续费冻结 305:交割手续费解冻 306:交割货款 307:交割税款 401:结算盈亏 402:结算递延费 403:分润收入 404:延期分润 501:授信增加 502:授信减少 503:转积分 504:转入 505:转出 506:转出冻结 507:转出解冻  601:履约金额冻结 602:履约最大冻结 603:履约金额解冻 604:履约扣款 605:履约收款 606:履约违约手续费 607:履约违约收入 608:履约最大扣款 701:供应链金融冻结 702:供应链金融解冻 703:供应链金融最大冻结 704:供应链金融利息 705:供应链金融货款 706:供应链金融押金 707:供应链金融最大扣款 801:仓单贸易冻结 802:仓单贸易解冻 803:仓单贸易首付款 804:仓单贸易最大扣款 901:商城扣款冻结 902:商城扣款解冻 903:商城扣款 904:商城收款 1001:期权冻结 1002:期权解冻 1003:期权权力金 1004:期权手续费冻结 1005:期权手续费解冻 1006:期权手续费 1007:期权盈亏 1101:营销扣款 1102:营销收款
+        description: 资金操作类型 (AccountFundCmdOp)- 101:入金 102:入金手续费 103:出金 104:出金冻结 105:出金解冻
+          106:出金手续费 107:出金手续费冻结 108:出金手续费解冻 201:交易冻结 202:交易解冻 203:交易占用 204:交易解占用 205:交易手续费冻结
+          206:交易手续费解冻 207:交易手续费 208:交易货款 209:交易盈亏 301:交割冻结 302:交割解冻 303:交割手续费 304:交割手续费冻结
+          305:交割手续费解冻 306:交割货款 307:交割税款 401:结算盈亏 402:结算递延费 403:分润收入 404:延期分润 501:授信增加
+          502:授信减少 503:转积分 504:转入 505:转出 506:转出冻结 507:转出解冻  601:履约金额冻结 602:履约最大冻结
+          603:履约金额解冻 604:履约扣款 605:履约收款 606:履约违约手续费 607:履约违约收入 608:履约最大扣款 701:供应链金融冻结
+          702:供应链金融解冻 703:供应链金融最大冻结 704:供应链金融利息 705:供应链金融货款 706:供应链金融押金 707:供应链金融最大扣款
+          801:仓单贸易冻结 802:仓单贸易解冻 803:仓单贸易首付款 804:仓单贸易最大扣款 901:商城扣款冻结 902:商城扣款解冻 903:商城扣款
+          904:商城收款 1001:期权冻结 1002:期权解冻 1003:期权权力金 1004:期权手续费冻结 1005:期权手续费解冻 1006:期权手续费
+          1007:期权盈亏 1101:营销扣款 1102:营销收款
         type: integer
       relationorderid:
         description: 关联单号
@@ -2817,7 +2885,16 @@ definitions:
         description: 资金流水号:银行端流水号
         type: integer
       operatetype:
-        description: 资金操作类型 (AccountFundCmdOp)- 101:入金 102:入金手续费 103:出金 104:出金冻结 105:出金解冻 106:出金手续费 107:出金手续费冻结 108:出金手续费解冻 201:交易冻结 202:交易解冻 203:交易占用 204:交易解占用 205:交易手续费冻结 206:交易手续费解冻 207:交易手续费 208:交易货款 209:交易盈亏 301:交割冻结 302:交割解冻 303:交割手续费 304:交割手续费冻结 305:交割手续费解冻 306:交割货款 307:交割税款 401:结算盈亏 402:结算递延费 403:分润收入 404:延期分润 501:授信增加 502:授信减少 503:转积分 504:转入 505:转出 506:转出冻结 507:转出解冻  601:履约金额冻结 602:履约最大冻结 603:履约金额解冻 604:履约扣款 605:履约收款 606:履约违约手续费 607:履约违约收入 608:履约最大扣款 701:供应链金融冻结 702:供应链金融解冻 703:供应链金融最大冻结 704:供应链金融利息 705:供应链金融货款 706:供应链金融押金 707:供应链金融最大扣款 801:仓单贸易冻结 802:仓单贸易解冻 803:仓单贸易首付款 804:仓单贸易最大扣款 901:商城扣款冻结 902:商城扣款解冻 903:商城扣款 904:商城收款 1001:期权冻结 1002:期权解冻 1003:期权权力金 1004:期权手续费冻结 1005:期权手续费解冻 1006:期权手续费 1007:期权盈亏 1101:营销扣款 1102:营销收款
+        description: 资金操作类型 (AccountFundCmdOp)- 101:入金 102:入金手续费 103:出金 104:出金冻结 105:出金解冻
+          106:出金手续费 107:出金手续费冻结 108:出金手续费解冻 201:交易冻结 202:交易解冻 203:交易占用 204:交易解占用 205:交易手续费冻结
+          206:交易手续费解冻 207:交易手续费 208:交易货款 209:交易盈亏 301:交割冻结 302:交割解冻 303:交割手续费 304:交割手续费冻结
+          305:交割手续费解冻 306:交割货款 307:交割税款 401:结算盈亏 402:结算递延费 403:分润收入 404:延期分润 501:授信增加
+          502:授信减少 503:转积分 504:转入 505:转出 506:转出冻结 507:转出解冻  601:履约金额冻结 602:履约最大冻结
+          603:履约金额解冻 604:履约扣款 605:履约收款 606:履约违约手续费 607:履约违约收入 608:履约最大扣款 701:供应链金融冻结
+          702:供应链金融解冻 703:供应链金融最大冻结 704:供应链金融利息 705:供应链金融货款 706:供应链金融押金 707:供应链金融最大扣款
+          801:仓单贸易冻结 802:仓单贸易解冻 803:仓单贸易首付款 804:仓单贸易最大扣款 901:商城扣款冻结 902:商城扣款解冻 903:商城扣款
+          904:商城收款 1001:期权冻结 1002:期权解冻 1003:期权权力金 1004:期权手续费冻结 1005:期权手续费解冻 1006:期权手续费
+          1007:期权盈亏 1101:营销扣款 1102:营销收款
         type: integer
       relationorderid:
         description: 关联单号
@@ -2842,7 +2919,6 @@ definitions:
 info:
   contact: {}
   description: 新的查询服务,替代原通用查询服务。
-  license: {}
   termsOfService: http://muchinfo.cn
   title: MTP2.0 查询服务 API
   version: "1.0"
@@ -3284,6 +3360,47 @@ paths:
       summary: 查询现货合同表信息(指定策略ID、未结束的)
       tags:
       - 风险管理
+  /HSBY/QueryTopGoods:
+    get:
+      description: 说明:查询结果已按Hotindex(景点热度)从大到小排序
+      parameters:
+      - description: 页码
+        in: query
+        name: page
+        type: integer
+      - description: 每页条数
+        in: query
+        name: pagesize
+        type: integer
+      - description: 市场ID
+        in: query
+        name: marketID
+        required: true
+        type: integer
+      - description: 目的地(省)ID
+        in: query
+        name: DescProvinceID
+        type: integer
+      - description: 目的地(市)ID
+        in: query
+        name: DescCityID
+        type: integer
+      produces:
+      - application/json
+      responses:
+        "200":
+          description: OK
+          schema:
+            $ref: '#/definitions/models.TopGoods'
+        "500":
+          description: Internal Server Error
+          schema:
+            $ref: '#/definitions/app.Response'
+      security:
+      - ApiKeyAuth: []
+      summary: 查询热门商品列表
+      tags:
+      - 定制【海商报业】
   /History/QueryTSData:
     get:
       parameters:
@@ -3513,7 +3630,8 @@ paths:
   /SZDZ/QueryConvertConfig:
     get:
       parameters:
-      - description: 转换类型 - 1:金点赞转交易 2:金点拍转交易 3:交易转金点赞(不设置) 4:交易转金点拍(不设置) 5:花生米转交易 6:交易转花生米(不设置)
+      - description: 转换类型 - 1:金点赞转交易 2:金点拍转交易 3:交易转金点赞(不设置) 4:交易转金点拍(不设置) 5:花生米转交易
+          6:交易转花生米(不设置)
         in: query
         name: convertType
         type: integer

+ 1 - 0
go.mod

@@ -19,6 +19,7 @@ require (
 	github.com/go-openapi/spec v0.19.9 // indirect
 	github.com/go-openapi/swag v0.19.9 // indirect
 	github.com/go-redis/redis v6.15.7+incompatible
+	github.com/go-sql-driver/mysql v1.5.0
 	github.com/golang/protobuf v1.4.1
 	github.com/jehiah/go-strftime v0.0.0-20171201141054-1d33003b3869 // indirect
 	github.com/jonboulle/clockwork v0.1.0 // indirect

+ 18 - 10
main.go

@@ -11,11 +11,13 @@ import (
 	"mtp2_if/config"
 	"mtp2_if/db"
 	"mtp2_if/logger"
+	"mtp2_if/models"
 	"mtp2_if/rediscli"
 	"mtp2_if/routers"
 
 	"github.com/DeanThompson/ginpprof"
 	"github.com/gin-gonic/gin"
+	_ "github.com/go-sql-driver/mysql"
 	_ "github.com/mattn/go-oci8"
 )
 
@@ -53,16 +55,22 @@ func main() {
 	defer db.Close()
 
 	// 初始化MongoDB引擎
-	// err = db.InitMongoDB()
-	// if err != nil {
-	// 	logger.GetLogger().Errorf("init mongodb engine failed:", err.Error())
-	// 	return
-	// }
-	// defer db.CloseMongoDB()
-	// test
-	// startTime, _ := time.ParseInLocation("2006-01-02 15:04:05", "2000-09-06 09:43:00", time.Local)
-	// endTime, _ := time.ParseInLocation("2006-01-02 15:04:05", "2020-01-01 00:00:00", time.Local)
-	// models.GetHistoryCycleDatas(models.CycleTypeMinutes1, "DXSY01", startTime, endTime, 1440, false)
+	err = db.InitMongoDB()
+	if err != nil {
+		logger.GetLogger().Errorf("init mongodb engine failed:", err.Error())
+		return
+	}
+	defer db.CloseMongoDB()
+
+	// 初始化MySQL引擎
+	err = db.InitMySQLDbEngine()
+	if err != nil {
+		logger.GetLogger().Errorf("init mysql engine failed:", err.Error())
+		return
+	}
+	defer db.CloseMySQL()
+
+	models.GetHsbyTopGoods(16201, 0, 0)
 
 	// 初始化Redis客户端
 	err = rediscli.InitRedisCli()

+ 108 - 0
models/hsby.go

@@ -0,0 +1,108 @@
+package models
+
+import (
+	"mtp2_if/db"
+	"mtp2_if/utils"
+	"time"
+)
+
+// Hsbygoodsex 商品扩展表
+type Hsbygoodsex struct {
+	Goodsid        int32     `json:"goodsid"  xorm:"'GOODSID'" binding:"required"` // 商 品ID
+	Hotindex       int32     `json:"hotindex"  xorm:"'HOTINDEX'"`                  // 景点热度
+	Descprovinceid int64     `json:"descprovinceid"  xorm:"'DESCPROVINCEID'"`      // 目的地(省)
+	Desccityid     int64     `json:"desccityid"  xorm:"'DESCCITYID'"`              // 目的地(市)
+	Vendorid       int32     `json:"vendorid"  xorm:"'VENDORID'"`                  // 供应商ID
+	Goodsdesc      string    `json:"goodsdesc"  xorm:"'GOODSDESC'"`                // 商品详情
+	Createtime     time.Time `json:"createtime"  xorm:"'CREATETIME'"`              // 创建时间
+	Creatorid      int64     `json:"creatorid"  xorm:"'CREATORID'"`                // 创建人
+	Modifierid     int64     `json:"modifierid"  xorm:"'MODIFIERID'"`              // 修改人
+	Modifytime     time.Time `json:"modifytime"  xorm:"'MODIFYTIME'"`              // 修改时间
+	Memberratio    float64   `json:"memberratio"  xorm:"'MEMBERRATIO'"`            // 会员货款比例 [71]
+	Videourls      string    `json:"videourls"  xorm:"'VIDEOURLS'"`                // 介绍视频[多张用逗号分隔]
+	Picurls        string    `json:"picurls"  xorm:"'PICURLS'"`                    // 介绍图片[多张用逗号分隔]
+}
+
+// TableName is HSBY_GOODSEX
+func (Hsbygoodsex) TableName() string {
+	return "HSBY_GOODSEX"
+}
+
+// TopGoods 热门商品列表
+type TopGoods struct {
+	Goodsid      int64  `json:"goodsid"  xorm:"'GOODSID'" binding:"required"`     // 商品ID(自增ID SEQ_GOODS)
+	Goodscode    string `json:"goodscode"  xorm:"'GOODSCODE'" binding:"required"` // 商品代码(内部)
+	Goodsname    string `json:"goodsname"  xorm:"'GOODSNAME'" binding:"required"` // 商品名称
+	Decimalplace int64  `json:"decimalplace"  xorm:"'DECIMALPLACE'"`              // 报价小数位
+
+	Hotindex  int32  `json:"hotindex"  xorm:"'HOTINDEX'"`   // 景点热度
+	Videourls string `json:"videourls"  xorm:"'VIDEOURLS'"` // 介绍视频[多张用逗号分隔]
+	Picurls   string `json:"picurls"  xorm:"'PICURLS'"`     // 介绍图片[多张用逗号分隔]
+
+	Currency     string `json:"currency" xorm:"'CURRENCY'"`         // 货币
+	Currencysign string `json:"currencysign" xorm:"'CURRENCYSIGN'"` // 货币符号
+
+	Last float64 `json:"last" xorm:"-"` // 现价
+}
+
+// GetHsbyTopGoods 获取热门商品列表
+// 参数 marketID int 所属市场ID
+// 参数 descProvinceID int 目标省ID
+// 参数 descCityID int 目标城市ID
+// 返回 []TopGoods 热门商品列表
+// 返回 error error
+func GetHsbyTopGoods(marketID int, descProvinceID int, descCityID int) ([]TopGoods, error) {
+	engine := db.GetEngine()
+
+	topGoodses := make([]TopGoods, 0)
+	// 获取挂牌商品信息,以及扩展表信息
+	session := engine.Table("GOODS").
+		Select(`GOODS.*, 
+				HSBY_GOODSEX.HOTINDEX, HSBY_GOODSEX.VIDEOURLS, HSBY_GOODSEX.PICURLS, 
+				ENUMDICITEM.ENUMDICNAME CURRENCY, ENUMDICITEM.PARAM2 CURRENCYSIGN`).
+		Join("LEFT", "HSBY_GOODSEX", "HSBY_GOODSEX.GOODSID = GOODS.GOODSID").
+		Join("LEFT", "ENUMDICITEM", "ENUMDICITEM.ENUMITEMNAME = GOODS.CURRENCYID and ENUMDICITEM.ENUMDICCODE = 'currency'").
+		Where("GOODS.MARKETID = ?", marketID)
+	if descProvinceID > 0 {
+		session = session.And("HSBY_GOODSEX.DESCPROVINCEID = ?", descProvinceID)
+	}
+	if descCityID > 0 {
+		session = session.And("HSBY_GOODSEX.DESCCITYID = ?", descCityID)
+	}
+	if err := session.Find(&topGoodses); err != nil {
+		return nil, err
+	}
+	if len(topGoodses) == 0 {
+		// 无数据
+		return topGoodses, nil
+	}
+	// 获取商品ID列表
+	goodsCodes := ""
+	for _, v := range topGoodses {
+		if len(goodsCodes) == 0 {
+			goodsCodes = v.Goodscode
+		} else {
+			goodsCodes += "," + v.Goodscode
+		}
+	}
+
+	// 获取商品现价
+	quoteDays, err := GetQuoteDays(goodsCodes)
+	if err != nil {
+		return nil, err
+	}
+	for i, g := range topGoodses {
+		for _, q := range quoteDays {
+			if g.Goodscode == q.Goodscode {
+				if q.Last != 0 {
+					topGoods := &topGoodses[i]
+					topGoods.Last = utils.IntToFloat64(int(q.Last), int(g.Decimalplace))
+				}
+
+				continue
+			}
+		}
+	}
+
+	return topGoodses, nil
+}

+ 149 - 0
models/quote.go

@@ -2,6 +2,7 @@ package models
 
 import (
 	"errors"
+	"fmt"
 	"mtp2_if/db"
 	"time"
 
@@ -48,6 +49,139 @@ type CycleData struct {
 	SP    int           `bson:"SP"`    // 结算价,日线周期(包括)以上才有
 }
 
+// Quoteday 行情盘面
+type Quoteday struct {
+	Id                   int64   `xorm:"pk autoincr BIGINT(20)"`
+	Exchangedate         int64   `xorm:"not null BIGINT(20)"`
+	Goodscode            string  `xorm:"not null unique CHAR(10)"`
+	Exchangecode         int     `xorm:"INT(11)"`
+	Preclose             int64   `xorm:"default 0 BIGINT(20)"`
+	Opentime             int64   `xorm:"BIGINT(20)"`
+	Opened               int64   `xorm:"not null default 0 BIGINT(20)"`
+	Highest              int64   `xorm:"not null default 0 BIGINT(20)"`
+	Lowest               int64   `xorm:"not null default 0 BIGINT(20)"`
+	Lasttime             string  `xorm:"VARCHAR(20)"`
+	Utclasttime          int64   `xorm:"not null BIGINT(20)"`
+	Last                 int64   `xorm:"not null BIGINT(20)"`
+	Lastvolume           int64   `xorm:"default 0 BIGINT(20)"`
+	Lastturnover         int64   `xorm:"default 0 BIGINT(20)"`
+	Totalbidvolume       int64   `xorm:"default 0 BIGINT(20)"`
+	Totalaskvolume       int64   `xorm:"default 0 BIGINT(20)"`
+	Totalvolume          int64   `xorm:"default 0 BIGINT(20)"`
+	Totalturnover        int64   `xorm:"default 0 BIGINT(20)"`
+	Bid                  int64   `xorm:"default 0 BIGINT(20)"`
+	Bid2                 int64   `xorm:"default 0 BIGINT(20)"`
+	Bid3                 int64   `xorm:"default 0 BIGINT(20)"`
+	Bid4                 int64   `xorm:"default 0 BIGINT(20)"`
+	Bid5                 int64   `xorm:"default 0 BIGINT(20)"`
+	Bidvolume            int64   `xorm:"default 0 BIGINT(20)"`
+	Bidvolume2           int64   `xorm:"default 0 BIGINT(20)"`
+	Bidvolume3           int64   `xorm:"default 0 BIGINT(20)"`
+	Bidvolume4           int64   `xorm:"default 0 BIGINT(20)"`
+	Bidvolume5           int64   `xorm:"default 0 BIGINT(20)"`
+	Ask                  int64   `xorm:"default 0 BIGINT(20)"`
+	Ask2                 int64   `xorm:"default 0 BIGINT(20)"`
+	Ask3                 int64   `xorm:"default 0 BIGINT(20)"`
+	Ask4                 int64   `xorm:"default 0 BIGINT(20)"`
+	Ask5                 int64   `xorm:"default 0 BIGINT(20)"`
+	Askvolume            int64   `xorm:"default 0 BIGINT(20)"`
+	Askvolume2           int64   `xorm:"default 0 BIGINT(20)"`
+	Askvolume3           int64   `xorm:"default 0 BIGINT(20)"`
+	Askvolume4           int64   `xorm:"default 0 BIGINT(20)"`
+	Askvolume5           int64   `xorm:"default 0 BIGINT(20)"`
+	Presettle            int64   `xorm:"default 0 BIGINT(20)"`
+	Settle               int64   `xorm:"default 0 BIGINT(20)"`
+	Preholdvolume        int64   `xorm:"default 0 BIGINT(20)"`
+	Holdvolume           int64   `xorm:"default 0 BIGINT(20)"`
+	Averageprice         int64   `xorm:"default 0 BIGINT(20)"`
+	Orderid              int64   `xorm:"default 0 BIGINT(20)"`
+	Limitup              int64   `xorm:"default 0 BIGINT(20)"`
+	Limitdown            int64   `xorm:"default 0 BIGINT(20)"`
+	Inventory            int64   `xorm:"default 0 BIGINT(20)"`
+	Holdincrement        int64   `xorm:"default 0 BIGINT(20)"`
+	Iscleared            int     `xorm:"INT(11)"`
+	Issettled            int     `xorm:"INT(11)"`
+	Hightime             string  `xorm:"VARCHAR(30)"`
+	Lowtime              string  `xorm:"VARCHAR(30)"`
+	Bidqueueinfo         string  `xorm:"VARCHAR(2000)"`
+	Askqueueinfo         string  `xorm:"VARCHAR(2000)"`
+	Bidorderid           int64   `xorm:"BIGINT(20)"`
+	Bidorderid2          int64   `xorm:"BIGINT(20)"`
+	Bidorderid3          int64   `xorm:"BIGINT(20)"`
+	Bidorderid4          int64   `xorm:"BIGINT(20)"`
+	Bidorderid5          int64   `xorm:"BIGINT(20)"`
+	Askorderid           int64   `xorm:"BIGINT(20)"`
+	Askorderid2          int64   `xorm:"BIGINT(20)"`
+	Askorderid3          int64   `xorm:"BIGINT(20)"`
+	Askorderid4          int64   `xorm:"BIGINT(20)"`
+	Askorderid5          int64   `xorm:"BIGINT(20)"`
+	Originalturnover     float64 `xorm:"default 0 DOUBLE"`
+	Lastlot              int64   `xorm:"BIGINT(20)"`
+	Totallot             int64   `xorm:"BIGINT(20)"`
+	Strikeprice          int64   `xorm:"BIGINT(20)"`
+	Cleartime            int64   `xorm:"BIGINT(20)"`
+	Calloptionpremiums   int64   `xorm:"default 0 BIGINT(20)"`
+	Calloptionpremiums2  int64   `xorm:"default 0 BIGINT(20)"`
+	Calloptionpremiums3  int64   `xorm:"default 0 BIGINT(20)"`
+	Calloptionpremiums4  int64   `xorm:"default 0 BIGINT(20)"`
+	Calloptionpremiums5  int64   `xorm:"default 0 BIGINT(20)"`
+	Putoptionpremiums    int64   `xorm:"default 0 BIGINT(20)"`
+	Putoptionpremiums2   int64   `xorm:"default 0 BIGINT(20)"`
+	Putoptionpremiums3   int64   `xorm:"default 0 BIGINT(20)"`
+	Putoptionpremiums4   int64   `xorm:"default 0 BIGINT(20)"`
+	Putoptionpremiums5   int64   `xorm:"default 0 BIGINT(20)"`
+	Nontotalvolume       int64   `xorm:"default 0 BIGINT(20)"`
+	Nontotalholdervolume int64   `xorm:"default 0 BIGINT(20)"`
+	Nontotalturnover     int64   `xorm:"default 0 BIGINT(20)"`
+	Nontotallot          int64   `xorm:"default 0 BIGINT(20)"`
+	Markprice            int64   `xorm:"default 0 BIGINT(20)"`
+	Fundsrate            int64   `xorm:"default 0 BIGINT(20)"`
+	Publictradetype      string  `xorm:"VARCHAR(2)"`
+	Iep                  int64   `xorm:"default 0 BIGINT(20)"`
+	Iev                  int64   `xorm:"default 0 BIGINT(20)"`
+	Grepmarketprice      int64   `xorm:"default 0 BIGINT(20)"`
+	Bid6                 int64   `xorm:"default 0 BIGINT(20)"`
+	Bid7                 int64   `xorm:"default 0 BIGINT(20)"`
+	Bid8                 int64   `xorm:"default 0 BIGINT(20)"`
+	Bid9                 int64   `xorm:"default 0 BIGINT(20)"`
+	Bid10                int64   `xorm:"default 0 BIGINT(20)"`
+	Bidvolume6           int64   `xorm:"default 0 BIGINT(20)"`
+	Bidvolume7           int64   `xorm:"default 0 BIGINT(20)"`
+	Bidvolume8           int64   `xorm:"default 0 BIGINT(20)"`
+	Bidvolume9           int64   `xorm:"default 0 BIGINT(20)"`
+	Bidvolume10          int64   `xorm:"default 0 BIGINT(20)"`
+	Ask6                 int64   `xorm:"default 0 BIGINT(20)"`
+	Ask7                 int64   `xorm:"default 0 BIGINT(20)"`
+	Ask8                 int64   `xorm:"default 0 BIGINT(20)"`
+	Ask9                 int64   `xorm:"default 0 BIGINT(20)"`
+	Ask10                int64   `xorm:"default 0 BIGINT(20)"`
+	Askvolume6           int64   `xorm:"default 0 BIGINT(20)"`
+	Askvolume7           int64   `xorm:"default 0 BIGINT(20)"`
+	Askvolume8           int64   `xorm:"default 0 BIGINT(20)"`
+	Askvolume9           int64   `xorm:"default 0 BIGINT(20)"`
+	Askvolume10          int64   `xorm:"default 0 BIGINT(20)"`
+	Bidordervolume       int64   `xorm:"default 0 BIGINT(20)"`
+	Bidordervolume2      int64   `xorm:"default 0 BIGINT(20)"`
+	Bidordervolume3      int64   `xorm:"default 0 BIGINT(20)"`
+	Bidordervolume4      int64   `xorm:"default 0 BIGINT(20)"`
+	Bidordervolume5      int64   `xorm:"default 0 BIGINT(20)"`
+	Bidordervolume6      int64   `xorm:"default 0 BIGINT(20)"`
+	Bidordervolume7      int64   `xorm:"default 0 BIGINT(20)"`
+	Bidordervolume8      int64   `xorm:"default 0 BIGINT(20)"`
+	Bidordervolume9      int64   `xorm:"default 0 BIGINT(20)"`
+	Bidordervolume10     int64   `xorm:"default 0 BIGINT(20)"`
+	Askordervolume       int64   `xorm:"default 0 BIGINT(20)"`
+	Askordervolume2      int64   `xorm:"default 0 BIGINT(20)"`
+	Askordervolume3      int64   `xorm:"default 0 BIGINT(20)"`
+	Askordervolume4      int64   `xorm:"default 0 BIGINT(20)"`
+	Askordervolume5      int64   `xorm:"default 0 BIGINT(20)"`
+	Askordervolume6      int64   `xorm:"default 0 BIGINT(20)"`
+	Askordervolume7      int64   `xorm:"default 0 BIGINT(20)"`
+	Askordervolume8      int64   `xorm:"default 0 BIGINT(20)"`
+	Askordervolume9      int64   `xorm:"default 0 BIGINT(20)"`
+	Askordervolume10     int64   `xorm:"default 0 BIGINT(20)"`
+}
+
 // GetHistoryCycleDatas 获取历史数据
 // 参数 cycleType CycleType 周期类型
 // 参数 goodsCode string 商品代码
@@ -92,3 +226,18 @@ func GetHistoryCycleDatas(cycleType CycleType, goodsCode string, startTime, endT
 
 	return cycleDatas, nil
 }
+
+// GetQuoteDays 获取目标商品的盘面数据
+// 参数 goodsCodes string 商品代码字串,以“,”分隔
+// 返回 []Quoteday 盘面数据
+// 返回 error error
+func GetQuoteDays(goodsCodes string) ([]Quoteday, error) {
+	engine := db.GetMySQLEngine()
+
+	datas := make([]Quoteday, 0)
+	if err := engine.Where(fmt.Sprintf("goodscode in ('%s')", goodsCodes)).Find(&datas); err != nil {
+		return nil, err
+	}
+
+	return datas, nil
+}

+ 8 - 0
routers/router.go

@@ -7,6 +7,7 @@ import (
 	"mtp2_if/controllers/cptrade"
 	"mtp2_if/controllers/delivery"
 	"mtp2_if/controllers/erms2"
+	"mtp2_if/controllers/hsby"
 	"mtp2_if/controllers/order"
 	"mtp2_if/controllers/szdz"
 	"mtp2_if/controllers/taaccount"
@@ -155,6 +156,13 @@ func InitRouter() *gin.Engine {
 		// 持仓汇总查询(尚志大宗)
 		szdzR.GET("/QuerySZDZTradePosition", szdz.QuerySZDZTradePosition)
 	}
+	// ************************ 定制【海商报业】 ************************
+	hsbyR := apiR.Group("HSBY")
+	hsbyR.Use(token.Auth())
+	{
+		// 查询热门商品列表
+		hsbyR.GET("/QueryTopGoods", hsby.QueryTopGoods)
+	}
 
 	return r
 }

+ 12 - 0
utils/mathUtils.go

@@ -2,6 +2,7 @@ package utils
 
 import (
 	"math"
+	"math/big"
 	"sort"
 	"strconv"
 )
@@ -26,3 +27,14 @@ func SortInIntSlice(haystack []int, needle int) bool {
 	index := sort.SearchInts(haystack, needle)
 	return index < len(haystack) && haystack[index] == needle
 }
+
+// IntToFloat64 IntToFloat64 高精度转
+func IntToFloat64(value int, decimal int) float64 {
+	numrator, _ := new(big.Float).SetPrec(uint(1024)).SetString(strconv.Itoa(value))
+
+	denominator := big.NewFloat(math.Pow10(decimal))
+	denominator1 := numrator.Quo(numrator, denominator)
+	rst, _ := denominator1.Float64()
+
+	return rst
+}