hsby.go 46 KB

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