hsby.go 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618
  1. package models
  2. import (
  3. "fmt"
  4. "math"
  5. "mtp2_if/db"
  6. "mtp2_if/utils"
  7. "strconv"
  8. "time"
  9. )
  10. // Hsbygoodsex 商品扩展表
  11. type Hsbygoodsex struct {
  12. Goodsid int32 `json:"goodsid" xorm:"'GOODSID'" binding:"required"` // 商 品ID
  13. Hotindex int32 `json:"hotindex" xorm:"'HOTINDEX'"` // 景点热度
  14. Descprovinceid int64 `json:"descprovinceid" xorm:"'DESCPROVINCEID'"` // 目的地(省)
  15. Desccityid int64 `json:"desccityid" xorm:"'DESCCITYID'"` // 目的地(市)
  16. Vendorid int32 `json:"vendorid" xorm:"'VENDORID'"` // 供应商ID
  17. Goodsdesc string `json:"goodsdesc" xorm:"'GOODSDESC'"` // 商品详情
  18. Createtime time.Time `json:"createtime" xorm:"'CREATETIME'"` // 创建时间
  19. Creatorid int64 `json:"creatorid" xorm:"'CREATORID'"` // 创建人
  20. Modifierid int64 `json:"modifierid" xorm:"'MODIFIERID'"` // 修改人
  21. Modifytime time.Time `json:"modifytime" xorm:"'MODIFYTIME'"` // 修改时间
  22. Memberratio float64 `json:"memberratio" xorm:"'MEMBERRATIO'"` // 会员货款比例 [71]
  23. Videourls string `json:"videourls" xorm:"'VIDEOURLS'"` // 介绍视频[多张用逗号分隔]
  24. Picurls string `json:"picurls" xorm:"'PICURLS'"` // 介绍图片[多张用逗号分隔]
  25. }
  26. // TableName is HSBY_GOODSEX
  27. func (Hsbygoodsex) TableName() string {
  28. return "HSBY_GOODSEX"
  29. }
  30. // Hsbysupplierinfo 供应商表
  31. type Hsbysupplierinfo struct {
  32. Vendorid int32 `json:"vendorid" xorm:"'VENDORID'" binding:"required"` // 供应商ID(SEQ_HSBY_SUPPLIERINFO)
  33. Vendorname string `json:"vendorname" xorm:"'VENDORNAME'"` // 名称描述客服电话名称
  34. Vendordesc string `json:"vendordesc" xorm:"'VENDORDESC'"` // 描述
  35. Vendorphone string `json:"vendorphone" xorm:"'VENDORPHONE'"` // 客服电话
  36. Vendorattr string `json:"vendorattr" xorm:"'VENDORATTR'"` // 附件(多张,逗号分隔)
  37. Createtime time.Time `json:"createtime" xorm:"'CREATETIME'"` // 创建时间
  38. Creatorid int64 `json:"creatorid" xorm:"'CREATORID'"` // 创建人
  39. Modifierid int64 `json:"modifierid" xorm:"'MODIFIERID'"` // 修改人
  40. Modifytime time.Time `json:"modifytime" xorm:"'MODIFYTIME'"` // 修改时间
  41. }
  42. // TableName is HSBY_SUPPLIERINFO
  43. func (Hsbysupplierinfo) TableName() string {
  44. return "HSBY_SUPPLIERINFO"
  45. }
  46. // HsbyTopGoods 热卖商品(二级市场挂牌点选)
  47. type HsbyTopGoods struct {
  48. Goodsid int64 `json:"goodsid" xorm:"'GOODSID'" binding:"required"` // 商品ID(自增ID SEQ_GOODS)
  49. Goodscode string `json:"goodscode" xorm:"'GOODSCODE'" binding:"required"` // 商品代码(内部)
  50. Goodsname string `json:"goodsname" xorm:"'GOODSNAME'" binding:"required"` // 商品名称
  51. Decimalplace int64 `json:"decimalplace" xorm:"'DECIMALPLACE'"` // 报价小数位
  52. Marketid int64 `json:"marketid" xorm:"'MARKETID'" binding:"required"` // 所属市场ID
  53. Quoteminunit int64 `json:"quoteminunit" xorm:"'QUOTEMINUNIT'"` // 行情最小变动单位 [整数,报价小数位一起使用]
  54. Hotindex int32 `json:"hotindex" xorm:"'HOTINDEX'"` // 景点热度
  55. Videourls string `json:"videourls" xorm:"'VIDEOURLS'"` // 介绍视频[多张用逗号分隔]
  56. Picurls string `json:"picurls" xorm:"'PICURLS'"` // 介绍图片[多张用逗号分隔]
  57. Currency string `json:"currency" xorm:"'CURRENCY'"` // 货币
  58. Currencysign string `json:"currencysign" xorm:"'CURRENCYSIGN'"` // 货币符号
  59. Last float64 `json:"last" xorm:"-"` // 现价
  60. LotSize float64 `json:"lotsize" xorm:"-"` // 最小变动单位
  61. }
  62. // GetHsbyTopGoodses 获取热门商品列表
  63. // 参数 marketIDs string 所属市场ID列表, 格式 1,2,3
  64. // 参数 descProvinceID int 目标省ID
  65. // 参数 descCityID int 目标城市ID
  66. // 返回 []TopGoods 热门商品列表
  67. // 返回 error error
  68. func GetHsbyTopGoodses(marketIDs string, descProvinceID, descCityID int) ([]HsbyTopGoods, error) {
  69. // 热门商品为二级市场(挂牌点选)下的商品信息
  70. engine := db.GetEngine()
  71. topGoodses := make([]HsbyTopGoods, 0)
  72. // 获取挂牌商品信息,以及扩展表信息
  73. session := engine.Table("GOODS").
  74. Select(`GOODS.*,
  75. HSBY_GOODSEX.HOTINDEX, HSBY_GOODSEX.VIDEOURLS, HSBY_GOODSEX.PICURLS,
  76. ENUMDICITEM.ENUMDICNAME CURRENCY, ENUMDICITEM.PARAM2 CURRENCYSIGN`).
  77. Join("LEFT", "HSBY_GOODSEX", "HSBY_GOODSEX.GOODSID = GOODS.GOODSID").
  78. Join("LEFT", "ENUMDICITEM", "ENUMDICITEM.ENUMITEMNAME = GOODS.CURRENCYID and ENUMDICITEM.ENUMDICCODE = 'currency'").
  79. Where(fmt.Sprintf("GOODS.GOODSSTATUS = 3 and GOODS.MARKETID in (%s)", marketIDs)) // 二级市场只获取 3:上市 状态的商品
  80. if descProvinceID > 0 {
  81. session = session.And("HSBY_GOODSEX.DESCPROVINCEID = ?", descProvinceID)
  82. }
  83. if descCityID > 0 {
  84. session = session.And("HSBY_GOODSEX.DESCCITYID = ?", descCityID)
  85. }
  86. if err := session.Find(&topGoodses); err != nil {
  87. return nil, err
  88. }
  89. if len(topGoodses) == 0 {
  90. // 无数据
  91. return topGoodses, nil
  92. }
  93. // 获取商品ID列表
  94. goodsCodes := ""
  95. for _, v := range topGoodses {
  96. if len(goodsCodes) == 0 {
  97. goodsCodes = v.Goodscode
  98. } else {
  99. goodsCodes += "," + v.Goodscode
  100. }
  101. }
  102. // 获取商品现价
  103. quoteDays, err := GetQuoteDays(goodsCodes)
  104. if err != nil {
  105. return nil, err
  106. }
  107. for i, g := range topGoodses {
  108. topGoods := &topGoodses[i]
  109. // FIXME: - 这里应该使用 Duck Typing,后期再处理
  110. // 计算最小变动单位
  111. lotSize := float64(topGoods.Quoteminunit) * math.Pow(0.1, float64(topGoods.Decimalplace))
  112. topGoods.LotSize, _ = strconv.ParseFloat(utils.FormatFloat(lotSize, int(topGoods.Decimalplace)), 64)
  113. for _, q := range quoteDays {
  114. if g.Goodscode == q.Goodscode {
  115. if q.Last != 0 {
  116. topGoods.Last = utils.IntToFloat64(int(q.Last), int(g.Decimalplace))
  117. }
  118. continue
  119. }
  120. }
  121. }
  122. return topGoodses, nil
  123. }
  124. // HsbyListingGoodsDetail 二级市场(挂牌点选)商品信息详情
  125. type HsbyListingGoodsDetail struct {
  126. Goodsid int64 `json:"goodsid" xorm:"'GOODSID'" binding:"required"` // 商品ID(自增ID SEQ_GOODS)
  127. Goodscode string `json:"goodscode" xorm:"'GOODSCODE'" binding:"required"` // 商品代码(内部)
  128. Goodsname string `json:"goodsname" xorm:"'GOODSNAME'" binding:"required"` // 商品名称
  129. Decimalplace int64 `json:"decimalplace" xorm:"'DECIMALPLACE'"` // 报价小数位
  130. Marketid int64 `json:"marketid" xorm:"'MARKETID'" binding:"required"` // 所属市场ID
  131. Quoteminunit int64 `json:"quoteminunit" xorm:"'QUOTEMINUNIT'"` // 行情最小变动单位 [整数,报价小数位一起使用]
  132. Hotindex int32 `json:"hotindex" xorm:"'HOTINDEX'"` // 景点热度
  133. Videourls string `json:"videourls" xorm:"'VIDEOURLS'"` // 介绍视频[多张用逗号分隔]
  134. Picurls string `json:"picurls" xorm:"'PICURLS'"` // 介绍图片[多张用逗号分隔]
  135. Descprovinceid int64 `json:"descprovinceid" xorm:"'DESCPROVINCEID'"` // 目的地(省)ID
  136. Desccityid int64 `json:"desccityid" xorm:"'DESCCITYID'"` // 目的地(市)ID
  137. Goodsdesc string `json:"goodsdesc" xorm:"'GOODSDESC'"` // 商品详情
  138. Currency string `json:"currency" xorm:"'CURRENCY'"` // 货币
  139. Currencysign string `json:"currencysign" xorm:"'CURRENCYSIGN'"` // 货币符号
  140. Vendorname string `json:"vendorname" xorm:"'VENDORNAME'"` // 供应商名称
  141. Vendorphone string `json:"vendorphone" xorm:"'VENDORPHONE'"` // 供应商客服电话
  142. Vendorattr string `json:"vendorattr" xorm:"'VENDORATTR'"` // 供应商附件(多张,逗号分隔)
  143. Last float64 `json:"last" xorm:"-"` // 现价
  144. Limitup float64 `json:"limitup" xorm:"-"` // 涨停价
  145. Limitdown float64 `json:"limitdown" xorm:"-"` // 跌停价
  146. LotSize float64 `json:"lotsize" xorm:"-"` // 最小变动单位
  147. }
  148. // GetHsbyListingGoodsDetail 获取二级市场(挂牌点选)商品信息详情
  149. // 参数 goodsID int 目标商品ID
  150. // 返回 *HsbyListingGoodsDetail 二级市场(挂牌点选)商品信息详情,查询无结果返回nil
  151. // 返回 error error
  152. func GetHsbyListingGoodsDetail(goodsID int) (*HsbyListingGoodsDetail, error) {
  153. engine := db.GetEngine()
  154. details := make([]HsbyListingGoodsDetail, 0)
  155. // 获取挂牌商品信息,以及扩展表信息
  156. // FIXME: - 这里使用Get方法,会造成SQL语句的嵌套出错,后期再研究
  157. session := engine.Table("GOODS").
  158. Select(`GOODS.GOODSID, GOODS.GOODSCODE, GOODS.GOODSNAME, GOODS.DECIMALPLACE, GOODS.MARKETID, GOODS.QUOTEMINUNIT,
  159. HSBY_GOODSEX.HOTINDEX, HSBY_GOODSEX.VIDEOURLS, HSBY_GOODSEX.PICURLS, HSBY_GOODSEX.DESCPROVINCEID, HSBY_GOODSEX.Desccityid, HSBY_GOODSEX.Goodsdesc,
  160. ENUMDICITEM.ENUMDICNAME CURRENCY, ENUMDICITEM.PARAM2 CURRENCYSIGN,
  161. HSBY_SUPPLIERINFO.VENDORNAME, HSBY_SUPPLIERINFO.VENDORPHONE, HSBY_SUPPLIERINFO.VENDORATTR`).
  162. Join("LEFT", "HSBY_GOODSEX", "HSBY_GOODSEX.GOODSID = GOODS.GOODSID").
  163. Join("LEFT", "ENUMDICITEM", "ENUMDICITEM.ENUMITEMNAME = GOODS.CURRENCYID and ENUMDICITEM.ENUMDICCODE = 'currency'").
  164. Join("LEFT", "HSBY_SUPPLIERINFO", "HSBY_SUPPLIERINFO.VENDORID = HSBY_GOODSEX.VENDORID").
  165. Where("GOODS.GOODSID = ?", goodsID)
  166. if err := session.Find(&details); err != nil {
  167. return nil, err
  168. }
  169. // 无目标商品
  170. if len(details) == 0 {
  171. return nil, nil
  172. }
  173. hsbyListingGoodsDetail := details[0]
  174. // 获取商品现价和涨跌停价
  175. quoteDays, err := GetQuoteDays(hsbyListingGoodsDetail.Goodscode)
  176. if err != nil {
  177. return nil, err
  178. }
  179. if len(quoteDays) > 0 {
  180. if quoteDays[0].Last != 0 {
  181. hsbyListingGoodsDetail.Last = utils.IntToFloat64(int(quoteDays[0].Last), int(hsbyListingGoodsDetail.Decimalplace))
  182. }
  183. if quoteDays[0].Limitup != 0 {
  184. hsbyListingGoodsDetail.Limitup = utils.IntToFloat64(int(quoteDays[0].Limitup), int(hsbyListingGoodsDetail.Decimalplace))
  185. }
  186. if quoteDays[0].Limitdown != 0 {
  187. hsbyListingGoodsDetail.Limitdown = utils.IntToFloat64(int(quoteDays[0].Limitdown), int(hsbyListingGoodsDetail.Decimalplace))
  188. }
  189. }
  190. // FIXME: - 这里应该使用 Duck Typing,后期再处理
  191. // 计算最小变动单位
  192. lotSize := float64(hsbyListingGoodsDetail.Quoteminunit) * math.Pow(0.1, float64(hsbyListingGoodsDetail.Decimalplace))
  193. hsbyListingGoodsDetail.LotSize, _ = strconv.ParseFloat(utils.FormatFloat(lotSize, int(hsbyListingGoodsDetail.Decimalplace)), 64)
  194. return &hsbyListingGoodsDetail, nil
  195. }
  196. // HsbyGoodsOrderDetail 二级市场挂牌商品当前可摘委托单信息
  197. type HsbyGoodsOrderDetail struct {
  198. Orderid string `json:"orderid" xorm:"'ORDERID'" binding:"required"` // 委托单号(100+Unix秒时间戳(10位)+2位(MarketServiceID)+xxxx)
  199. Buyorsell int32 `json:"buyorsell" xorm:"'BUYORSELL'" binding:"required"` // 买卖 - 0:买 1:卖
  200. Ordertime time.Time `json:"ordertime" xorm:"'ORDERTIME'" binding:"required"` // 委托时间
  201. Orderprice float64 `json:"orderprice" xorm:"'ORDERPRICE'"` // 委托价格
  202. Enableqty int64 `json:"enableqty" xorm:"ENABLEQTY"` // 可用数量
  203. Customername string `json:"customername" xorm:"'CUSTOMERNAME'"` // 客户名称(企业名称),已脱敏
  204. Currencysign string `json:"currencysign" xorm:"-"` // 货币符号
  205. Goodunit string `json:"goodunit" xorm:"-"` // 报价单位
  206. }
  207. // GetHsbyGoodsOrderDetails 获取二级市场(挂牌点选)商品对应的挂牌委托单信息
  208. // 输入 goodsID int 商品ID
  209. // 输入 buyOrSell int 委托单方向,0:买 1:卖
  210. // 输入 price float64 参考价格。买方向委托单则价格大于等于(站在摘牌人的角度);卖方向委托单则价格小于等于
  211. // 输出 []HsbyGoodsOrderDetail 商品对应的挂牌委托单信息
  212. // 输出 error error
  213. func GetHsbyGoodsOrderDetails(goodsID, buyOrSell int, price float64) ([]HsbyGoodsOrderDetail, error) {
  214. engine := db.GetEngine()
  215. // 获取与目标商品相关的挂牌委托单信息(ListingSelectType = 1 or 3; OrderStatus =3 or 7)
  216. hsbyGoodsOrderDetails := make([]HsbyGoodsOrderDetail, 0)
  217. session := engine.Table("TRADE_ORDERDETAIL").
  218. Select(`to_char(TRADE_ORDERDETAIL.ORDERID) ORDERID, TRADE_ORDERDETAIL.BUYORSELL, TRADE_ORDERDETAIL.ORDERTIME, TRADE_ORDERDETAIL.ORDERPRICE, (TRADE_ORDERDETAIL.ORDERQTY - TRADE_ORDERDETAIL.TRADEQTY - TRADE_ORDERDETAIL.CANCELQTY) ENABLEQTY,
  219. substr(USERINFO.CUSTOMERNAME,0,1)||'****' as CUSTOMERNAME`).
  220. Join("LEFT", "TAACCOUNT", "TAACCOUNT.ACCOUNTID = TRADE_ORDERDETAIL.ACCOUNTID").
  221. Join("LEFT", "USERINFO", "USERINFO.USERID = TAACCOUNT.RELATEDUSERID").
  222. Where("(TRADE_ORDERDETAIL.LISTINGSELECTTYPE = 1 or TRADE_ORDERDETAIL.LISTINGSELECTTYPE = 3) and (TRADE_ORDERDETAIL.ORDERSTATUS = 3 or TRADE_ORDERDETAIL.ORDERSTATUS = 7)").
  223. And("TRADE_ORDERDETAIL.GOODSID = ?", goodsID).
  224. And("TRADE_ORDERDETAIL.BUYORSELL = ?", buyOrSell)
  225. if price > 0 {
  226. if buyOrSell == 0 {
  227. // 买方向委托单则价格大于等于(站在摘牌人的角度)
  228. session = session.And("TRADE_ORDERDETAIL.ORDERPRICE >= ?", price)
  229. } else {
  230. // 卖方向委托单则价格小于等于
  231. session = session.And("TRADE_ORDERDETAIL.ORDERPRICE <= ?", price)
  232. }
  233. }
  234. if err := session.Find(&hsbyGoodsOrderDetails); err != nil {
  235. return nil, err
  236. }
  237. // 获取商品货币符号和报价单位
  238. goods, err := GetGoods(goodsID)
  239. if err != nil {
  240. return nil, err
  241. }
  242. currencyEnums, err := GetEnumDicItem("currency", int(goods.Currencyid))
  243. if err != nil {
  244. return nil, err
  245. }
  246. currencysign := ""
  247. if len(currencyEnums) > 0 {
  248. currencysign = currencyEnums[0].Param2
  249. }
  250. goodsUnitEnums, err := GetEnumDicItem("goodsunit", int(goods.Goodunitid))
  251. if err != nil {
  252. return nil, err
  253. }
  254. goodsUnit := ""
  255. if len(goodsUnitEnums) > 0 {
  256. goodsUnit = goodsUnitEnums[0].Enumdicname
  257. }
  258. for i := range hsbyGoodsOrderDetails {
  259. orderDetail := &hsbyGoodsOrderDetails[i]
  260. // 设置货币符号和报价单位
  261. orderDetail.Currencysign = currencysign
  262. orderDetail.Goodunit = goodsUnit
  263. }
  264. return hsbyGoodsOrderDetails, nil
  265. }
  266. // HybsMyBuyOrderDetail 我的订单(一二级市场的买方向委托单)
  267. type HybsMyBuyOrderDetail struct {
  268. Orderid string `json:"orderid" xorm:"'ORDERID'" binding:"required"` // 委托单号(100+Unix秒时间戳(10位)+2位(MarketServiceID)+xxxx)
  269. Marketid int32 `json:"marketid" xorm:"'MARKETID'" binding:"required"` // 市场ID
  270. Goodsid int32 `json:"goodsid" xorm:"'GOODSID'" binding:"required"` // 商品ID
  271. Accountid int64 `json:"accountid" xorm:"'ACCOUNTID'" binding:"required"` // 账户ID[报价币种]
  272. Buyorsell int32 `json:"buyorsell" xorm:"'BUYORSELL'" binding:"required"` // 买卖 - 0:买 1:卖
  273. Orderprice float64 `json:"orderprice" xorm:"'ORDERPRICE'"` // 委托价格
  274. Orderqty int64 `json:"orderqty" xorm:"'ORDERQTY'" binding:"required"` // 委托数量
  275. Tradeqty int64 `json:"tradeqty" xorm:"'TRADEQTY'"` // 成交数量
  276. Cancelqty int64 `json:"cancelqty" xorm:"'CANCELQTY'"` // 撤单数量
  277. Ordertime time.Time `json:"ordertime" xorm:"'ORDERTIME'" binding:"required"` // 委托时间
  278. Listingselecttype int32 `json:"listingselecttype" xorm:"'LISTINGSELECTTYPE'"` // 挂牌点选类型 - 1:挂牌 2:摘牌 3:先摘后挂
  279. Orderstatus int32 `json:"orderstatus" xorm:"'ORDERSTATUS'"` // 委托状态 - 1: 委托请求 2:待冻结 3:委托成功 4: 委托失败 5:配对成功 6: 已撤销 7:部分成交 8:已成交 9:部成部撤 10:成交失败 11:已拒绝 12:经过摘牌(先摘后挂专用-先摘后挂已摘过) 13:冻结成功(通道交易专用) 14:通道已撤 15:通道部成部撤 16:成交失败违约(荷兰式竞拍专用)
  280. Goodscode string `json:"goodscode" xorm:"'GOODSCODE'" binding:"required"` // 商品代码(内部)
  281. Goodsname string `json:"goodsname" xorm:"'GOODSNAME'" binding:"required"` // 商品名称
  282. Decimalplace int64 `json:"decimalplace" xorm:"'DECIMALPLACE'"` // 报价小数位
  283. Agreeunit float64 `json:"agreeunit" xorm:"'AGREEUNIT'"` // 合约单位
  284. Picurls string `json:"picurls" xorm:"'PICURLS'"` // 介绍图片[多张用逗号分隔]
  285. Trademode uint32 `json:"trademode" xorm:"'TRADEMODE'" binding:"required"` // 交易模式 - 10:做市 13:竞价 15:通道交易 16:挂牌点选 17:仓单贸易 18:期权 19:竞拍-降价式 20:竞拍-竞价式 21:竞拍-大宗式 22:受托竞价
  286. Currencysign string `json:"currencysign" xorm:"'CURRENCYSIGN'"` // 货币符号
  287. Vendorname string `json:"vendorname" xorm:"'VENDORNAME'"` // 供应商名称
  288. MyBuyStatus int `json:"mybuystatus" xorm:"-"` // "我的订单"显示状态- 1:抢购中 2:求购中 3:已完成 4:已撤消 5:委托失败
  289. Orderamount float64 `json:"" xorm:"-"` // 委托金额
  290. }
  291. // GetHsbyBuyMyOrderDetails 获取“我的订单”数据(包括一二级市场)
  292. // 输入 accountIDs string 资金账户列表
  293. // 输入 myBuyStatus int "我的订单"状态, 1:抢购中 2:求购中 3:已完成
  294. // 输出 []HybsMyBuyOrderDetail “我的订单”数据
  295. // 输出 error error
  296. func GetHsbyBuyMyOrderDetails(accountIDs string, myBuyStatus int) ([]HybsMyBuyOrderDetail, error) {
  297. // 获取市场信息
  298. markets, err := GetMarkets()
  299. if err != nil {
  300. return nil, err
  301. }
  302. engine := db.GetEngine()
  303. // 委托状态
  304. orderStatus := "0" // 单据状态,为0的时候查询全部
  305. marketID := 0 // 我的订单包括一二级市场的单据,目前暂时由服务直接报相关类型的第一个市场
  306. switch myBuyStatus {
  307. case 1: // 抢购中 (一级市场)
  308. // 获取市场ID
  309. for _, v := range markets {
  310. if v.Trademode == 71 { // 预售挂牌
  311. marketID = int(v.Marketid)
  312. break
  313. }
  314. }
  315. orderStatus = "3,7"
  316. case 2: // 求购中(二级市场)
  317. // 获取市场ID
  318. for _, v := range markets {
  319. if v.Trademode == 16 { // 挂牌点选
  320. marketID = int(v.Marketid)
  321. break
  322. }
  323. }
  324. orderStatus = "3,7"
  325. case 3: // 已完成
  326. orderStatus = "8,9"
  327. }
  328. hybsMyBuyOrderDetails := make([]HybsMyBuyOrderDetail, 0)
  329. session := engine.Table("TRADE_ORDERDETAIL").
  330. Select(`to_char(TRADE_ORDERDETAIL.ORDERID) ORDERID, TRADE_ORDERDETAIL.*,
  331. GOODS.GOODSCODE, GOODS.GOODSNAME, GOODS.DECIMALPLACE, GOODS.AGREEUNIT,
  332. HSBY_GOODSEX.PICURLS,
  333. MARKET.TRADEMODE,
  334. ENUMDICITEM.PARAM2 CURRENCYSIGN,
  335. HSBY_SUPPLIERINFO.VENDORNAME`).
  336. Join("LEFT", "GOODS", "GOODS.GOODSID = TRADE_ORDERDETAIL.GOODSID").
  337. Join("LEFT", "HSBY_GOODSEX", "HSBY_GOODSEX.GOODSID = GOODS.GOODSID").
  338. Join("LEFT", "ENUMDICITEM", "GOODS.CURRENCYID = ENUMDICITEM.ENUMITEMNAME and ENUMDICITEM.ENUMDICCODE = 'currency'").
  339. Join("LEFT", "MARKET", "MARKET.MARKETID = TRADE_ORDERDETAIL.MARKETID").
  340. Join("LEFT", "HSBY_SUPPLIERINFO", "HSBY_SUPPLIERINFO.VENDORID = HSBY_GOODSEX.VENDORID").
  341. Where(fmt.Sprintf("TRADE_ORDERDETAIL.ACCOUNTID in (%s)", accountIDs))
  342. // 是否过滤市场(抢购中、求购中)
  343. if marketID > 0 {
  344. session = session.And("TRADE_ORDERDETAIL.MARKETID = ?", marketID)
  345. }
  346. // 是否过滤状态(抢购中、求购中、已完成)
  347. if orderStatus != "0" {
  348. session = session.And(fmt.Sprintf("TRADE_ORDERDETAIL.ORDERSTATUS in (%s)", orderStatus))
  349. }
  350. if err := session.Find(&hybsMyBuyOrderDetails); err != nil {
  351. return nil, err
  352. }
  353. // 设置“我的订单”显示状态
  354. for i := range hybsMyBuyOrderDetails {
  355. detail := &hybsMyBuyOrderDetails[i]
  356. // 委托金额 = 委托价格 * 委托数量 * 合约单位
  357. detail.Orderamount = detail.Orderprice * float64(detail.Orderqty) * float64(detail.Agreeunit)
  358. if detail.Trademode == 71 && (detail.Orderstatus == 3 || detail.Orderstatus == 7) {
  359. // 抢购中
  360. detail.MyBuyStatus = 1
  361. } else if detail.Trademode == 16 && (detail.Orderstatus == 3 || detail.Orderstatus == 7) {
  362. // 求购中
  363. detail.MyBuyStatus = 2
  364. } else if detail.Orderstatus == 8 || detail.Orderstatus == 9 {
  365. // 已完成
  366. detail.MyBuyStatus = 3
  367. } else if detail.Orderstatus == 6 {
  368. // 已撤销
  369. detail.MyBuyStatus = 4
  370. } else if detail.Orderstatus == 4 {
  371. // 委托失败
  372. detail.MyBuyStatus = 5
  373. }
  374. }
  375. return hybsMyBuyOrderDetails, nil
  376. }
  377. // HsbyMyGoods 我的商品(买方向持仓)
  378. type HsbyMyGoods struct {
  379. Accountid int64 `json:"accountid" xorm:"'ACCOUNTID'" binding:"required"` // 账号Id
  380. Goodsid int32 `json:"goodsid" xorm:"'GOODSID'" binding:"required"` // 商品Id
  381. Buycurpositionqty int64 `json:"buycurpositionqty" xorm:"'BUYCURPOSITIONQTY'"` // 买当前持仓总数量
  382. Buycurholderamount float64 `json:"buycurholderamount" xorm:"'BUYCURHOLDERAMOUNT'"` // 买当前持仓总金额[商品币种]
  383. Goodscode string `json:"goodscode" xorm:"'GOODSCODE'" binding:"required"` // 商品代码(内部)
  384. Goodsname string `json:"goodsname" xorm:"'GOODSNAME'" binding:"required"` // 商品名称
  385. Decimalplace int64 `json:"decimalplace" xorm:"'DECIMALPLACE'"` // 报价小数位
  386. Agreeunit float64 `json:"agreeunit" xorm:"'AGREEUNIT'"` // 合约单位
  387. Picurls string `json:"picurls" xorm:"'PICURLS'"` // 介绍图片[多张用逗号分隔]
  388. Currencysign string `json:"currencysign" xorm:"'CURRENCYSIGN'"` // 货币符号
  389. Buyaverageprice float64 `json:"buyaverageprice" xorm:"-"` // 持仓均价
  390. }
  391. // GetHsbyMyGoods 获取“我的商品”信息
  392. // 输入 accountIDs string 资金账户列表,格式 1,2,3
  393. // 输出 []HsbyMyGoods “我的商品”信息
  394. // 输入 error error
  395. func GetHsbyMyGoods(accountIDs string) ([]HsbyMyGoods, error) {
  396. engine := db.GetEngine()
  397. hsbyMyGoodses := make([]HsbyMyGoods, 0)
  398. // 此定制版本,只查询出当前手数(期末)大于0的数据 (TRADEPOSITION.BUYCURPOSITIONQTY > 0)
  399. if err := engine.Table("TRADEPOSITION").
  400. Select(`TRADEPOSITION.*,
  401. GOODS.GOODSCODE, GOODS.GOODSNAME, GOODS.DECIMALPLACE, GOODS.AGREEUNIT,
  402. HSBY_GOODSEX.PICURLS,
  403. ENUMDICITEM.PARAM2 CURRENCYSIGN`).
  404. Join("LEFT", "GOODS", "GOODS.GOODSID = TRADEPOSITION.GOODSID").
  405. Join("INNER", "HSBY_GOODSEX", "HSBY_GOODSEX.GOODSID = GOODS.GOODSID").
  406. Join("LEFT", "ENUMDICITEM", "GOODS.CURRENCYID = ENUMDICITEM.ENUMITEMNAME and ENUMDICITEM.ENUMDICCODE = 'currency'").
  407. Where(fmt.Sprintf("TRADEPOSITION.BUYCURPOSITIONQTY > 0 and TRADEPOSITION.ACCOUNTID in (%s)", accountIDs)).Find(&hsbyMyGoodses); err != nil {
  408. return nil, err
  409. }
  410. // 计算持仓均价
  411. for i := range hsbyMyGoodses {
  412. myGoods := &hsbyMyGoodses[i]
  413. averagePrice := myGoods.Buycurholderamount / float64(myGoods.Buycurpositionqty) / myGoods.Agreeunit
  414. myGoods.Buyaverageprice, _ = strconv.ParseFloat(utils.FormatFloat(averagePrice, int(myGoods.Decimalplace)), 64)
  415. }
  416. return hsbyMyGoodses, nil
  417. }
  418. // HsbyPreGoods 新品上市商品(一级市场产能预售)
  419. type HsbyPreGoods struct {
  420. Goodsid int64 `json:"goodsid" xorm:"'GOODSID'" binding:"required"` // 商品ID(自增ID SEQ_GOODS)
  421. Goodscode string `json:"goodscode" xorm:"'GOODSCODE'" binding:"required"` // 商品代码(内部)
  422. Goodsname string `json:"goodsname" xorm:"'GOODSNAME'" binding:"required"` // 商品名称
  423. Decimalplace int64 `json:"decimalplace" xorm:"'DECIMALPLACE'"` // 报价小数位
  424. Marketid int64 `json:"marketid" xorm:"'MARKETID'" binding:"required"` // 所属市场ID
  425. Goodsstatus int64 `json:"goodsstatus" xorm:"'GOODSSTATUS'"` // 商品状态- 2:未上市 3:上市
  426. Quoteminunit int64 `json:"quoteminunit" xorm:"'QUOTEMINUNIT'"` // 行情最小变动单位 [整数,报价小数位一起使用]
  427. Relatedgoodsid int64 `json:"relatedgoodsid" xorm:"'RELATEDGOODSID'"` // 关联交易合约ID
  428. Presaleqty int64 `json:"presaleqty" xorm:"'PRESALEQTY'"` // 预售数量
  429. Starttime time.Time `json:"starttime" xorm:"'STARTTIME'"` // 预售开始时间
  430. Endtime time.Time `json:"endtime" xorm:"'ENDTIME'"` // 预售结束时间
  431. Refprice float64 `json:"refprice" xorm:"'REFPRICE'"` // 参考价格[一口价]
  432. Currency string `json:"currency" xorm:"'CURRENCY'"` // 货币
  433. Currencysign string `json:"currencysign" xorm:"'CURRENCYSIGN'"` // 货币符号
  434. Videourls string `json:"videourls" xorm:"'VIDEOURLS'"` // 介绍视频[多张用逗号分隔]
  435. Picurls string `json:"picurls" xorm:"'PICURLS'"` // 介绍图片[多张用逗号分隔]
  436. LotSize float64 `json:"lotsize" xorm:"-"` // 最小变动单位
  437. }
  438. // GetHsbyPreGoodses 获取“新品上市”商品列表(一级市场产能预售)
  439. // 输入 marketIDs string 市场ID列表,格式 1,2,3
  440. // 输入 descProvinceID int 省ID
  441. // 输入 descCityID int 市ID
  442. // 输出 []HsbyPreGoods “新品上市”商品列表
  443. // 输出 error error
  444. func GetHsbyPreGoodses(marketIDs string, descProvinceID, descCityID int) ([]HsbyPreGoods, error) {
  445. engine := db.GetEngine()
  446. // 注意:一级产能预售市场使用的商品实际上是和二级市场有关系的,所以要使用 CPTRADE_PRESALEGOODSEX.RELATEDGOODSID 进行关联
  447. preGoodses := make([]HsbyPreGoods, 0)
  448. session := engine.Table("GOODS").
  449. Select(`GOODS.*,
  450. CPTRADE_PRESALEGOODSEX.RELATEDGOODSID, CPTRADE_PRESALEGOODSEX.PRESALEQTY,
  451. CPTRADE_PRESALEGOODSEX.STARTTIME, CPTRADE_PRESALEGOODSEX.ENDTIME, CPTRADE_PRESALEGOODSEX.REFPRICE,
  452. ENUMDICITEM.ENUMDICNAME CURRENCY, ENUMDICITEM.PARAM2 CURRENCYSIGN,
  453. HSBY_GOODSEX.VIDEOURLS, HSBY_GOODSEX.PICURLS`).
  454. Join("INNER", "CPTRADE_PRESALEGOODSEX", "CPTRADE_PRESALEGOODSEX.GOODSID = GOODS.GOODSID").
  455. Join("LEFT", "ENUMDICITEM", "ENUMDICITEM.ENUMITEMNAME = GOODS.CURRENCYID and ENUMDICITEM.ENUMDICCODE = 'currency'").
  456. Join("LEFT", "HSBY_GOODSEX", "HSBY_GOODSEX.GOODSID = CPTRADE_PRESALEGOODSEX.RELATEDGOODSID").
  457. Where(fmt.Sprintf("GOODS.GOODSSTATUS in (2,3) and GOODS.MARKETID in (%s)", marketIDs)) // 一级市场获取 2:未上市 3:上市 状态的商品
  458. if descProvinceID > 0 {
  459. session = session.And("HSBY_GOODSEX.DESCPROVINCEID = ?", descProvinceID)
  460. }
  461. if descCityID > 0 {
  462. session = session.And("HSBY_GOODSEX.DESCCITYID = ?", descCityID)
  463. }
  464. if err := session.Find(&preGoodses); err != nil {
  465. return nil, err
  466. }
  467. for i := range preGoodses {
  468. preGoods := &preGoodses[i]
  469. // FIXME: - 这里应该使用 Duck Typing,后期再处理
  470. // 计算最小变动单位
  471. lotSize := float64(preGoods.Quoteminunit) * math.Pow(0.1, float64(preGoods.Decimalplace))
  472. preGoods.LotSize, _ = strconv.ParseFloat(utils.FormatFloat(lotSize, int(preGoods.Decimalplace)), 64)
  473. }
  474. return preGoodses, nil
  475. }
  476. // HsbyPreGoodsDetail 一级市场(产能预售)商品信息详情
  477. type HsbyPreGoodsDetail struct {
  478. Goodsid int64 `json:"goodsid" xorm:"'GOODSID'" binding:"required"` // 商品ID(自增ID SEQ_GOODS)
  479. Goodscode string `json:"goodscode" xorm:"'GOODSCODE'" binding:"required"` // 商品代码(内部)
  480. Goodsname string `json:"goodsname" xorm:"'GOODSNAME'" binding:"required"` // 商品名称
  481. Decimalplace int64 `json:"decimalplace" xorm:"'DECIMALPLACE'"` // 报价小数位
  482. Marketid int64 `json:"marketid" xorm:"'MARKETID'" binding:"required"` // 所属市场ID
  483. Goodsstatus int64 `json:"goodsstatus" xorm:"'GOODSSTATUS'"` // 商品状态- 2:未上市 3:上市
  484. Quoteminunit int64 `json:"quoteminunit" xorm:"'QUOTEMINUNIT'"` // 行情最小变动单位 [整数,报价小数位一起使用]
  485. Relatedgoodsid int64 `json:"relatedgoodsid" xorm:"'RELATEDGOODSID'"` // 关联交易合约ID
  486. Presaleqty int64 `json:"presaleqty" xorm:"'PRESALEQTY'"` // 预售数量
  487. Starttime time.Time `json:"starttime" xorm:"'STARTTIME'"` // 预售开始时间
  488. Endtime time.Time `json:"endtime" xorm:"'ENDTIME'"` // 预售结束时间
  489. Refprice float64 `json:"refprice" xorm:"'REFPRICE'"` // 参考价格[一口价]
  490. Videourls string `json:"videourls" xorm:"'VIDEOURLS'"` // 介绍视频[多张用逗号分隔]
  491. Picurls string `json:"picurls" xorm:"'PICURLS'"` // 介绍图片[多张用逗号分隔]
  492. Descprovinceid int64 `json:"descprovinceid" xorm:"'DESCPROVINCEID'"` // 目的地(省)ID
  493. Desccityid int64 `json:"desccityid" xorm:"'DESCCITYID'"` // 目的地(市)ID
  494. Goodsdesc string `json:"goodsdesc" xorm:"'GOODSDESC'"` // 商品详情
  495. Currency string `json:"currency" xorm:"'CURRENCY'"` // 货币
  496. Currencysign string `json:"currencysign" xorm:"'CURRENCYSIGN'"` // 货币符号
  497. Goodunit string `json:"goodunit" xorm:"GOODUNIT"` // 报价单位
  498. Vendorname string `json:"vendorname" xorm:"'VENDORNAME'"` // 供应商名称
  499. Vendorphone string `json:"vendorphone" xorm:"'VENDORPHONE'"` // 供应商客服电话
  500. Vendorattr string `json:"vendorattr" xorm:"'VENDORATTR'"` // 供应商附件(多张,逗号分隔)
  501. LotSize float64 `json:"lotsize" xorm:"-"` // 最小变动单位
  502. }
  503. // GetHsbyPreGoodsDetail 获取一级市场(产能预售)商品信息详情
  504. // 参数 goodsID int 目标商品ID
  505. // 返回 *HsbyListingGoodsDetail 二级市场(挂牌点选)商品信息详情,查询无结果返回nil
  506. // 返回 error error
  507. func GetHsbyPreGoodsDetail(goodsID int) (*HsbyPreGoodsDetail, error) {
  508. engine := db.GetEngine()
  509. details := make([]HsbyPreGoodsDetail, 0)
  510. // 获取挂牌商品信息,以及扩展表信息
  511. // FIXME: - 这里使用Get方法,会造成SQL语句的嵌套出错,后期再研究
  512. session := engine.Table("GOODS").
  513. Select(`GOODS.*,
  514. CPTRADE_PRESALEGOODSEX.RELATEDGOODSID, CPTRADE_PRESALEGOODSEX.PRESALEQTY,
  515. CPTRADE_PRESALEGOODSEX.STARTTIME, CPTRADE_PRESALEGOODSEX.ENDTIME, CPTRADE_PRESALEGOODSEX.REFPRICE,
  516. HSBY_GOODSEX.VIDEOURLS, HSBY_GOODSEX.PICURLS, HSBY_GOODSEX.DESCPROVINCEID, HSBY_GOODSEX.Desccityid, HSBY_GOODSEX.Goodsdesc,
  517. ENUMDICITEM.ENUMDICNAME CURRENCY, ENUMDICITEM.PARAM2 CURRENCYSIGN,
  518. E1.ENUMDICNAME GOODUNIT,
  519. HSBY_SUPPLIERINFO.VENDORNAME, HSBY_SUPPLIERINFO.VENDORPHONE, HSBY_SUPPLIERINFO.VENDORATTR`).
  520. Join("INNER", "CPTRADE_PRESALEGOODSEX", "CPTRADE_PRESALEGOODSEX.GOODSID = GOODS.GOODSID").
  521. Join("LEFT", "HSBY_GOODSEX", "HSBY_GOODSEX.GOODSID = CPTRADE_PRESALEGOODSEX.RELATEDGOODSID").
  522. Join("LEFT", "ENUMDICITEM", "ENUMDICITEM.ENUMITEMNAME = GOODS.CURRENCYID and ENUMDICITEM.ENUMDICCODE = 'currency'").
  523. Join("LEFT", "ENUMDICITEM E1", "E1.ENUMITEMNAME = GOODS.GOODUNITID and E1.ENUMDICCODE = 'goodsunit'").
  524. Join("LEFT", "HSBY_SUPPLIERINFO", "HSBY_SUPPLIERINFO.VENDORID = HSBY_GOODSEX.VENDORID").
  525. Where("GOODS.GOODSID = ?", goodsID)
  526. if err := session.Find(&details); err != nil {
  527. return nil, err
  528. }
  529. // 无目标商品
  530. if len(details) == 0 {
  531. return nil, nil
  532. }
  533. preGoodsDetail := details[0]
  534. // FIXME: - 这里应该使用 Duck Typing,后期再处理
  535. // 计算最小变动单位
  536. lotSize := float64(preGoodsDetail.Quoteminunit) * math.Pow(0.1, float64(preGoodsDetail.Decimalplace))
  537. preGoodsDetail.LotSize, _ = strconv.ParseFloat(utils.FormatFloat(lotSize, int(preGoodsDetail.Decimalplace)), 64)
  538. return &preGoodsDetail, nil
  539. }