hsby.go 55 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068
  1. package models
  2. import (
  3. "encoding/hex"
  4. "fmt"
  5. "math"
  6. "mtp2_if/db"
  7. "mtp2_if/utils"
  8. "strconv"
  9. "time"
  10. )
  11. // Hsbygoodsex 商品扩展表
  12. type Hsbygoodsex struct {
  13. Goodsid int32 `json:"goodsid" xorm:"'GOODSID'" binding:"required"` // 商 品ID
  14. Hotindex int32 `json:"hotindex" xorm:"'HOTINDEX'"` // 景点热度
  15. Descprovinceid int64 `json:"descprovinceid" xorm:"'DESCPROVINCEID'"` // 目的地(省)
  16. Desccityid int64 `json:"desccityid" xorm:"'DESCCITYID'"` // 目的地(市)
  17. Vendorid int32 `json:"vendorid" xorm:"'VENDORID'"` // 供应商ID
  18. Goodsdesc string `json:"goodsdesc" xorm:"'GOODSDESC'"` // 商品详情
  19. Createtime time.Time `json:"createtime" xorm:"'CREATETIME'"` // 创建时间
  20. Creatorid int64 `json:"creatorid" xorm:"'CREATORID'"` // 创建人
  21. Modifierid int64 `json:"modifierid" xorm:"'MODIFIERID'"` // 修改人
  22. Modifytime time.Time `json:"modifytime" xorm:"'MODIFYTIME'"` // 修改时间
  23. Memberratio float64 `json:"memberratio" xorm:"'MEMBERRATIO'"` // 会员货款比例 [71]
  24. Videourls string `json:"videourls" xorm:"'VIDEOURLS'"` // 介绍视频[多张用逗号分隔]
  25. Picurls string `json:"picurls" xorm:"'PICURLS'"` // 介绍图片[多张用逗号分隔]
  26. }
  27. // TableName is HSBY_GOODSEX
  28. func (Hsbygoodsex) TableName() string {
  29. return "HSBY_GOODSEX"
  30. }
  31. // Hsbysupplierinfo 供应商表
  32. type Hsbysupplierinfo struct {
  33. Vendorid int32 `json:"vendorid" xorm:"'VENDORID'" binding:"required"` // 供应商ID(SEQ_HSBY_SUPPLIERINFO)
  34. Vendorname string `json:"vendorname" xorm:"'VENDORNAME'"` // 名称描述客服电话名称
  35. Vendordesc string `json:"vendordesc" xorm:"'VENDORDESC'"` // 描述
  36. Vendorphone string `json:"vendorphone" xorm:"'VENDORPHONE'"` // 客服电话
  37. Vendorattr string `json:"vendorattr" xorm:"'VENDORATTR'"` // 附件(多张,逗号分隔)
  38. Createtime time.Time `json:"createtime" xorm:"'CREATETIME'"` // 创建时间
  39. Creatorid int64 `json:"creatorid" xorm:"'CREATORID'"` // 创建人
  40. Modifierid int64 `json:"modifierid" xorm:"'MODIFIERID'"` // 修改人
  41. Modifytime time.Time `json:"modifytime" xorm:"'MODIFYTIME'"` // 修改时间
  42. }
  43. // TableName is HSBY_SUPPLIERINFO
  44. func (Hsbysupplierinfo) TableName() string {
  45. return "HSBY_SUPPLIERINFO"
  46. }
  47. // HsbyTopGoods 热卖商品(二级市场挂牌点选)
  48. type HsbyTopGoods struct {
  49. Goodsid int64 `json:"goodsid" xorm:"'GOODSID'" binding:"required"` // 商品ID(自增ID SEQ_GOODS)
  50. Goodscode string `json:"goodscode" xorm:"'GOODSCODE'" binding:"required"` // 商品代码(内部)
  51. Goodsname string `json:"goodsname" xorm:"'GOODSNAME'" binding:"required"` // 商品名称
  52. Decimalplace int64 `json:"decimalplace" xorm:"'DECIMALPLACE'"` // 报价小数位
  53. Marketid int64 `json:"marketid" xorm:"'MARKETID'" binding:"required"` // 所属市场ID
  54. Quoteminunit int64 `json:"quoteminunit" xorm:"'QUOTEMINUNIT'"` // 行情最小变动单位 [整数,报价小数位一起使用]
  55. Agreeunit float64 `json:"agreeunit" xorm:"'AGREEUNIT'"` // 合约单位
  56. Hotindex int32 `json:"hotindex" xorm:"'HOTINDEX'"` // 景点热度
  57. Videourls string `json:"videourls" xorm:"'VIDEOURLS'"` // 介绍视频[多张用逗号分隔]
  58. Picurls string `json:"picurls" xorm:"'PICURLS'"` // 介绍图片[多张用逗号分隔]
  59. Currency string `json:"currency" xorm:"'CURRENCY'"` // 货币
  60. Currencysign string `json:"currencysign" xorm:"'CURRENCYSIGN'"` // 货币符号
  61. Trademode int32 `json:"trademode" xorm:"'TRADEMODE'" binding:"required"` // 交易模式 - 10:做市 13:竞价 15:通道交易 16:挂牌点选 17:仓单贸易 18:期权 19:竞拍-降价式 20:竞拍-竞价式 21:竞拍-大宗式 22:受托竞价
  62. Last float64 `json:"last" xorm:"-"` // 现价
  63. }
  64. // GetHsbyTopGoodses 获取热门商品列表
  65. // 参数 marketIDs string 所属市场ID列表, 格式 1,2,3
  66. // 参数 descProvinceID int 目标省ID
  67. // 参数 descCityID int 目标城市ID
  68. // 返回 []TopGoods 热门商品列表
  69. // 返回 error error
  70. func GetHsbyTopGoodses(marketIDs string, descProvinceID, descCityID int) ([]HsbyTopGoods, error) {
  71. // 热门商品为二级市场(挂牌点选)下的商品信息
  72. engine := db.GetEngine()
  73. topGoodses := make([]HsbyTopGoods, 0)
  74. // 获取挂牌商品信息,以及扩展表信息
  75. session := engine.Table("GOODS").
  76. Select(`GOODS.*,
  77. HSBY_GOODSEX.HOTINDEX, HSBY_GOODSEX.VIDEOURLS, HSBY_GOODSEX.PICURLS,
  78. ENUMDICITEM.ENUMDICNAME CURRENCY, ENUMDICITEM.PARAM2 CURRENCYSIGN,
  79. MARKET.TRADEMODE`).
  80. Join("LEFT", "HSBY_GOODSEX", "HSBY_GOODSEX.GOODSID = GOODS.GOODSID").
  81. Join("LEFT", "ENUMDICITEM", "ENUMDICITEM.ENUMITEMNAME = GOODS.CURRENCYID and ENUMDICITEM.ENUMDICCODE = 'currency'").
  82. Join("LEFT", "MARKET", "MARKET.MARKETID = GOODS.MARKETID").
  83. Where(fmt.Sprintf("GOODS.GOODSSTATUS = 3 and GOODS.MARKETID in (%s)", marketIDs)) // 二级市场只获取 3:上市 状态的商品
  84. if descProvinceID > 0 {
  85. session = session.And("HSBY_GOODSEX.DESCPROVINCEID = ?", descProvinceID)
  86. }
  87. if descCityID > 0 {
  88. session = session.And("HSBY_GOODSEX.DESCCITYID = ?", descCityID)
  89. }
  90. if err := session.Find(&topGoodses); err != nil {
  91. return nil, err
  92. }
  93. if len(topGoodses) == 0 {
  94. // 无数据
  95. return topGoodses, nil
  96. }
  97. // 获取商品ID列表
  98. goodsCodes := ""
  99. for _, v := range topGoodses {
  100. if len(goodsCodes) == 0 {
  101. goodsCodes = v.Goodscode
  102. } else {
  103. goodsCodes += "," + v.Goodscode
  104. }
  105. }
  106. // 获取商品现价
  107. quoteDays, err := GetQuoteDays(goodsCodes)
  108. if err != nil {
  109. return nil, err
  110. }
  111. for i, g := range topGoodses {
  112. topGoods := &topGoodses[i]
  113. // FIXME: - 这里应该使用 Duck Typing,后期再处理
  114. // 计算最小变动单位
  115. // lotSize := float64(topGoods.Quoteminunit) * math.Pow(0.1, float64(topGoods.Decimalplace))
  116. // topGoods.LotSize, _ = strconv.ParseFloat(utils.FormatFloat(lotSize, int(topGoods.Decimalplace)), 64)
  117. for _, q := range quoteDays {
  118. if g.Goodscode == q.Goodscode {
  119. if q.Last != 0 {
  120. topGoods.Last = utils.IntToFloat64(int(q.Last), int(g.Decimalplace))
  121. }
  122. // 没有现价则尝试用昨结
  123. if topGoods.Last == 0 && q.Presettle != 0 {
  124. topGoods.Last = utils.IntToFloat64(int(q.Presettle), int(g.Decimalplace))
  125. }
  126. continue
  127. }
  128. }
  129. }
  130. return topGoodses, nil
  131. }
  132. // HsbyListingGoodsDetail 二级市场(挂牌点选)商品信息详情
  133. type HsbyListingGoodsDetail struct {
  134. Goodsid int64 `json:"goodsid" xorm:"'GOODSID'" binding:"required"` // 商品ID(自增ID SEQ_GOODS)
  135. Goodscode string `json:"goodscode" xorm:"'GOODSCODE'" binding:"required"` // 商品代码(内部)
  136. Goodsname string `json:"goodsname" xorm:"'GOODSNAME'" binding:"required"` // 商品名称
  137. Decimalplace int64 `json:"decimalplace" xorm:"'DECIMALPLACE'"` // 报价小数位
  138. Marketid int64 `json:"marketid" xorm:"'MARKETID'" binding:"required"` // 所属市场ID
  139. Quoteminunit int64 `json:"quoteminunit" xorm:"'QUOTEMINUNIT'"` // 行情最小变动单位 [整数,报价小数位一起使用]
  140. Agreeunit float64 `json:"agreeunit" xorm:"'AGREEUNIT'"` // 合约单位
  141. Hotindex int32 `json:"hotindex" xorm:"'HOTINDEX'"` // 景点热度
  142. Videourls string `json:"videourls" xorm:"'VIDEOURLS'"` // 介绍视频[多张用逗号分隔]
  143. Picurls string `json:"picurls" xorm:"'PICURLS'"` // 介绍图片[多张用逗号分隔]
  144. Descprovinceid int64 `json:"descprovinceid" xorm:"'DESCPROVINCEID'"` // 目的地(省)ID
  145. Desccityid int64 `json:"desccityid" xorm:"'DESCCITYID'"` // 目的地(市)ID
  146. Goodsdesc string `json:"goodsdesc" xorm:"'GOODSDESC'"` // 商品详情
  147. Currency string `json:"currency" xorm:"'CURRENCY'"` // 货币
  148. Currencysign string `json:"currencysign" xorm:"'CURRENCYSIGN'"` // 货币符号
  149. Vendorname string `json:"vendorname" xorm:"'VENDORNAME'"` // 供应商名称
  150. Vendorphone string `json:"vendorphone" xorm:"'VENDORPHONE'"` // 供应商客服电话
  151. Vendorattr string `json:"vendorattr" xorm:"'VENDORATTR'"` // 供应商附件(多张,逗号分隔)
  152. Trademode int32 `json:"trademode" xorm:"'TRADEMODE'" binding:"required"` // 交易模式 - 10:做市 13:竞价 15:通道交易 16:挂牌点选 17:仓单贸易 18:期权 19:竞拍-降价式 20:竞拍-竞价式 21:竞拍-大宗式 22:受托竞价
  153. Last float64 `json:"last" xorm:"-"` // 现价
  154. Limitup float64 `json:"limitup" xorm:"-"` // 涨停价
  155. Limitdown float64 `json:"limitdown" xorm:"-"` // 跌停价
  156. }
  157. // GetHsbyListingGoodsDetail 获取二级市场(挂牌点选)商品信息详情
  158. // 参数 goodsID int 目标商品ID
  159. // 返回 *HsbyListingGoodsDetail 二级市场(挂牌点选)商品信息详情,查询无结果返回nil
  160. // 返回 error error
  161. func GetHsbyListingGoodsDetail(goodsID int) (*HsbyListingGoodsDetail, error) {
  162. engine := db.GetEngine()
  163. details := make([]HsbyListingGoodsDetail, 0)
  164. // 获取挂牌商品信息,以及扩展表信息
  165. // FIXME: - 这里使用Get方法,会造成SQL语句的嵌套出错,后期再研究
  166. session := engine.Table("GOODS").
  167. Select(`GOODS.GOODSID, GOODS.GOODSCODE, GOODS.GOODSNAME, GOODS.DECIMALPLACE, GOODS.MARKETID, GOODS.QUOTEMINUNIT, GOODS.AGREEUNIT,
  168. HSBY_GOODSEX.HOTINDEX, HSBY_GOODSEX.VIDEOURLS, HSBY_GOODSEX.PICURLS, HSBY_GOODSEX.DESCPROVINCEID, HSBY_GOODSEX.Desccityid, HSBY_GOODSEX.Goodsdesc,
  169. ENUMDICITEM.ENUMDICNAME CURRENCY, ENUMDICITEM.PARAM2 CURRENCYSIGN,
  170. HSBY_SUPPLIERINFO.VENDORNAME, HSBY_SUPPLIERINFO.VENDORPHONE, HSBY_SUPPLIERINFO.VENDORATTR,
  171. MARKET.TRADEMODE`).
  172. Join("LEFT", "HSBY_GOODSEX", "HSBY_GOODSEX.GOODSID = GOODS.GOODSID").
  173. Join("LEFT", "ENUMDICITEM", "ENUMDICITEM.ENUMITEMNAME = GOODS.CURRENCYID and ENUMDICITEM.ENUMDICCODE = 'currency'").
  174. Join("LEFT", "HSBY_SUPPLIERINFO", "HSBY_SUPPLIERINFO.VENDORID = HSBY_GOODSEX.VENDORID").
  175. Join("LEFT", "MARKET", "MARKET.MARKETID = GOODS.MARKETID").
  176. Where("GOODS.GOODSID = ?", goodsID)
  177. if err := session.Find(&details); err != nil {
  178. return nil, err
  179. }
  180. // 无目标商品
  181. if len(details) == 0 {
  182. return nil, nil
  183. }
  184. hsbyListingGoodsDetail := details[0]
  185. // 获取商品现价和涨跌停价
  186. quoteDays, err := GetQuoteDays(hsbyListingGoodsDetail.Goodscode)
  187. if err != nil {
  188. return nil, err
  189. }
  190. if len(quoteDays) > 0 {
  191. if quoteDays[0].Last != 0 {
  192. hsbyListingGoodsDetail.Last = utils.IntToFloat64(int(quoteDays[0].Last), int(hsbyListingGoodsDetail.Decimalplace))
  193. }
  194. // 没有现价则尝试用昨结
  195. if hsbyListingGoodsDetail.Last == 0 && quoteDays[0].Presettle != 0 {
  196. hsbyListingGoodsDetail.Last = utils.IntToFloat64(int(quoteDays[0].Presettle), int(hsbyListingGoodsDetail.Decimalplace))
  197. }
  198. if quoteDays[0].Limitup != 0 {
  199. hsbyListingGoodsDetail.Limitup = utils.IntToFloat64(int(quoteDays[0].Limitup), int(hsbyListingGoodsDetail.Decimalplace))
  200. }
  201. if quoteDays[0].Limitdown != 0 {
  202. hsbyListingGoodsDetail.Limitdown = utils.IntToFloat64(int(quoteDays[0].Limitdown), int(hsbyListingGoodsDetail.Decimalplace))
  203. }
  204. }
  205. // FIXME: - 这里应该使用 Duck Typing,后期再处理
  206. // 计算最小变动单位
  207. // lotSize := float64(hsbyListingGoodsDetail.Quoteminunit) * math.Pow(0.1, float64(hsbyListingGoodsDetail.Decimalplace))
  208. // hsbyListingGoodsDetail.LotSize, _ = strconv.ParseFloat(utils.FormatFloat(lotSize, int(hsbyListingGoodsDetail.Decimalplace)), 64)
  209. return &hsbyListingGoodsDetail, nil
  210. }
  211. // HsbyGoodsOrderDetail 二级市场挂牌商品当前可摘委托单信息
  212. type HsbyGoodsOrderDetail struct {
  213. Orderid string `json:"orderid" xorm:"'ORDERID'" binding:"required"` // 委托单号(100+Unix秒时间戳(10位)+2位(MarketServiceID)+xxxx)
  214. Buyorsell int32 `json:"buyorsell" xorm:"'BUYORSELL'" binding:"required"` // 买卖 - 0:买 1:卖
  215. Ordertime time.Time `json:"ordertime" xorm:"'ORDERTIME'" binding:"required"` // 委托时间
  216. Orderprice float64 `json:"orderprice" xorm:"'ORDERPRICE'"` // 委托价格
  217. Enableqty int64 `json:"enableqty" xorm:"ENABLEQTY"` // 可用数量
  218. Customername string `json:"customername" xorm:"'CUSTOMERNAME'"` // 客户名称(企业名称),已脱敏
  219. Currencysign string `json:"currencysign" xorm:"-"` // 货币符号
  220. Goodunit string `json:"goodunit" xorm:"-"` // 报价单位
  221. }
  222. // GetHsbyGoodsOrderDetails 获取二级市场(挂牌点选)商品对应的挂牌委托单信息
  223. // 输入 goodsID int 商品ID
  224. // 输入 buyOrSell int 挂牌委托单方向(对手单方向),0:买 1:卖
  225. // 输入 price float64 参考价格。买方向委托单则价格小于等于(站在摘牌人的角度);卖方向委托单则价格大于等于
  226. // 输出 []HsbyGoodsOrderDetail 商品对应的挂牌委托单信息
  227. // 输出 error error
  228. func GetHsbyGoodsOrderDetails(goodsID, buyOrSell int, price float64, accountIDs string) ([]HsbyGoodsOrderDetail, error) {
  229. engine := db.GetEngine()
  230. // 获取与目标商品相关的挂牌委托单信息(ListingSelectType = 1 or 3; OrderStatus =3 or 7)
  231. hsbyGoodsOrderDetails := make([]HsbyGoodsOrderDetail, 0)
  232. session := engine.Table("TRADE_ORDERDETAIL").
  233. 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,
  234. substr(USERINFO.CUSTOMERNAME,0,1)||'****' as CUSTOMERNAME`).
  235. Join("LEFT", "TAACCOUNT", "TAACCOUNT.ACCOUNTID = TRADE_ORDERDETAIL.ACCOUNTID").
  236. Join("LEFT", "USERINFO", "USERINFO.USERID = TAACCOUNT.RELATEDUSERID").
  237. Where("(TRADE_ORDERDETAIL.LISTINGSELECTTYPE = 1 or TRADE_ORDERDETAIL.LISTINGSELECTTYPE = 3) and (TRADE_ORDERDETAIL.ORDERSTATUS = 3 or TRADE_ORDERDETAIL.ORDERSTATUS = 7)").
  238. And("TRADE_ORDERDETAIL.GOODSID = ?", goodsID).
  239. And("TRADE_ORDERDETAIL.BUYORSELL = ?", buyOrSell).
  240. And(fmt.Sprintf("TRADE_ORDERDETAIL.ACCOUNTID not in (%s)", accountIDs))
  241. if price > 0 {
  242. if buyOrSell == 0 {
  243. // 对手单买方向委托单则价格大于等于(站在摘牌人的角度,摘牌方面是卖,我的闲置下单)
  244. session = session.And("TRADE_ORDERDETAIL.ORDERPRICE >= ?", price)
  245. } else {
  246. // 对手单卖方向委托单则价格小于等于(站在摘牌人的角度,摘牌方面是买,热门商品下单)
  247. session = session.And("TRADE_ORDERDETAIL.ORDERPRICE <= ?", price)
  248. }
  249. }
  250. if err := session.Find(&hsbyGoodsOrderDetails); err != nil {
  251. return nil, err
  252. }
  253. // 获取商品货币符号和报价单位
  254. goods, err := GetGoods(goodsID)
  255. if err != nil {
  256. return nil, err
  257. }
  258. currencyEnums, err := GetEnumDicItem("currency", int(goods.Currencyid))
  259. if err != nil {
  260. return nil, err
  261. }
  262. currencysign := ""
  263. if len(currencyEnums) > 0 {
  264. currencysign = currencyEnums[0].Param2
  265. }
  266. goodsUnitEnums, err := GetEnumDicItem("goodsunit", int(goods.Goodunitid))
  267. if err != nil {
  268. return nil, err
  269. }
  270. goodsUnit := ""
  271. if len(goodsUnitEnums) > 0 {
  272. goodsUnit = goodsUnitEnums[0].Enumdicname
  273. }
  274. for i := range hsbyGoodsOrderDetails {
  275. orderDetail := &hsbyGoodsOrderDetails[i]
  276. // 设置货币符号和报价单位
  277. orderDetail.Currencysign = currencysign
  278. orderDetail.Goodunit = goodsUnit
  279. }
  280. return hsbyGoodsOrderDetails, nil
  281. }
  282. // HybsMyBuyOrderDetail 我的订单(一二级市场的买方向委托单)
  283. type HybsMyBuyOrderDetail struct {
  284. Orderid string `json:"orderid" xorm:"'ORDERID'" binding:"required"` // 委托单号(100+Unix秒时间戳(10位)+2位(MarketServiceID)+xxxx)
  285. Marketid int32 `json:"marketid" xorm:"'MARKETID'" binding:"required"` // 市场ID
  286. Goodsid int32 `json:"goodsid" xorm:"'GOODSID'" binding:"required"` // 商品ID
  287. Accountid int64 `json:"accountid" xorm:"'ACCOUNTID'" binding:"required"` // 账户ID[报价币种]
  288. Buyorsell int32 `json:"buyorsell" xorm:"'BUYORSELL'" binding:"required"` // 买卖 - 0:买 1:卖
  289. Orderprice float64 `json:"orderprice" xorm:"'ORDERPRICE'"` // 委托价格
  290. Orderqty int64 `json:"orderqty" xorm:"'ORDERQTY'" binding:"required"` // 委托数量
  291. Tradeqty int64 `json:"tradeqty" xorm:"'TRADEQTY'"` // 成交数量
  292. Cancelqty int64 `json:"cancelqty" xorm:"'CANCELQTY'"` // 撤单数量
  293. Ordertime time.Time `json:"ordertime" xorm:"'ORDERTIME'" binding:"required"` // 委托时间
  294. Listingselecttype int32 `json:"listingselecttype" xorm:"'LISTINGSELECTTYPE'"` // 挂牌点选类型 - 1:挂牌 2:摘牌 3:先摘后挂
  295. Orderstatus int32 `json:"orderstatus" xorm:"'ORDERSTATUS'"` // 委托状态 - 1: 委托请求 2:待冻结 3:委托成功 4: 委托失败 5:配对成功 6: 已撤销 7:部分成交 8:已成交 9:部成部撤 10:成交失败 11:已拒绝 12:经过摘牌(先摘后挂专用-先摘后挂已摘过) 13:冻结成功(通道交易专用) 14:通道已撤 15:通道部成部撤 16:成交失败违约(荷兰式竞拍专用)
  296. Goodscode string `json:"goodscode" xorm:"'GOODSCODE'" binding:"required"` // 商品代码(内部)
  297. Goodsname string `json:"goodsname" xorm:"'GOODSNAME'" binding:"required"` // 商品名称
  298. Decimalplace int64 `json:"decimalplace" xorm:"'DECIMALPLACE'"` // 报价小数位
  299. Agreeunit float64 `json:"agreeunit" xorm:"'AGREEUNIT'"` // 合约单位
  300. Picurls1 string `json:"picurls1" xorm:"'PICURLS1'"` // 预售商品介绍图片[多张用逗号分隔]
  301. Picurls2 string `json:"picurls2" xorm:"'PICURLS2'"` // 挂牌商品介绍图片[多张用逗号分隔]
  302. Trademode uint32 `json:"trademode" xorm:"'TRADEMODE'" binding:"required"` // 交易模式 - 10:做市 13:竞价 15:通道交易 16:挂牌点选 17:仓单贸易 18:期权 19:竞拍-降价式 20:竞拍-竞价式 21:竞拍-大宗式 22:受托竞价
  303. Currencysign string `json:"currencysign" xorm:"'CURRENCYSIGN'"` // 货币符号
  304. Vendorname1 string `json:"vendorname1" xorm:"'VENDORNAME1'"` // 预售商品供应商名称
  305. Vendorname2 string `json:"vendorname2" xorm:"'VENDORNAME2'"` // 挂牌商品供应商名称
  306. MyBuyStatus int `json:"mybuystatus" xorm:"-"` // "我的订单"显示状态- 1:抢购中 2:求购中 3:已完成 4:已撤消 5:委托失败
  307. Orderamount float64 `json:"orderamount" xorm:"-"` // 委托金额
  308. }
  309. // GetHsbyBuyMyOrderDetails 获取“我的订单”数据(包括一二级市场)
  310. // 输入 accountIDs string 资金账户列表
  311. // 输入 myBuyStatus int "我的订单"状态, 1:抢购中 2:求购中 3:已完成
  312. // 输出 []HybsMyBuyOrderDetail “我的订单”数据
  313. // 输出 error error
  314. func GetHsbyBuyMyOrderDetails(accountIDs string, myBuyStatus int) ([]HybsMyBuyOrderDetail, error) {
  315. // 获取市场信息
  316. markets, err := GetMarkets()
  317. if err != nil {
  318. return nil, err
  319. }
  320. engine := db.GetEngine()
  321. // 委托状态
  322. orderStatus := "0" // 单据状态,为0的时候查询全部
  323. marketIDs := "" // 我的订单包括一二级市场的单据
  324. switch myBuyStatus {
  325. case 1: // 抢购中 (一级市场)
  326. // 获取市场ID
  327. for _, v := range markets {
  328. if v.Trademode == 71 { // 预售挂牌
  329. if len(marketIDs) == 0 {
  330. marketIDs = strconv.Itoa(int(v.Marketid))
  331. } else {
  332. marketIDs += "," + strconv.Itoa(int(v.Marketid))
  333. }
  334. }
  335. }
  336. orderStatus = "3,7"
  337. case 2: // 求购中(二级市场)
  338. // 获取市场ID
  339. for _, v := range markets {
  340. if v.Trademode == 16 { // 挂牌点选
  341. if len(marketIDs) == 0 {
  342. marketIDs = strconv.Itoa(int(v.Marketid))
  343. } else {
  344. marketIDs += "," + strconv.Itoa(int(v.Marketid))
  345. }
  346. }
  347. }
  348. orderStatus = "3,7"
  349. case 3: // 已完成
  350. orderStatus = "8,9"
  351. }
  352. // 默认取 TradeMode = 16 or 71 的市场
  353. if len(marketIDs) == 0 {
  354. for _, v := range markets {
  355. if v.Trademode == 16 || v.Trademode == 71 {
  356. if len(marketIDs) == 0 {
  357. marketIDs = strconv.Itoa(int(v.Marketid))
  358. } else {
  359. marketIDs += "," + strconv.Itoa(int(v.Marketid))
  360. }
  361. }
  362. }
  363. }
  364. hybsMyBuyOrderDetails := make([]HybsMyBuyOrderDetail, 0)
  365. // "我的订单"都是买委托
  366. session := engine.Table("TRADE_ORDERDETAIL").
  367. Select(`to_char(TRADE_ORDERDETAIL.ORDERID) ORDERID, TRADE_ORDERDETAIL.*,
  368. GOODS.GOODSCODE, GOODS.GOODSNAME, GOODS.DECIMALPLACE, GOODS.AGREEUNIT,
  369. HG1.PICURLS PICURLS1,
  370. HG2.PICURLS PICURLS2,
  371. MARKET.TRADEMODE,
  372. ENUMDICITEM.PARAM2 CURRENCYSIGN,
  373. HS1.VENDORNAME VENDORNAME1,
  374. HS2.VENDORNAME VENDORNAME2`).
  375. Join("LEFT", "GOODS", "GOODS.GOODSID = TRADE_ORDERDETAIL.GOODSID").
  376. Join("LEFT", "CPTRADE_PRESALEGOODSEX", "CPTRADE_PRESALEGOODSEX.GOODSID = TRADE_ORDERDETAIL.GOODSID").
  377. Join("LEFT", "HSBY_GOODSEX HG1", "HG1.GOODSID = CPTRADE_PRESALEGOODSEX.RELATEDGOODSID").
  378. Join("LEFT", "HSBY_GOODSEX HG2", "HG2.GOODSID = GOODS.GOODSID").
  379. Join("LEFT", "ENUMDICITEM", "GOODS.CURRENCYID = ENUMDICITEM.ENUMITEMNAME and ENUMDICITEM.ENUMDICCODE = 'currency'").
  380. Join("LEFT", "MARKET", "MARKET.MARKETID = TRADE_ORDERDETAIL.MARKETID").
  381. Join("LEFT", "HSBY_SUPPLIERINFO HS1", "HS1.VENDORID = HG1.VENDORID").
  382. Join("LEFT", "HSBY_SUPPLIERINFO HS2", "HS2.VENDORID = HG2.VENDORID").
  383. Where(fmt.Sprintf("TRADE_ORDERDETAIL.BUYORSELL = 0 and TRADE_ORDERDETAIL.ACCOUNTID in (%s)", accountIDs)).
  384. And(fmt.Sprintf("TRADE_ORDERDETAIL.MARKETID in (%s)", marketIDs))
  385. // 是否过滤状态(抢购中、求购中、已完成)
  386. if orderStatus != "0" {
  387. session = session.And(fmt.Sprintf("TRADE_ORDERDETAIL.ORDERSTATUS in (%s)", orderStatus))
  388. }
  389. if err := session.Find(&hybsMyBuyOrderDetails); err != nil {
  390. return nil, err
  391. }
  392. // 设置“我的订单”显示状态
  393. for i := range hybsMyBuyOrderDetails {
  394. detail := &hybsMyBuyOrderDetails[i]
  395. // 委托金额 = 委托价格 * 委托数量 * 合约单位
  396. detail.Orderamount = detail.Orderprice * float64(detail.Orderqty) * float64(detail.Agreeunit)
  397. if detail.Trademode == 71 && (detail.Orderstatus == 3 || detail.Orderstatus == 7) {
  398. // 抢购中
  399. detail.MyBuyStatus = 1
  400. } else if detail.Trademode == 16 && (detail.Orderstatus == 3 || detail.Orderstatus == 7) {
  401. // 求购中
  402. detail.MyBuyStatus = 2
  403. } else if detail.Orderstatus == 8 || detail.Orderstatus == 9 {
  404. // 已完成
  405. detail.MyBuyStatus = 3
  406. } else if detail.Orderstatus == 6 {
  407. // 已撤销
  408. detail.MyBuyStatus = 4
  409. } else if detail.Orderstatus == 4 {
  410. // 委托失败
  411. detail.MyBuyStatus = 5
  412. }
  413. }
  414. return hybsMyBuyOrderDetails, nil
  415. }
  416. // HsbyMyGoods 我的商品(买方向持仓)
  417. type HsbyMyGoods struct {
  418. Accountid int64 `json:"accountid" xorm:"'ACCOUNTID'" binding:"required"` // 账号Id
  419. Goodsid int32 `json:"goodsid" xorm:"'GOODSID'" binding:"required"` // 商品Id
  420. Buycurpositionqty int64 `json:"buycurpositionqty" xorm:"'BUYCURPOSITIONQTY'"` // 买当前持仓总数量
  421. Buycurholderamount float64 `json:"buycurholderamount" xorm:"'BUYCURHOLDERAMOUNT'"` // 买当前持仓总金额[商品币种]
  422. EnableQty int64 `json:"enableqty" xorm:"'ENABLEQTY'"` // 可用数量
  423. Goodscode string `json:"goodscode" xorm:"'GOODSCODE'" binding:"required"` // 商品代码(内部)
  424. Goodsname string `json:"goodsname" xorm:"'GOODSNAME'" binding:"required"` // 商品名称
  425. Decimalplace int64 `json:"decimalplace" xorm:"'DECIMALPLACE'"` // 报价小数位
  426. Agreeunit float64 `json:"agreeunit" xorm:"'AGREEUNIT'"` // 合约单位
  427. Goodsstatus int64 `json:"goodsstatus" xorm:"'GOODSSTATUS'"` // 商品状态- 1:待审核 2:未上市 3:上市 4:已注销 5:审核拒绝 6:退市 7:待退市
  428. Picurls string `json:"picurls" xorm:"'PICURLS'"` // 介绍图片[多张用逗号分隔]
  429. Currencysign string `json:"currencysign" xorm:"'CURRENCYSIGN'"` // 货币符号
  430. Buyaverageprice float64 `json:"buyaverageprice" xorm:"-"` // 持仓均价
  431. }
  432. // GetHsbyMyGoods 获取“我的商品”信息
  433. // 输入 accountIDs string 资金账户列表,格式 1,2,3
  434. // 输出 []HsbyMyGoods “我的商品”信息
  435. // 输入 error error
  436. func GetHsbyMyGoods(accountIDs string) ([]HsbyMyGoods, error) {
  437. engine := db.GetEngine()
  438. hsbyMyGoodses := make([]HsbyMyGoods, 0)
  439. // 此定制版本,只查询出当前手数(期末)大于0的数据 (TRADEPOSITION.BUYCURPOSITIONQTY > 0)
  440. if err := engine.Table("TRADEPOSITION").
  441. Select(`TRADEPOSITION.*, (TRADEPOSITION.BUYCURPOSITIONQTY - TRADEPOSITION.BUYFROZENQTY - TRADEPOSITION.BUYOTHERFROZENQTY) ENABLEQTY,
  442. GOODS.GOODSCODE, GOODS.GOODSNAME, GOODS.DECIMALPLACE, GOODS.AGREEUNIT, GOODS.GOODSSTATUS,
  443. HSBY_GOODSEX.PICURLS,
  444. ENUMDICITEM.PARAM2 CURRENCYSIGN`).
  445. Join("LEFT", "GOODS", "GOODS.GOODSID = TRADEPOSITION.GOODSID").
  446. Join("INNER", "HSBY_GOODSEX", "HSBY_GOODSEX.GOODSID = GOODS.GOODSID").
  447. Join("LEFT", "ENUMDICITEM", "GOODS.CURRENCYID = ENUMDICITEM.ENUMITEMNAME and ENUMDICITEM.ENUMDICCODE = 'currency'").
  448. Where(fmt.Sprintf("TRADEPOSITION.BUYCURPOSITIONQTY > 0 and TRADEPOSITION.ACCOUNTID in (%s)", accountIDs)).Find(&hsbyMyGoodses); err != nil {
  449. return nil, err
  450. }
  451. for i := range hsbyMyGoodses {
  452. myGoods := &hsbyMyGoodses[i]
  453. // 持仓均价
  454. averagePrice := myGoods.Buycurholderamount / float64(myGoods.Buycurpositionqty) / myGoods.Agreeunit
  455. myGoods.Buyaverageprice, _ = strconv.ParseFloat(utils.FormatFloat(averagePrice, int(myGoods.Decimalplace)), 64)
  456. }
  457. return hsbyMyGoodses, nil
  458. }
  459. // HsbyPreGoods 新品上市商品(一级市场产能预售)
  460. type HsbyPreGoods struct {
  461. Goodsid int64 `json:"goodsid" xorm:"'GOODSID'" binding:"required"` // 商品ID(自增ID SEQ_GOODS)
  462. Goodscode string `json:"goodscode" xorm:"'GOODSCODE'" binding:"required"` // 商品代码(内部)
  463. Goodsname string `json:"goodsname" xorm:"'GOODSNAME'" binding:"required"` // 商品名称
  464. Decimalplace int64 `json:"decimalplace" xorm:"'DECIMALPLACE'"` // 报价小数位
  465. Marketid int64 `json:"marketid" xorm:"'MARKETID'" binding:"required"` // 所属市场ID
  466. Goodsstatus int64 `json:"goodsstatus" xorm:"'GOODSSTATUS'"` // 商品状态- 2:未上市 3:上市
  467. Quoteminunit int64 `json:"quoteminunit" xorm:"'QUOTEMINUNIT'"` // 行情最小变动单位 [整数,报价小数位一起使用]
  468. Agreeunit float64 `json:"agreeunit" xorm:"'AGREEUNIT'"` // 合约单位
  469. Relatedgoodsid int64 `json:"relatedgoodsid" xorm:"'RELATEDGOODSID'"` // 关联交易合约ID
  470. Presaleqty int64 `json:"presaleqty" xorm:"'PRESALEQTY'"` // 预售数量
  471. Starttime time.Time `json:"starttime" xorm:"'STARTTIME'"` // 预售开始时间
  472. Endtime time.Time `json:"endtime" xorm:"'ENDTIME'"` // 预售结束时间
  473. Refprice float64 `json:"refprice" xorm:"'REFPRICE'"` // 参考价格[一口价]
  474. Presaledqty int64 `json:"presaledqty" xorm:"'PRESALEDQTY'"` // 已预售量(预售结束时更新)
  475. EnableQty int64 `json:"enableqty" xorm:"ENABLEQTY"` // 剩余数量
  476. Currency string `json:"currency" xorm:"'CURRENCY'"` // 货币
  477. Currencysign string `json:"currencysign" xorm:"'CURRENCYSIGN'"` // 货币符号
  478. Videourls string `json:"videourls" xorm:"'VIDEOURLS'"` // 介绍视频[多张用逗号分隔]
  479. Picurls string `json:"picurls" xorm:"'PICURLS'"` // 介绍图片[多张用逗号分隔]
  480. Trademode int32 `json:"trademode" xorm:"'TRADEMODE'" binding:"required"` // 交易模式 - 10:做市 13:竞价 15:通道交易 16:挂牌点选 17:仓单贸易 18:期权 19:竞拍-降价式 20:竞拍-竞价式 21:竞拍-大宗式 22:受托竞价
  481. }
  482. // GetHsbyPreGoodses 获取“新品上市”商品列表(一级市场产能预售)
  483. // 输入 marketIDs string 市场ID列表,格式 1,2,3
  484. // 输入 descProvinceID int 省ID
  485. // 输入 descCityID int 市ID
  486. // 输出 []HsbyPreGoods “新品上市”商品列表
  487. // 输出 error error
  488. func GetHsbyPreGoodses(marketIDs string, descProvinceID, descCityID int) ([]HsbyPreGoods, error) {
  489. engine := db.GetEngine()
  490. // 注意:一级产能预售市场使用的商品实际上是和二级市场有关系的,所以要使用 CPTRADE_PRESALEGOODSEX.RELATEDGOODSID 进行关联
  491. preGoodses := make([]HsbyPreGoods, 0)
  492. session := engine.Table("GOODS").
  493. Select(`GOODS.*,
  494. CPTRADE_PRESALEGOODSEX.RELATEDGOODSID, CPTRADE_PRESALEGOODSEX.PRESALEQTY,
  495. CPTRADE_PRESALEGOODSEX.STARTTIME, CPTRADE_PRESALEGOODSEX.ENDTIME, CPTRADE_PRESALEGOODSEX.REFPRICE,
  496. CPTRADE_PRESALEGOODSEX.PRESALEDQTY, (CPTRADE_PRESALEGOODSEX.PRESALEQTY - CPTRADE_PRESALEGOODSEX.PRESALEDQTY) ENABLEQTY,
  497. ENUMDICITEM.ENUMDICNAME CURRENCY, ENUMDICITEM.PARAM2 CURRENCYSIGN,
  498. HSBY_GOODSEX.VIDEOURLS, HSBY_GOODSEX.PICURLS,
  499. MARKET.TRADEMODE`).
  500. Join("INNER", "CPTRADE_PRESALEGOODSEX", "CPTRADE_PRESALEGOODSEX.GOODSID = GOODS.GOODSID").
  501. Join("LEFT", "ENUMDICITEM", "ENUMDICITEM.ENUMITEMNAME = GOODS.CURRENCYID and ENUMDICITEM.ENUMDICCODE = 'currency'").
  502. Join("LEFT", "HSBY_GOODSEX", "HSBY_GOODSEX.GOODSID = CPTRADE_PRESALEGOODSEX.RELATEDGOODSID").
  503. Join("LEFT", "MARKET", "MARKET.MARKETID = GOODS.MARKETID").
  504. Where(fmt.Sprintf("GOODS.GOODSSTATUS in (2,3) and GOODS.MARKETID in (%s)", marketIDs)) // 一级市场获取 2:未上市 3:上市 状态的商品
  505. if descProvinceID > 0 {
  506. session = session.And("HSBY_GOODSEX.DESCPROVINCEID = ?", descProvinceID)
  507. }
  508. if descCityID > 0 {
  509. session = session.And("HSBY_GOODSEX.DESCCITYID = ?", descCityID)
  510. }
  511. if err := session.Find(&preGoodses); err != nil {
  512. return nil, err
  513. }
  514. // for i := range preGoodses {
  515. // preGoods := &preGoodses[i]
  516. // // FIXME: - 这里应该使用 Duck Typing,后期再处理
  517. // // 计算最小变动单位
  518. // lotSize := float64(preGoods.Quoteminunit) * math.Pow(0.1, float64(preGoods.Decimalplace))
  519. // preGoods.LotSize, _ = strconv.ParseFloat(utils.FormatFloat(lotSize, int(preGoods.Decimalplace)), 64)
  520. // }
  521. return preGoodses, nil
  522. }
  523. // HsbyPreGoodsDetail 一级市场(产能预售)商品信息详情
  524. type HsbyPreGoodsDetail struct {
  525. Goodsid int64 `json:"goodsid" xorm:"'GOODSID'" binding:"required"` // 商品ID(自增ID SEQ_GOODS)
  526. Goodscode string `json:"goodscode" xorm:"'GOODSCODE'" binding:"required"` // 商品代码(内部)
  527. Goodsname string `json:"goodsname" xorm:"'GOODSNAME'" binding:"required"` // 商品名称
  528. Decimalplace int64 `json:"decimalplace" xorm:"'DECIMALPLACE'"` // 报价小数位
  529. Marketid int64 `json:"marketid" xorm:"'MARKETID'" binding:"required"` // 所属市场ID
  530. Goodsstatus int64 `json:"goodsstatus" xorm:"'GOODSSTATUS'"` // 商品状态- 2:未上市 3:上市
  531. Quoteminunit int64 `json:"quoteminunit" xorm:"'QUOTEMINUNIT'"` // 行情最小变动单位 [整数,报价小数位一起使用]
  532. Agreeunit float64 `json:"agreeunit" xorm:"'AGREEUNIT'"` // 合约单位
  533. Relatedgoodsid int64 `json:"relatedgoodsid" xorm:"'RELATEDGOODSID'"` // 关联交易合约ID
  534. Presaleqty int64 `json:"presaleqty" xorm:"'PRESALEQTY'"` // 预售数量
  535. Starttime time.Time `json:"starttime" xorm:"'STARTTIME'"` // 预售开始时间
  536. Endtime time.Time `json:"endtime" xorm:"'ENDTIME'"` // 预售结束时间
  537. Refprice float64 `json:"refprice" xorm:"'REFPRICE'"` // 参考价格[一口价]
  538. Presaledqty int64 `json:"presaledqty" xorm:"'PRESALEDQTY'"` // 已预售量(预售结束时更新)
  539. EnableQty int64 `json:"enableqty" xorm:"ENABLEQTY"` // 剩余数量
  540. Videourls string `json:"videourls" xorm:"'VIDEOURLS'"` // 介绍视频[多张用逗号分隔]
  541. Picurls string `json:"picurls" xorm:"'PICURLS'"` // 介绍图片[多张用逗号分隔]
  542. Descprovinceid int64 `json:"descprovinceid" xorm:"'DESCPROVINCEID'"` // 目的地(省)ID
  543. Desccityid int64 `json:"desccityid" xorm:"'DESCCITYID'"` // 目的地(市)ID
  544. Goodsdesc string `json:"goodsdesc" xorm:"'GOODSDESC'"` // 商品详情
  545. Currency string `json:"currency" xorm:"'CURRENCY'"` // 货币
  546. Currencysign string `json:"currencysign" xorm:"'CURRENCYSIGN'"` // 货币符号
  547. Goodunit string `json:"goodunit" xorm:"GOODUNIT"` // 报价单位
  548. Vendorname string `json:"vendorname" xorm:"'VENDORNAME'"` // 供应商名称
  549. Vendorphone string `json:"vendorphone" xorm:"'VENDORPHONE'"` // 供应商客服电话
  550. Vendorattr string `json:"vendorattr" xorm:"'VENDORATTR'"` // 供应商附件(多张,逗号分隔)
  551. Trademode int32 `json:"trademode" xorm:"'TRADEMODE'" binding:"required"` // 交易模式 - 10:做市 13:竞价 15:通道交易 16:挂牌点选 17:仓单贸易 18:期权 19:竞拍-降价式 20:竞拍-竞价式 21:竞拍-大宗式 22:受托竞价
  552. Customername string `json:"customername" xorm:"'CUSTOMERNAME'"` // 发行单位
  553. StepValue float64 `json:"stepValue" xorm:"-"` // 价格最小变动单位
  554. LotSize int `json:"lotsize" xorm:"-"` // 手数最小变动单位
  555. Buymaxqty int `json:"buymaxqty" xorm:"'-'"` // 购买上限 [71] - 0为不限
  556. }
  557. // GetHsbyPreGoodsDetail 获取一级市场(产能预售)商品信息详情
  558. // 参数 goodsID int 目标商品ID
  559. // 返回 *HsbyListingGoodsDetail 二级市场(挂牌点选)商品信息详情,查询无结果返回nil
  560. // 返回 error error
  561. func GetHsbyPreGoodsDetail(goodsID, accountID int) (*HsbyPreGoodsDetail, error) {
  562. engine := db.GetEngine()
  563. details := make([]HsbyPreGoodsDetail, 0)
  564. // 获取挂牌商品信息,以及扩展表信息
  565. // FIXME: - 这里使用Get方法,会造成SQL语句的嵌套出错,后期再研究
  566. session := engine.Table("GOODS").
  567. Select(`GOODS.*,
  568. CPTRADE_PRESALEGOODSEX.RELATEDGOODSID, CPTRADE_PRESALEGOODSEX.PRESALEQTY,
  569. CPTRADE_PRESALEGOODSEX.STARTTIME, CPTRADE_PRESALEGOODSEX.ENDTIME, CPTRADE_PRESALEGOODSEX.REFPRICE,
  570. CPTRADE_PRESALEGOODSEX.PRESALEDQTY, (CPTRADE_PRESALEGOODSEX.PRESALEQTY - CPTRADE_PRESALEGOODSEX.PRESALEDQTY) ENABLEQTY,
  571. HSBY_GOODSEX.VIDEOURLS, HSBY_GOODSEX.PICURLS, HSBY_GOODSEX.DESCPROVINCEID, HSBY_GOODSEX.Desccityid, HSBY_GOODSEX.Goodsdesc,
  572. ENUMDICITEM.ENUMDICNAME CURRENCY, ENUMDICITEM.PARAM2 CURRENCYSIGN,
  573. E1.ENUMDICNAME GOODUNIT,
  574. HSBY_SUPPLIERINFO.VENDORNAME, HSBY_SUPPLIERINFO.VENDORPHONE, HSBY_SUPPLIERINFO.VENDORATTR,
  575. MARKET.TRADEMODE,
  576. USERINFO.CUSTOMERNAME`).
  577. Join("INNER", "CPTRADE_PRESALEGOODSEX", "CPTRADE_PRESALEGOODSEX.GOODSID = GOODS.GOODSID").
  578. Join("LEFT", "HSBY_GOODSEX", "HSBY_GOODSEX.GOODSID = CPTRADE_PRESALEGOODSEX.RELATEDGOODSID").
  579. Join("LEFT", "ENUMDICITEM", "ENUMDICITEM.ENUMITEMNAME = GOODS.CURRENCYID and ENUMDICITEM.ENUMDICCODE = 'currency'").
  580. Join("LEFT", "ENUMDICITEM E1", "E1.ENUMITEMNAME = GOODS.GOODUNITID and E1.ENUMDICCODE = 'goodsunit'").
  581. Join("LEFT", "HSBY_SUPPLIERINFO", "HSBY_SUPPLIERINFO.VENDORID = HSBY_GOODSEX.VENDORID").
  582. Join("LEFT", "MARKET", "MARKET.MARKETID = GOODS.MARKETID").
  583. Join("LEFT", "USERINFO", "USERINFO.USERID = CPTRADE_PRESALEGOODSEX.USERID").
  584. Where("GOODS.GOODSID = ?", goodsID)
  585. if err := session.Find(&details); err != nil {
  586. return nil, err
  587. }
  588. // 无目标商品
  589. if len(details) == 0 {
  590. return nil, nil
  591. }
  592. preGoodsDetail := details[0]
  593. // FIXME: - 这里应该使用 Duck Typing,后期再处理
  594. // 计算价格最小变动单位
  595. lotSize := float64(preGoodsDetail.Quoteminunit) * math.Pow(0.1, float64(preGoodsDetail.Decimalplace))
  596. preGoodsDetail.StepValue, _ = strconv.ParseFloat(utils.FormatFloat(lotSize, int(preGoodsDetail.Decimalplace)), 64)
  597. // 计算手数最小变动单位,一级市场固定为1
  598. preGoodsDetail.LotSize = 1
  599. // 获取购买上限
  600. buyMaxQty, err := GetCPTradeBuyLimit(goodsID, accountID)
  601. if err != nil {
  602. return nil, err
  603. }
  604. preGoodsDetail.Buymaxqty = buyMaxQty
  605. return &preGoodsDetail, nil
  606. }
  607. // HsbySellMyDetail "我的闲置"单据信息(已发布 - 二级市场卖挂,3:委托成功、7:部分成交; 已完成 - 二级市场成交单,包括历史数据)
  608. type HsbySellMyDetail struct {
  609. Orderid string `json:"orderid" xorm:"'ORDERID'" binding:"required"` // 单号(已发布 - 委托单号;已完成 - 成交单号)
  610. Marketid int32 `json:"marketid" xorm:"'MARKETID'" binding:"required"` // 市场ID
  611. Goodsid int32 `json:"goodsid" xorm:"'GOODSID'" binding:"required"` // 商品ID
  612. Accountid int64 `json:"accountid" xorm:"'ACCOUNTID'" binding:"required"` // 账户ID[报价币种]
  613. Buyorsell int32 `json:"buyorsell" xorm:"'BUYORSELL'" binding:"required"` // 买卖 - 0:买 1:卖
  614. Price float64 `json:"price" xorm:"'PRICE'"` // 价格
  615. Qty int64 `json:"qty" xorm:"'QTY'" binding:"required"` // 数量
  616. Time time.Time `json:"time" xorm:"'TIME'" binding:"required"` // 时间
  617. Amount float64 `json:"amount" xorm:"'AMOUNT'"` // 金额 = 价格 * 数量 * 合约单位
  618. Goodscode string `json:"goodscode" xorm:"'GOODSCODE'" binding:"required"` // 商品代码(内部)
  619. Goodsname string `json:"goodsname" xorm:"'GOODSNAME'" binding:"required"` // 商品名称
  620. Decimalplace int64 `json:"decimalplace" xorm:"'DECIMALPLACE'"` // 报价小数位
  621. Agreeunit float64 `json:"agreeunit" xorm:"'AGREEUNIT'"` // 合约单位
  622. Picurls string `json:"picurls" xorm:"'PICURLS'"` // 介绍图片[多张用逗号分隔]
  623. Trademode uint32 `json:"trademode" xorm:"'TRADEMODE'" binding:"required"` // 交易模式 - 10:做市 13:竞价 15:通道交易 16:挂牌点选 17:仓单贸易 18:期权 19:竞拍-降价式 20:竞拍-竞价式 21:竞拍-大宗式 22:受托竞价
  624. Currencysign string `json:"currencysign" xorm:"'CURRENCYSIGN'"` // 货币符号
  625. Vendorname string `json:"vendorname" xorm:"'VENDORNAME'"` // 供应商名称
  626. OrderType int32 `json:"ordertype" xorm:"'ORDERTYPE'"` // 单据类型:0 - 已发布, 1 - 已完成
  627. }
  628. // GetHsbySellMyOrderDetails 获取"我的闲置 - 已发布"单据信息
  629. // 输入 accountIDs string 资金账户列表
  630. // 输出 []HsbySellMyDetail "我的闲置 - 已发布"单据信息
  631. // 输出 error error
  632. func GetHsbySellMyOrderDetails(accountIDs string) ([]HsbySellMyDetail, error) {
  633. // 获取市场信息
  634. markets, err := GetMarkets()
  635. if err != nil {
  636. return nil, err
  637. }
  638. engine := db.GetEngine()
  639. marketIDs := "" // 我的闲置-已发布: 二级市场卖挂牌
  640. // 默认取 TradeMode = 16
  641. for _, v := range markets {
  642. if v.Trademode == 16 {
  643. if len(marketIDs) == 0 {
  644. marketIDs = strconv.Itoa(int(v.Marketid))
  645. } else {
  646. marketIDs += "," + strconv.Itoa(int(v.Marketid))
  647. }
  648. }
  649. }
  650. orderDetails := make([]HsbySellMyDetail, 0)
  651. // “我的闲置 - 已发布”都是卖挂委托
  652. session := engine.Table("TRADE_ORDERDETAIL").
  653. Select(`to_char(TRADE_ORDERDETAIL.ORDERID) ORDERID,
  654. TRADE_ORDERDETAIL.MARKETID, TRADE_ORDERDETAIL.GOODSID, TRADE_ORDERDETAIL.ACCOUNTID, TRADE_ORDERDETAIL.BUYORSELL,
  655. TRADE_ORDERDETAIL.ORDERPRICE PRICE, TRADE_ORDERDETAIL.ORDERQTY QTY, TRADE_ORDERDETAIL.ORDERTIME TIME,
  656. (TRADE_ORDERDETAIL.ORDERPRICE * TRADE_ORDERDETAIL.ORDERQTY * GOODS.AGREEUNIT) AMOUNT,
  657. GOODS.GOODSCODE, GOODS.GOODSNAME, GOODS.DECIMALPLACE, GOODS.AGREEUNIT,
  658. HSBY_GOODSEX.PICURLS,
  659. MARKET.TRADEMODE,
  660. ENUMDICITEM.PARAM2 CURRENCYSIGN,
  661. HSBY_SUPPLIERINFO.VENDORNAME,
  662. 0 ORDERTYPE`).
  663. Join("LEFT", "GOODS", "GOODS.GOODSID = TRADE_ORDERDETAIL.GOODSID").
  664. Join("LEFT", "HSBY_GOODSEX", "HSBY_GOODSEX.GOODSID = GOODS.GOODSID").
  665. Join("LEFT", "ENUMDICITEM", "GOODS.CURRENCYID = ENUMDICITEM.ENUMITEMNAME and ENUMDICITEM.ENUMDICCODE = 'currency'").
  666. Join("LEFT", "MARKET", "MARKET.MARKETID = TRADE_ORDERDETAIL.MARKETID").
  667. Join("LEFT", "HSBY_SUPPLIERINFO", "HSBY_SUPPLIERINFO.VENDORID = HSBY_GOODSEX.VENDORID").
  668. Where(fmt.Sprintf(`TRADE_ORDERDETAIL.BUYORSELL = 1 and TRADE_ORDERDETAIL.LISTINGSELECTTYPE = 1 and (TRADE_ORDERDETAIL.ORDERSTATUS = 3 or TRADE_ORDERDETAIL.ORDERSTATUS = 7)
  669. and TRADE_ORDERDETAIL.ACCOUNTID in (%s)`, accountIDs)).
  670. And(fmt.Sprintf("TRADE_ORDERDETAIL.MARKETID in (%s)", marketIDs))
  671. if err := session.Find(&orderDetails); err != nil {
  672. return nil, err
  673. }
  674. return orderDetails, nil
  675. }
  676. // GetHsbySellMyTradeDetails 获取"我的闲置 - 已完成"单据信息
  677. // 输入 accountIDs string 资金账户列表
  678. // 输出 []HsbySellMyDetail "我的闲置 - 已完成"单据信息
  679. // 输出 error error
  680. func GetHsbySellMyTradeDetails(accountIDs string) ([]HsbySellMyDetail, error) {
  681. // 获取市场信息
  682. markets, err := GetMarkets()
  683. if err != nil {
  684. return nil, err
  685. }
  686. engine := db.GetEngine()
  687. marketIDs := "" // 我的闲置-已发布: 二级市场卖方向成交单(包括历史成交单)
  688. // 默认取 TradeMode = 16
  689. for _, v := range markets {
  690. if v.Trademode == 16 {
  691. if len(marketIDs) == 0 {
  692. marketIDs = strconv.Itoa(int(v.Marketid))
  693. } else {
  694. marketIDs += "," + strconv.Itoa(int(v.Marketid))
  695. }
  696. }
  697. }
  698. orders := make([]HsbySellMyDetail, 0)
  699. // 当前成交单
  700. curOrders := make([]HsbySellMyDetail, 0)
  701. if err := engine.Table("TRADE_TRADEDETAIL").
  702. Select(`to_char(TRADE_TRADEDETAIL.TRADEID) ORDERID,
  703. TRADE_TRADEDETAIL.MARKETID, TRADE_TRADEDETAIL.GOODSID, TRADE_TRADEDETAIL.ACCOUNTID, TRADE_TRADEDETAIL.BUYORSELL,
  704. TRADE_TRADEDETAIL.TRADEPRICE PRICE, TRADE_TRADEDETAIL.TRADEQTY QTY, TRADE_TRADEDETAIL.TRADETIME TIME, TRADE_TRADEDETAIL.TRADEAMOUNT AMOUNT,
  705. GOODS.GOODSCODE, GOODS.GOODSNAME, GOODS.DECIMALPLACE, GOODS.AGREEUNIT,
  706. HSBY_GOODSEX.PICURLS,
  707. MARKET.TRADEMODE,
  708. ENUMDICITEM.PARAM2 CURRENCYSIGN,
  709. HSBY_SUPPLIERINFO.VENDORNAME,
  710. 1 ORDERTYPE`).
  711. Join("LEFT", "GOODS", "GOODS.GOODSID = TRADE_TRADEDETAIL.GOODSID").
  712. Join("LEFT", "HSBY_GOODSEX", "HSBY_GOODSEX.GOODSID = GOODS.GOODSID").
  713. Join("LEFT", "ENUMDICITEM", "GOODS.CURRENCYID = ENUMDICITEM.ENUMITEMNAME and ENUMDICITEM.ENUMDICCODE = 'currency'").
  714. Join("LEFT", "MARKET", "MARKET.MARKETID = TRADE_TRADEDETAIL.MARKETID").
  715. Join("LEFT", "HSBY_SUPPLIERINFO", "HSBY_SUPPLIERINFO.VENDORID = HSBY_GOODSEX.VENDORID").
  716. Where(fmt.Sprintf(`TRADE_TRADEDETAIL.BUYORSELL = 1
  717. and TRADE_TRADEDETAIL.ACCOUNTID in (%s)`, accountIDs)).
  718. And(fmt.Sprintf("TRADE_TRADEDETAIL.MARKETID in (%s)", marketIDs)).Find(&curOrders); err != nil {
  719. return nil, err
  720. }
  721. if len(curOrders) > 0 {
  722. orders = append(orders, curOrders...)
  723. }
  724. // 历史成交单
  725. hisOrders := make([]HsbySellMyDetail, 0)
  726. if err := engine.Table("HIS_TRADE_TRADEDETAIL").
  727. Select(`to_char(HIS_TRADE_TRADEDETAIL.TRADEID) ORDERID,
  728. HIS_TRADE_TRADEDETAIL.MARKETID, HIS_TRADE_TRADEDETAIL.GOODSID, HIS_TRADE_TRADEDETAIL.ACCOUNTID, HIS_TRADE_TRADEDETAIL.BUYORSELL,
  729. HIS_TRADE_TRADEDETAIL.TRADEPRICE PRICE, HIS_TRADE_TRADEDETAIL.TRADEQTY QTY, HIS_TRADE_TRADEDETAIL.TRADETIME TIME, HIS_TRADE_TRADEDETAIL.TRADEAMOUNT AMOUNT,
  730. GOODS.GOODSCODE, GOODS.GOODSNAME, GOODS.DECIMALPLACE, GOODS.AGREEUNIT,
  731. HSBY_GOODSEX.PICURLS,
  732. MARKET.TRADEMODE,
  733. ENUMDICITEM.PARAM2 CURRENCYSIGN,
  734. HSBY_SUPPLIERINFO.VENDORNAME,
  735. 1 ORDERTYPE`).
  736. Join("LEFT", "GOODS", "GOODS.GOODSID = HIS_TRADE_TRADEDETAIL.GOODSID").
  737. Join("LEFT", "HSBY_GOODSEX", "HSBY_GOODSEX.GOODSID = GOODS.GOODSID").
  738. Join("LEFT", "ENUMDICITEM", "GOODS.CURRENCYID = ENUMDICITEM.ENUMITEMNAME and ENUMDICITEM.ENUMDICCODE = 'currency'").
  739. Join("LEFT", "MARKET", "MARKET.MARKETID = HIS_TRADE_TRADEDETAIL.MARKETID").
  740. Join("LEFT", "HSBY_SUPPLIERINFO", "HSBY_SUPPLIERINFO.VENDORID = HSBY_GOODSEX.VENDORID").
  741. Where(fmt.Sprintf(`HIS_TRADE_TRADEDETAIL.BUYORSELL = 1 and HIS_TRADE_TRADEDETAIL.ISVALIDDATA = 1
  742. and HIS_TRADE_TRADEDETAIL.ACCOUNTID in (%s)`, accountIDs)).
  743. And(fmt.Sprintf("HIS_TRADE_TRADEDETAIL.MARKETID in (%s)", marketIDs)).Find(&hisOrders); err != nil {
  744. return nil, err
  745. }
  746. if len(hisOrders) > 0 {
  747. orders = append(orders, hisOrders...)
  748. }
  749. return orders, nil
  750. }
  751. // HsbyMyPackage 我的包裹信息
  752. type HsbyMyPackage struct {
  753. Takeorderid string `json:"takeorderid" xorm:"'TAKEORDERID'" binding:"required"` // 提货单号(905+Unix秒时间戳(10位)+xxxxxx)
  754. Accountid int64 `json:"accountid" xorm:"'ACCOUNTID'"` // 账户ID
  755. Goodsid int64 `json:"goodsid" xorm:"'GOODSID'"` // 商品ID
  756. Userid int64 `json:"userid" xorm:"'USERID'"` // 用户ID
  757. Qty float64 `json:"qty" xorm:"'QTY'"` // 提货数量
  758. Reqtime time.Time `json:"reqtime" xorm:"'REQTIME'"` // 更新时间
  759. Recivername string `json:"recivername" xorm:"'RECIVERNAME'"` // 提货人姓名
  760. Cardtypeid int32 `json:"cardtypeid" xorm:"'CARDTYPEID'"` // 提货人证件类型
  761. Cardnum string `json:"cardnum" xorm:"'CARDNUM'"` // 提货人证件号码
  762. Phonenum string `json:"phonenum" xorm:"'PHONENUM'"` // 提货人联系方式
  763. Takemode int32 `json:"takemode" xorm:"'TAKEMODE'"` // 提货方式 - 2:自提 3:配送
  764. Address string `json:"address" xorm:"'ADDRESS'"` // 提货人详细地址
  765. Takeremark string `json:"takeremark" xorm:"'TAKEREMARK'"` // 提货备注
  766. Takeorderstatus int32 `json:"takeorderstatus" xorm:"'TAKEORDERSTATUS'"` // 提货状态 - 1:待发货 2:已发货 3:已收货
  767. Auditer int32 `json:"auditer" xorm:"'AUDITER'"` // 审核人
  768. Audittime time.Time `json:"audittime" xorm:"'AUDITTIME'"` // 审核时间
  769. Checkremark string `json:"checkremark" xorm:"'CHECKREMARK'"` // 审核备注
  770. Tradedate string `json:"tradedate" xorm:"'TRADEDATE'"` // 交易日(yyyyMMdd)
  771. Marketid int32 `json:"marketid" xorm:"'MARKETID'"` // 市场ID
  772. Handlestatus int32 `json:"handlestatus" xorm:"'HANDLESTATUS'"` // 处理状态
  773. Amount float64 `json:"amount" xorm:"'AMOUNT'"` // 提货金额
  774. Averageprice float64 `json:"averageprice" xorm:"'AVERAGEPRICE'"` // 均价
  775. Goodscode string `json:"goodscode" xorm:"'GOODSCODE'" binding:"required"` // 商品代码(内部)
  776. Goodsname string `json:"goodsname" xorm:"'GOODSNAME'" binding:"required"` // 商品名称
  777. Decimalplace int64 `json:"decimalplace" xorm:"'DECIMALPLACE'"` // 报价小数位
  778. Agreeunit float64 `json:"agreeunit" xorm:"'AGREEUNIT'"` // 合约单位
  779. Picurls string `json:"picurls" xorm:"'PICURLS'"` // 介绍图片[多张用逗号分隔]
  780. Currencysign string `json:"currencysign" xorm:"'CURRENCYSIGN'"` // 货币符号
  781. Vendorname string `json:"vendorname" xorm:"'VENDORNAME'"` // 供应商名称
  782. }
  783. // GetHsbyMyPackages 获取我的包裹信息
  784. // 输入 accountIDs string 资金账户列表
  785. // 输入 takeOrderStatus int 提货状态 - 1:待发货 2:已发货 3:已收货
  786. // 输出 []HsbyMyPackage 我的包裹信息
  787. // 输出 error error
  788. func GetHsbyMyPackages(accountIDs string, takeOrderStatus int) ([]HsbyMyPackage, error) {
  789. engine := db.GetEngine()
  790. myPackages := make([]HsbyMyPackage, 0)
  791. session := engine.Table("TRADE_GOODSPICKUP").
  792. Select(`to_char(TRADE_GOODSPICKUP.TAKEORDERID) TAKEORDERID, TRADE_GOODSPICKUP.*,
  793. (TRADE_GOODSPICKUP.AMOUNT/TRADE_GOODSPICKUP.QTY/GOODS.AGREEUNIT) AVERAGEPRICE,
  794. GOODS.GOODSCODE, GOODS.GOODSNAME, GOODS.DECIMALPLACE, GOODS.AGREEUNIT,
  795. HSBY_GOODSEX.PICURLS,
  796. ENUMDICITEM.PARAM2 CURRENCYSIGN,
  797. HSBY_SUPPLIERINFO.VENDORNAME`).
  798. Join("LEFT", "GOODS", "GOODS.GOODSID = TRADE_GOODSPICKUP.GOODSID").
  799. Join("LEFT", "HSBY_GOODSEX", "HSBY_GOODSEX.GOODSID = GOODS.GOODSID").
  800. Join("LEFT", "ENUMDICITEM", "GOODS.CURRENCYID = ENUMDICITEM.ENUMITEMNAME and ENUMDICITEM.ENUMDICCODE = 'currency'").
  801. Join("LEFT", "HSBY_SUPPLIERINFO", "HSBY_SUPPLIERINFO.VENDORID = HSBY_GOODSEX.VENDORID").
  802. Where(fmt.Sprintf("TRADE_GOODSPICKUP.ACCOUNTID in (%s)", accountIDs))
  803. if takeOrderStatus > 0 {
  804. session = session.And("TAKEORDERSTATUS = ?", takeOrderStatus)
  805. }
  806. if err := session.Find(&myPackages); err != nil {
  807. return nil, err
  808. }
  809. // FIXME:- 目前暂时在服务端对手机号码进行解密
  810. key, _ := hex.DecodeString(utils.AESSecretKey)
  811. for i := range myPackages {
  812. myPackage := &myPackages[i]
  813. // 解密手机号码
  814. if phonenum, err := hex.DecodeString(myPackage.Phonenum); err == nil { // hex -> []byte
  815. if mobile, err := utils.AESDecrypt(phonenum, key); err == nil {
  816. myPackage.Phonenum = string(mobile)
  817. }
  818. }
  819. }
  820. return myPackages, nil
  821. }
  822. // SetHsbyMyPackagesStatus 设置我的包裹提货状态
  823. func SetHsbyMyPackagesStatus(takeOrderID string, accountID, status int) error {
  824. engine := db.GetEngine()
  825. sql := fmt.Sprintf("update TRADE_GOODSPICKUP set TAKEORDERSTATUS = %d where TAKEORDERID = %s and ACCOUNTID = %d", status, takeOrderID, accountID)
  826. _, err := engine.Exec(sql)
  827. return err
  828. }
  829. // GetHsbyProvincesAndCities 获取省市信息数组
  830. // 参数 provinceID int 省ID,选填
  831. // 返回 []Division 枚举信息数组
  832. // 返回 error error
  833. func GetHsbyProvincesAndCities(provinceID int) ([]Division, error) {
  834. engine := db.GetEngine()
  835. divisions := make([]Division, 0)
  836. session := engine.Where("DIVISIONLEVEL = 'province' or DIVISIONLEVEL = 'city'").
  837. And("AUTOID in ((select DESCPROVINCEID AUTOID from HSBY_GOODSEX) union all (select DESCCITYID AUTOID from HSBY_GOODSEX))")
  838. if provinceID > 0 {
  839. session = session.And("AUTOID = ?", provinceID)
  840. }
  841. if err := session.Find(&divisions); err != nil {
  842. return nil, err
  843. }
  844. return divisions, nil
  845. }
  846. // HsbyBuyMyTradeDetail "我的订单 - 已完成"单据信息(一二级市场成交单,包括历史数据)
  847. type HsbyBuyMyTradeDetail struct {
  848. Orderid string `json:"orderid" xorm:"'ORDERID'" binding:"required"` // 单号(成交单号)
  849. Marketid int32 `json:"marketid" xorm:"'MARKETID'" binding:"required"` // 市场ID
  850. Goodsid int32 `json:"goodsid" xorm:"'GOODSID'" binding:"required"` // 商品ID
  851. Accountid int64 `json:"accountid" xorm:"'ACCOUNTID'" binding:"required"` // 账户ID[报价币种]
  852. Buyorsell int32 `json:"buyorsell" xorm:"'BUYORSELL'" binding:"required"` // 买卖 - 0:买 1:卖
  853. Price float64 `json:"price" xorm:"'PRICE'"` // 价格
  854. Qty int64 `json:"qty" xorm:"'QTY'" binding:"required"` // 数量
  855. Time time.Time `json:"time" xorm:"'TIME'" binding:"required"` // 时间
  856. Amount float64 `json:"amount" xorm:"'AMOUNT'"` // 金额 = 价格 * 数量 * 合约单位
  857. Goodscode string `json:"goodscode" xorm:"'GOODSCODE'" binding:"required"` // 商品代码(内部)
  858. Goodsname string `json:"goodsname" xorm:"'GOODSNAME'" binding:"required"` // 商品名称
  859. Decimalplace int64 `json:"decimalplace" xorm:"'DECIMALPLACE'"` // 报价小数位
  860. Agreeunit float64 `json:"agreeunit" xorm:"'AGREEUNIT'"` // 合约单位
  861. Picurls string `json:"picurls" xorm:"'PICURLS'"` // 介绍图片[多张用逗号分隔]
  862. Trademode uint32 `json:"trademode" xorm:"'TRADEMODE'" binding:"required"` // 交易模式 - 10:做市 13:竞价 15:通道交易 16:挂牌点选 17:仓单贸易 18:期权 19:竞拍-降价式 20:竞拍-竞价式 21:竞拍-大宗式 22:受托竞价
  863. Currencysign string `json:"currencysign" xorm:"'CURRENCYSIGN'"` // 货币符号
  864. Vendorname string `json:"vendorname" xorm:"'VENDORNAME'"` // 供应商名称
  865. }
  866. // GetHsbyBuyMyTradeDetails 获取"我的订单 - 已完成"单据信息(一二级市场成交单,包括历史数据)
  867. // 输入 accountIDs string 资金账户列表
  868. // 输出 []HsbyBuyMyTradeDetail "我的订单 - 已完成"单据信息
  869. // 输出 error error
  870. func GetHsbyBuyMyTradeDetails(accountIDs string) ([]HsbyBuyMyTradeDetail, error) {
  871. // 获取市场信息
  872. markets, err := GetMarkets()
  873. if err != nil {
  874. return nil, err
  875. }
  876. engine := db.GetEngine()
  877. marketIDs := "" // 我的订单包括一二级市场卖方向成交单(包括历史成交单)
  878. // 默认取 TradeMode = 16
  879. for _, v := range markets {
  880. if v.Trademode == 16 || v.Trademode == 71 {
  881. if len(marketIDs) == 0 {
  882. marketIDs = strconv.Itoa(int(v.Marketid))
  883. } else {
  884. marketIDs += "," + strconv.Itoa(int(v.Marketid))
  885. }
  886. }
  887. }
  888. orders := make([]HsbyBuyMyTradeDetail, 0)
  889. // 当前成交单
  890. curOrders := make([]HsbyBuyMyTradeDetail, 0)
  891. if err := engine.Table("TRADE_TRADEDETAIL").
  892. Select(`to_char(TRADE_TRADEDETAIL.TRADEID) ORDERID,
  893. TRADE_TRADEDETAIL.MARKETID, TRADE_TRADEDETAIL.GOODSID, TRADE_TRADEDETAIL.ACCOUNTID, TRADE_TRADEDETAIL.BUYORSELL,
  894. TRADE_TRADEDETAIL.TRADEPRICE PRICE, TRADE_TRADEDETAIL.TRADEQTY QTY, TRADE_TRADEDETAIL.TRADETIME TIME, TRADE_TRADEDETAIL.TRADEAMOUNT AMOUNT,
  895. GOODS.GOODSCODE, GOODS.GOODSNAME, GOODS.DECIMALPLACE, GOODS.AGREEUNIT,
  896. HSBY_GOODSEX.PICURLS,
  897. MARKET.TRADEMODE,
  898. ENUMDICITEM.PARAM2 CURRENCYSIGN,
  899. HSBY_SUPPLIERINFO.VENDORNAME`).
  900. Join("LEFT", "GOODS", "GOODS.GOODSID = TRADE_TRADEDETAIL.GOODSID").
  901. Join("LEFT", "HSBY_GOODSEX", "HSBY_GOODSEX.GOODSID = GOODS.GOODSID").
  902. Join("LEFT", "ENUMDICITEM", "GOODS.CURRENCYID = ENUMDICITEM.ENUMITEMNAME and ENUMDICITEM.ENUMDICCODE = 'currency'").
  903. Join("LEFT", "MARKET", "MARKET.MARKETID = TRADE_TRADEDETAIL.MARKETID").
  904. Join("LEFT", "HSBY_SUPPLIERINFO", "HSBY_SUPPLIERINFO.VENDORID = HSBY_GOODSEX.VENDORID").
  905. Where(fmt.Sprintf(`TRADE_TRADEDETAIL.BUYORSELL = 0
  906. and TRADE_TRADEDETAIL.ACCOUNTID in (%s)`, accountIDs)).
  907. And(fmt.Sprintf("TRADE_TRADEDETAIL.MARKETID in (%s)", marketIDs)).Find(&curOrders); err != nil {
  908. return nil, err
  909. }
  910. if len(curOrders) > 0 {
  911. orders = append(orders, curOrders...)
  912. }
  913. // 历史成交单
  914. hisOrders := make([]HsbyBuyMyTradeDetail, 0)
  915. if err := engine.Table("HIS_TRADE_TRADEDETAIL").
  916. Select(`to_char(HIS_TRADE_TRADEDETAIL.TRADEID) ORDERID,
  917. HIS_TRADE_TRADEDETAIL.MARKETID, HIS_TRADE_TRADEDETAIL.GOODSID, HIS_TRADE_TRADEDETAIL.ACCOUNTID, HIS_TRADE_TRADEDETAIL.BUYORSELL,
  918. HIS_TRADE_TRADEDETAIL.TRADEPRICE PRICE, HIS_TRADE_TRADEDETAIL.TRADEQTY QTY, HIS_TRADE_TRADEDETAIL.TRADETIME TIME, HIS_TRADE_TRADEDETAIL.TRADEAMOUNT AMOUNT,
  919. GOODS.GOODSCODE, GOODS.GOODSNAME, GOODS.DECIMALPLACE, GOODS.AGREEUNIT,
  920. HSBY_GOODSEX.PICURLS,
  921. MARKET.TRADEMODE,
  922. ENUMDICITEM.PARAM2 CURRENCYSIGN,
  923. HSBY_SUPPLIERINFO.VENDORNAME`).
  924. Join("LEFT", "GOODS", "GOODS.GOODSID = HIS_TRADE_TRADEDETAIL.GOODSID").
  925. Join("LEFT", "HSBY_GOODSEX", "HSBY_GOODSEX.GOODSID = GOODS.GOODSID").
  926. Join("LEFT", "ENUMDICITEM", "GOODS.CURRENCYID = ENUMDICITEM.ENUMITEMNAME and ENUMDICITEM.ENUMDICCODE = 'currency'").
  927. Join("LEFT", "MARKET", "MARKET.MARKETID = HIS_TRADE_TRADEDETAIL.MARKETID").
  928. Join("LEFT", "HSBY_SUPPLIERINFO", "HSBY_SUPPLIERINFO.VENDORID = HSBY_GOODSEX.VENDORID").
  929. Where(fmt.Sprintf(`HIS_TRADE_TRADEDETAIL.BUYORSELL = 0 and HIS_TRADE_TRADEDETAIL.ISVALIDDATA = 1
  930. and HIS_TRADE_TRADEDETAIL.ACCOUNTID in (%s)`, accountIDs)).
  931. And(fmt.Sprintf("HIS_TRADE_TRADEDETAIL.MARKETID in (%s)", marketIDs)).Find(&hisOrders); err != nil {
  932. return nil, err
  933. }
  934. if len(hisOrders) > 0 {
  935. orders = append(orders, hisOrders...)
  936. }
  937. return orders, nil
  938. }