hsby.go 88 KB

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