hsby.go 93 KB

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