hsby.go 100 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846
  1. package models
  2. import (
  3. "encoding/hex"
  4. "fmt"
  5. "math"
  6. "mtp2_if/db"
  7. "mtp2_if/utils"
  8. "strconv"
  9. "strings"
  10. "time"
  11. )
  12. // Hsbygoodsex 商品扩展表
  13. type Hsbygoodsex struct {
  14. Goodsid int32 `json:"goodsid" xorm:"'GOODSID'" binding:"required"` // 商 品ID
  15. Hotindex int32 `json:"hotindex" xorm:"'HOTINDEX'"` // 景点热度
  16. Descprovinceid int64 `json:"descprovinceid" xorm:"'DESCPROVINCEID'"` // 目的地(省)
  17. Desccityid int64 `json:"desccityid" xorm:"'DESCCITYID'"` // 目的地(市)
  18. Vendorid int32 `json:"vendorid" xorm:"'VENDORID'"` // 供应商ID
  19. Goodsdesc string `json:"goodsdesc" xorm:"'GOODSDESC'"` // 商品详情
  20. Createtime time.Time `json:"createtime" xorm:"'CREATETIME'"` // 创建时间
  21. Creatorid int64 `json:"creatorid" xorm:"'CREATORID'"` // 创建人
  22. Modifierid int64 `json:"modifierid" xorm:"'MODIFIERID'"` // 修改人
  23. Modifytime time.Time `json:"modifytime" xorm:"'MODIFYTIME'"` // 修改时间
  24. Memberratio float64 `json:"memberratio" xorm:"'MEMBERRATIO'"` // 会员货款比例 [71]
  25. Videourls string `json:"videourls" xorm:"'VIDEOURLS'"` // 介绍视频[多张用逗号分隔]
  26. Picurls string `json:"picurls" xorm:"'PICURLS'"` // 介绍图片[多张用逗号分隔]
  27. Goodsprice float64 `json:"goodsprice" xorm:"'GOODSPRICE'"` // 商品价格
  28. Categoryid int32 `json:"categoryid" xorm:"'CATEGORYID'"` // 类别ID(WRCATEGORY)
  29. }
  30. // TableName is HSBY_GOODSEX
  31. func (Hsbygoodsex) TableName() string {
  32. return "HSBY_GOODSEX"
  33. }
  34. // Hsbysupplierinfo 供应商表
  35. type Hsbysupplierinfo struct {
  36. Vendorid int32 `json:"vendorid" xorm:"'VENDORID'" binding:"required"` // 供应商ID(SEQ_HSBY_SUPPLIERINFO)
  37. Vendorname string `json:"vendorname" xorm:"'VENDORNAME'"` // 名称描述客服电话名称
  38. Vendordesc string `json:"vendordesc" xorm:"'VENDORDESC'"` // 描述
  39. Vendorphone string `json:"vendorphone" xorm:"'VENDORPHONE'"` // 客服电话
  40. Vendorattr string `json:"vendorattr" xorm:"'VENDORATTR'"` // 附件(多张,逗号分隔)
  41. Createtime time.Time `json:"createtime" xorm:"'CREATETIME'"` // 创建时间
  42. Creatorid int64 `json:"creatorid" xorm:"'CREATORID'"` // 创建人
  43. Modifierid int64 `json:"modifierid" xorm:"'MODIFIERID'"` // 修改人
  44. Modifytime time.Time `json:"modifytime" xorm:"'MODIFYTIME'"` // 修改时间
  45. }
  46. // TableName is HSBY_SUPPLIERINFO
  47. func (Hsbysupplierinfo) TableName() string {
  48. return "HSBY_SUPPLIERINFO"
  49. }
  50. // Tradepayorder 交易待付款表
  51. type Tradepayorder struct {
  52. Tradeid int64 `json:"tradeid" xorm:"'TRADEID'" binding:"required"` // 成交单号(101+Unix秒时间戳(10位)+2位(MarketServiceID)+xxxx)
  53. Tradedate string `json:"tradedate" xorm:"'TRADEDATE'"` // 交易日(yyyyMMdd)
  54. Marketid int32 `json:"marketid" xorm:"'MARKETID'"` // 市场ID
  55. Goodsid int32 `json:"goodsid" xorm:"'GOODSID'"` // 商品ID
  56. Buyorderid int64 `json:"buyorderid" xorm:"'BUYORDERID'"` // 买方委托单号
  57. Buyaccountid int64 `json:"buyaccountid" xorm:"'BUYACCOUNTID'"` // 买方账号ID[报价币种]
  58. Sellorderid int64 `json:"sellorderid" xorm:"'SELLORDERID'"` // 卖方委托单号
  59. Sellaccountid int64 `json:"sellaccountid" xorm:"'SELLACCOUNTID'"` // 卖方账号ID[报价币种]
  60. Tradeamount float64 `json:"tradeamount" xorm:"'TRADEAMOUNT'"` // 成交金额
  61. Tradecharge float64 `json:"tradecharge" xorm:"'TRADECHARGE'"` // 成交手续费(买方)
  62. Payflag int32 `json:"payflag" xorm:"'PAYFLAG'"` // 付款标识 - 1:未支付 2:已支付 3:已过期 4:已撤销 5:结算过期 6:预售终止
  63. Createtime time.Time `json:"createtime" xorm:"'CREATETIME'"` // 创建时间
  64. Paytime time.Time `json:"paytime" xorm:"'PAYTIME'"` // 付款时间
  65. Paylimitedtime time.Time `json:"paylimitedtime" xorm:"'PAYLIMITEDTIME'"` // 支付期限
  66. Offamount float64 `json:"offamount" xorm:"'OFFAMOUNT'"` // 优惠金额
  67. Tradeprice float64 `json:"tradeprice" xorm:"'TRADEPRICE'"` // 成交价格
  68. Tradeqty int64 `json:"tradeqty" xorm:"'TRADEQTY'"` // 成交数量
  69. Payamount float64 `json:"payamount" xorm:"'PAYAMOUNT'"` // 支付金额 = TradeAmount + TradeCharge - OffAmount
  70. }
  71. // TableName is TRADE_PAYORDER
  72. func (Tradepayorder) TableName() string {
  73. return "TRADE_PAYORDER"
  74. }
  75. // Coupontype 优惠券类型表
  76. type Coupontype struct {
  77. Coupontypeid int32 `json:"coupontypeid" xorm:"'COUPONTYPEID'" binding:"required"` // 优惠券类型ID - SEQ_COUPONTYPE
  78. Areauserid int64 `json:"areauserid" xorm:"'AREAUSERID'"` // 所属机构
  79. Couponname string `json:"couponname" xorm:"'COUPONNAME'"` // 优惠券名称
  80. Couponcategroy int32 `json:"couponcategroy" xorm:"'COUPONCATEGROY'"` // 种类 - 1:现金券 2:折扣券 3:折扣券(单张)
  81. Conditionvalue float64 `json:"conditionvalue" xorm:"'CONDITIONVALUE'"` // 条件阈值(可为0)
  82. Couponvalue float64 `json:"couponvalue" xorm:"'COUPONVALUE'"` // 面值[1:现金券 - 抵扣值 2:折扣券-折扣值]
  83. Limitedflag int32 `json:"limitedflag" xorm:"'LIMITEDFLAG'"` // 是否指定商品 - 0:不限 1:限制
  84. Limitedgoodsids string `json:"limitedgoodsids" xorm:"'LIMITEDGOODSIDS'"` // 指定商品IDs[逗号分隔,前后加逗号]
  85. Isgeneral int32 `json:"isgeneral" xorm:"'ISGENERAL'"` // 是否通用券 - 0:否 1:是
  86. Userscope string `json:"userscope" xorm:"'USERSCOPE'"` // 卖家范围(用户ID,逗号分隔,前后加逗号) [IsGeneral =0时使用]
  87. Qty int64 `json:"qty" xorm:"'QTY'"` // 数量
  88. Curqty int64 `json:"curqty" xorm:"'CURQTY'"` // 剩余数量
  89. Createtime time.Time `json:"createtime" xorm:"'CREATETIME'"` // 创建时间
  90. Creatorid int64 `json:"creatorid" xorm:"'CREATORID'"` // 创建人
  91. Modifierid int64 `json:"modifierid" xorm:"'MODIFIERID'"` // 修改人
  92. Modifytime time.Time `json:"modifytime" xorm:"'MODIFYTIME'"` // 修改时间
  93. Usedqty int64 `json:"usedqty" xorm:"'USEDQTY'"` // 使用量
  94. Isvalid int32 `json:"isvalid" xorm:"'ISVALID'"` // 是否有效 - 0:无效 1:有效
  95. Expiredqty int64 `json:"expiredqty" xorm:"'EXPIREDQTY'"` // 失效量
  96. }
  97. // TableName is COUPONTYPE
  98. func (Coupontype) TableName() string {
  99. return "COUPONTYPE"
  100. }
  101. // Couponposition 优惠券头寸表 - 导历史(期末为0的清除)
  102. type Couponposition struct {
  103. Accountid int64 `json:"accountid" xorm:"'ACCOUNTID'" binding:"required"` // 资金账户ID
  104. Coupontypeid int32 `json:"coupontypeid" xorm:"'COUPONTYPEID'" binding:"required"` // 优惠券类型ID
  105. Userid int64 `json:"userid" xorm:"'USERID'"` // 用户ID
  106. Oriqty int64 `json:"oriqty" xorm:"'ORIQTY'"` // 期初数量
  107. Orifreezeqty int64 `json:"orifreezeqty" xorm:"'ORIFREEZEQTY'"` // 期初冻结数量
  108. Curqty int64 `json:"curqty" xorm:"'CURQTY'"` // 期末数量
  109. Curfreezeqty int64 `json:"curfreezeqty" xorm:"'CURFREEZEQTY'"` // 期末冻结数量
  110. Todayincrease int64 `json:"todayincrease" xorm:"'TODAYINCREASE'"` // 今日增加
  111. Todaydecrease int64 `json:"todaydecrease" xorm:"'TODAYDECREASE'"` // 今日减少
  112. }
  113. // TableName is COUPONPOSITION
  114. func (Couponposition) TableName() string {
  115. return "COUPONPOSITION"
  116. }
  117. // Couponhold 优惠券持仓表 - 导历史(不清当前表) - 每一个数量一条记录
  118. type Couponhold struct {
  119. Couponholdid int64 `json:"couponholdid" xorm:"'COUPONHOLDID'" binding:"required"` // 优惠券持仓ID(229+Unix秒时间戳(10位)+xxxxxx)
  120. Giveapplyid int64 `json:"giveapplyid" xorm:"'GIVEAPPLYID'"` // 发放申请ID(SEQ_COUPONGIVEAPPLY)
  121. Accountid int64 `json:"accountid" xorm:"'ACCOUNTID'"` // 资金账户ID
  122. Coupontypeid int32 `json:"coupontypeid" xorm:"'COUPONTYPEID'"` // 优惠券类型ID - SEQ_COUPONTYPE
  123. Couponcategroy int32 `json:"couponcategroy" xorm:"'COUPONCATEGROY'"` // 种类 - 1:现金券 2:折扣券 3:折扣券(单个商品)
  124. Conditionvalue float64 `json:"conditionvalue" xorm:"'CONDITIONVALUE'"` // 条件阈值(可为0)
  125. Couponvalue float64 `json:"couponvalue" xorm:"'COUPONVALUE'"` // 面值[1:现金券 - 抵扣值 2:折扣券-折扣值]
  126. Limitedflag int32 `json:"limitedflag" xorm:"'LIMITEDFLAG'"` // 是否指定商品 - 0:不限 1:限制
  127. Limitedgoodsids string `json:"limitedgoodsids" xorm:"'LIMITEDGOODSIDS'"` // 指定商品IDs[逗号分隔]
  128. Isgeneral int32 `json:"isgeneral" xorm:"'ISGENERAL'"` // 是否通用券 - 0:否 1:是
  129. Userscope string `json:"userscope" xorm:"'USERSCOPE'"` // 卖家范围(用户ID,逗号分隔) [IsGeneral =0时使用]
  130. Userid int64 `json:"userid" xorm:"'USERID'"` // 用户ID
  131. Qty int64 `json:"qty" xorm:"'QTY'"` // 数量(按1平铺)
  132. Startdate time.Time `json:"startdate" xorm:"'STARTDATE'"` // 开始日期
  133. Holdstatus int32 `json:"holdstatus" xorm:"'HOLDSTATUS'"` // 持仓状态 - 1:未生效 2:已生效 3:已使用 4:已过期
  134. Enddate time.Time `json:"enddate" xorm:"'ENDDATE'"` // 结束日期
  135. Createtime time.Time `json:"createtime" xorm:"'CREATETIME'"` // 创建时间
  136. }
  137. // TableName is COUPONHOLD
  138. func (Couponhold) TableName() string {
  139. return "COUPONHOLD"
  140. }
  141. // Tradeordercoupon 交易委托优惠券表
  142. type Tradeordercoupon struct {
  143. Orderid string `json:"orderid" xorm:"'ORDERIDSTR'" binding:"required"` // 委托单号(100+Unix秒时间戳(10位)+2位(MarketServiceID)+xxxx)
  144. Coupontypeid string `json:"coupontypeid" xorm:"'COUPONTYPEIDSTR'" binding:"required"` // 优惠券类型ID(买方)
  145. Accountid int64 `json:"accountid" xorm:"'ACCOUNTID'"` // 资金账户ID(买方)
  146. Usedqty int64 `json:"usedqty" xorm:"'USEDQTY'"` // 使用数量
  147. Couponcategroy int32 `json:"couponcategroy" xorm:"'COUPONCATEGROY'"` // 种类 - 1:现金券 2:折扣券
  148. Conditionvalue float64 `json:"conditionvalue" xorm:"'CONDITIONVALUE'"` // 条件阈值(可为0)
  149. Couponvalue float64 `json:"couponvalue" xorm:"'COUPONVALUE'"` // 面值[1:现金券 - 抵扣值 2:折扣券-折扣值(0-100)]
  150. Sellaccountid int64 `json:"sellaccountid" xorm:"'SELLACCOUNTID'"` // 资金账户ID(卖方)
  151. Marketid int32 `json:"marketid" xorm:"'MARKETID'"` // 市场ID
  152. Goodsid int32 `json:"goodsid" xorm:"'GOODSID'"` // 商品ID
  153. Tradeid string `json:"tradeid" xorm:"'TRADEIDSTR'"` // 成交单号(101+Unix秒时间戳(10位)+2位(MarketServiceID)+xxxx)
  154. Tradeamount float64 `json:"tradeamount" xorm:"'TRADEAMOUNT'"` // 成交金额
  155. Offamount float64 `json:"offamount" xorm:"'OFFAMOUNT'"` // 优惠金额
  156. Handlestatus int32 `json:"handlestatus" xorm:"'HANDLESTATUS'"` // 处理状态
  157. Createtime time.Time `json:"createtime" xorm:"'CREATETIME'"` // 创建时间
  158. }
  159. // TableName is TRADE_ORDERCOUPON
  160. func (Tradeordercoupon) TableName() string {
  161. return "TRADE_ORDERCOUPON"
  162. }
  163. // HsbyTopGoods 热卖商品(二级市场挂牌点选)
  164. type HsbyTopGoods struct {
  165. Goodsid int64 `json:"goodsid" xorm:"'GOODSID'" binding:"required"` // 商品ID(自增ID SEQ_GOODS)
  166. Goodscode string `json:"goodscode" xorm:"'GOODSCODE'" binding:"required"` // 商品代码(内部)
  167. Goodsname string `json:"goodsname" xorm:"'GOODSNAME'" binding:"required"` // 商品名称
  168. Decimalplace int64 `json:"decimalplace" xorm:"'DECIMALPLACE'"` // 报价小数位
  169. Marketid int64 `json:"marketid" xorm:"'MARKETID'" binding:"required"` // 所属市场ID
  170. Quoteminunit int64 `json:"quoteminunit" xorm:"'QUOTEMINUNIT'"` // 行情最小变动单位 [整数,报价小数位一起使用]
  171. Agreeunit float64 `json:"agreeunit" xorm:"'AGREEUNIT'"` // 合约单位
  172. Hotindex int32 `json:"hotindex" xorm:"'HOTINDEX'"` // 景点热度
  173. Videourls string `json:"videourls" xorm:"'VIDEOURLS'"` // 介绍视频[多张用逗号分隔]
  174. Picurls string `json:"picurls" xorm:"'PICURLS'"` // 介绍图片[多张用逗号分隔]
  175. Currency string `json:"currency" xorm:"'CURRENCY'"` // 货币
  176. Currencysign string `json:"currencysign" xorm:"'CURRENCYSIGN'"` // 货币符号
  177. Trademode int32 `json:"trademode" xorm:"'TRADEMODE'" binding:"required"` // 交易模式 - 10:做市 13:竞价 15:通道交易 16:挂牌点选 17:仓单贸易 18:期权 19:竞拍-降价式 20:竞拍-竞价式 21:竞拍-大宗式 22:受托竞价
  178. Last float64 `json:"last" xorm:"-"` // 现价
  179. }
  180. // GetHsbyTopGoodses 获取热门商品列表
  181. // 参数 marketIDs string 所属市场ID列表, 格式 1,2,3
  182. // 参数 descProvinceID int 目标省ID
  183. // 参数 descCityID int 目标城市ID
  184. // 返回 []TopGoods 热门商品列表
  185. // 返回 error error
  186. func GetHsbyTopGoodses(marketIDs string, descProvinceID, descCityID int) ([]HsbyTopGoods, error) {
  187. // 热门商品为二级市场(挂牌点选)下的商品信息
  188. engine := db.GetEngine()
  189. topGoodses := make([]HsbyTopGoods, 0)
  190. // 获取挂牌商品信息,以及扩展表信息
  191. // 与商城不一样的是,挂牌点选以商品表作为主表,同一商品可有多个委托单
  192. session := engine.Table("GOODS").
  193. Select(`GOODS.*,
  194. HSBY_GOODSEX.HOTINDEX, HSBY_GOODSEX.VIDEOURLS, HSBY_GOODSEX.PICURLS,
  195. ENUMDICITEM.ENUMDICNAME CURRENCY, ENUMDICITEM.PARAM2 CURRENCYSIGN,
  196. MARKET.TRADEMODE`).
  197. Join("LEFT", "HSBY_GOODSEX", "HSBY_GOODSEX.GOODSID = GOODS.GOODSID").
  198. Join("LEFT", "ENUMDICITEM", "ENUMDICITEM.ENUMITEMNAME = GOODS.CURRENCYID and ENUMDICITEM.ENUMDICCODE = 'currency'").
  199. Join("LEFT", "MARKET", "MARKET.MARKETID = GOODS.MARKETID").
  200. Where(fmt.Sprintf("GOODS.GOODSSTATUS = 3 and GOODS.MARKETID in (%s)", marketIDs)) // 二级市场只获取 3:上市 状态的商品
  201. if descProvinceID > 0 {
  202. session = session.And("HSBY_GOODSEX.DESCPROVINCEID = ?", descProvinceID)
  203. }
  204. if descCityID > 0 {
  205. session = session.And("HSBY_GOODSEX.DESCCITYID = ?", descCityID)
  206. }
  207. if err := session.Find(&topGoodses); err != nil {
  208. return nil, err
  209. }
  210. if len(topGoodses) == 0 {
  211. // 无数据
  212. return topGoodses, nil
  213. }
  214. // 获取商品ID列表
  215. goodsCodes := ""
  216. for _, v := range topGoodses {
  217. if len(goodsCodes) == 0 {
  218. goodsCodes = v.Goodscode
  219. } else {
  220. goodsCodes += "," + v.Goodscode
  221. }
  222. }
  223. // 获取商品现价
  224. quoteDays, err := GetQuoteDays(goodsCodes)
  225. if err != nil {
  226. return nil, err
  227. }
  228. for i, g := range topGoodses {
  229. topGoods := &topGoodses[i]
  230. // FIXME: - 这里应该使用 Duck Typing,后期再处理
  231. // 计算最小变动单位
  232. // lotSize := float64(topGoods.Quoteminunit) * math.Pow(0.1, float64(topGoods.Decimalplace))
  233. // topGoods.LotSize, _ = strconv.ParseFloat(utils.FormatFloat(lotSize, int(topGoods.Decimalplace)), 64)
  234. for _, q := range quoteDays {
  235. if g.Goodscode == q.Goodscode {
  236. if q.Last != 0 {
  237. topGoods.Last = utils.IntToFloat64(int(q.Last), int(g.Decimalplace))
  238. }
  239. // 没有现价则尝试用昨结
  240. if topGoods.Last == 0 && q.Presettle != 0 {
  241. topGoods.Last = utils.IntToFloat64(int(q.Presettle), int(g.Decimalplace))
  242. }
  243. continue
  244. }
  245. }
  246. }
  247. return topGoodses, nil
  248. }
  249. // HsbyListingGoodsDetail 二级市场(挂牌点选)商品信息详情
  250. type HsbyListingGoodsDetail struct {
  251. Goodsid int64 `json:"goodsid" xorm:"'GOODSID'" binding:"required"` // 商品ID(自增ID SEQ_GOODS)
  252. Goodscode string `json:"goodscode" xorm:"'GOODSCODE'" binding:"required"` // 商品代码(内部)
  253. Goodsname string `json:"goodsname" xorm:"'GOODSNAME'" binding:"required"` // 商品名称
  254. Decimalplace int64 `json:"decimalplace" xorm:"'DECIMALPLACE'"` // 报价小数位
  255. Marketid int64 `json:"marketid" xorm:"'MARKETID'" binding:"required"` // 所属市场ID
  256. Quoteminunit int64 `json:"quoteminunit" xorm:"'QUOTEMINUNIT'"` // 行情最小变动单位 [整数,报价小数位一起使用]
  257. Agreeunit float64 `json:"agreeunit" xorm:"'AGREEUNIT'"` // 合约单位
  258. Hotindex int32 `json:"hotindex" xorm:"'HOTINDEX'"` // 景点热度
  259. Videourls string `json:"videourls" xorm:"'VIDEOURLS'"` // 介绍视频[多张用逗号分隔]
  260. Picurls string `json:"picurls" xorm:"'PICURLS'"` // 介绍图片[多张用逗号分隔]
  261. Descprovinceid int64 `json:"descprovinceid" xorm:"'DESCPROVINCEID'"` // 目的地(省)ID
  262. Desccityid int64 `json:"desccityid" xorm:"'DESCCITYID'"` // 目的地(市)ID
  263. Goodsdesc string `json:"goodsdesc" xorm:"'GOODSDESC'"` // 商品详情
  264. Goodsprice float64 `json:"goodsprice" xorm:"'GOODSPRICE'"` // 商品价格
  265. Currency string `json:"currency" xorm:"'CURRENCY'"` // 货币
  266. Currencysign string `json:"currencysign" xorm:"'CURRENCYSIGN'"` // 货币符号
  267. Vendorname string `json:"vendorname" xorm:"'VENDORNAME'"` // 供应商名称
  268. Vendorphone string `json:"vendorphone" xorm:"'VENDORPHONE'"` // 供应商客服电话
  269. Vendorattr string `json:"vendorattr" xorm:"'VENDORATTR'"` // 供应商附件(多张,逗号分隔)
  270. Trademode int32 `json:"trademode" xorm:"'TRADEMODE'" binding:"required"` // 交易模式 - 10:做市 13:竞价 15:通道交易 16:挂牌点选 17:仓单贸易 18:期权 19:竞拍-降价式 20:竞拍-竞价式 21:竞拍-大宗式 22:受托竞价
  271. Last float64 `json:"last" xorm:"-"` // 现价
  272. Limitup float64 `json:"limitup" xorm:"-"` // 涨停价
  273. Limitdown float64 `json:"limitdown" xorm:"-"` // 跌停价
  274. StepValue float64 `json:"stepvalue" xorm:"-"` // 价格最小变动单位
  275. LotSize int `json:"lotsize" xorm:"-"` // 手数最小变动单位
  276. Buymaxqty int `json:"buymaxqty" xorm:"'-'"` // 购买上限 [71] - 0为不限
  277. }
  278. // GetHsbyListingGoodsDetail 获取二级市场(挂牌点选)商品信息详情
  279. // 参数 goodsID int 目标商品ID
  280. // 返回 *HsbyListingGoodsDetail 二级市场(挂牌点选)商品信息详情,查询无结果返回nil
  281. // 返回 error error
  282. func GetHsbyListingGoodsDetail(goodsID, accountID int) (*HsbyListingGoodsDetail, error) {
  283. engine := db.GetEngine()
  284. details := make([]HsbyListingGoodsDetail, 0)
  285. // 获取挂牌商品信息,以及扩展表信息
  286. // FIXME: - 这里使用Get方法,会造成SQL语句的嵌套出错,后期再研究
  287. session := engine.Table("GOODS").
  288. Select(`GOODS.GOODSID, GOODS.GOODSCODE, GOODS.GOODSNAME, GOODS.DECIMALPLACE, GOODS.MARKETID, GOODS.QUOTEMINUNIT, GOODS.AGREEUNIT,
  289. HSBY_GOODSEX.HOTINDEX, HSBY_GOODSEX.VIDEOURLS, HSBY_GOODSEX.PICURLS, HSBY_GOODSEX.DESCPROVINCEID, HSBY_GOODSEX.Desccityid, HSBY_GOODSEX.Goodsdesc, HSBY_GOODSEX.GOODSPRICE,
  290. ENUMDICITEM.ENUMDICNAME CURRENCY, ENUMDICITEM.PARAM2 CURRENCYSIGN,
  291. HSBY_SUPPLIERINFO.VENDORNAME, HSBY_SUPPLIERINFO.VENDORPHONE, HSBY_SUPPLIERINFO.VENDORATTR,
  292. MARKET.TRADEMODE`).
  293. Join("LEFT", "HSBY_GOODSEX", "HSBY_GOODSEX.GOODSID = GOODS.GOODSID").
  294. Join("LEFT", "ENUMDICITEM", "ENUMDICITEM.ENUMITEMNAME = GOODS.CURRENCYID and ENUMDICITEM.ENUMDICCODE = 'currency'").
  295. Join("LEFT", "HSBY_SUPPLIERINFO", "HSBY_SUPPLIERINFO.VENDORID = HSBY_GOODSEX.VENDORID").
  296. Join("LEFT", "MARKET", "MARKET.MARKETID = GOODS.MARKETID").
  297. Where("GOODS.GOODSID = ?", goodsID)
  298. if err := session.Find(&details); err != nil {
  299. return nil, err
  300. }
  301. // 无目标商品
  302. if len(details) == 0 {
  303. return nil, nil
  304. }
  305. hsbyListingGoodsDetail := details[0]
  306. // 获取商品现价和涨跌停价
  307. quoteDays, err := GetQuoteDays(hsbyListingGoodsDetail.Goodscode)
  308. if err != nil {
  309. return nil, err
  310. }
  311. if len(quoteDays) > 0 {
  312. if quoteDays[0].Last != 0 {
  313. hsbyListingGoodsDetail.Last = utils.IntToFloat64(int(quoteDays[0].Last), int(hsbyListingGoodsDetail.Decimalplace))
  314. }
  315. // 没有现价则尝试用昨结
  316. if hsbyListingGoodsDetail.Last == 0 && quoteDays[0].Presettle != 0 {
  317. hsbyListingGoodsDetail.Last = utils.IntToFloat64(int(quoteDays[0].Presettle), int(hsbyListingGoodsDetail.Decimalplace))
  318. }
  319. if quoteDays[0].Limitup != 0 {
  320. hsbyListingGoodsDetail.Limitup = utils.IntToFloat64(int(quoteDays[0].Limitup), int(hsbyListingGoodsDetail.Decimalplace))
  321. }
  322. if quoteDays[0].Limitdown != 0 {
  323. hsbyListingGoodsDetail.Limitdown = utils.IntToFloat64(int(quoteDays[0].Limitdown), int(hsbyListingGoodsDetail.Decimalplace))
  324. }
  325. }
  326. // 计算价格最小变动单位
  327. stepValue := float64(hsbyListingGoodsDetail.Quoteminunit) * math.Pow(0.1, float64(hsbyListingGoodsDetail.Decimalplace))
  328. hsbyListingGoodsDetail.StepValue, _ = strconv.ParseFloat(utils.FormatFloat(stepValue, int(hsbyListingGoodsDetail.Decimalplace)), 64)
  329. // 计算手数最小变动单位,改在上层进行设置,这里暂时设置成1
  330. hsbyListingGoodsDetail.LotSize = 1
  331. // 获取购买上限
  332. if accountID != 0 {
  333. buyMaxQty, err := GetCPTradeBuyLimit(goodsID, accountID)
  334. if err != nil {
  335. return nil, err
  336. }
  337. hsbyListingGoodsDetail.Buymaxqty = buyMaxQty
  338. }
  339. return &hsbyListingGoodsDetail, nil
  340. }
  341. // HsbyGoodsOrderDetail 二级市场挂牌商品当前可摘委托单信息
  342. type HsbyGoodsOrderDetail struct {
  343. Orderid string `json:"orderid" xorm:"'ORDERID'" binding:"required"` // 委托单号(100+Unix秒时间戳(10位)+2位(MarketServiceID)+xxxx)
  344. Buyorsell int32 `json:"buyorsell" xorm:"'BUYORSELL'" binding:"required"` // 买卖 - 0:买 1:卖
  345. Ordertime time.Time `json:"ordertime" xorm:"'ORDERTIME'" binding:"required"` // 委托时间
  346. Orderprice float64 `json:"orderprice" xorm:"'ORDERPRICE'"` // 委托价格
  347. Enableqty int64 `json:"enableqty" xorm:"ENABLEQTY"` // 可用数量
  348. Customername string `json:"customername" xorm:"'CUSTOMERNAME'"` // 客户名称(企业名称),已脱敏
  349. Currencysign string `json:"currencysign" xorm:"-"` // 货币符号
  350. Goodunit string `json:"goodunit" xorm:"-"` // 报价单位
  351. }
  352. // GetHsbyGoodsOrderDetails 获取二级市场(挂牌点选)商品对应的挂牌委托单信息
  353. // 输入 goodsID int 商品ID
  354. // 输入 buyOrSell int 挂牌委托单方向(对手单方向),0:买 1:卖
  355. // 输入 price float64 参考价格。买方向委托单则价格小于等于(站在摘牌人的角度);卖方向委托单则价格大于等于
  356. // 输出 []HsbyGoodsOrderDetail 商品对应的挂牌委托单信息
  357. // 输出 error error
  358. func GetHsbyGoodsOrderDetails(goodsID, buyOrSell int, price float64, accountIDs string) ([]HsbyGoodsOrderDetail, error) {
  359. engine := db.GetEngine()
  360. // 获取与目标商品相关的挂牌委托单信息(ListingSelectType = 1 or 3; OrderStatus =3 or 7)
  361. hsbyGoodsOrderDetails := make([]HsbyGoodsOrderDetail, 0)
  362. session := engine.Table("TRADE_ORDERDETAIL").
  363. 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,
  364. substr(USERINFO.CUSTOMERNAME,0,1)||'****' as CUSTOMERNAME`).
  365. Join("LEFT", "TAACCOUNT", "TAACCOUNT.ACCOUNTID = TRADE_ORDERDETAIL.ACCOUNTID").
  366. Join("LEFT", "USERINFO", "USERINFO.USERID = TAACCOUNT.RELATEDUSERID").
  367. Where("(TRADE_ORDERDETAIL.LISTINGSELECTTYPE = 1 or TRADE_ORDERDETAIL.LISTINGSELECTTYPE = 3) and (TRADE_ORDERDETAIL.ORDERSTATUS = 3 or TRADE_ORDERDETAIL.ORDERSTATUS = 7)").
  368. And("TRADE_ORDERDETAIL.GOODSID = ?", goodsID).
  369. And("TRADE_ORDERDETAIL.BUYORSELL = ?", buyOrSell)
  370. if len(accountIDs) > 0 {
  371. session = session.And(fmt.Sprintf("TRADE_ORDERDETAIL.ACCOUNTID not in (%s)", accountIDs))
  372. }
  373. if price > 0 {
  374. if buyOrSell == 0 {
  375. // 对手单买方向委托单则价格大于等于(站在摘牌人的角度,摘牌方面是卖,我的闲置下单)
  376. session = session.And("TRADE_ORDERDETAIL.ORDERPRICE >= ?", price)
  377. } else {
  378. // 对手单卖方向委托单则价格小于等于(站在摘牌人的角度,摘牌方面是买,热门商品下单)
  379. session = session.And("TRADE_ORDERDETAIL.ORDERPRICE <= ?", price)
  380. }
  381. }
  382. if err := session.Find(&hsbyGoodsOrderDetails); err != nil {
  383. return nil, err
  384. }
  385. // 获取商品货币符号和报价单位
  386. goods, err := GetGoods(goodsID)
  387. if err != nil {
  388. return nil, err
  389. }
  390. currencyEnums, err := GetEnumDicItem("currency", int(goods.Currencyid))
  391. if err != nil {
  392. return nil, err
  393. }
  394. currencysign := ""
  395. if len(currencyEnums) > 0 {
  396. currencysign = currencyEnums[0].Param2
  397. }
  398. goodsUnitEnums, err := GetEnumDicItem("goodsunit", int(goods.Goodunitid))
  399. if err != nil {
  400. return nil, err
  401. }
  402. goodsUnit := ""
  403. if len(goodsUnitEnums) > 0 {
  404. goodsUnit = goodsUnitEnums[0].Enumdicname
  405. }
  406. for i := range hsbyGoodsOrderDetails {
  407. orderDetail := &hsbyGoodsOrderDetails[i]
  408. // 设置货币符号和报价单位
  409. orderDetail.Currencysign = currencysign
  410. orderDetail.Goodunit = goodsUnit
  411. }
  412. return hsbyGoodsOrderDetails, nil
  413. }
  414. // HybsMyBuyOrderDetail 我的订单(一二级市场的买方向委托单)
  415. type HybsMyBuyOrderDetail struct {
  416. Orderid string `json:"orderid" xorm:"'ORDERID'" binding:"required"` // 委托单号(100+Unix秒时间戳(10位)+2位(MarketServiceID)+xxxx)
  417. Marketid int32 `json:"marketid" xorm:"'MARKETID'" binding:"required"` // 市场ID
  418. Goodsid int32 `json:"goodsid" xorm:"'GOODSID'" binding:"required"` // 商品ID
  419. Accountid int64 `json:"accountid" xorm:"'ACCOUNTID'" binding:"required"` // 账户ID[报价币种]
  420. Buyorsell int32 `json:"buyorsell" xorm:"'BUYORSELL'" binding:"required"` // 买卖 - 0:买 1:卖
  421. Orderprice float64 `json:"orderprice" xorm:"'ORDERPRICE'"` // 委托价格
  422. Orderqty int64 `json:"orderqty" xorm:"'ORDERQTY'" binding:"required"` // 委托数量
  423. Tradeqty int64 `json:"tradeqty" xorm:"'TRADEQTY'"` // 成交数量
  424. Cancelqty int64 `json:"cancelqty" xorm:"'CANCELQTY'"` // 撤单数量
  425. Ordertime time.Time `json:"ordertime" xorm:"'ORDERTIME'" binding:"required"` // 委托时间
  426. Listingselecttype int32 `json:"listingselecttype" xorm:"'LISTINGSELECTTYPE'"` // 挂牌点选类型 - 1:挂牌 2:摘牌 3:先摘后挂
  427. Orderstatus int32 `json:"orderstatus" xorm:"'ORDERSTATUS'"` // 委托状态 - 1: 委托请求 2:待冻结 3:委托成功 4: 委托失败 5:配对成功 6: 已撤销 7:部分成交 8:已成交 9:部成部撤 10:成交失败 11:已拒绝 12:经过摘牌(先摘后挂专用-先摘后挂已摘过) 13:冻结成功(通道交易专用) 14:通道已撤 15:通道部成部撤 16:成交失败违约(荷兰式竞拍专用)
  428. Goodscode string `json:"goodscode" xorm:"'GOODSCODE'" binding:"required"` // 商品代码(内部)
  429. Goodsname string `json:"goodsname" xorm:"'GOODSNAME'" binding:"required"` // 商品名称
  430. Decimalplace int64 `json:"decimalplace" xorm:"'DECIMALPLACE'"` // 报价小数位
  431. Agreeunit float64 `json:"agreeunit" xorm:"'AGREEUNIT'"` // 合约单位
  432. Picurls1 string `json:"picurls1" xorm:"'PICURLS1'"` // 预售商品介绍图片[多张用逗号分隔]
  433. Picurls2 string `json:"picurls2" xorm:"'PICURLS2'"` // 挂牌商品介绍图片[多张用逗号分隔]
  434. Trademode uint32 `json:"trademode" xorm:"'TRADEMODE'" binding:"required"` // 交易模式 - 10:做市 13:竞价 15:通道交易 16:挂牌点选 17:仓单贸易 18:期权 19:竞拍-降价式 20:竞拍-竞价式 21:竞拍-大宗式 22:受托竞价
  435. Currencysign string `json:"currencysign" xorm:"'CURRENCYSIGN'"` // 货币符号
  436. Vendorname1 string `json:"vendorname1" xorm:"'VENDORNAME1'"` // 预售商品供应商名称
  437. Vendorname2 string `json:"vendorname2" xorm:"'VENDORNAME2'"` // 挂牌商品供应商名称
  438. MyBuyStatus int `json:"mybuystatus" xorm:"-"` // "我的订单"显示状态- 1:抢购中 2:求购中 3:已完成 4:已撤消 5:委托失败
  439. Orderamount float64 `json:"orderamount" xorm:"-"` // 委托金额
  440. }
  441. // GetHsbyBuyMyOrderDetails 获取“我的订单”数据(包括一二级市场)
  442. // 输入 accountIDs string 资金账户列表
  443. // 输入 myBuyStatus int "我的订单"状态, 1:抢购中 2:求购中 3:已完成
  444. // 输出 []HybsMyBuyOrderDetail “我的订单”数据
  445. // 输出 error error
  446. func GetHsbyBuyMyOrderDetails(accountIDs string, myBuyStatus int) ([]HybsMyBuyOrderDetail, error) {
  447. // 获取市场信息
  448. markets, err := GetMarkets()
  449. if err != nil {
  450. return nil, err
  451. }
  452. engine := db.GetEngine()
  453. // 委托状态
  454. orderStatus := "0" // 单据状态,为0的时候查询全部
  455. marketIDs := "" // 我的订单包括一二级市场的单据
  456. // FIXME: myBuyStatus 目前终端不传
  457. switch myBuyStatus {
  458. case 1: // 抢购中 (一级市场)
  459. // 获取市场ID
  460. for _, v := range markets {
  461. if v.Trademode == 71 { // 预售挂牌
  462. if len(marketIDs) == 0 {
  463. marketIDs = strconv.Itoa(int(v.Marketid))
  464. } else {
  465. marketIDs += "," + strconv.Itoa(int(v.Marketid))
  466. }
  467. }
  468. }
  469. orderStatus = "3,7"
  470. case 2: // 求购中(二级市场)
  471. // 获取市场ID
  472. for _, v := range markets {
  473. if v.Trademode == 16 { // 挂牌点选
  474. if len(marketIDs) == 0 {
  475. marketIDs = strconv.Itoa(int(v.Marketid))
  476. } else {
  477. marketIDs += "," + strconv.Itoa(int(v.Marketid))
  478. }
  479. }
  480. }
  481. orderStatus = "3,7"
  482. case 3: // 已完成
  483. orderStatus = "8,9"
  484. }
  485. // 默认取 TradeMode = 16 or 71 的市场
  486. if len(marketIDs) == 0 {
  487. for _, v := range markets {
  488. if v.Trademode == 16 || v.Trademode == 71 || v.Trademode == 70 {
  489. if len(marketIDs) == 0 {
  490. marketIDs = strconv.Itoa(int(v.Marketid))
  491. } else {
  492. marketIDs += "," + strconv.Itoa(int(v.Marketid))
  493. }
  494. }
  495. }
  496. }
  497. hybsMyBuyOrderDetails := make([]HybsMyBuyOrderDetail, 0)
  498. // "我的订单"都是买委托
  499. session := engine.Table("TRADE_ORDERDETAIL").
  500. Select(`to_char(TRADE_ORDERDETAIL.ORDERID) ORDERID, TRADE_ORDERDETAIL.*,
  501. GOODS.GOODSCODE, GOODS.GOODSNAME, GOODS.DECIMALPLACE, GOODS.AGREEUNIT,
  502. HG1.PICURLS PICURLS1,
  503. HG2.PICURLS PICURLS2,
  504. MARKET.TRADEMODE,
  505. ENUMDICITEM.PARAM2 CURRENCYSIGN,
  506. HS1.VENDORNAME VENDORNAME1,
  507. HS2.VENDORNAME VENDORNAME2`).
  508. Join("LEFT", "GOODS", "GOODS.GOODSID = TRADE_ORDERDETAIL.GOODSID").
  509. Join("LEFT", "CPTRADE_PRESALEGOODSEX", "CPTRADE_PRESALEGOODSEX.GOODSID = TRADE_ORDERDETAIL.GOODSID").
  510. Join("LEFT", "HSBY_GOODSEX HG1", "HG1.GOODSID = CPTRADE_PRESALEGOODSEX.RELATEDGOODSID").
  511. Join("LEFT", "HSBY_GOODSEX HG2", "HG2.GOODSID = GOODS.GOODSID").
  512. Join("LEFT", "ENUMDICITEM", "GOODS.CURRENCYID = ENUMDICITEM.ENUMITEMNAME and ENUMDICITEM.ENUMDICCODE = 'currency'").
  513. Join("LEFT", "MARKET", "MARKET.MARKETID = TRADE_ORDERDETAIL.MARKETID").
  514. Join("LEFT", "HSBY_SUPPLIERINFO HS1", "HS1.VENDORID = HG1.VENDORID").
  515. Join("LEFT", "HSBY_SUPPLIERINFO HS2", "HS2.VENDORID = HG2.VENDORID").
  516. Where(fmt.Sprintf("TRADE_ORDERDETAIL.BUYORSELL = 0 and TRADE_ORDERDETAIL.ACCOUNTID in (%s)", accountIDs)).
  517. And(fmt.Sprintf("TRADE_ORDERDETAIL.MARKETID in (%s)", marketIDs))
  518. // 是否过滤状态(抢购中、求购中、已完成)
  519. if orderStatus != "0" {
  520. session = session.And(fmt.Sprintf("TRADE_ORDERDETAIL.ORDERSTATUS in (%s)", orderStatus))
  521. }
  522. if err := session.Find(&hybsMyBuyOrderDetails); err != nil {
  523. return nil, err
  524. }
  525. // 设置“我的订单”显示状态
  526. for i := range hybsMyBuyOrderDetails {
  527. detail := &hybsMyBuyOrderDetails[i]
  528. // 委托金额 = 委托价格 * 委托数量 * 合约单位
  529. detail.Orderamount = detail.Orderprice * float64(detail.Orderqty) * float64(detail.Agreeunit)
  530. if detail.Trademode == 71 && (detail.Orderstatus == 3 || detail.Orderstatus == 7) {
  531. // 抢购中
  532. detail.MyBuyStatus = 1
  533. } else if detail.Trademode == 16 && (detail.Orderstatus == 3 || detail.Orderstatus == 7) {
  534. // 求购中
  535. detail.MyBuyStatus = 2
  536. } else if detail.Orderstatus == 8 || detail.Orderstatus == 9 {
  537. // 已完成
  538. detail.MyBuyStatus = 3
  539. } else if detail.Orderstatus == 6 || detail.Orderstatus == 22 {
  540. // 已撤销
  541. detail.MyBuyStatus = 4
  542. } else if detail.Orderstatus == 4 {
  543. // 委托失败
  544. detail.MyBuyStatus = 5
  545. }
  546. }
  547. return hybsMyBuyOrderDetails, nil
  548. }
  549. // HsbyMyGoods 我的商品(买方向持仓)
  550. type HsbyMyGoods struct {
  551. Accountid int64 `json:"accountid" xorm:"'ACCOUNTID'" binding:"required"` // 账号Id
  552. Goodsid int32 `json:"goodsid" xorm:"'GOODSID'" binding:"required"` // 商品Id
  553. Buycurpositionqty int64 `json:"buycurpositionqty" xorm:"'BUYCURPOSITIONQTY'"` // 买当前持仓总数量
  554. Buycurholderamount float64 `json:"buycurholderamount" xorm:"'BUYCURHOLDERAMOUNT'"` // 买当前持仓总金额[商品币种]
  555. EnableQty int64 `json:"enableqty" xorm:"'ENABLEQTY'"` // 可用数量
  556. Goodscode string `json:"goodscode" xorm:"'GOODSCODE'" binding:"required"` // 商品代码(内部)
  557. Goodsname string `json:"goodsname" xorm:"'GOODSNAME'" binding:"required"` // 商品名称
  558. Decimalplace int64 `json:"decimalplace" xorm:"'DECIMALPLACE'"` // 报价小数位
  559. Agreeunit float64 `json:"agreeunit" xorm:"'AGREEUNIT'"` // 合约单位
  560. Goodsstatus int64 `json:"goodsstatus" xorm:"'GOODSSTATUS'"` // 商品状态- 1:待审核 2:未上市 3:上市 4:已注销 5:审核拒绝 6:退市 7:待退市
  561. Marketid int64 `json:"marketid" xorm:"'MARKETID'" binding:"required"` // 所属市场ID
  562. Picurls string `json:"picurls" xorm:"'PICURLS'"` // 介绍图片[多张用逗号分隔]
  563. Goodsprice float64 `json:"goodsprice" xorm:"'GOODSPRICE'"` // 商品价格
  564. Currencysign string `json:"currencysign" xorm:"'CURRENCYSIGN'"` // 货币符号
  565. Trademode int32 `json:"trademode" xorm:"'TRADEMODE'" binding:"required"` // 交易模式 - 10:做市 13:竞价 15:通道交易 16:挂牌点选 17:仓单贸易 18:期权 19:竞拍-降价式 20:竞拍-竞价式 21:竞拍-大宗式 22:受托竞价
  566. Buyaverageprice float64 `json:"buyaverageprice" xorm:"-"` // 持仓均价
  567. }
  568. // GetHsbyMyGoods 获取“我的商品”信息
  569. // 输入 accountIDs string 资金账户列表,格式 1,2,3
  570. // 输出 []HsbyMyGoods “我的商品”信息
  571. // 输入 error error
  572. func GetHsbyMyGoods(accountIDs string) ([]HsbyMyGoods, error) {
  573. engine := db.GetEngine()
  574. hsbyMyGoodses := make([]HsbyMyGoods, 0)
  575. // 此定制版本,只查询出当前手数(期末)大于0的数据 (TRADEPOSITION.BUYCURPOSITIONQTY > 0)
  576. if err := engine.Table("TRADEPOSITION TP").
  577. Select(`TP.*, (TP.BUYCURPOSITIONQTY - TP.BUYFROZENQTY - TP.BUYOTHERFROZENQTY) ENABLEQTY,
  578. G.GOODSCODE, G.GOODSNAME, G.DECIMALPLACE, G.AGREEUNIT, G.GOODSSTATUS, G.MARKETID,
  579. GX.PICURLS, GX.GOODSPRICE,
  580. E.PARAM2 CURRENCYSIGN,
  581. M.TRADEMODE`).
  582. Join("LEFT", "GOODS G", "G.GOODSID = TP.GOODSID").
  583. Join("INNER", "HSBY_GOODSEX GX", "GX.GOODSID = G.GOODSID").
  584. Join("LEFT", "ENUMDICITEM E", "G.CURRENCYID = E.ENUMITEMNAME and E.ENUMDICCODE = 'currency'").
  585. Join("LEFT", "MARKET M", "M.MARKETID = G.MARKETID").
  586. Where(fmt.Sprintf("G.GOODSSTATUS = 3 and TP.BUYCURPOSITIONQTY > 0 and TP.ACCOUNTID in (%s)", accountIDs)).Find(&hsbyMyGoodses); err != nil {
  587. return nil, err
  588. }
  589. for i := range hsbyMyGoodses {
  590. myGoods := &hsbyMyGoodses[i]
  591. // 持仓均价
  592. averagePrice := myGoods.Buycurholderamount / float64(myGoods.Buycurpositionqty) / myGoods.Agreeunit
  593. myGoods.Buyaverageprice, _ = strconv.ParseFloat(utils.FormatFloat(averagePrice, int(myGoods.Decimalplace)), 64)
  594. }
  595. return hsbyMyGoodses, nil
  596. }
  597. // HsbyPreGoods 新品上市商品(一级市场产能预售)
  598. type HsbyPreGoods struct {
  599. Goodsid int64 `json:"goodsid" xorm:"'GOODSID'" binding:"required"` // 商品ID(自增ID SEQ_GOODS)
  600. Goodscode string `json:"goodscode" xorm:"'GOODSCODE'" binding:"required"` // 商品代码(内部)
  601. Goodsname string `json:"goodsname" xorm:"'GOODSNAME'" binding:"required"` // 商品名称
  602. Decimalplace int64 `json:"decimalplace" xorm:"'DECIMALPLACE'"` // 报价小数位
  603. Marketid int64 `json:"marketid" xorm:"'MARKETID'" binding:"required"` // 所属市场ID
  604. Goodsstatus int64 `json:"goodsstatus" xorm:"'GOODSSTATUS'"` // 商品状态- 2:未上市 3:上市
  605. Quoteminunit int64 `json:"quoteminunit" xorm:"'QUOTEMINUNIT'"` // 行情最小变动单位 [整数,报价小数位一起使用]
  606. Agreeunit float64 `json:"agreeunit" xorm:"'AGREEUNIT'"` // 合约单位
  607. Listingdate time.Time `json:"listingdate" xorm:"'LISTINGDATE'"` // 交易开始日期
  608. Lasttradedate time.Time `json:"lasttradedate" xorm:"'LASTTRADEDATE'"` // 最后交易日期(状态:待退市)
  609. Relatedgoodsid int64 `json:"relatedgoodsid" xorm:"'RELATEDGOODSID'"` // 关联交易合约ID
  610. Presaleqty int64 `json:"presaleqty" xorm:"'PRESALEQTY'"` // 预售数量
  611. Refprice float64 `json:"refprice" xorm:"'REFPRICE'"` // 参考价格[一口价]
  612. Presaledqty int64 `json:"presaledqty" xorm:"'PRESALEDQTY'"` // 已预售量(预售结束时更新)
  613. EnableQty int64 `json:"enableqty" xorm:"ENABLEQTY"` // 剩余数量
  614. Currency string `json:"currency" xorm:"'CURRENCY'"` // 货币
  615. Currencysign string `json:"currencysign" xorm:"'CURRENCYSIGN'"` // 货币符号
  616. Videourls string `json:"videourls" xorm:"'VIDEOURLS'"` // 介绍视频[多张用逗号分隔]
  617. Picurls string `json:"picurls" xorm:"'PICURLS'"` // 介绍图片[多张用逗号分隔]
  618. Trademode int32 `json:"trademode" xorm:"'TRADEMODE'" binding:"required"` // 交易模式 - 10:做市 13:竞价 15:通道交易 16:挂牌点选 17:仓单贸易 18:期权 19:竞拍-降价式 20:竞拍-竞价式 21:竞拍-大宗式 22:受托竞价
  619. }
  620. // GetHsbyPreGoodses 获取“新品上市”商品列表(一级市场产能预售)
  621. // 输入 marketIDs string 市场ID列表,格式 1,2,3
  622. // 输入 descProvinceID int 省ID
  623. // 输入 descCityID int 市ID
  624. // 输出 []HsbyPreGoods “新品上市”商品列表
  625. // 输出 error error
  626. func GetHsbyPreGoodses(marketIDs string, descProvinceID, descCityID int) ([]HsbyPreGoods, error) {
  627. engine := db.GetEngine()
  628. // 注意:一级产能预售市场使用的商品实际上是和二级市场有关系的,所以要使用 CPTRADE_PRESALEGOODSEX.RELATEDGOODSID 进行关联
  629. // 注意:CPTRADE_PRESALEGOODSEX 表的开始与结束时间是给大宗用的
  630. preGoodses := make([]HsbyPreGoods, 0)
  631. session := engine.Table("GOODS").
  632. Select(`GOODS.*,
  633. CPTRADE_PRESALEGOODSEX.RELATEDGOODSID, CPTRADE_PRESALEGOODSEX.PRESALEQTY, CPTRADE_PRESALEGOODSEX.REFPRICE,
  634. CPTRADE_PRESALEGOODSEX.PRESALEDQTY, (CPTRADE_PRESALEGOODSEX.PRESALEQTY - CPTRADE_PRESALEGOODSEX.PRESALEDQTY) ENABLEQTY,
  635. ENUMDICITEM.ENUMDICNAME CURRENCY, ENUMDICITEM.PARAM2 CURRENCYSIGN,
  636. HSBY_GOODSEX.VIDEOURLS, HSBY_GOODSEX.PICURLS,
  637. MARKET.TRADEMODE`).
  638. Join("INNER", "CPTRADE_PRESALEGOODSEX", "CPTRADE_PRESALEGOODSEX.GOODSID = GOODS.GOODSID").
  639. Join("LEFT", "ENUMDICITEM", "ENUMDICITEM.ENUMITEMNAME = GOODS.CURRENCYID and ENUMDICITEM.ENUMDICCODE = 'currency'").
  640. Join("LEFT", "HSBY_GOODSEX", "HSBY_GOODSEX.GOODSID = CPTRADE_PRESALEGOODSEX.RELATEDGOODSID").
  641. Join("LEFT", "MARKET", "MARKET.MARKETID = GOODS.MARKETID").
  642. Where(fmt.Sprintf("GOODS.GOODSSTATUS in (2,3) and GOODS.MARKETID in (%s)", marketIDs)) // 一级市场获取 2:未上市 3:上市 状态的商品
  643. if descProvinceID > 0 {
  644. session = session.And("HSBY_GOODSEX.DESCPROVINCEID = ?", descProvinceID)
  645. }
  646. if descCityID > 0 {
  647. session = session.And("HSBY_GOODSEX.DESCCITYID = ?", descCityID)
  648. }
  649. if err := session.Find(&preGoodses); err != nil {
  650. return nil, err
  651. }
  652. // for i := range preGoodses {
  653. // preGoods := &preGoodses[i]
  654. // // FIXME: - 这里应该使用 Duck Typing,后期再处理
  655. // // 计算最小变动单位
  656. // lotSize := float64(preGoods.Quoteminunit) * math.Pow(0.1, float64(preGoods.Decimalplace))
  657. // preGoods.LotSize, _ = strconv.ParseFloat(utils.FormatFloat(lotSize, int(preGoods.Decimalplace)), 64)
  658. // }
  659. return preGoodses, nil
  660. }
  661. // HsbyPreGoodsDetail 一级市场(产能预售)商品信息详情
  662. type HsbyPreGoodsDetail struct {
  663. Goodsid int64 `json:"goodsid" xorm:"'GOODSID'" binding:"required"` // 商品ID(自增ID SEQ_GOODS)
  664. Goodscode string `json:"goodscode" xorm:"'GOODSCODE'" binding:"required"` // 商品代码(内部)
  665. Goodsname string `json:"goodsname" xorm:"'GOODSNAME'" binding:"required"` // 商品名称
  666. Decimalplace int64 `json:"decimalplace" xorm:"'DECIMALPLACE'"` // 报价小数位
  667. Marketid int64 `json:"marketid" xorm:"'MARKETID'" binding:"required"` // 所属市场ID
  668. Goodsstatus int64 `json:"goodsstatus" xorm:"'GOODSSTATUS'"` // 商品状态- 2:未上市 3:上市
  669. Quoteminunit int64 `json:"quoteminunit" xorm:"'QUOTEMINUNIT'"` // 行情最小变动单位 [整数,报价小数位一起使用]
  670. Agreeunit float64 `json:"agreeunit" xorm:"'AGREEUNIT'"` // 合约单位
  671. Listingdate time.Time `json:"listingdate" xorm:"'LISTINGDATE'"` // 交易开始日期
  672. Lasttradedate time.Time `json:"lasttradedate" xorm:"'LASTTRADEDATE'"` // 最后交易日期(状态:待退市)
  673. Relatedgoodsid int64 `json:"relatedgoodsid" xorm:"'RELATEDGOODSID'"` // 关联交易合约ID
  674. Presaleqty int64 `json:"presaleqty" xorm:"'PRESALEQTY'"` // 预售数量
  675. Refprice float64 `json:"refprice" xorm:"'REFPRICE'"` // 参考价格[一口价]
  676. Presaledqty int64 `json:"presaledqty" xorm:"'PRESALEDQTY'"` // 已预售量(预售结束时更新)
  677. EnableQty int64 `json:"enableqty" xorm:"ENABLEQTY"` // 剩余数量
  678. Videourls string `json:"videourls" xorm:"'VIDEOURLS'"` // 介绍视频[多张用逗号分隔]
  679. Picurls string `json:"picurls" xorm:"'PICURLS'"` // 介绍图片[多张用逗号分隔]
  680. Descprovinceid int64 `json:"descprovinceid" xorm:"'DESCPROVINCEID'"` // 目的地(省)ID
  681. Desccityid int64 `json:"desccityid" xorm:"'DESCCITYID'"` // 目的地(市)ID
  682. Goodsdesc string `json:"goodsdesc" xorm:"'GOODSDESC'"` // 商品详情
  683. Currency string `json:"currency" xorm:"'CURRENCY'"` // 货币
  684. Currencysign string `json:"currencysign" xorm:"'CURRENCYSIGN'"` // 货币符号
  685. Goodunit string `json:"goodunit" xorm:"GOODUNIT"` // 报价单位
  686. Vendorname string `json:"vendorname" xorm:"'VENDORNAME'"` // 供应商名称
  687. Vendorphone string `json:"vendorphone" xorm:"'VENDORPHONE'"` // 供应商客服电话
  688. Vendorattr string `json:"vendorattr" xorm:"'VENDORATTR'"` // 供应商附件(多张,逗号分隔)
  689. Trademode int32 `json:"trademode" xorm:"'TRADEMODE'" binding:"required"` // 交易模式 - 10:做市 13:竞价 15:通道交易 16:挂牌点选 17:仓单贸易 18:期权 19:竞拍-降价式 20:竞拍-竞价式 21:竞拍-大宗式 22:受托竞价
  690. Customername string `json:"customername" xorm:"'CUSTOMERNAME'"` // 发行单位
  691. StepValue float64 `json:"stepvalue" xorm:"-"` // 价格最小变动单位
  692. LotSize int `json:"lotsize" xorm:"-"` // 手数最小变动单位
  693. Buymaxqty int `json:"buymaxqty" xorm:"'-'"` // 购买上限 [71] - 0为不限
  694. }
  695. // GetHsbyPreGoodsDetail 获取一级市场(产能预售)商品信息详情
  696. // 参数 goodsID int 目标商品ID
  697. // 返回 *HsbyListingGoodsDetail 二级市场(挂牌点选)商品信息详情,查询无结果返回nil
  698. // 返回 error error
  699. func GetHsbyPreGoodsDetail(goodsID, accountID int) (*HsbyPreGoodsDetail, error) {
  700. engine := db.GetEngine()
  701. details := make([]HsbyPreGoodsDetail, 0)
  702. // 获取挂牌商品信息,以及扩展表信息
  703. // FIXME: - 这里使用Get方法,会造成SQL语句的嵌套出错,后期再研究
  704. session := engine.Table("GOODS").
  705. Select(`GOODS.*,
  706. CPTRADE_PRESALEGOODSEX.RELATEDGOODSID, CPTRADE_PRESALEGOODSEX.PRESALEQTY, CPTRADE_PRESALEGOODSEX.REFPRICE,
  707. CPTRADE_PRESALEGOODSEX.PRESALEDQTY, (CPTRADE_PRESALEGOODSEX.PRESALEQTY - CPTRADE_PRESALEGOODSEX.PRESALEDQTY) ENABLEQTY,
  708. HSBY_GOODSEX.VIDEOURLS, HSBY_GOODSEX.PICURLS, HSBY_GOODSEX.DESCPROVINCEID, HSBY_GOODSEX.Desccityid, HSBY_GOODSEX.Goodsdesc,
  709. ENUMDICITEM.ENUMDICNAME CURRENCY, ENUMDICITEM.PARAM2 CURRENCYSIGN,
  710. E1.ENUMDICNAME GOODUNIT,
  711. HSBY_SUPPLIERINFO.VENDORNAME, HSBY_SUPPLIERINFO.VENDORPHONE, HSBY_SUPPLIERINFO.VENDORATTR,
  712. MARKET.TRADEMODE,
  713. USERINFO.CUSTOMERNAME`).
  714. Join("INNER", "CPTRADE_PRESALEGOODSEX", "CPTRADE_PRESALEGOODSEX.GOODSID = GOODS.GOODSID").
  715. Join("LEFT", "HSBY_GOODSEX", "HSBY_GOODSEX.GOODSID = CPTRADE_PRESALEGOODSEX.RELATEDGOODSID").
  716. Join("LEFT", "ENUMDICITEM", "ENUMDICITEM.ENUMITEMNAME = GOODS.CURRENCYID and ENUMDICITEM.ENUMDICCODE = 'currency'").
  717. Join("LEFT", "ENUMDICITEM E1", "E1.ENUMITEMNAME = GOODS.GOODUNITID and E1.ENUMDICCODE = 'goodsunit'").
  718. Join("LEFT", "HSBY_SUPPLIERINFO", "HSBY_SUPPLIERINFO.VENDORID = HSBY_GOODSEX.VENDORID").
  719. Join("LEFT", "MARKET", "MARKET.MARKETID = GOODS.MARKETID").
  720. Join("LEFT", "USERINFO", "USERINFO.USERID = CPTRADE_PRESALEGOODSEX.USERID").
  721. Where("GOODS.GOODSID = ?", goodsID)
  722. if err := session.Find(&details); err != nil {
  723. return nil, err
  724. }
  725. // 无目标商品
  726. if len(details) == 0 {
  727. return nil, nil
  728. }
  729. preGoodsDetail := details[0]
  730. // FIXME: - 这里应该使用 Duck Typing,后期再处理
  731. // 计算价格最小变动单位
  732. stepValue := float64(preGoodsDetail.Quoteminunit) * math.Pow(0.1, float64(preGoodsDetail.Decimalplace))
  733. preGoodsDetail.StepValue, _ = strconv.ParseFloat(utils.FormatFloat(stepValue, int(preGoodsDetail.Decimalplace)), 64)
  734. // 计算手数最小变动单位,一级市场固定为1
  735. preGoodsDetail.LotSize = 1
  736. // 获取购买上限
  737. if accountID != 0 {
  738. buyMaxQty, err := GetCPTradeBuyLimit(goodsID, accountID)
  739. if err != nil {
  740. return nil, err
  741. }
  742. preGoodsDetail.Buymaxqty = buyMaxQty
  743. }
  744. return &preGoodsDetail, nil
  745. }
  746. // HsbySellMyDetail "我的闲置"单据信息(发布中 - 二级市场卖挂,3:委托成功、7:部分成交; 已完成 - 二级市场成交单,包括历史数据)
  747. type HsbySellMyDetail struct {
  748. Orderid string `json:"orderid" xorm:"'ORDERID'" binding:"required"` // 单号(发布中 - 委托单号;已完成 - 成交单号)
  749. Marketid int32 `json:"marketid" xorm:"'MARKETID'" binding:"required"` // 市场ID
  750. Goodsid int32 `json:"goodsid" xorm:"'GOODSID'" binding:"required"` // 商品ID
  751. Accountid int64 `json:"accountid" xorm:"'ACCOUNTID'" binding:"required"` // 账户ID[报价币种]
  752. Buyorsell int32 `json:"buyorsell" xorm:"'BUYORSELL'" binding:"required"` // 买卖 - 0:买 1:卖
  753. Price float64 `json:"price" xorm:"'PRICE'"` // 价格
  754. Time time.Time `json:"time" xorm:"'TIME'" binding:"required"` // 时间
  755. Qty int64 `json:"qty" xorm:"'QTY'"` // 数量
  756. Goodscode string `json:"goodscode" xorm:"'GOODSCODE'" binding:"required"` // 商品代码(内部)
  757. Goodsname string `json:"goodsname" xorm:"'GOODSNAME'" binding:"required"` // 商品名称
  758. Decimalplace int64 `json:"decimalplace" xorm:"'DECIMALPLACE'"` // 报价小数位
  759. Agreeunit float64 `json:"agreeunit" xorm:"'AGREEUNIT'"` // 合约单位
  760. Picurls string `json:"picurls" xorm:"'PICURLS'"` // 介绍图片[多张用逗号分隔]
  761. Trademode uint32 `json:"trademode" xorm:"'TRADEMODE'" binding:"required"` // 交易模式 - 10:做市 13:竞价 15:通道交易 16:挂牌点选 17:仓单贸易 18:期权 19:竞拍-降价式 20:竞拍-竞价式 21:竞拍-大宗式 22:受托竞价
  762. Currencysign string `json:"currencysign" xorm:"'CURRENCYSIGN'"` // 货币符号
  763. Vendorname string `json:"vendorname" xorm:"'VENDORNAME'"` // 供应商名称
  764. OrderType int32 `json:"ordertype" xorm:"'ORDERTYPE'"` // 单据类型:0 - 发布中, 1 - 已完成
  765. }
  766. // GetHsbySellMyOrderDetails 获取"我的闲置 - 发布中"单据信息
  767. // 输入 accountIDs string 资金账户列表
  768. // 输出 []HsbySellMyDetail "我的闲置 - 发布中"单据信息
  769. // 输出 error error
  770. func GetHsbySellMyOrderDetails(accountIDs string) ([]HsbySellMyDetail, error) {
  771. // 获取市场信息
  772. markets, err := GetMarkets()
  773. if err != nil {
  774. return nil, err
  775. }
  776. engine := db.GetEngine()
  777. marketIDs := "" // 我的闲置-发布中: 二级市场卖挂牌、三级商城
  778. for _, v := range markets {
  779. if v.Trademode == 16 || v.Trademode == 70 {
  780. if len(marketIDs) == 0 {
  781. marketIDs = strconv.Itoa(int(v.Marketid))
  782. } else {
  783. marketIDs += "," + strconv.Itoa(int(v.Marketid))
  784. }
  785. }
  786. }
  787. orderDetails := make([]HsbySellMyDetail, 0)
  788. // “我的闲置 - 发布中”都是卖挂委托
  789. session := engine.Table("TRADE_ORDERDETAIL").
  790. Select(`to_char(TRADE_ORDERDETAIL.ORDERID) ORDERID,
  791. TRADE_ORDERDETAIL.MARKETID, TRADE_ORDERDETAIL.GOODSID, TRADE_ORDERDETAIL.ACCOUNTID, TRADE_ORDERDETAIL.BUYORSELL,
  792. TRADE_ORDERDETAIL.ORDERPRICE PRICE, TRADE_ORDERDETAIL.ORDERTIME TIME,
  793. (TRADE_ORDERDETAIL.ORDERQTY - TRADE_ORDERDETAIL.TRADEQTY - TRADE_ORDERDETAIL.CANCELQTY) QTY,
  794. GOODS.GOODSCODE, GOODS.GOODSNAME, GOODS.DECIMALPLACE, GOODS.AGREEUNIT,
  795. HSBY_GOODSEX.PICURLS,
  796. MARKET.TRADEMODE,
  797. ENUMDICITEM.PARAM2 CURRENCYSIGN,
  798. HSBY_SUPPLIERINFO.VENDORNAME,
  799. 0 ORDERTYPE`).
  800. Join("LEFT", "GOODS", "GOODS.GOODSID = TRADE_ORDERDETAIL.GOODSID").
  801. Join("LEFT", "HSBY_GOODSEX", "HSBY_GOODSEX.GOODSID = GOODS.GOODSID").
  802. Join("LEFT", "ENUMDICITEM", "GOODS.CURRENCYID = ENUMDICITEM.ENUMITEMNAME and ENUMDICITEM.ENUMDICCODE = 'currency'").
  803. Join("LEFT", "MARKET", "MARKET.MARKETID = TRADE_ORDERDETAIL.MARKETID").
  804. Join("LEFT", "HSBY_SUPPLIERINFO", "HSBY_SUPPLIERINFO.VENDORID = HSBY_GOODSEX.VENDORID").
  805. Where(fmt.Sprintf(`TRADE_ORDERDETAIL.BUYORSELL = 1 and TRADE_ORDERDETAIL.LISTINGSELECTTYPE = 1 and (TRADE_ORDERDETAIL.ORDERSTATUS = 3 or TRADE_ORDERDETAIL.ORDERSTATUS = 7)
  806. and TRADE_ORDERDETAIL.ACCOUNTID in (%s)`, accountIDs)).
  807. And(fmt.Sprintf("TRADE_ORDERDETAIL.MARKETID in (%s)", marketIDs))
  808. if err := session.Find(&orderDetails); err != nil {
  809. return nil, err
  810. }
  811. return orderDetails, nil
  812. }
  813. // GetHsbySellMyTradeDetails 获取"我的闲置 - 已完成"单据信息
  814. // 输入 accountIDs string 资金账户列表
  815. // 输出 []HsbySellMyDetail "我的闲置 - 已完成"单据信息
  816. // 输出 error error
  817. func GetHsbySellMyTradeDetails(accountIDs string) ([]HsbySellMyDetail, error) {
  818. // 获取市场信息
  819. markets, err := GetMarkets()
  820. if err != nil {
  821. return nil, err
  822. }
  823. engine := db.GetEngine()
  824. marketIDs := "" // 我的闲置-发布中: 二级市场卖方向成交单(包括历史成交单)
  825. // 默认取 TradeMode = 16
  826. for _, v := range markets {
  827. if v.Trademode == 16 {
  828. if len(marketIDs) == 0 {
  829. marketIDs = strconv.Itoa(int(v.Marketid))
  830. } else {
  831. marketIDs += "," + strconv.Itoa(int(v.Marketid))
  832. }
  833. }
  834. }
  835. orders := make([]HsbySellMyDetail, 0)
  836. // 当前成交单
  837. curOrders := make([]HsbySellMyDetail, 0)
  838. if err := engine.Table("TRADE_TRADEDETAIL").
  839. Select(`to_char(TRADE_TRADEDETAIL.TRADEID) ORDERID,
  840. TRADE_TRADEDETAIL.MARKETID, TRADE_TRADEDETAIL.GOODSID, TRADE_TRADEDETAIL.ACCOUNTID, TRADE_TRADEDETAIL.BUYORSELL,
  841. TRADE_TRADEDETAIL.TRADEPRICE PRICE, TRADE_TRADEDETAIL.TRADEQTY QTY, TRADE_TRADEDETAIL.TRADETIME TIME, TRADE_TRADEDETAIL.TRADEAMOUNT AMOUNT,
  842. GOODS.GOODSCODE, GOODS.GOODSNAME, GOODS.DECIMALPLACE, GOODS.AGREEUNIT,
  843. HSBY_GOODSEX.PICURLS,
  844. MARKET.TRADEMODE,
  845. ENUMDICITEM.PARAM2 CURRENCYSIGN,
  846. HSBY_SUPPLIERINFO.VENDORNAME,
  847. 1 ORDERTYPE`).
  848. Join("LEFT", "GOODS", "GOODS.GOODSID = TRADE_TRADEDETAIL.GOODSID").
  849. Join("LEFT", "HSBY_GOODSEX", "HSBY_GOODSEX.GOODSID = GOODS.GOODSID").
  850. Join("LEFT", "ENUMDICITEM", "GOODS.CURRENCYID = ENUMDICITEM.ENUMITEMNAME and ENUMDICITEM.ENUMDICCODE = 'currency'").
  851. Join("LEFT", "MARKET", "MARKET.MARKETID = TRADE_TRADEDETAIL.MARKETID").
  852. Join("LEFT", "HSBY_SUPPLIERINFO", "HSBY_SUPPLIERINFO.VENDORID = HSBY_GOODSEX.VENDORID").
  853. Where(fmt.Sprintf(`TRADE_TRADEDETAIL.BUYORSELL = 1 and TRADE_TRADEDETAIL.TRADETYPE in (1,24)
  854. and TRADE_TRADEDETAIL.ACCOUNTID in (%s)`, accountIDs)).
  855. And(fmt.Sprintf("TRADE_TRADEDETAIL.MARKETID in (%s)", marketIDs)).Find(&curOrders); err != nil {
  856. return nil, err
  857. }
  858. if len(curOrders) > 0 {
  859. orders = append(orders, curOrders...)
  860. }
  861. // 历史成交单
  862. hisOrders := make([]HsbySellMyDetail, 0)
  863. if err := engine.Table("HIS_TRADE_TRADEDETAIL").
  864. Select(`to_char(HIS_TRADE_TRADEDETAIL.TRADEID) ORDERID,
  865. HIS_TRADE_TRADEDETAIL.MARKETID, HIS_TRADE_TRADEDETAIL.GOODSID, HIS_TRADE_TRADEDETAIL.ACCOUNTID, HIS_TRADE_TRADEDETAIL.BUYORSELL,
  866. HIS_TRADE_TRADEDETAIL.TRADEPRICE PRICE, HIS_TRADE_TRADEDETAIL.TRADEQTY QTY, HIS_TRADE_TRADEDETAIL.TRADETIME TIME, HIS_TRADE_TRADEDETAIL.TRADEAMOUNT AMOUNT,
  867. GOODS.GOODSCODE, GOODS.GOODSNAME, GOODS.DECIMALPLACE, GOODS.AGREEUNIT,
  868. HSBY_GOODSEX.PICURLS,
  869. MARKET.TRADEMODE,
  870. ENUMDICITEM.PARAM2 CURRENCYSIGN,
  871. HSBY_SUPPLIERINFO.VENDORNAME,
  872. 1 ORDERTYPE`).
  873. Join("LEFT", "GOODS", "GOODS.GOODSID = HIS_TRADE_TRADEDETAIL.GOODSID").
  874. Join("LEFT", "HSBY_GOODSEX", "HSBY_GOODSEX.GOODSID = GOODS.GOODSID").
  875. Join("LEFT", "ENUMDICITEM", "GOODS.CURRENCYID = ENUMDICITEM.ENUMITEMNAME and ENUMDICITEM.ENUMDICCODE = 'currency'").
  876. Join("LEFT", "MARKET", "MARKET.MARKETID = HIS_TRADE_TRADEDETAIL.MARKETID").
  877. Join("LEFT", "HSBY_SUPPLIERINFO", "HSBY_SUPPLIERINFO.VENDORID = HSBY_GOODSEX.VENDORID").
  878. Where(fmt.Sprintf(`HIS_TRADE_TRADEDETAIL.BUYORSELL = 1 and HIS_TRADE_TRADEDETAIL.TRADETYPE in (1,24) and HIS_TRADE_TRADEDETAIL.ISVALIDDATA = 1
  879. and HIS_TRADE_TRADEDETAIL.ACCOUNTID in (%s)`, accountIDs)).
  880. And(fmt.Sprintf("HIS_TRADE_TRADEDETAIL.MARKETID in (%s)", marketIDs)).Find(&hisOrders); err != nil {
  881. return nil, err
  882. }
  883. if len(hisOrders) > 0 {
  884. orders = append(orders, hisOrders...)
  885. }
  886. return orders, nil
  887. }
  888. // HsbyMyPackage 我的包裹信息
  889. type HsbyMyPackage struct {
  890. Takeorderid string `json:"takeorderid" xorm:"'TAKEORDERID'" binding:"required"` // 提货单号(905+Unix秒时间戳(10位)+xxxxxx)
  891. Accountid int64 `json:"accountid" xorm:"'ACCOUNTID'"` // 账户ID
  892. Goodsid int64 `json:"goodsid" xorm:"'GOODSID'"` // 商品ID
  893. Userid int64 `json:"userid" xorm:"'USERID'"` // 用户ID
  894. Qty float64 `json:"qty" xorm:"'QTY'"` // 提货数量
  895. Reqtime time.Time `json:"reqtime" xorm:"'REQTIME'"` // 更新时间
  896. Recivername string `json:"recivername" xorm:"'RECIVERNAME'"` // 提货人姓名
  897. Cardtypeid int32 `json:"cardtypeid" xorm:"'CARDTYPEID'"` // 提货人证件类型
  898. Cardnum string `json:"cardnum" xorm:"'CARDNUM'"` // 提货人证件号码
  899. Phonenum string `json:"phonenum" xorm:"'PHONENUM'"` // 提货人联系方式
  900. Takemode int32 `json:"takemode" xorm:"'TAKEMODE'"` // 提货方式 - 2:自提 3:配送
  901. Address string `json:"address" xorm:"'ADDRESS'"` // 提货人详细地址
  902. Takeremark string `json:"takeremark" xorm:"'TAKEREMARK'"` // 提货备注
  903. Takeorderstatus int32 `json:"takeorderstatus" xorm:"'TAKEORDERSTATUS'"` // 提货状态 - 1:待发货 2:已发货 3:已收货
  904. Auditer int32 `json:"auditer" xorm:"'AUDITER'"` // 审核人
  905. Audittime time.Time `json:"audittime" xorm:"'AUDITTIME'"` // 审核时间
  906. Checkremark string `json:"checkremark" xorm:"'CHECKREMARK'"` // 审核备注
  907. Tradedate string `json:"tradedate" xorm:"'TRADEDATE'"` // 交易日(yyyyMMdd)
  908. Marketid int32 `json:"marketid" xorm:"'MARKETID'"` // 市场ID
  909. Handlestatus int32 `json:"handlestatus" xorm:"'HANDLESTATUS'"` // 处理状态
  910. Amount float64 `json:"amount" xorm:"'AMOUNT'"` // 提货金额
  911. Averageprice float64 `json:"averageprice" xorm:"'AVERAGEPRICE'"` // 均价
  912. Goodscode string `json:"goodscode" xorm:"'GOODSCODE'" binding:"required"` // 商品代码(内部)
  913. Goodsname string `json:"goodsname" xorm:"'GOODSNAME'" binding:"required"` // 商品名称
  914. Decimalplace int64 `json:"decimalplace" xorm:"'DECIMALPLACE'"` // 报价小数位
  915. Agreeunit float64 `json:"agreeunit" xorm:"'AGREEUNIT'"` // 合约单位
  916. Picurls string `json:"picurls" xorm:"'PICURLS'"` // 介绍图片[多张用逗号分隔]
  917. Currencysign string `json:"currencysign" xorm:"'CURRENCYSIGN'"` // 货币符号
  918. Vendorname string `json:"vendorname" xorm:"'VENDORNAME'"` // 供应商名称
  919. }
  920. // GetHsbyMyPackages 获取我的包裹信息
  921. // 输入 accountIDs string 资金账户列表
  922. // 输入 takeOrderStatus int 提货状态 - 1:待发货 2:已发货 3:已收货
  923. // 输出 []HsbyMyPackage 我的包裹信息
  924. // 输出 error error
  925. func GetHsbyMyPackages(accountIDs string, takeOrderStatus int) ([]HsbyMyPackage, error) {
  926. engine := db.GetEngine()
  927. myPackages := make([]HsbyMyPackage, 0)
  928. session := engine.Table("TRADE_GOODSPICKUP").
  929. Select(`to_char(TRADE_GOODSPICKUP.TAKEORDERID) TAKEORDERID, (DIVISION.PATHNAME || TRADE_GOODSPICKUP.ADDRESS) ADDRESS, TRADE_GOODSPICKUP.*,
  930. (TRADE_GOODSPICKUP.AMOUNT/TRADE_GOODSPICKUP.QTY/GOODS.AGREEUNIT) AVERAGEPRICE,
  931. GOODS.GOODSCODE, GOODS.GOODSNAME, GOODS.DECIMALPLACE, GOODS.AGREEUNIT,
  932. HSBY_GOODSEX.PICURLS,
  933. ENUMDICITEM.PARAM2 CURRENCYSIGN,
  934. HSBY_SUPPLIERINFO.VENDORNAME`).
  935. Join("LEFT", "GOODS", "GOODS.GOODSID = TRADE_GOODSPICKUP.GOODSID").
  936. Join("LEFT", "HSBY_GOODSEX", "HSBY_GOODSEX.GOODSID = GOODS.GOODSID").
  937. Join("LEFT", "ENUMDICITEM", "GOODS.CURRENCYID = ENUMDICITEM.ENUMITEMNAME and ENUMDICITEM.ENUMDICCODE = 'currency'").
  938. Join("LEFT", "HSBY_SUPPLIERINFO", "HSBY_SUPPLIERINFO.VENDORID = HSBY_GOODSEX.VENDORID").
  939. Join("LEFT", "DIVISION", "DIVISION.AUTOID = TRADE_GOODSPICKUP.DISTRICTID").
  940. Where(fmt.Sprintf("TRADE_GOODSPICKUP.ACCOUNTID in (%s)", accountIDs))
  941. if takeOrderStatus > 0 {
  942. session = session.And("TAKEORDERSTATUS = ?", takeOrderStatus)
  943. }
  944. if err := session.Find(&myPackages); err != nil {
  945. return nil, err
  946. }
  947. // FIXME:- 目前暂时在服务端对手机号码进行解密
  948. key, _ := hex.DecodeString(utils.AESSecretKey)
  949. for i := range myPackages {
  950. myPackage := &myPackages[i]
  951. if len(myPackage.Phonenum) > 0 {
  952. // 解密手机号码
  953. if phonenum, err := hex.DecodeString(myPackage.Phonenum); err == nil { // hex -> []byte
  954. if mobile, err := utils.AESDecrypt(phonenum, key); err == nil {
  955. myPackage.Phonenum = string(mobile)
  956. }
  957. }
  958. }
  959. }
  960. return myPackages, nil
  961. }
  962. // SetHsbyMyPackagesStatus 设置我的包裹提货状态
  963. func SetHsbyMyPackagesStatus(takeOrderID string, accountID, status int) error {
  964. engine := db.GetEngine()
  965. sql := fmt.Sprintf("update TRADE_GOODSPICKUP set TAKEORDERSTATUS = %d where TAKEORDERID = %s and ACCOUNTID = %d", status, takeOrderID, accountID)
  966. _, err := engine.Exec(sql)
  967. return err
  968. }
  969. // GetHsbyProvincesAndCities 获取省市信息数组
  970. // 参数 provinceID int 省ID,选填
  971. // 返回 []Division 枚举信息数组
  972. // 返回 error error
  973. func GetHsbyProvincesAndCities(provinceID int) ([]Division, error) {
  974. engine := db.GetEngine()
  975. divisions := make([]Division, 0)
  976. session := engine.Where("DIVISIONLEVEL = 'province' or DIVISIONLEVEL = 'city'").
  977. And(`AUTOID in (
  978. (select DESCPROVINCEID AUTOID from HSBY_GOODSEX inner join GOODS on GOODS.GOODSID = HSBY_GOODSEX.GOODSID and GOODS.GOODSSTATUS in (2,3))
  979. union all
  980. (select DESCCITYID AUTOID from HSBY_GOODSEX inner join GOODS on GOODS.GOODSID = HSBY_GOODSEX.GOODSID and GOODS.GOODSSTATUS in (2,3))
  981. )`)
  982. if provinceID > 0 {
  983. session = session.And("AUTOID = ?", provinceID)
  984. }
  985. if err := session.Find(&divisions); err != nil {
  986. return nil, err
  987. }
  988. return divisions, nil
  989. }
  990. // HsbyBuyMyTradeDetail "我的订单 - 已完成"单据信息(一二级市场成交单,包括历史数据)
  991. type HsbyBuyMyTradeDetail struct {
  992. Orderid string `json:"orderid" xorm:"'ORDERID'" binding:"required"` // 单号(成交单号)
  993. Marketid int32 `json:"marketid" xorm:"'MARKETID'" binding:"required"` // 市场ID
  994. Goodsid int32 `json:"goodsid" xorm:"'GOODSID'" binding:"required"` // 商品ID
  995. Accountid int64 `json:"accountid" xorm:"'ACCOUNTID'" binding:"required"` // 账户ID[报价币种]
  996. Buyorsell int32 `json:"buyorsell" xorm:"'BUYORSELL'" binding:"required"` // 买卖 - 0:买 1:卖
  997. Price float64 `json:"price" xorm:"'PRICE'"` // 价格
  998. Qty int64 `json:"qty" xorm:"'QTY'" binding:"required"` // 数量
  999. Time time.Time `json:"time" xorm:"'TIME'" binding:"required"` // 时间
  1000. Amount float64 `json:"amount" xorm:"'AMOUNT'"` // 金额 = 价格 * 数量 * 合约单位
  1001. Goodscode string `json:"goodscode" xorm:"'GOODSCODE'" binding:"required"` // 商品代码(内部)
  1002. Goodsname string `json:"goodsname" xorm:"'GOODSNAME'" binding:"required"` // 商品名称
  1003. Decimalplace int64 `json:"decimalplace" xorm:"'DECIMALPLACE'"` // 报价小数位
  1004. Agreeunit float64 `json:"agreeunit" xorm:"'AGREEUNIT'"` // 合约单位
  1005. Picurls1 string `json:"picurls1" xorm:"'PICURLS1'"` // 预售商品介绍图片[多张用逗号分隔]
  1006. Picurls2 string `json:"picurls2" xorm:"'PICURLS2'"` // 挂牌商品介绍图片[多张用逗号分隔]
  1007. Trademode uint32 `json:"trademode" xorm:"'TRADEMODE'" binding:"required"` // 交易模式 - 10:做市 13:竞价 15:通道交易 16:挂牌点选 17:仓单贸易 18:期权 19:竞拍-降价式 20:竞拍-竞价式 21:竞拍-大宗式 22:受托竞价
  1008. Currencysign string `json:"currencysign" xorm:"'CURRENCYSIGN'"` // 货币符号
  1009. Vendorname1 string `json:"vendorname1" xorm:"'VENDORNAME1'"` // 预售商品供应商名称
  1010. Vendorname2 string `json:"vendorname2" xorm:"'VENDORNAME2'"` // 挂牌商品供应商名称
  1011. }
  1012. // GetHsbyBuyMyTradeDetails 获取"我的订单 - 已完成"单据信息(一二级市场成交单,包括历史数据)
  1013. // 输入 accountIDs string 资金账户列表
  1014. // 输出 []HsbyBuyMyTradeDetail "我的订单 - 已完成"单据信息
  1015. // 输出 error error
  1016. func GetHsbyBuyMyTradeDetails(accountIDs string) ([]HsbyBuyMyTradeDetail, error) {
  1017. // 获取市场信息
  1018. markets, err := GetMarkets()
  1019. if err != nil {
  1020. return nil, err
  1021. }
  1022. engine := db.GetEngine()
  1023. marketIDs := "" // 我的订单包括一二级市场卖方向成交单(包括历史成交单)
  1024. // 默认取 TradeMode = 16
  1025. for _, v := range markets {
  1026. if v.Trademode == 16 || v.Trademode == 71 {
  1027. if len(marketIDs) == 0 {
  1028. marketIDs = strconv.Itoa(int(v.Marketid))
  1029. } else {
  1030. marketIDs += "," + strconv.Itoa(int(v.Marketid))
  1031. }
  1032. }
  1033. }
  1034. orders := make([]HsbyBuyMyTradeDetail, 0)
  1035. // 当前成交单
  1036. curOrders := make([]HsbyBuyMyTradeDetail, 0)
  1037. if err := engine.Table("TRADE_TRADEDETAIL").
  1038. Select(`to_char(TRADE_TRADEDETAIL.TRADEID) ORDERID,
  1039. TRADE_TRADEDETAIL.MARKETID, TRADE_TRADEDETAIL.GOODSID, TRADE_TRADEDETAIL.ACCOUNTID, TRADE_TRADEDETAIL.BUYORSELL,
  1040. TRADE_TRADEDETAIL.TRADEPRICE PRICE, TRADE_TRADEDETAIL.TRADEQTY QTY, TRADE_TRADEDETAIL.TRADETIME TIME, TRADE_TRADEDETAIL.TRADEAMOUNT AMOUNT,
  1041. GOODS.GOODSCODE, GOODS.GOODSNAME, GOODS.DECIMALPLACE, GOODS.AGREEUNIT,
  1042. HG1.PICURLS PICURLS1, HG2.PICURLS PICURLS2,
  1043. MARKET.TRADEMODE,
  1044. ENUMDICITEM.PARAM2 CURRENCYSIGN,
  1045. HS1.VENDORNAME VENDORNAME1, HS2.VENDORNAME VENDORNAME2`).
  1046. Join("LEFT", "GOODS", "GOODS.GOODSID = TRADE_TRADEDETAIL.GOODSID").
  1047. Join("LEFT", "CPTRADE_PRESALEGOODSEX", "CPTRADE_PRESALEGOODSEX.GOODSID = TRADE_TRADEDETAIL.GOODSID").
  1048. Join("LEFT", "HSBY_GOODSEX HG1", "HG1.GOODSID = CPTRADE_PRESALEGOODSEX.RELATEDGOODSID").
  1049. Join("LEFT", "HSBY_GOODSEX HG2", "HG2.GOODSID = GOODS.GOODSID").
  1050. Join("LEFT", "ENUMDICITEM", "GOODS.CURRENCYID = ENUMDICITEM.ENUMITEMNAME and ENUMDICITEM.ENUMDICCODE = 'currency'").
  1051. Join("LEFT", "MARKET", "MARKET.MARKETID = TRADE_TRADEDETAIL.MARKETID").
  1052. Join("LEFT", "HSBY_SUPPLIERINFO HS1", "HS1.VENDORID = HG1.VENDORID").
  1053. Join("LEFT", "HSBY_SUPPLIERINFO HS2", "HS2.VENDORID = HG2.VENDORID").
  1054. Where(fmt.Sprintf(`TRADE_TRADEDETAIL.BUYORSELL = 0 and TRADE_TRADEDETAIL.TRADETYPE in (1,24)
  1055. and TRADE_TRADEDETAIL.ACCOUNTID in (%s)`, accountIDs)).
  1056. And(fmt.Sprintf("TRADE_TRADEDETAIL.MARKETID in (%s)", marketIDs)).Find(&curOrders); err != nil {
  1057. return nil, err
  1058. }
  1059. if len(curOrders) > 0 {
  1060. orders = append(orders, curOrders...)
  1061. }
  1062. // 历史成交单
  1063. hisOrders := make([]HsbyBuyMyTradeDetail, 0)
  1064. if err := engine.Table("HIS_TRADE_TRADEDETAIL").
  1065. Select(`to_char(HIS_TRADE_TRADEDETAIL.TRADEID) ORDERID,
  1066. HIS_TRADE_TRADEDETAIL.MARKETID, HIS_TRADE_TRADEDETAIL.GOODSID, HIS_TRADE_TRADEDETAIL.ACCOUNTID, HIS_TRADE_TRADEDETAIL.BUYORSELL,
  1067. HIS_TRADE_TRADEDETAIL.TRADEPRICE PRICE, HIS_TRADE_TRADEDETAIL.TRADEQTY QTY, HIS_TRADE_TRADEDETAIL.TRADETIME TIME, HIS_TRADE_TRADEDETAIL.TRADEAMOUNT AMOUNT,
  1068. GOODS.GOODSCODE, GOODS.GOODSNAME, GOODS.DECIMALPLACE, GOODS.AGREEUNIT,
  1069. HG1.PICURLS PICURLS1, HG2.PICURLS PICURLS2,
  1070. MARKET.TRADEMODE,
  1071. ENUMDICITEM.PARAM2 CURRENCYSIGN,
  1072. HS1.VENDORNAME VENDORNAME1, HS2.VENDORNAME VENDORNAME2`).
  1073. Join("LEFT", "GOODS", "GOODS.GOODSID = HIS_TRADE_TRADEDETAIL.GOODSID").
  1074. Join("LEFT", "CPTRADE_PRESALEGOODSEX", "CPTRADE_PRESALEGOODSEX.GOODSID = HIS_TRADE_TRADEDETAIL.GOODSID").
  1075. Join("LEFT", "HSBY_GOODSEX HG1", "HG1.GOODSID = CPTRADE_PRESALEGOODSEX.RELATEDGOODSID").
  1076. Join("LEFT", "HSBY_GOODSEX HG2", "HG2.GOODSID = GOODS.GOODSID").
  1077. Join("LEFT", "ENUMDICITEM", "GOODS.CURRENCYID = ENUMDICITEM.ENUMITEMNAME and ENUMDICITEM.ENUMDICCODE = 'currency'").
  1078. Join("LEFT", "MARKET", "MARKET.MARKETID = HIS_TRADE_TRADEDETAIL.MARKETID").
  1079. Join("LEFT", "HSBY_SUPPLIERINFO HS1", "HS1.VENDORID = HG1.VENDORID").
  1080. Join("LEFT", "HSBY_SUPPLIERINFO HS2", "HS2.VENDORID = HG2.VENDORID").
  1081. Where(fmt.Sprintf(`HIS_TRADE_TRADEDETAIL.BUYORSELL = 0 and HIS_TRADE_TRADEDETAIL.TRADETYPE in (1,24) and HIS_TRADE_TRADEDETAIL.ISVALIDDATA = 1
  1082. and HIS_TRADE_TRADEDETAIL.ACCOUNTID in (%s)`, accountIDs)).
  1083. And(fmt.Sprintf("HIS_TRADE_TRADEDETAIL.MARKETID in (%s)", marketIDs)).Find(&hisOrders); err != nil {
  1084. return nil, err
  1085. }
  1086. if len(hisOrders) > 0 {
  1087. orders = append(orders, hisOrders...)
  1088. }
  1089. return orders, nil
  1090. }
  1091. // HsbyBuyMyPayOrder "我的订单 - 待付款"单据信息(一二级市场待付款信息)
  1092. type HsbyBuyMyPayOrder struct {
  1093. Tradeid string `json:"tradeid" xorm:"'TRADEIDSTR'" binding:"required"` // 成交单号(101+Unix秒时间戳(10位)+2位(MarketServiceID)+xxxx)
  1094. Tradedate string `json:"tradedate" xorm:"'TRADEDATE'"` // 交易日(yyyyMMdd)
  1095. Marketid int32 `json:"marketid" xorm:"'MARKETID'"` // 市场ID
  1096. Goodsid int32 `json:"goodsid" xorm:"'GOODSID'"` // 商品ID
  1097. Buyorderid string `json:"buyorderid" xorm:"'BUYORDERIDSTR'"` // 买方委托单号
  1098. Buyaccountid int64 `json:"buyaccountid" xorm:"'BUYACCOUNTID'"` // 买方账号ID[报价币种]
  1099. Sellorderid string `json:"sellorderid" xorm:"'SELLORDERIDSTR'"` // 卖方委托单号
  1100. Sellaccountid int64 `json:"sellaccountid" xorm:"'SELLACCOUNTID'"` // 卖方账号ID[报价币种]
  1101. Tradeamount float64 `json:"tradeamount" xorm:"'TRADEAMOUNT'"` // 成交金额
  1102. Tradecharge float64 `json:"tradecharge" xorm:"'TRADECHARGE'"` // 成交手续费(买方)
  1103. Payflag int32 `json:"payflag" xorm:"'PAYFLAG'"` // 付款标识 - 1:未支付 2:已支付 3:已过期 4:已撤销 5:结算过期 6:预售终止
  1104. Createtime time.Time `json:"createtime" xorm:"'CREATETIME'"` // 创建时间
  1105. Paytime time.Time `json:"paytime" xorm:"'PAYTIME'"` // 付款时间
  1106. Paylimitedtime time.Time `json:"paylimitedtime" xorm:"'PAYLIMITEDTIME'"` // 支付期限
  1107. Offamount float64 `json:"offamount" xorm:"'OFFAMOUNT'"` // 优惠金额
  1108. Tradeprice float64 `json:"tradeprice" xorm:"'TRADEPRICE'"` // 成交价格
  1109. Tradeqty int64 `json:"tradeqty" xorm:"'TRADEQTY'"` // 成交数量
  1110. Payamount float64 `json:"payamount" xorm:"'PAYAMOUNT'"` // 支付金额 = TradeAmount + TradeCharge - OffAmount
  1111. Goodscode string `json:"goodscode" xorm:"'GOODSCODE'" binding:"required"` // 商品代码(内部)
  1112. Goodsname string `json:"goodsname" xorm:"'GOODSNAME'" binding:"required"` // 商品名称
  1113. Decimalplace int64 `json:"decimalplace" xorm:"'DECIMALPLACE'"` // 报价小数位
  1114. Agreeunit float64 `json:"agreeunit" xorm:"'AGREEUNIT'"` // 合约单位
  1115. Picurls1 string `json:"picurls1" xorm:"'PICURLS1'"` // 预售商品介绍图片[多张用逗号分隔]
  1116. Picurls2 string `json:"picurls2" xorm:"'PICURLS2'"` // 挂牌商品介绍图片[多张用逗号分隔]
  1117. Trademode uint32 `json:"trademode" xorm:"'TRADEMODE'" binding:"required"` // 交易模式 - 10:做市 13:竞价 15:通道交易 16:挂牌点选 17:仓单贸易 18:期权 19:竞拍-降价式 20:竞拍-竞价式 21:竞拍-大宗式 22:受托竞价
  1118. Currencysign string `json:"currencysign" xorm:"'CURRENCYSIGN'"` // 货币符号
  1119. Vendorname1 string `json:"vendorname1" xorm:"'VENDORNAME1'"` // 预售商品供应商名称
  1120. Vendorname2 string `json:"vendorname2" xorm:"'VENDORNAME2'"` // 挂牌商品供应商名称
  1121. }
  1122. // GetHsbyBuyMyPayOrders 获取待付款信息
  1123. func GetHsbyBuyMyPayOrders(accountIDs string, buyOrderID, sellOrderID int) ([]HsbyBuyMyPayOrder, error) {
  1124. // 获取市场信息
  1125. markets, err := GetMarkets()
  1126. if err != nil {
  1127. return nil, err
  1128. }
  1129. engine := db.GetEngine()
  1130. marketIDs := "" // 我的订单包括一二级市场卖方向成交单
  1131. // 默认取 TradeMode = 16
  1132. for _, v := range markets {
  1133. if v.Trademode == 16 || v.Trademode == 71 || v.Trademode == 70 {
  1134. if len(marketIDs) == 0 {
  1135. marketIDs = strconv.Itoa(int(v.Marketid))
  1136. } else {
  1137. marketIDs += "," + strconv.Itoa(int(v.Marketid))
  1138. }
  1139. }
  1140. }
  1141. orders := make([]HsbyBuyMyPayOrder, 0)
  1142. session := engine.Table("TRADE_PAYORDER TP").
  1143. Select(`to_char(TP.TRADEID) TRADEIDSTR, to_char(TP.BUYORDERID) BUYORDERIDSTR, to_char(TP.SELLORDERID) SELLORDERIDSTR, TP.*,
  1144. GOODS.GOODSCODE, GOODS.GOODSNAME, GOODS.DECIMALPLACE, GOODS.AGREEUNIT,
  1145. HG1.PICURLS PICURLS1, HG2.PICURLS PICURLS2,
  1146. MARKET.TRADEMODE,
  1147. ENUMDICITEM.PARAM2 CURRENCYSIGN,
  1148. HS1.VENDORNAME VENDORNAME1, HS2.VENDORNAME VENDORNAME2`).
  1149. Join("LEFT", "GOODS", "GOODS.GOODSID = TP.GOODSID").
  1150. Join("LEFT", "CPTRADE_PRESALEGOODSEX CP", "CP.GOODSID = TP.GOODSID").
  1151. Join("LEFT", "HSBY_GOODSEX HG1", "HG1.GOODSID = CP.RELATEDGOODSID").
  1152. Join("LEFT", "HSBY_GOODSEX HG2", "HG2.GOODSID = GOODS.GOODSID").
  1153. Join("LEFT", "ENUMDICITEM", "GOODS.CURRENCYID = ENUMDICITEM.ENUMITEMNAME and ENUMDICITEM.ENUMDICCODE = 'currency'").
  1154. Join("LEFT", "MARKET", "MARKET.MARKETID = TP.MARKETID").
  1155. Join("LEFT", "HSBY_SUPPLIERINFO HS1", "HS1.VENDORID = HG1.VENDORID").
  1156. Join("LEFT", "HSBY_SUPPLIERINFO HS2", "HS2.VENDORID = HG2.VENDORID").
  1157. Where(fmt.Sprintf(`TP.PAYFLAG = 1 and TP.BUYACCOUNTID in (%s)`, accountIDs)).
  1158. And(fmt.Sprintf("TP.MARKETID in (%s)", marketIDs))
  1159. if buyOrderID != 0 {
  1160. session = session.And("TP.BUYORDERID = ?", buyOrderID)
  1161. }
  1162. if sellOrderID != 0 {
  1163. session = session.And("TP.SELLORDERID = ?", sellOrderID)
  1164. }
  1165. if err := session.Find(&orders); err != nil {
  1166. return nil, err
  1167. }
  1168. return orders, nil
  1169. }
  1170. // HsbyMarketInfo 海商报业相关市场信息
  1171. type HsbyMarketInfo struct {
  1172. Marketid int32 `json:"marketid" xorm:"'MARKETID'" binding:"required"` // 市场ID正常5位,前三位固定:两位表示交易模式, 一位表示交易属性(1:收益权,2:所有权) 其它特殊市场:0-系统 1-交割服务 2-账户服务3-履约服务 4-仓单服务 5-积分服务 6-银行服务
  1173. Marketname string `json:"marketname" xorm:"'MARKETNAME'"` // 市场名称
  1174. Trademode int32 `json:"trademode" xorm:"'TRADEMODE'" binding:"required"` // 交易模式 - 10:做市 13:竞价 15:通道交易 16:挂牌点选 17:仓单贸易 18:期权 19:竞拍-降价式 20:竞拍-竞价式 21:竞拍-大宗式 22:受托竞价
  1175. Marketstatus int32 `json:"marketstatus" xorm:"'MARKETSTATUS'" binding:"required"` // 生效状态(ValidStatus枚举): 1:待生效 2:正常 3:注销
  1176. }
  1177. // GetHsbyMarketInfos 获取海商报业相关市场信息
  1178. func GetHsbyMarketInfos() ([]HsbyMarketInfo, error) {
  1179. engine := db.GetEngine()
  1180. markets := make([]HsbyMarketInfo, 0)
  1181. if err := engine.Table("MARKET").Where("TRADEMODE in (71,16,70)").Find(&markets); err != nil {
  1182. return nil, err
  1183. }
  1184. return markets, nil
  1185. }
  1186. // HsbySellCollectionOrder 我的闲置中收款信息
  1187. type HsbySellCollectionOrder struct {
  1188. Tradeid string `json:"tradeid" xorm:"'TRADEIDSTR'" binding:"required"` // 成交单号(101+Unix秒时间戳(10位)+2位(MarketServiceID)+xxxx)
  1189. Tradedate string `json:"tradedate" xorm:"'TRADEDATE'"` // 交易日(yyyyMMdd)
  1190. Marketid int32 `json:"marketid" xorm:"'MARKETID'"` // 市场ID
  1191. Goodsid int32 `json:"goodsid" xorm:"'GOODSID'"` // 商品ID
  1192. Buyorderid string `json:"buyorderid" xorm:"'BUYORDERIDSTR'"` // 买方委托单号
  1193. Buyaccountid int64 `json:"buyaccountid" xorm:"'BUYACCOUNTID'"` // 买方账号ID[报价币种]
  1194. Sellorderid string `json:"sellorderid" xorm:"'SELLORDERIDSTR'"` // 卖方委托单号
  1195. Sellaccountid int64 `json:"sellaccountid" xorm:"'SELLACCOUNTID'"` // 卖方账号ID[报价币种]
  1196. Tradeamount float64 `json:"tradeamount" xorm:"'TRADEAMOUNT'"` // 成交金额
  1197. Tradecharge float64 `json:"tradecharge" xorm:"'TRADECHARGE'"` // 成交手续费(买方)
  1198. Payflag int32 `json:"payflag" xorm:"'PAYFLAG'"` // 付款标识 - 1:未支付 2:已支付 3:已过期 4:已撤销 5:结算过期 6:预售终止
  1199. Createtime time.Time `json:"createtime" xorm:"'CREATETIME'"` // 创建时间
  1200. Paytime time.Time `json:"paytime" xorm:"'PAYTIME'"` // 付款时间
  1201. Paylimitedtime time.Time `json:"paylimitedtime" xorm:"'PAYLIMITEDTIME'"` // 支付期限
  1202. Offamount float64 `json:"offamount" xorm:"'OFFAMOUNT'"` // 优惠金额
  1203. Tradeprice float64 `json:"tradeprice" xorm:"'TRADEPRICE'"` // 成交价格
  1204. Tradeqty int64 `json:"tradeqty" xorm:"'TRADEQTY'"` // 成交数量
  1205. Payamount float64 `json:"payamount" xorm:"'PAYAMOUNT'"` // 支付金额 = TradeAmount + TradeCharge - OffAmount
  1206. Goodscode string `json:"goodscode" xorm:"'GOODSCODE'" binding:"required"` // 商品代码(内部)
  1207. Goodsname string `json:"goodsname" xorm:"'GOODSNAME'" binding:"required"` // 商品名称
  1208. Decimalplace int64 `json:"decimalplace" xorm:"'DECIMALPLACE'"` // 报价小数位
  1209. Agreeunit float64 `json:"agreeunit" xorm:"'AGREEUNIT'"` // 合约单位
  1210. Picurls string `json:"picurls" xorm:"'PICURLS'"` // 商品介绍图片[多张用逗号分隔]
  1211. Trademode uint32 `json:"trademode" xorm:"'TRADEMODE'" binding:"required"` // 交易模式 - 10:做市 13:竞价 15:通道交易 16:挂牌点选 17:仓单贸易 18:期权 19:竞拍-降价式 20:竞拍-竞价式 21:竞拍-大宗式 22:受托竞价
  1212. Currencysign string `json:"currencysign" xorm:"'CURRENCYSIGN'"` // 货币符号
  1213. }
  1214. // GetHsbySellCollectionOrders 获取我的闲置中待收款信息
  1215. func GetHsbySellCollectionOrders(accountIDs string) ([]HsbySellCollectionOrder, error) {
  1216. // 获取市场信息
  1217. markets, err := GetMarkets()
  1218. if err != nil {
  1219. return nil, err
  1220. }
  1221. engine := db.GetEngine()
  1222. marketIDs := ""
  1223. for _, v := range markets {
  1224. if v.Trademode == 16 || v.Trademode == 70 {
  1225. if len(marketIDs) == 0 {
  1226. marketIDs = strconv.Itoa(int(v.Marketid))
  1227. } else {
  1228. marketIDs += "," + strconv.Itoa(int(v.Marketid))
  1229. }
  1230. }
  1231. }
  1232. orders := make([]HsbySellCollectionOrder, 0)
  1233. session := engine.Table("TRADE_PAYORDER TP").
  1234. Select(`to_char(TP.TRADEID) TRADEIDSTR, to_char(TP.BUYORDERID) BUYORDERIDSTR, to_char(TP.SELLORDERID) SELLORDERIDSTR, TP.*,
  1235. G.GOODSCODE, G.GOODSNAME, G.DECIMALPLACE, G.AGREEUNIT,
  1236. HG.PICURLS,
  1237. M.TRADEMODE,
  1238. E.PARAM2 CURRENCYSIGN`).
  1239. Join("LEFT", "GOODS G", "G.GOODSID = TP.GOODSID").
  1240. Join("LEFT", "HSBY_GOODSEX HG", "HG.GOODSID = G.GOODSID").
  1241. Join("LEFT", "ENUMDICITEM E", "G.CURRENCYID = E.ENUMITEMNAME and E.ENUMDICCODE = 'currency'").
  1242. Join("LEFT", "MARKET M", "M.MARKETID = TP.MARKETID").
  1243. Join("LEFT", "HSBY_SUPPLIERINFO HS", "HS.VENDORID = HG.VENDORID").
  1244. Where(fmt.Sprintf(`TP.PAYFLAG = 1 and TP.SELLACCOUNTID in (%s)`, accountIDs)).
  1245. And(fmt.Sprintf("TP.MARKETID in (%s)", marketIDs))
  1246. if err := session.Find(&orders); err != nil {
  1247. return nil, err
  1248. }
  1249. return orders, nil
  1250. }
  1251. // HsbyMarketGoods 特卖商城商品(三级市场商场)
  1252. type HsbyMarketGoods struct {
  1253. Orderid string `json:"orderid" xorm:"'ORDERIDSTR'" binding:"required"` // 委托单号(100+Unix秒时间戳(10位)+2位(MarketServiceID)+xxxx)
  1254. Marketid int32 `json:"marketid" xorm:"'MARKETID'" binding:"required"` // 市场ID
  1255. Goodsid int32 `json:"goodsid" xorm:"'GOODSID'" binding:"required"` // 商品ID
  1256. Accountid int64 `json:"accountid" xorm:"'ACCOUNTID'" binding:"required"` // 账户ID[报价币种]
  1257. Buyorsell int32 `json:"buyorsell" xorm:"'BUYORSELL'" binding:"required"` // 买卖 - 0:买 1:卖
  1258. Orderprice float64 `json:"orderprice" xorm:"'ORDERPRICE'"` // 委托价格
  1259. Orderstatus int32 `json:"orderstatus" xorm:"'ORDERSTATUS'"` // 委托状态 - 1: 委托请求 2:待冻结 3:委托成功 4: 委托失败 5:配对成功 6: 已撤销 7:部分成交 8:已成交 9:部成部撤 10:成交失败 11:已拒绝 12:经过摘牌(先摘后挂专用-先摘后挂已摘过) 13:冻结成功(通道交易专用) 14:通道已撤 15:通道部成部撤 16:成交失败违约(荷兰式竞拍专用)
  1260. Goodscode string `json:"goodscode" xorm:"'GOODSCODE'" binding:"required"` // 商品代码(内部)
  1261. Goodsname string `json:"goodsname" xorm:"'GOODSNAME'" binding:"required"` // 商品名称
  1262. Decimalplace int64 `json:"decimalplace" xorm:"'DECIMALPLACE'"` // 报价小数位
  1263. Quoteminunit int64 `json:"quoteminunit" xorm:"'QUOTEMINUNIT'"` // 行情最小变动单位 [整数,报价小数位一起使用]
  1264. Agreeunit float64 `json:"agreeunit" xorm:"'AGREEUNIT'"` // 合约单位
  1265. Hotindex int32 `json:"hotindex" xorm:"'HOTINDEX'"` // 景点热度
  1266. Videourls string `json:"videourls" xorm:"'VIDEOURLS'"` // 介绍视频[多张用逗号分隔]
  1267. Picurls string `json:"picurls" xorm:"'PICURLS'"` // 介绍图片[多张用逗号分隔]
  1268. Categoryid int32 `json:"categoryid" xorm:"'CATEGORYID'"` // 类别ID(WRCATEGORY)
  1269. Currency string `json:"currency" xorm:"'CURRENCY'"` // 货币
  1270. Currencysign string `json:"currencysign" xorm:"'CURRENCYSIGN'"` // 货币符号
  1271. Trademode int32 `json:"trademode" xorm:"'TRADEMODE'" binding:"required"` // 交易模式 - 10:做市 13:竞价 15:通道交易 16:挂牌点选 17:仓单贸易 18:期权 19:竞拍-降价式 20:竞拍-竞价式 21:竞拍-大宗式 22:受托竞价
  1272. Customername string `json:"customername" xorm:"'CUSTOMERNAME'"` // 卖家名称
  1273. HasCoupon bool `json:"hascoupon" xorm:"-"` // 是否可用优惠卷
  1274. SellUserID int `json:"sellUserID" xorm:"-"` // 卖方UserID
  1275. }
  1276. // GetHsbyMarketGoodses 获取商城商品列表(三级商城)
  1277. func GetHsbyMarketGoodses(marketIDs string, accountID, categoryID int, goodsIDs string, couponTypeID int) ([]HsbyMarketGoods, error) {
  1278. engine := db.GetEngine()
  1279. // 获取优惠卷类型信息
  1280. var couponType Coupontype
  1281. if _, err := engine.Where("ISVALID = 1 and COUPONTYPEID = ?", couponTypeID).Get(&couponType); err != nil {
  1282. return nil, err
  1283. }
  1284. orders := make([]HsbyMarketGoods, 0)
  1285. // 与挂牌点选不一样的是商城是以委托单为主表;已经卖完的委托单不显示
  1286. session := engine.Table("TRADE_ORDERDETAIL T").
  1287. Select(`to_char(T.ORDERID) ORDERIDSTR, T.*,
  1288. G.GOODSCODE, G.GOODSNAME, G.DECIMALPLACE, G.QUOTEMINUNIT, G.AGREEUNIT,
  1289. GX.HOTINDEX, GX.PICURLS, GX.CATEGORYID, GX.GOODSDESC,
  1290. E.ENUMDICNAME CURRENCY, E.PARAM2 CURRENCYSIGN,
  1291. M.TRADEMODE,
  1292. U.CUSTOMERNAME`).
  1293. Join("LEFT", "GOODS G", "G.GOODSID = T.GOODSID").
  1294. Join("LEFT", "HSBY_GOODSEX GX", "GX.GOODSID = T.GOODSID").
  1295. Join("LEFT", "ENUMDICITEM E", "E.ENUMITEMNAME = G.CURRENCYID and E.ENUMDICCODE = 'currency'").
  1296. Join("LEFT", "MARKET M", "M.MARKETID = T.MARKETID").
  1297. Join("LEFT", "TAACCOUNT TA", "TA.ACCOUNTID = T.ACCOUNTID").
  1298. Join("LEFT", "USERINFO U", "U.USERID = TA.RELATEDUSERID").
  1299. Where(fmt.Sprintf("T.MARKETID in (%s)", marketIDs)).
  1300. And("T.ORDERSTATUS in (3,7) and T.BUYORSELL = 1 and (T.ORDERQTY - T.TRADEQTY - T.CANCELQTY) > 0")
  1301. if categoryID != 0 {
  1302. session = session.And("GX.CATEGORYID = ?", categoryID)
  1303. }
  1304. if len(goodsIDs) > 0 {
  1305. session = session.And(fmt.Sprintf("G.GOODSID in (%s)", goodsIDs))
  1306. }
  1307. if couponTypeID > 0 {
  1308. if couponType.Coupontypeid == 0 {
  1309. // 没有查询到对应的优惠卷,直接返回空数组
  1310. return make([]HsbyMarketGoods, 0), nil
  1311. }
  1312. // 优惠卷特定商品
  1313. if couponType.Limitedflag == 1 {
  1314. // 去掉头尾逗号
  1315. limitedGoodsIDs := couponType.Limitedgoodsids
  1316. if strings.HasPrefix(limitedGoodsIDs, ",") && strings.HasSuffix(limitedGoodsIDs, ",") {
  1317. limitedGoodsIDs = limitedGoodsIDs[1 : len(limitedGoodsIDs)-1]
  1318. }
  1319. session = session.And(fmt.Sprintf("T.GOODSID in (%s)", limitedGoodsIDs))
  1320. }
  1321. // 优惠卷特定卖家
  1322. if couponType.Isgeneral == 0 {
  1323. // 去掉头尾逗号
  1324. userScope := couponType.Userscope
  1325. if strings.HasPrefix(userScope, ",") && strings.HasSuffix(userScope, ",") {
  1326. userScope = userScope[1 : len(userScope)-1]
  1327. }
  1328. // 查询对应的卖家资金账户信息
  1329. taAccounts := make([]Taaccount, 0)
  1330. if err := engine.Where(fmt.Sprintf("RELATEDUSERID in (%s)", userScope)).Find(&taAccounts); err != nil {
  1331. return nil, err
  1332. }
  1333. sellAccountIDs := ""
  1334. for _, v := range taAccounts {
  1335. if len(sellAccountIDs) == 0 {
  1336. sellAccountIDs = strconv.Itoa(int(v.Accountid))
  1337. } else {
  1338. sellAccountIDs += "," + strconv.Itoa(int(v.Accountid))
  1339. }
  1340. }
  1341. session = session.And(fmt.Sprintf("T.ACCOUNTID in (%s)", sellAccountIDs))
  1342. }
  1343. }
  1344. if err := session.Find(&orders); err != nil {
  1345. return nil, err
  1346. }
  1347. // 获取当前账户的优惠卷
  1348. type myCouponPosition struct {
  1349. Accountid int64 `json:"accountid" xorm:"'ACCOUNTID'" binding:"required"` // 资金账户ID
  1350. Coupontypeid int32 `json:"coupontypeid" xorm:"'COUPONTYPEID'" binding:"required"` // 优惠券类型ID
  1351. Curqty int64 `json:"curqty" xorm:"'CURQTY'"` // 期末数量
  1352. Curfreezeqty int64 `json:"curfreezeqty" xorm:"'CURFREEZEQTY'"` // 期末冻结数量
  1353. Limitedflag int32 `json:"limitedflag" xorm:"'LIMITEDFLAG'"` // 是否指定商品 - 0:不限 1:限制
  1354. Limitedgoodsids string `json:"limitedgoodsids" xorm:"'LIMITEDGOODSIDS'"` // 指定商品IDs[逗号分隔,前后加逗号]
  1355. Isgeneral int32 `json:"isgeneral" xorm:"'ISGENERAL'"` // 是否通用券 - 0:否 1:是
  1356. Userscope string `json:"userscope" xorm:"'USERSCOPE'"` // 卖家范围(用户ID,逗号分隔,前后加逗号) [IsGeneral =0时使用]
  1357. }
  1358. myCouponPositions := make([]myCouponPosition, 0)
  1359. if accountID != 0 {
  1360. if err := engine.Table("COUPONPOSITION C").
  1361. Select(`C.ACCOUNTID, C.COUPONTYPEID, C.CURQTY, C.CURFREEZEQTY,
  1362. CT.LIMITEDFLAG, CT.LIMITEDGOODSIDS, CT.ISGENERAL, CT.USERSCOPE`).
  1363. Join("INNER", "COUPONTYPE CT", "CT.COUPONTYPEID = C.COUPONTYPEID").
  1364. Where("C.ACCOUNTID = ?", accountID).Find(&myCouponPositions); err != nil {
  1365. return nil, err
  1366. }
  1367. }
  1368. // 是否有优惠卷可用
  1369. if len(orders) > 0 && len(myCouponPositions) > 0 {
  1370. for _, coupon := range myCouponPositions {
  1371. if coupon.Limitedflag == 0 && coupon.Isgeneral == 1 {
  1372. // 有不指定商品的通用卷则所有委托单都可以用卷
  1373. for i := range orders {
  1374. order := &orders[i]
  1375. order.HasCoupon = true
  1376. }
  1377. break
  1378. } else {
  1379. for i := range orders {
  1380. order := &orders[i]
  1381. // 获取卖家UserID
  1382. userInfo, err := GetUserInfoByAccountID(int(order.Accountid))
  1383. if err != nil {
  1384. continue
  1385. }
  1386. order.SellUserID = int(userInfo.Userid)
  1387. // order.Customername = userInfo.Customername
  1388. tmpGoodsID := fmt.Sprintf(",%d,", order.Goodsid)
  1389. tmpUserID := fmt.Sprintf(",%d,", userInfo.Userid)
  1390. // 优惠卷是否可用于商品
  1391. isRightGoods := false
  1392. if coupon.Limitedflag == 0 {
  1393. isRightGoods = true
  1394. } else {
  1395. if strings.Contains(coupon.Limitedgoodsids, tmpGoodsID) {
  1396. isRightGoods = true
  1397. }
  1398. }
  1399. // 优惠卷是否可用于卖家
  1400. isRightAccount := false
  1401. if coupon.Isgeneral == 1 {
  1402. isRightAccount = true
  1403. } else {
  1404. if strings.Contains(coupon.Userscope, tmpUserID) {
  1405. isRightAccount = true
  1406. }
  1407. }
  1408. if isRightGoods && isRightAccount {
  1409. order.HasCoupon = true
  1410. }
  1411. }
  1412. }
  1413. }
  1414. }
  1415. return orders, nil
  1416. }
  1417. // HsbyMarketGoodsDetail 特卖商城商品(三级市场商场)
  1418. type HsbyMarketGoodsDetail struct {
  1419. Orderid string `json:"orderid" xorm:"'ORDERIDSTR'" binding:"required"` // 委托单号(100+Unix秒时间戳(10位)+2位(MarketServiceID)+xxxx)
  1420. Marketid int32 `json:"marketid" xorm:"'MARKETID'" binding:"required"` // 市场ID
  1421. Goodsid int32 `json:"goodsid" xorm:"'GOODSID'" binding:"required"` // 商品ID
  1422. Accountid int64 `json:"accountid" xorm:"'ACCOUNTID'" binding:"required"` // 账户ID[报价币种]
  1423. Buyorsell int32 `json:"buyorsell" xorm:"'BUYORSELL'" binding:"required"` // 买卖 - 0:买 1:卖
  1424. Orderprice float64 `json:"orderprice" xorm:"'ORDERPRICE'"` // 委托价格
  1425. Orderqty int64 `json:"orderqty" xorm:"'ORDERQTY'" binding:"required"` // 委托数量
  1426. Tradeqty int64 `json:"tradeqty" xorm:"'TRADEQTY'"` // 成交数量
  1427. Cancelqty int64 `json:"cancelqty" xorm:"'CANCELQTY'"` // 撤单数量
  1428. Orderstatus int32 `json:"orderstatus" xorm:"'ORDERSTATUS'"` // 委托状态 - 1: 委托请求 2:待冻结 3:委托成功 4: 委托失败 5:配对成功 6: 已撤销 7:部分成交 8:已成交 9:部成部撤 10:成交失败 11:已拒绝 12:经过摘牌(先摘后挂专用-先摘后挂已摘过) 13:冻结成功(通道交易专用) 14:通道已撤 15:通道部成部撤 16:成交失败违约(荷兰式竞拍专用)
  1429. Goodscode string `json:"goodscode" xorm:"'GOODSCODE'" binding:"required"` // 商品代码(内部)
  1430. Goodsname string `json:"goodsname" xorm:"'GOODSNAME'" binding:"required"` // 商品名称
  1431. Decimalplace int64 `json:"decimalplace" xorm:"'DECIMALPLACE'"` // 报价小数位
  1432. Quoteminunit int64 `json:"quoteminunit" xorm:"'QUOTEMINUNIT'"` // 行情最小变动单位 [整数,报价小数位一起使用]
  1433. Agreeunit float64 `json:"agreeunit" xorm:"'AGREEUNIT'"` // 合约单位
  1434. Hotindex int32 `json:"hotindex" xorm:"'HOTINDEX'"` // 景点热度
  1435. Videourls string `json:"videourls" xorm:"'VIDEOURLS'"` // 介绍视频[多张用逗号分隔]
  1436. Picurls string `json:"picurls" xorm:"'PICURLS'"` // 介绍图片[多张用逗号分隔]
  1437. Categoryid int32 `json:"categoryid" xorm:"'CATEGORYID'"` // 类别ID(WRCATEGORY)
  1438. Goodsdesc string `json:"goodsdesc" xorm:"'GOODSDESC'"` // 商品详情
  1439. Currency string `json:"currency" xorm:"'CURRENCY'"` // 货币
  1440. Currencysign string `json:"currencysign" xorm:"'CURRENCYSIGN'"` // 货币符号
  1441. Trademode int32 `json:"trademode" xorm:"'TRADEMODE'" binding:"required"` // 交易模式 - 10:做市 13:竞价 15:通道交易 16:挂牌点选 17:仓单贸易 18:期权 19:竞拍-降价式 20:竞拍-竞价式 21:竞拍-大宗式 22:受托竞价
  1442. Vendorname string `json:"vendorname" xorm:"'VENDORNAME'"` // 供应商名称
  1443. Customername string `json:"customername" xorm:"'CUSTOMERNAME'"` // 卖家名称
  1444. SellUserID int `json:"sellUserID" xorm:"SELLUSERID"` // 卖方UserID
  1445. LotSize int `json:"lotsize" xorm:"-"` // 手数最小变动单位
  1446. Buymaxqty int `json:"buymaxqty" xorm:"'-'"` // 购买上限 [71] - 0为不限
  1447. }
  1448. // GetHsbyMarketGoodsDetail 获取商城商品详情(三级商城)
  1449. func GetHsbyMarketGoodsDetail(orderID, accountID int) (*HsbyMarketGoodsDetail, error) {
  1450. engine := db.GetEngine()
  1451. orders := make([]HsbyMarketGoodsDetail, 0)
  1452. // 与挂牌点选不一样的是商城是以委托单为主表
  1453. session := engine.Table("TRADE_ORDERDETAIL T").
  1454. Select(`to_char(T.ORDERID) ORDERIDSTR, T.*,
  1455. G.GOODSCODE, G.GOODSNAME, G.DECIMALPLACE, G.QUOTEMINUNIT, G.AGREEUNIT,
  1456. GX.HOTINDEX, GX.VIDEOURLS, GX.PICURLS, GX.CATEGORYID, GX.GOODSDESC,
  1457. E.ENUMDICNAME CURRENCY, E.PARAM2 CURRENCYSIGN,
  1458. M.TRADEMODE,
  1459. H.VENDORNAME,
  1460. U.USERID SELLUSERID, U.CUSTOMERNAME`).
  1461. Join("LEFT", "GOODS G", "G.GOODSID = T.GOODSID").
  1462. Join("LEFT", "HSBY_GOODSEX GX", "GX.GOODSID = T.GOODSID").
  1463. Join("LEFT", "ENUMDICITEM E", "E.ENUMITEMNAME = G.CURRENCYID and E.ENUMDICCODE = 'currency'").
  1464. Join("LEFT", "MARKET M", "M.MARKETID = T.MARKETID").
  1465. Join("LEFT", "HSBY_SUPPLIERINFO H", "H.VENDORID = GX.VENDORID").
  1466. Join("LEFT", "TAACCOUNT TA", "TA.ACCOUNTID = T.ACCOUNTID").
  1467. Join("LEFT", "USERINFO U", "U.USERID = TA.RELATEDUSERID").
  1468. Where("T.ORDERID = ?", orderID)
  1469. if err := session.Find(&orders); err != nil {
  1470. return nil, err
  1471. }
  1472. // 无目标商品
  1473. if len(orders) == 0 {
  1474. return nil, nil
  1475. }
  1476. hsbyMarketGoodsDetail := orders[0]
  1477. // 最小交易手数在上层进行设置,这里暂设置为1
  1478. hsbyMarketGoodsDetail.LotSize = 1
  1479. // 获取购买上限
  1480. if accountID != 0 {
  1481. buyMaxQty, err := GetCPTradeBuyLimit(int(hsbyMarketGoodsDetail.Goodsid), accountID)
  1482. if err != nil {
  1483. return nil, err
  1484. }
  1485. hsbyMarketGoodsDetail.Buymaxqty = buyMaxQty
  1486. }
  1487. return &hsbyMarketGoodsDetail, nil
  1488. }
  1489. // MyCoupon 我的优惠卷
  1490. type MyCoupon struct {
  1491. Accountid int64 `json:"accountid" xorm:"'ACCOUNTID'" binding:"required"` // 资金账户ID
  1492. Coupontypeid string `json:"coupontypeid" xorm:"'COUPONTYPEIDSTR'" binding:"required"` // 优惠券类型ID
  1493. Userid int64 `json:"userid" xorm:"'USERID'"` // 用户ID
  1494. Oriqty int64 `json:"oriqty" xorm:"'ORIQTY'"` // 期初数量
  1495. Orifreezeqty int64 `json:"orifreezeqty" xorm:"'ORIFREEZEQTY'"` // 期初冻结数量
  1496. Curqty int64 `json:"curqty" xorm:"'CURQTY'"` // 期末数量
  1497. Curfreezeqty int64 `json:"curfreezeqty" xorm:"'CURFREEZEQTY'"` // 期末冻结数量
  1498. Todayincrease int64 `json:"todayincrease" xorm:"'TODAYINCREASE'"` // 今日增加
  1499. Todaydecrease int64 `json:"todaydecrease" xorm:"'TODAYDECREASE'"` // 今日减少
  1500. Areauserid int64 `json:"areauserid" xorm:"'AREAUSERID'"` // 所属机构
  1501. Couponname string `json:"couponname" xorm:"'COUPONNAME'"` // 优惠券名称
  1502. Couponcategroy int32 `json:"couponcategroy" xorm:"'COUPONCATEGROY'"` // 种类 - 1:现金券 2:折扣券 3:折扣券(单张)
  1503. Conditionvalue float64 `json:"conditionvalue" xorm:"'CONDITIONVALUE'"` // 条件阈值(可为0)
  1504. Couponvalue float64 `json:"couponvalue" xorm:"'COUPONVALUE'"` // 面值[1:现金券 - 抵扣值 2:折扣券-折扣值]
  1505. Limitedflag int32 `json:"limitedflag" xorm:"'LIMITEDFLAG'"` // 是否指定商品 - 0:不限 1:限制
  1506. Limitedgoodsids string `json:"limitedgoodsids" xorm:"'LIMITEDGOODSIDS'"` // 指定商品IDs[逗号分隔,前后加逗号]
  1507. Isgeneral int32 `json:"isgeneral" xorm:"'ISGENERAL'"` // 是否通用券 - 0:否 1:是
  1508. Userscope string `json:"userscope" xorm:"'USERSCOPE'"` // 卖家范围(用户ID,逗号分隔,前后加逗号) [IsGeneral =0时使用]
  1509. IsUnusable bool `json:"isunusable" xorm:"-"` // 是否不可用
  1510. ReasonType int `json:"reasontype"` // 不可用原因 - 0:未确认 1:不可用于此商品 2:不可用于此卖家
  1511. }
  1512. // GetMyCoupons 获取我的优惠卷信息
  1513. func GetMyCoupons(accountIDs string, goodsID, sellUserID int) ([]MyCoupon, error) {
  1514. engine := db.GetEngine()
  1515. myCoupons := make([]MyCoupon, 0)
  1516. session := engine.Table("COUPONPOSITION CP").
  1517. Select("to_char(CP.COUPONTYPEID) COUPONTYPEIDSTR, CP.*").
  1518. Join("INNER", "COUPONTYPE CT", "CT.COUPONTYPEID = CP.COUPONTYPEID").
  1519. Where(fmt.Sprintf("CP.ACCOUNTID in (%s)", accountIDs))
  1520. if err := session.Find(&myCoupons); err != nil {
  1521. return nil, err
  1522. }
  1523. // 如果传入了商品ID和卖方UserID,则判断优惠卷是否可用
  1524. if goodsID != 0 && sellUserID != 0 && len(myCoupons) > 0 {
  1525. for i := range myCoupons {
  1526. myCoupon := &myCoupons[i]
  1527. // 优惠卷是否可用于商品
  1528. isRightGoods := false
  1529. if myCoupon.Limitedflag == 0 {
  1530. isRightGoods = true
  1531. } else {
  1532. if strings.Contains(myCoupon.Limitedgoodsids, fmt.Sprintf(",%d,", goodsID)) {
  1533. isRightGoods = true
  1534. }
  1535. }
  1536. // 优惠卷是否可用于卖家
  1537. isRightAccount := false
  1538. if myCoupon.Isgeneral == 1 {
  1539. isRightAccount = true
  1540. } else {
  1541. if strings.Contains(myCoupon.Userscope, fmt.Sprintf(",%d,", sellUserID)) {
  1542. isRightAccount = true
  1543. }
  1544. }
  1545. if !isRightGoods {
  1546. myCoupon.IsUnusable = true
  1547. myCoupon.ReasonType = 1
  1548. }
  1549. if !isRightAccount {
  1550. myCoupon.IsUnusable = true
  1551. myCoupon.ReasonType = 2
  1552. }
  1553. }
  1554. }
  1555. return myCoupons, nil
  1556. }
  1557. // MyCouponHold 我的优惠卷持仓
  1558. type MyCouponHold struct {
  1559. Couponholdid string `json:"couponholdid" xorm:"'COUPONHOLDIDSTR'" binding:"required"` // 优惠券持仓ID(229+Unix秒时间戳(10位)+xxxxxx)
  1560. Giveapplyid int64 `json:"giveapplyid" xorm:"'GIVEAPPLYID'"` // 发放申请ID(SEQ_COUPONGIVEAPPLY)
  1561. Accountid int64 `json:"accountid" xorm:"'ACCOUNTID'"` // 资金账户ID
  1562. Coupontypeid string `json:"coupontypeid" xorm:"'COUPONTYPEIDSTR'"` // 优惠券类型ID - SEQ_COUPONTYPE
  1563. Couponcategroy int32 `json:"couponcategroy" xorm:"'COUPONCATEGROY'"` // 种类 - 1:现金券 2:折扣券 3:折扣券(单个商品)
  1564. Conditionvalue float64 `json:"conditionvalue" xorm:"'CONDITIONVALUE'"` // 条件阈值(可为0)
  1565. Couponvalue float64 `json:"couponvalue" xorm:"'COUPONVALUE'"` // 面值[1:现金券 - 抵扣值 2:折扣券-折扣值]
  1566. Limitedflag int32 `json:"limitedflag" xorm:"'LIMITEDFLAG'"` // 是否指定商品 - 0:不限 1:限制
  1567. Limitedgoodsids string `json:"limitedgoodsids" xorm:"'LIMITEDGOODSIDS'"` // 指定商品IDs[逗号分隔]
  1568. Isgeneral int32 `json:"isgeneral" xorm:"'ISGENERAL'"` // 是否通用券 - 0:否 1:是
  1569. Userscope string `json:"userscope" xorm:"'USERSCOPE'"` // 卖家范围(用户ID,逗号分隔) [IsGeneral =0时使用]
  1570. Userid int64 `json:"userid" xorm:"'USERID'"` // 用户ID
  1571. Qty int64 `json:"qty" xorm:"'QTY'"` // 数量(按1平铺)
  1572. Startdate time.Time `json:"startdate" xorm:"'STARTDATE'"` // 开始日期
  1573. Holdstatus int32 `json:"holdstatus" xorm:"'HOLDSTATUS'"` // 持仓状态 - 1:未生效 2:已生效 3:已使用 4:已过期
  1574. Enddate time.Time `json:"enddate" xorm:"'ENDDATE'"` // 结束日期
  1575. Createtime time.Time `json:"createtime" xorm:"'CREATETIME'"` // 创建时间
  1576. Couponname string `json:"couponname" xorm:"'COUPONNAME'"` // 优惠券名称
  1577. }
  1578. // GetMyCouponHolds 获取优惠卷明细
  1579. func GetMyCouponHolds(accountIDs string, holdStatus string) ([]MyCouponHold, error) {
  1580. engine := db.GetEngine()
  1581. myCouponHolds := make([]MyCouponHold, 0)
  1582. session := engine.Table("COUPONHOLD CH").
  1583. Select(`to_char(CH.COUPONHOLDID) COUPONHOLDIDSTR, to_char(CH.COUPONTYPEID) COUPONTYPEIDSTR, CH.*, CT.COUPONNAME`).
  1584. Join("INNER", "COUPONTYPE CT", "CT.COUPONTYPEID = CH.COUPONTYPEID").
  1585. Where(fmt.Sprintf("CH.ACCOUNTID in (%s)", accountIDs))
  1586. if len(holdStatus) > 0 {
  1587. session = session.And(fmt.Sprintf("CH.HOLDSTATUS in (%s)", holdStatus))
  1588. }
  1589. if err := session.Find(&myCouponHolds); err != nil {
  1590. return nil, err
  1591. }
  1592. return myCouponHolds, nil
  1593. }
  1594. // MyUsedCoupon 已使用优惠卷
  1595. type MyUsedCoupon struct {
  1596. Orderid string `json:"orderid" xorm:"'ORDERIDSTR'" binding:"required"` // 委托单号(100+Unix秒时间戳(10位)+2位(MarketServiceID)+xxxx)
  1597. Coupontypeid string `json:"coupontypeid" xorm:"'COUPONTYPEIDSTR'" binding:"required"` // 优惠券类型ID(买方)
  1598. Accountid int64 `json:"accountid" xorm:"'ACCOUNTID'"` // 资金账户ID(买方)
  1599. Usedqty int64 `json:"usedqty" xorm:"'USEDQTY'"` // 使用数量
  1600. Couponcategroy int32 `json:"couponcategroy" xorm:"'COUPONCATEGROY'"` // 种类 - 1:现金券 2:折扣券
  1601. Conditionvalue float64 `json:"conditionvalue" xorm:"'CONDITIONVALUE'"` // 条件阈值(可为0)
  1602. Couponvalue float64 `json:"couponvalue" xorm:"'COUPONVALUE'"` // 面值[1:现金券 - 抵扣值 2:折扣券-折扣值(0-100)]
  1603. Sellaccountid int64 `json:"sellaccountid" xorm:"'SELLACCOUNTID'"` // 资金账户ID(卖方)
  1604. Marketid int32 `json:"marketid" xorm:"'MARKETID'"` // 市场ID
  1605. Goodsid int32 `json:"goodsid" xorm:"'GOODSID'"` // 商品ID
  1606. Tradeid string `json:"tradeid" xorm:"'TRADEIDSTR'"` // 成交单号(101+Unix秒时间戳(10位)+2位(MarketServiceID)+xxxx)
  1607. Tradeamount float64 `json:"tradeamount" xorm:"'TRADEAMOUNT'"` // 成交金额
  1608. Offamount float64 `json:"offamount" xorm:"'OFFAMOUNT'"` // 优惠金额
  1609. Handlestatus int32 `json:"handlestatus" xorm:"'HANDLESTATUS'"` // 处理状态
  1610. Createtime time.Time `json:"createtime" xorm:"'CREATETIME'"` // 创建时间
  1611. Couponname string `json:"couponname" xorm:"'COUPONNAME'"` // 优惠券名称
  1612. }
  1613. // GetMyUsedCoupon 获取已使用优惠卷
  1614. func GetMyUsedCoupon(accountIDs string) ([]MyUsedCoupon, error) {
  1615. engine := db.GetEngine()
  1616. myUsedCoupons := make([]MyUsedCoupon, 0)
  1617. if err := engine.Table("TRADE_ORDERCOUPON T").
  1618. Select(`to_char(T.ORDERID) ORDERIDSTR, to_char(T.COUPONTYPEID) COUPONTYPEIDSTR, to_char(T.TRADEID) TRADEIDSTR, T.*,
  1619. C.COUPONNAME`).
  1620. Join("INNER", "COUPONTYPE C", "C.COUPONTYPEID = T.COUPONTYPEID").
  1621. Where(fmt.Sprintf("T.ACCOUNTID in (%s)", accountIDs)).
  1622. Desc("T.CREATETIME").
  1623. Find(&myUsedCoupons); err != nil {
  1624. return nil, err
  1625. }
  1626. return myUsedCoupons, nil
  1627. }