hsby.go 65 KB

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