goods.go 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312
  1. /**
  2. * @Author: zou.yingbin
  3. * @Create : 2021/10/27 14:20
  4. * @Modify : 2021/10/27 14:20
  5. * @note : 商品信息缓存
  6. */
  7. package mtpcache
  8. import (
  9. "mtp2_if/db"
  10. "mtp2_if/utils"
  11. "strings"
  12. "time"
  13. "github.com/muesli/cache2go"
  14. )
  15. var goodsCache *cache2go.CacheTable
  16. var goodsExCache *cache2go.CacheTable
  17. func init() {
  18. goodsCache = cache2go.Cache("goods")
  19. goodsCache.SetDataLoader(func(key interface{}, param ...interface{}) *cache2go.CacheItem {
  20. if v, ok := key.(string); ok {
  21. m := Goods{GOODSCODE: v}
  22. if d, err := m.GetData(); err == nil {
  23. if len(d) > 0 {
  24. val := d[0]
  25. item := cache2go.NewCacheItem(val.Key(), 0, val)
  26. return item
  27. }
  28. }
  29. }
  30. return nil
  31. })
  32. goodsExCache = cache2go.Cache("goodsex")
  33. goodsExCache.SetDataLoader(func(key interface{}, param ...interface{}) *cache2go.CacheItem {
  34. if v, ok := key.(string); ok {
  35. m := Goodsex{GOODSCODE: v}
  36. if d, err := m.GetData(); err == nil {
  37. if len(d) > 0 {
  38. val := d[0]
  39. item := cache2go.NewCacheItem(val.Key(), 0, val)
  40. return item
  41. }
  42. }
  43. }
  44. return nil
  45. })
  46. // 延时5秒 加载所有商品
  47. go func() {
  48. ticker := time.NewTicker(10 * time.Second)
  49. for range ticker.C {
  50. loadData()
  51. }
  52. // time.Sleep(time.Second * 5)
  53. // loadData()
  54. }()
  55. }
  56. func loadData() {
  57. m := Goods{}
  58. d, err := m.GetData()
  59. if err == nil {
  60. for _, v := range d {
  61. goodsCache.Add(v.Key(), 0, v)
  62. }
  63. }
  64. m1 := Goodsex{}
  65. if d, err := m1.GetData(); err == nil {
  66. for _, v := range d {
  67. goodsExCache.Add(v.Key(), 0, v)
  68. }
  69. }
  70. }
  71. // Goods 商品信息
  72. type Goods struct {
  73. GOODSID int64 `json:"goodsid" xorm:"'GOODSID'"` // 商品ID(自增ID SEQ_GOODS)
  74. GOODSCODE string `json:"goodscode" xorm:"'GOODSCODE'"` // 商品代码(内部)
  75. GOODSNAME string `json:"goodsname" xorm:"'GOODSNAME'"` // 商品名称
  76. MARKETID string `json:"marketid" xorm:"'MARKETID'"` // 所属市场ID
  77. GOODSGROUPID int32 `json:"goodsgroupid" xorm:"'GOODSGROUPID'"` // 所属商品组ID
  78. GOODSSTATUS int32 `json:"goodsstatus" xorm:"'GOODSSTATUS'"` // 商品状态- 1:待审核 2:未上市 3:上市 4:已注销 5:审核拒绝 6:退市 7:待退市
  79. CURRENCYID int32 `json:"currencyid" xorm:"'CURRENCYID'"` // 报价货币ID(80:计价货币)
  80. GOODUNITID int32 `json:"goodunitid" xorm:"'GOODUNITID'"` // 报价单位ID
  81. AGREEUNIT float64 `json:"agreeunit" xorm:"'AGREEUNIT'"` // 合约乘数
  82. DECIMALPLACE int32 `json:"decimalplace" xorm:"'DECIMALPLACE'"` // 报价小数位
  83. QTYDECIMALPLACE int32 `json:"qtydecimalplace" xorm:"'QTYDECIMALPLACE'"` // 成交量小数位
  84. GOODSCURRENCYID int32 `json:"goodscurrencyid" xorm:"'GOODSCURRENCYID'"` // 合约货币ID(80:基础货币)
  85. REFGOODSID int64 `json:"refgoodsid" xorm:"'REFGOODSID'"` // 参考商品ID
  86. REFGOODSCODE string `json:"refgoodscode" xorm:"'REFGOODSCODE'"` // 参考商品代码
  87. THUMURLS string `json:"thumurls" xorm:"THUMURLS"` // 缩略图片(1:1)(逗号分隔)
  88. }
  89. func (r *Goods) Key() string {
  90. return r.GOODSCODE
  91. }
  92. func (r *Goods) calc() {
  93. }
  94. func (r *Goods) buildSql() string {
  95. var sqlId utils.SQLVal = `
  96. select t.goodsid,
  97. upper(t.goodscode) goodscode,
  98. t.goodsname,
  99. t.marketid,
  100. t.goodsgroupid,
  101. t.goodsstatus,
  102. t.currencyid,
  103. t.goodunitid,
  104. t.agreeunit,
  105. t.decimalplace,
  106. t.qtydecimalplace,
  107. t.goodscurrencyid,
  108. t.goodsquotetype,
  109. t.refgoodsid,
  110. t.refgoodscode,
  111. t.thumurls
  112. from goods t
  113. where 1=1
  114. `
  115. sqlId.AndEx("t.goodsid", r.GOODSID, r.GOODSID > 0)
  116. if r.GOODSCODE != "" {
  117. // 不区分大小写加载商品
  118. sqlId.JoinFormat(" and upper(t.goodscode) = '%v'", strings.ToUpper(r.GOODSCODE))
  119. }
  120. return sqlId.String()
  121. }
  122. // GetDataEx 获取商品信息
  123. func (r *Goods) GetData() ([]Goods, error) {
  124. sData := make([]Goods, 0)
  125. e := db.GetEngine()
  126. if e == nil {
  127. return sData, nil
  128. }
  129. err := e.SQL(r.buildSql()).Find(&sData)
  130. for i := range sData {
  131. sData[i].calc()
  132. }
  133. return sData, err
  134. }
  135. // GetGoods 获取商品信息
  136. func GetGoods(goodsCode string) (Goods, bool) {
  137. // 缓存是用大写的goodscode, 查找也转成大写的来查找
  138. goodsCode2 := strings.ToUpper(goodsCode)
  139. item, err := goodsCache.Value(goodsCode2)
  140. if err == nil {
  141. d := item.Data()
  142. if v, ok := d.(Goods); ok {
  143. return v, true
  144. } else if v2, ok2 := d.(*Goods); ok2 {
  145. return *v2, true
  146. }
  147. }
  148. return Goods{}, false
  149. }
  150. // GetGoodsDecimalplace 获取商品小数位
  151. func GetGoodsDecimalplace(goodsCode string) int {
  152. if d, ok := GetGoods(strings.ToUpper(goodsCode)); ok {
  153. return int(d.DECIMALPLACE)
  154. }
  155. if d, ok := GetGoods(goodsCode); ok {
  156. return int(d.DECIMALPLACE)
  157. }
  158. return 0
  159. }
  160. type Goodsex struct {
  161. GOODSID int32 `json:"goodsid" xorm:"GOODSID"` // 期货合约ID
  162. GOODSCODE string `json:"goodscode" xorm:"'GOODSCODE'"` // 商品代码(内部)
  163. MARKETID int32 `json:"marketid" xorm:"MARKETID"` // 所属市场ID
  164. LATEFEEDAYS int32 `json:"latefeedays" xorm:"LATEFEEDAYS"` // 滞纳金起计天数(52)
  165. LATEFEEALGORITHM int32 `json:"latefeealgorithm" xorm:"LATEFEEALGORITHM"` // 滞纳金收取方式 1:比率 2:固定(52)
  166. LATEFEEVALUE float64 `json:"latefeevalue" xorm:"LATEFEEVALUE"` // 滞纳金收取值(52)
  167. BUYPREMIUM float64 `json:"buypremium" xorm:"BUYPREMIUM"` // 买交收升贴水(52)
  168. SELLPREMIUM float64 `json:"sellpremium" xorm:"SELLPREMIUM"` // 卖交收升贴水(52)
  169. PROMPTDEPOSITRATE float64 `json:"promptdepositrate" xorm:"PROMPTDEPOSITRATE"` // 提示定金率(52)
  170. CUTDEPOSITRATE float64 `json:"cutdepositrate" xorm:"CUTDEPOSITRATE"` // 斩仓定金率(52)
  171. ISDEPOSITCHANGED int32 `json:"isdepositchanged" xorm:"ISDEPOSITCHANGED"` // 定金率是否变更 - 0:否 1:是(52)
  172. ISTOALL int32 `json:"istoall" xorm:"ISTOALL"` // 是否全部单据生效 - 0:否(仅新单据生效) 1:是(全部单据生效)(52)
  173. NEWPROMPTDEPOSITRATE float64 `json:"newpromptdepositrate" xorm:"NEWPROMPTDEPOSITRATE"` // 新提示定金率(52)
  174. NEWCUTDEPOSITRATE float64 `json:"newcutdepositrate" xorm:"NEWCUTDEPOSITRATE"` // 新斩仓定金率(52)
  175. MINDELIVERYLOT int32 `json:"mindeliverylot" xorm:"MINDELIVERYLOT"` // 最小交收手数(50-线下交收)
  176. MINSPREAD float64 `json:"minspread" xorm:"MINSPREAD"` // 点差下限(46)
  177. MAXSPREAD float64 `json:"maxspread" xorm:"MAXSPREAD"` // 点差上限(46)
  178. GOODSORDER string `json:"goodsorder" xorm:"GOODSORDER"` // 商品显示顺序(99)
  179. CANAUTOADDDEPOSIT int32 `json:"canautoadddeposit" xorm:"CANAUTOADDDEPOSIT"` // 是否允许自动追加定金: 0-否 1-是(52)
  180. ADDDEPOSITRATE float64 `json:"adddepositrate" xorm:"ADDDEPOSITRATE"` // 自动追加定金率(52) - 允许时显示
  181. CANAUTOREFUNDDEPOSIT int32 `json:"canautorefunddeposit" xorm:"CANAUTOREFUNDDEPOSIT"` // 是否允许自动退还定金: 0-否 1-是(52)
  182. NEWADDDEPOSITRATE float64 `json:"newadddepositrate" xorm:"NEWADDDEPOSITRATE"` // 新自动追加定金率(52) - 允许时显示
  183. DRAUDITFLAG int32 `json:"drauditflag" xorm:"DRAUDITFLAG"` // 定金率修改待审核标识(52) - 0:不需审核 1:待审核
  184. TMPTRANSFERDEPOSITRATIO float64 `json:"tmptransferdepositratio" xorm:"TMPTRANSFERDEPOSITRATIO"` // 临时转让定金比例(49)
  185. GOODSNAMETH string `json:"goodsnameth" xorm:"GOODSNAMETH"` // 期货合约名称泰文)
  186. GOODSNAMEEN string `json:"goodsnameen" xorm:"GOODSNAMEEN"` // 期货合约名称(英文)
  187. GOODSNAMETW string `json:"goodsnametw" xorm:"GOODSNAMETW"` // 期货合约名称(繁体)
  188. BUYPRICEMOVEALGORITHM int32 `json:"buypricemovealgorithm" xorm:"BUYPRICEMOVEALGORITHM"` // 买交收升贴水算法
  189. BUYPRICEMOVEVALUE float64 `json:"buypricemovevalue" xorm:"BUYPRICEMOVEVALUE"` // 买交收升贴水值
  190. BUYSHIPPINGFEEALGORITHM int32 `json:"buyshippingfeealgorithm" xorm:"BUYSHIPPINGFEEALGORITHM"` // 买交收运费算法
  191. BUYSHIPPINGFEEVALUE float64 `json:"buyshippingfeevalue" xorm:"BUYSHIPPINGFEEVALUE"` // 买交收运费值
  192. BUYOTHERFEEALGORITHM int32 `json:"buyotherfeealgorithm" xorm:"BUYOTHERFEEALGORITHM"` // 买交收其它费用算法
  193. BUYOTHERFEEVALUE float64 `json:"buyotherfeevalue" xorm:"BUYOTHERFEEVALUE"` // 买交收其它费用值
  194. SELLPRICEMOVEALGORITHM int32 `json:"sellpricemovealgorithm" xorm:"SELLPRICEMOVEALGORITHM"` // 卖交收升贴水算法
  195. SELLPRICEMOVEVALUE float64 `json:"sellpricemovevalue" xorm:"SELLPRICEMOVEVALUE"` // 卖交收升贴水值
  196. SELLSHIPPINGFEEALGORITHM int32 `json:"sellshippingfeealgorithm" xorm:"SELLSHIPPINGFEEALGORITHM"` // 卖交收运费算法
  197. SELLSHIPPINGFEEVALUE float64 `json:"sellshippingfeevalue" xorm:"SELLSHIPPINGFEEVALUE"` // 卖交收运费值
  198. SELLOTHERFEEALGORITHM int32 `json:"sellotherfeealgorithm" xorm:"SELLOTHERFEEALGORITHM"` // 卖交收其它费用算法
  199. SELLOTHERFEEVALUE float64 `json:"sellotherfeevalue" xorm:"SELLOTHERFEEVALUE"` // 卖交收其它费用值
  200. GOODSNAMEVI string `json:"goodsnamevi" xorm:"GOODSNAMEVI"` // 期货合约名称(越南语)
  201. }
  202. func (r *Goodsex) Key() string {
  203. return r.GOODSCODE
  204. }
  205. func (r *Goodsex) calc() {
  206. }
  207. func (r *Goodsex) buildSql() string {
  208. var sqlId utils.SQLVal = `
  209. select
  210. t.goodsid,
  211. t.marketid,
  212. t.latefeedays,
  213. t.latefeealgorithm,
  214. t.latefeevalue,
  215. t.buypremium,
  216. t.sellpremium,
  217. t.promptdepositrate,
  218. t.cutdepositrate,
  219. t.isdepositchanged,
  220. t.istoall,
  221. t.newpromptdepositrate,
  222. t.newcutdepositrate,
  223. t.mindeliverylot,
  224. t.minspread,
  225. t.maxspread,
  226. t.goodsorder,
  227. t.canautoadddeposit,
  228. t.adddepositrate,
  229. t.canautorefunddeposit,
  230. t.newadddepositrate,
  231. t.drauditflag,
  232. t.tmptransferdepositratio,
  233. t.goodsnameth,
  234. t.goodsnameen,
  235. t.goodsnametw,
  236. t.goodsnamevi,
  237. t.buypricemovealgorithm,
  238. t.buypricemovevalue,
  239. t.buyshippingfeealgorithm,
  240. t.buyshippingfeevalue,
  241. t.buyotherfeealgorithm,
  242. t.buyotherfeevalue,
  243. t.sellpricemovealgorithm,
  244. t.sellpricemovevalue,
  245. t.sellshippingfeealgorithm,
  246. t.sellshippingfeevalue,
  247. t.sellotherfeealgorithm,
  248. t.sellotherfeevalue,
  249. g.goodscode
  250. from goodsex t
  251. inner join goods g on g.goodsid = t.goodsid
  252. where 1=1
  253. `
  254. sqlId.AndEx("t.goodsid", r.GOODSID, r.GOODSID > 0)
  255. if r.GOODSCODE != "" {
  256. // 不区分大小写加载商品
  257. sqlId.JoinFormat(" and upper(g.goodscode) = '%v'", strings.ToUpper(r.GOODSCODE))
  258. }
  259. return sqlId.String()
  260. }
  261. // GetDataEx 获取商品信息
  262. func (r *Goodsex) GetData() ([]Goodsex, error) {
  263. sData := make([]Goodsex, 0)
  264. e := db.GetEngine()
  265. if e == nil {
  266. return sData, nil
  267. }
  268. err := e.SQL(r.buildSql()).Find(&sData)
  269. for i := range sData {
  270. sData[i].calc()
  271. }
  272. return sData, err
  273. }
  274. func GetGoodsEx(goodsCode string) (Goodsex, bool) {
  275. // 缓存是用大写的goodscode, 查找也转成大写的来查找
  276. goodsCode2 := strings.ToUpper(goodsCode)
  277. if item, err := goodsExCache.Value(goodsCode2); err == nil {
  278. d := item.Data()
  279. if v, ok := d.(Goodsex); ok {
  280. return v, true
  281. } else if v2, ok2 := d.(*Goodsex); ok2 {
  282. return *v2, true
  283. }
  284. }
  285. return Goodsex{}, false
  286. }