order.go 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860
  1. package dao
  2. import (
  3. "context"
  4. "crypto/md5"
  5. "database/sql"
  6. "encoding/json"
  7. "errors"
  8. "fmt"
  9. "net/url"
  10. "strings"
  11. "time"
  12. "go-common/app/service/openplatform/ticket-sales/model"
  13. "go-common/app/service/openplatform/ticket-sales/model/consts"
  14. "go-common/library/cache/redis"
  15. xsql "go-common/library/database/sql"
  16. "go-common/library/ecode"
  17. "github.com/gogo/protobuf/types"
  18. )
  19. //订单相关常量
  20. const (
  21. cacheTimeout = 10
  22. DefaultOrderPSize = 20 //默认每页数量
  23. DefaultOrderOrderBy = "id desc" //默认排序
  24. //sqlGetUserOrders 查询用户订单列表
  25. sqlGetUserOrders = "SELECT %s FROM order_main WHERE uid=? AND is_deleted = 0 ORDER BY %s LIMIT %d,%d"
  26. //sqlGetUserItemOrders 查询用户已购买的某个项目订单
  27. sqlGetUserItemOrders = "SELECT %s FROM order_main WHERE uid=? AND item_id=? AND status IN (%s)"
  28. //sqlCountUserOrders 查询用户订单数量
  29. sqlCountUserOrders = "SELECT COUNT(*) FROM order_main WHERE uid=? AND is_deleted=0"
  30. //sqlGetOrders 查询订单列表
  31. sqlGetOrders = "SELECT %s FROM order_main WHERE order_id IN (%s)"
  32. //sqlInsertOrderMains 批量写入order_main
  33. sqlInsertOrderMains = "INSERT INTO order_main(%s) VALUES %s"
  34. //sqlGetOrderDetails 查询订单详情
  35. sqlGetOrderDetails = "SELECT %s FROM order_detail WHERE order_id IN (%s)"
  36. //sqlInsertOrderDetails 批量写入order_detail
  37. sqlInsertOrderDetails = "INSERT INTO order_detail(%s) VALUES %s"
  38. //sqlGetOrderSkus 查询order_sku
  39. sqlGetOrderSkus = "SELECT %s FROM order_sku WHERE order_id IN (%s)"
  40. //sqlInsertOrderSkus 批量写入order_sku
  41. sqlInsertOrderSkus = "INSERT INTO order_sku(%s) VALUES %s"
  42. //sqlGetBoughtSkus 获取已购买的sku
  43. sqlGetBoughtSkus = "SELECT `count` FROM order_sku WHERE order_id IN (%s) AND sku_id IN (%s)"
  44. //sqlGetOrderPayChs 获取支付流水
  45. sqlGetOrderPayChs = "SELECT %s FROM order_pay_charge WHERE order_id IN (%s) AND paid=1"
  46. //获取结算对账订单(0元单)
  47. sqlGetSettleCompareOrders = "SELECT id,order_id FROM order_main WHERE ctime>=? and ctime<? AND id>? AND status IN (%s) AND pay_money=0 ORDER BY ctime,id LIMIT ?"
  48. //获取结算对帐退款单
  49. sqlGetSettleCompareRefunds = "SELECT id,order_id,refund_apply_time FROM order_refund WHERE ctime>=? AND ctime<? AND id>? AND status IN (%s) AND refund_money=0 ORDER BY ctime,id LIMIT ?"
  50. )
  51. //RawOrders 从db查询用户订单信息,包括以下情况
  52. //* 按照订单号查询
  53. //* 按照uid查分页
  54. //* 按照uid+商品id+状态查询列表
  55. func (d *Dao) RawOrders(ctx context.Context, req *model.OrderMainQuerier) (orders []*model.OrderMain, err error) {
  56. defer LogX(ctx, req, orders, err)
  57. o := new(model.OrderMain)
  58. sqls, args := pickOrderSQL(req, o.GetFields(nil))
  59. q := sqls[0]
  60. if q == "" {
  61. return
  62. }
  63. r, err := d.db.Query(ctx, q, args...)
  64. if err != nil {
  65. if err == sql.ErrNoRows {
  66. err = nil
  67. }
  68. return
  69. }
  70. defer r.Close()
  71. for r.Next() {
  72. vptrs := make(map[int]interface{})
  73. ptrs := o.GetPtrs(nil, vptrs)
  74. if err = r.Scan(ptrs...); err != nil {
  75. return
  76. }
  77. for k, v := range vptrs {
  78. json.Unmarshal([]byte(*ptrs[k].(*string)), v)
  79. }
  80. orders = append(orders, o)
  81. o = new(model.OrderMain)
  82. }
  83. return
  84. }
  85. //RawOrderCount 从db获取用户订单数目,当查询条件仅有uid时生效,否则返回0
  86. func (d *Dao) RawOrderCount(ctx context.Context, req *model.OrderMainQuerier) (cnt int64, err error) {
  87. defer LogX(ctx, req, cnt, err)
  88. sqls, args := pickOrderSQL(req, nil)
  89. q := sqls[1]
  90. if q == "" {
  91. return
  92. }
  93. r := d.db.QueryRow(ctx, q, args...)
  94. err = r.Scan(&cnt)
  95. //缓存回源逻辑0会被当成没命中缓存
  96. if cnt == 0 {
  97. cnt = -1
  98. }
  99. return
  100. }
  101. //RawOrderDetails 从db获取订单详细
  102. func (d *Dao) RawOrderDetails(ctx context.Context, oids []int64) (orders map[int64]*model.OrderDetail, err error) {
  103. defer LogX(ctx, oids, orders, err)
  104. lo := len(oids)
  105. if lo == 0 {
  106. return
  107. }
  108. a := make([]interface{}, lo)
  109. for k, v := range oids {
  110. a[k] = v
  111. }
  112. o := new(model.OrderDetail)
  113. f := o.GetFields(nil)
  114. q := fmt.Sprintf(sqlGetOrderDetails, "`"+strings.Join(f, "`,`")+"`", strings.Repeat(",?", lo)[1:])
  115. r, err := d.db.Query(ctx, q, a...)
  116. if err != nil {
  117. if err == sql.ErrNoRows {
  118. err = nil
  119. }
  120. return
  121. }
  122. defer r.Close()
  123. orders = make(map[int64]*model.OrderDetail, lo)
  124. for r.Next() {
  125. vptrs := make(map[int]interface{})
  126. ptrs := o.GetPtrs(nil, vptrs)
  127. if err = r.Scan(ptrs...); err != nil {
  128. return
  129. }
  130. for k, v := range vptrs {
  131. json.Unmarshal([]byte(*ptrs[k].(*string)), v)
  132. }
  133. o.Decrypt(d.c.Encrypt)
  134. orders[o.OrderID] = o
  135. o = new(model.OrderDetail)
  136. }
  137. return
  138. }
  139. //RawOrderSKUs 从db获取订单的sku
  140. func (d *Dao) RawOrderSKUs(ctx context.Context, oids []int64) (skus map[int64][]*model.OrderSKU, err error) {
  141. defer LogX(ctx, oids, skus, err)
  142. lo := len(oids)
  143. if lo == 0 {
  144. return
  145. }
  146. a := make([]interface{}, lo)
  147. for k, v := range oids {
  148. a[k] = v
  149. }
  150. o := new(model.OrderSKU)
  151. f := o.GetFields(nil)
  152. q := fmt.Sprintf(sqlGetOrderSkus, "`"+strings.Join(f, "`,`")+"`", strings.Repeat(",?", lo)[1:])
  153. r, err := d.db.Query(ctx, q, a...)
  154. if err != nil {
  155. if err == sql.ErrNoRows {
  156. err = nil
  157. }
  158. return
  159. }
  160. defer r.Close()
  161. skus = make(map[int64][]*model.OrderSKU, lo)
  162. for r.Next() {
  163. vptrs := make(map[int]interface{})
  164. ptrs := o.GetPtrs(nil, vptrs)
  165. if err = r.Scan(ptrs...); err != nil {
  166. return
  167. }
  168. for k, v := range vptrs {
  169. json.Unmarshal([]byte(*ptrs[k].(*string)), v)
  170. }
  171. skus[o.OrderID] = append(skus[o.OrderID], o)
  172. o = new(model.OrderSKU)
  173. }
  174. return
  175. }
  176. //RawBoughtCount 按照票种获取用户已购的订单票数
  177. func (d *Dao) RawBoughtCount(ctx context.Context, uid string, itemID int64, skuIDs []int64) (cnt int64, err error) {
  178. query := &model.OrderMainQuerier{
  179. UID: uid,
  180. ItemID: itemID,
  181. Status: []int16{consts.OrderStatusUnpaid, consts.OrderStatusPaid},
  182. }
  183. orders, err := d.RawOrders(ctx, query)
  184. if err != nil {
  185. return
  186. }
  187. //存在部分退款,要减去已退款票数
  188. pt := false
  189. lo := len(orders)
  190. oids := make([]int64, lo)
  191. for k, v := range orders {
  192. if v.RefundStatus == consts.RefundStatusPtRefunded {
  193. pt = true
  194. }
  195. cnt += v.Count
  196. oids[k] = v.OrderID
  197. }
  198. ls := len(skuIDs)
  199. //查具体sku的,要再次从order_sku表统计
  200. if ls > 0 && lo > 0 {
  201. cnt, err = d.rawBoughtSkusCnt(ctx, oids, skuIDs)
  202. if err != nil {
  203. return
  204. }
  205. }
  206. //部分退款的减去已退款张数
  207. if pt {
  208. var rCnt int64
  209. rCnt, err = d.rawRefundTicketCnt(ctx, oids)
  210. if err != nil {
  211. return
  212. }
  213. cnt -= rCnt
  214. }
  215. return
  216. }
  217. //rawBoughtSkusCnt 按照skuID统计用户购买数
  218. func (d *Dao) rawBoughtSkusCnt(ctx context.Context, oids []int64, skuIDs []int64) (cnt int64, err error) {
  219. lo := len(oids)
  220. ls := len(skuIDs)
  221. if lo == 0 || ls == 0 {
  222. err = ecode.RequestErr
  223. return
  224. }
  225. q := fmt.Sprintf(sqlGetBoughtSkus, strings.Repeat(",?", lo)[1:], strings.Repeat(",?", ls)[1:])
  226. a := make([]interface{}, lo+ls)
  227. for k, v := range oids {
  228. a[k] = v
  229. }
  230. for k, v := range skuIDs {
  231. a[k+lo] = v
  232. }
  233. r, err := d.db.Query(ctx, q, a...)
  234. if err != nil {
  235. return
  236. }
  237. defer r.Close()
  238. var c int64
  239. for r.Next() {
  240. if err = r.Scan(&c); err != nil {
  241. return
  242. }
  243. cnt += c
  244. }
  245. return
  246. }
  247. //RawOrderPayCharges 从db获取订单流水
  248. func (d *Dao) RawOrderPayCharges(ctx context.Context, oids []int64) (chs map[int64]*model.OrderPayCharge, err error) {
  249. defer LogX(ctx, oids, chs, err)
  250. lo := len(oids)
  251. if lo == 0 {
  252. return
  253. }
  254. a := make([]interface{}, lo)
  255. for k, v := range oids {
  256. a[k] = v
  257. }
  258. o := new(model.OrderPayCharge)
  259. f := o.GetFields(nil)
  260. q := fmt.Sprintf(sqlGetOrderPayChs, "`"+strings.Join(f, "`,`")+"`", strings.Repeat(",?", lo)[1:])
  261. r, err := d.db.Query(ctx, q, a...)
  262. if err != nil {
  263. if err == sql.ErrNoRows {
  264. err = nil
  265. }
  266. return
  267. }
  268. defer r.Close()
  269. chs = make(map[int64]*model.OrderPayCharge, lo)
  270. for r.Next() {
  271. ptrs := o.GetPtrs(&types.FieldMask{Paths: f}, nil)
  272. if err = r.Scan(ptrs...); err != nil {
  273. return
  274. }
  275. chs[o.OrderID] = o
  276. o = new(model.OrderPayCharge)
  277. }
  278. return
  279. }
  280. //CacheOrders 从缓存获取订单基础信息
  281. func (d *Dao) CacheOrders(ctx context.Context, req *model.OrderMainQuerier) (orders []*model.OrderMain, err error) {
  282. pool := d.redis.Get(ctx)
  283. defer func() {
  284. pool.Close()
  285. LogX(ctx, req, orders, err)
  286. }()
  287. var keys []interface{}
  288. if l := len(req.OrderID); l > 0 {
  289. keys = make([]interface{}, l)
  290. for k, v := range req.OrderID {
  291. keys[k] = fmt.Sprintf("%s:%d", model.CacheKeyOrderMn, v)
  292. }
  293. } else if key := oidCacheKey(req); key != "" {
  294. //如果查的是列表,先查出列表缓存的orderId,再根据orderId查订单信息
  295. var b []byte
  296. key = model.CacheKeyOrderList + ":" + key
  297. if b, err = redis.Bytes(pool.Do("GET", key)); err != nil {
  298. if err == redis.ErrNil {
  299. err = nil
  300. }
  301. return
  302. }
  303. s := string(b)
  304. LogX(ctx, []string{"GET", key}, s, err)
  305. oids := strings.Split(s, ",")
  306. keys = make([]interface{}, len(oids))
  307. for k, v := range oids {
  308. keys[k] = model.CacheKeyOrderMn + ":" + v
  309. }
  310. }
  311. if len(keys) == 0 {
  312. return
  313. }
  314. var data [][]byte
  315. if data, err = redis.ByteSlices(pool.Do("MGET", keys...)); err != nil {
  316. return
  317. }
  318. LogX(ctx, append([]interface{}{"MGET"}, keys...), data, err)
  319. for _, v := range data {
  320. if v != nil {
  321. o := &model.OrderMain{}
  322. orders = append(orders, o)
  323. json.Unmarshal(v, o)
  324. }
  325. }
  326. return
  327. }
  328. //CacheOrderCount 从缓存获取订单数目
  329. func (d *Dao) CacheOrderCount(ctx context.Context, req *model.OrderMainQuerier) (cnt int64, err error) {
  330. pool := d.redis.Get(ctx)
  331. defer func() {
  332. pool.Close()
  333. LogX(ctx, req, cnt, err)
  334. }()
  335. if key := oidCacheKey(req); key != "" {
  336. if cnt, err = redis.Int64(pool.Do("GET", model.CacheKeyOrderCnt+":"+key)); err == redis.ErrNil {
  337. err = nil
  338. }
  339. }
  340. return
  341. }
  342. //CacheOrderDetails 从缓存获取订单详细
  343. func (d *Dao) CacheOrderDetails(ctx context.Context, oids []int64) (orders map[int64]*model.OrderDetail, err error) {
  344. pool := d.redis.Get(ctx)
  345. defer func() {
  346. pool.Close()
  347. LogX(ctx, oids, orders, err)
  348. }()
  349. lo := len(oids)
  350. keys := make([]interface{}, lo)
  351. for k, v := range oids {
  352. keys[k] = fmt.Sprintf("%s:%d", model.CacheKeyOrderDt, v)
  353. }
  354. var data [][]byte
  355. if data, err = redis.ByteSlices(pool.Do("MGET", keys...)); err != nil {
  356. return
  357. }
  358. LogX(ctx, append([]interface{}{"MGET"}, keys...), data, nil)
  359. orders = make(map[int64]*model.OrderDetail, lo)
  360. for k, v := range oids {
  361. if data[k] == nil {
  362. continue
  363. }
  364. o := &model.OrderDetail{}
  365. if err = json.Unmarshal(data[k], o); err != nil {
  366. err = nil
  367. } else {
  368. orders[v] = o
  369. }
  370. }
  371. return
  372. }
  373. //CacheOrderSKUs 获取订单sku缓存
  374. func (d *Dao) CacheOrderSKUs(ctx context.Context, oids []int64) (skus map[int64][]*model.OrderSKU, err error) {
  375. pool := d.redis.Get(ctx)
  376. defer func() {
  377. pool.Close()
  378. LogX(ctx, oids, skus, err)
  379. }()
  380. lo := len(oids)
  381. keys := make([]interface{}, lo)
  382. for k, v := range oids {
  383. keys[k] = fmt.Sprintf("%s:%d", model.CacheKeyOrderSKU, v)
  384. }
  385. var data [][]byte
  386. if data, err = redis.ByteSlices(pool.Do("MGET", keys...)); err != nil {
  387. return
  388. }
  389. LogX(ctx, append([]interface{}{"MGET"}, keys...), data, nil)
  390. skus = make(map[int64][]*model.OrderSKU, lo)
  391. for k, v := range oids {
  392. if data[k] == nil {
  393. continue
  394. }
  395. o := []*model.OrderSKU{}
  396. if err = json.Unmarshal(data[k], &o); err != nil {
  397. err = nil
  398. } else {
  399. skus[v] = o
  400. }
  401. }
  402. return
  403. }
  404. //CacheOrderPayCharges 从缓存获取订单流水
  405. func (d *Dao) CacheOrderPayCharges(ctx context.Context, oids []int64) (chs map[int64]*model.OrderPayCharge, err error) {
  406. pool := d.redis.Get(ctx)
  407. defer func() {
  408. pool.Close()
  409. LogX(ctx, oids, chs, err)
  410. }()
  411. lo := len(oids)
  412. if lo == 0 {
  413. return
  414. }
  415. keys := make([]interface{}, lo)
  416. for k, v := range oids {
  417. keys[k] = fmt.Sprintf("%s:%d", model.CacheKeyOrderPayCh, v)
  418. }
  419. var data [][]byte
  420. if data, err = redis.ByteSlices(pool.Do("MGET", keys...)); err != nil {
  421. return
  422. }
  423. LogX(ctx, append([]interface{}{"MGET"}, keys...), data, nil)
  424. chs = make(map[int64]*model.OrderPayCharge, lo)
  425. for k, v := range oids {
  426. if data[k] == nil {
  427. continue
  428. }
  429. ch := &model.OrderPayCharge{}
  430. if err = json.Unmarshal(data[k], ch); err != nil {
  431. err = nil
  432. } else {
  433. chs[v] = ch
  434. }
  435. }
  436. return
  437. }
  438. //AddCacheOrders 设置订单基础信息缓存
  439. func (d *Dao) AddCacheOrders(ctx context.Context, req *model.OrderMainQuerier, res []*model.OrderMain) (err error) {
  440. pool := d.redis.Get(ctx)
  441. defer func() {
  442. pool.Flush()
  443. pool.Close()
  444. LogX(ctx, []interface{}{req, res}, nil, err)
  445. }()
  446. data := make([]interface{}, len(res)*2)
  447. var sOids string
  448. for k, v := range res {
  449. if sOids == "" {
  450. sOids = fmt.Sprintf("%d", v.OrderID)
  451. } else {
  452. sOids += fmt.Sprintf(",%d", v.OrderID)
  453. }
  454. b, _ := json.Marshal(v)
  455. data[k*2] = fmt.Sprintf("%s:%d", model.CacheKeyOrderMn, v.OrderID)
  456. data[k*2+1] = b
  457. }
  458. //设置列表orderID缓存
  459. if key := oidCacheKey(req); key != "" {
  460. arg := []interface{}{model.CacheKeyOrderList + ":" + key, cacheTimeout, sOids}
  461. LogX(ctx, append([]interface{}{"SETEX"}, arg...), nil, nil)
  462. if err = pool.Send("SETEX", arg...); err != nil {
  463. return
  464. }
  465. }
  466. LogX(ctx, append([]interface{}{"MSET"}, data...), nil, nil)
  467. if err = pool.Send("MSET", data...); err != nil {
  468. return
  469. }
  470. for i := 0; i < len(data); i += 2 {
  471. pool.Send("EXPIRE", data[i], cacheTimeout)
  472. }
  473. return
  474. }
  475. //AddCacheOrderCount 设置订单数目缓存
  476. func (d *Dao) AddCacheOrderCount(ctx context.Context, req *model.OrderMainQuerier, res int64) (err error) {
  477. pool := d.redis.Get(ctx)
  478. defer func() {
  479. pool.Close()
  480. LogX(ctx, []interface{}{req, res}, nil, err)
  481. }()
  482. if key := oidCacheKey(req); key != "" {
  483. _, err = pool.Do("SETEX", model.CacheKeyOrderCnt+":"+key, cacheTimeout, res)
  484. }
  485. return
  486. }
  487. //AddCacheOrderDetails 增加订单详细缓存
  488. func (d *Dao) AddCacheOrderDetails(ctx context.Context, orders map[int64]*model.OrderDetail) (err error) {
  489. pool := d.redis.Get(ctx)
  490. defer func() {
  491. pool.Flush()
  492. pool.Close()
  493. LogX(ctx, orders, nil, err)
  494. }()
  495. data := make([]interface{}, len(orders)*2)
  496. i := 0
  497. for k, v := range orders {
  498. key := fmt.Sprintf("%s:%d", model.CacheKeyOrderDt, k)
  499. var b []byte
  500. b, _ = json.Marshal(v)
  501. data[i] = key
  502. data[i+1] = b
  503. i += 2
  504. }
  505. LogX(ctx, append([]interface{}{"MSET"}, data...), nil, nil)
  506. if err = pool.Send("MSET", data...); err != nil {
  507. return
  508. }
  509. for i := 0; i < len(data); i += 2 {
  510. pool.Send("EXPIRE", data[i], cacheTimeout)
  511. }
  512. return
  513. }
  514. //AddCacheOrderSKUs 增加订单sku缓存
  515. func (d *Dao) AddCacheOrderSKUs(ctx context.Context, skus map[int64][]*model.OrderSKU) (err error) {
  516. pool := d.redis.Get(ctx)
  517. defer func() {
  518. pool.Flush()
  519. pool.Close()
  520. LogX(ctx, skus, nil, err)
  521. }()
  522. data := make([]interface{}, len(skus)*2)
  523. i := 0
  524. for k, v := range skus {
  525. key := fmt.Sprintf("%s:%d", model.CacheKeyOrderSKU, k)
  526. var b []byte
  527. b, err = json.Marshal(v)
  528. data[i] = key
  529. data[i+1] = b
  530. i += 2
  531. }
  532. LogX(ctx, append([]interface{}{"MSET"}, data...), nil, nil)
  533. if err = pool.Send("MSET", data...); err != nil {
  534. return
  535. }
  536. for i := 0; i < len(data); i += 2 {
  537. pool.Send("EXPIRE", data[i], cacheTimeout)
  538. }
  539. return
  540. }
  541. //AddCacheOrderPayCharges 增加订单流水缓存
  542. func (d *Dao) AddCacheOrderPayCharges(ctx context.Context, chs map[int64]*model.OrderPayCharge) (err error) {
  543. pool := d.redis.Get(ctx)
  544. defer func() {
  545. pool.Flush()
  546. pool.Close()
  547. LogX(ctx, chs, nil, err)
  548. }()
  549. data := make([]interface{}, len(chs)*2)
  550. i := 0
  551. for k, v := range chs {
  552. key := fmt.Sprintf("%s:%d", model.CacheKeyOrderPayCh, k)
  553. var b []byte
  554. b, _ = json.Marshal(v)
  555. data[i] = key
  556. data[i+1] = b
  557. i += 2
  558. }
  559. LogX(ctx, append([]interface{}{"MSET"}, data...), nil, nil)
  560. if err = pool.Send("MSET", data...); err != nil {
  561. return
  562. }
  563. for i := 0; i < len(data); i += 2 {
  564. pool.Send("EXPIRE", data[i], cacheTimeout)
  565. }
  566. return
  567. }
  568. //DelCacheOrders 删除订单相关缓存,如果是新增或删除订单,要删除这个uid的订单列表缓存
  569. func (d *Dao) DelCacheOrders(ctx context.Context, req *model.OrderMainQuerier) {
  570. pool := d.redis.Get(ctx)
  571. var ret interface{}
  572. defer func() {
  573. pool.Close()
  574. LogX(ctx, req, ret, nil)
  575. }()
  576. for _, v := range req.OrderID {
  577. ret, _ = pool.Do("DEL",
  578. fmt.Sprintf("%s:%d", model.CacheKeyOrderMn, v),
  579. fmt.Sprintf("%s:%d", model.CacheKeyOrderDt, v),
  580. fmt.Sprintf("%s:%d", model.CacheKeyOrderSKU, v),
  581. )
  582. }
  583. if key := oidCacheKey(req); key != "" {
  584. ret, _ = pool.Do("DEL", model.CacheKeyOrderList+":"+key, model.CacheKeyOrderCnt+":"+key)
  585. }
  586. }
  587. //TxInsertOrders 插入订单表,返回成功行数
  588. func (d *Dao) TxInsertOrders(tx *xsql.Tx, orders []*model.OrderMain) (cnt int64, err error) {
  589. lo := len(orders)
  590. if lo == 0 {
  591. return
  592. }
  593. f := orders[0].GetFields(&types.FieldMask{Paths: []string{"ctime", "mtime"}})
  594. lf := len(f)
  595. hlds := model.InsPlHlds(lf, lo)
  596. a := make([]interface{}, lf*lo)
  597. i := 0
  598. for _, o := range orders {
  599. vals := o.GetVals(&types.FieldMask{Paths: f}, true)
  600. copy(a[i:], vals)
  601. i += lf
  602. }
  603. r, err := tx.Exec(fmt.Sprintf(sqlInsertOrderMains, "`"+strings.Join(f, "`,`")+"`", hlds), a...)
  604. if err != nil {
  605. return
  606. }
  607. cnt, err = r.RowsAffected()
  608. return
  609. }
  610. //TxInsertOrderDetails 写入orderDetail表
  611. func (d *Dao) TxInsertOrderDetails(tx *xsql.Tx, orders []*model.OrderDetail) (cnt int64, err error) {
  612. for _, v := range orders {
  613. v.Encrypt(d.c.Encrypt)
  614. }
  615. lo := len(orders)
  616. if lo == 0 {
  617. return
  618. }
  619. f := orders[0].GetFields(&types.FieldMask{Paths: []string{"ctime", "mtime"}})
  620. lf := len(f)
  621. hlds := model.InsPlHlds(lf, lo)
  622. a := make([]interface{}, lf*lo)
  623. i := 0
  624. for _, o := range orders {
  625. vals := o.GetVals(&types.FieldMask{Paths: f}, true)
  626. copy(a[i:], vals)
  627. i += lf
  628. }
  629. r, err := tx.Exec(fmt.Sprintf(sqlInsertOrderDetails, "`"+strings.Join(f, "`,`")+"`", hlds), a...)
  630. if err != nil {
  631. cnt = 0
  632. return
  633. }
  634. cnt, err = r.RowsAffected()
  635. return
  636. }
  637. //TxInsertOrderSKUs 增加订单Sku
  638. func (d *Dao) TxInsertOrderSKUs(tx *xsql.Tx, orders []*model.OrderSKU) (cnt int64, err error) {
  639. lo := len(orders)
  640. if lo == 0 {
  641. return
  642. }
  643. f := orders[0].GetFields(&types.FieldMask{Paths: []string{"ctime", "mtime"}})
  644. lf := len(f)
  645. hlds := model.InsPlHlds(lf, lo)
  646. a := make([]interface{}, lf*lo)
  647. i := 0
  648. for _, o := range orders {
  649. vals := o.GetVals(&types.FieldMask{Paths: f}, true)
  650. copy(a[i:], vals)
  651. i += lf
  652. }
  653. r, err := tx.Exec(fmt.Sprintf(sqlInsertOrderSkus, "`"+strings.Join(f, "`,`")+"`", hlds), a...)
  654. if err != nil {
  655. cnt = 0
  656. return
  657. }
  658. cnt, err = r.RowsAffected()
  659. return
  660. }
  661. //OrderID 获取订单号的方法
  662. func (d *Dao) OrderID(ctx context.Context, n int) ([]int64, error) {
  663. if n <= 0 {
  664. return nil, nil
  665. }
  666. if _, ok := d.c.URLs["basecenter"]; !ok {
  667. return nil, errors.New("miss basecenter's url conf")
  668. }
  669. u := d.c.URLs["basecenter"]
  670. var res struct {
  671. Errno int32 `json:"errno"`
  672. Data []int64 `json:"data"`
  673. }
  674. uv := url.Values{}
  675. uv.Set("app_id", d.c.BaseCenter.AppID)
  676. uv.Set("app_token", d.c.BaseCenter.Token)
  677. uv.Set("count", fmt.Sprintf("%d", n))
  678. if err := d.httpClientR.Get(ctx, u+"/orderid/get", "", uv, &res); err != nil {
  679. return nil, err
  680. }
  681. if len(res.Data) == 0 {
  682. return nil, ecode.TicketGetOidFail
  683. }
  684. return res.Data, nil
  685. }
  686. //pickOrderSQL 查订单的sql,返回sqls:{0:查列表的sql, 1:查数量的sql}, args:需要代入的变量
  687. func pickOrderSQL(q *model.OrderMainQuerier, fields []string) (sqls []string, args []interface{}) {
  688. sqls = make([]string, 2)
  689. var f string
  690. if len(fields) > 0 {
  691. f = "`" + strings.Join(fields, "`,`") + "`"
  692. }
  693. if l := len(q.OrderID); l > 0 {
  694. if f != "" {
  695. sqls[0] = fmt.Sprintf(sqlGetOrders, f, strings.Repeat(",?", l)[1:])
  696. }
  697. args = make([]interface{}, len(q.OrderID))
  698. for k, v := range q.OrderID {
  699. args[k] = v
  700. }
  701. return
  702. }
  703. if l := len(q.Status); l > 0 && q.ItemID > 0 {
  704. if f != "" {
  705. sqls[0] = fmt.Sprintf(sqlGetUserItemOrders, f, strings.Repeat(",?", l)[1:])
  706. }
  707. args = make([]interface{}, 2+l)
  708. args[0] = q.UID
  709. args[1] = q.ItemID
  710. for k, v := range q.Status {
  711. args[k+2] = v
  712. }
  713. return
  714. }
  715. if q.OrderBy == "" {
  716. q.OrderBy = DefaultOrderOrderBy
  717. }
  718. if q.Limit == 0 {
  719. q.Limit = DefaultOrderPSize
  720. }
  721. if f != "" {
  722. sqls[0] = fmt.Sprintf(sqlGetUserOrders, f, q.OrderBy, q.Offset, q.Limit)
  723. }
  724. sqls[1] = sqlCountUserOrders
  725. args = []interface{}{q.UID}
  726. return
  727. }
  728. //oidCacheKey orderId列表的缓存key, 返回空不缓存列表
  729. func oidCacheKey(q *model.OrderMainQuerier) string {
  730. s := ""
  731. if len(q.OrderID) > 0 {
  732. return s
  733. }
  734. if q.OrderBy == "" {
  735. q.OrderBy = DefaultOrderOrderBy
  736. }
  737. if q.Limit == 0 {
  738. q.Limit = DefaultOrderPSize
  739. }
  740. //仅缓存第一页
  741. if q.Offset > 0 || q.Limit != DefaultOrderPSize || strings.ToLower(q.OrderBy) != DefaultOrderOrderBy {
  742. return ""
  743. }
  744. if q.UID != "" {
  745. s = "&uid=" + q.UID
  746. }
  747. if q.ItemID > 0 {
  748. s += fmt.Sprintf("&item_id=%d", q.ItemID)
  749. }
  750. fs := map[string][]int16{
  751. "status": q.Status,
  752. "sub_status": q.SubStatus,
  753. "refund_status": q.RefundStatus,
  754. }
  755. for k, v := range fs {
  756. if len(v) > 0 {
  757. s += fmt.Sprintf("&%s=%s", k, strings.Trim(strings.Join(strings.Fields(fmt.Sprint(v)), ","), "[]"))
  758. }
  759. }
  760. ls := len(s)
  761. if ls > 32 {
  762. return fmt.Sprintf("%x", md5.Sum([]byte(s[1:])))
  763. }
  764. if ls > 2 {
  765. return s[1:]
  766. }
  767. //空缓存key
  768. return "nil"
  769. }
  770. //RawGetSettleOrders 获取待结算订单
  771. func (d *Dao) RawGetSettleOrders(ctx context.Context, bt time.Time, et time.Time, id int64, size int) (res *model.SettleOrders, offset int64, err error) {
  772. q := fmt.Sprintf(sqlGetSettleCompareOrders, "?,?")
  773. if size > 200 || size <= 0 {
  774. size = 200
  775. }
  776. r, err := d.db.Query(ctx, q, bt.Format("2006-01-02"), et.Format("2006-01-02"), id, consts.OrderStatusPaid, consts.OrderStatusRefunded, size+1)
  777. if err != nil {
  778. if err == sql.ErrNoRows {
  779. err = nil
  780. }
  781. return
  782. }
  783. defer r.Close()
  784. res = &model.SettleOrders{}
  785. res.Data = make([]*model.SettleOrder, 0, size+1)
  786. for r.Next() {
  787. o := &model.SettleOrder{}
  788. if err = r.Scan(&o.ID, &o.OrderID); err != nil {
  789. return
  790. }
  791. res.Data = append(res.Data, o)
  792. }
  793. l := len(res.Data)
  794. if l > size {
  795. res.Data = res.Data[:l-1]
  796. offset = res.Data[l-2].ID
  797. }
  798. return
  799. }
  800. //RawGetSettleRefunds 获取待结算退款订单
  801. func (d *Dao) RawGetSettleRefunds(ctx context.Context, bt time.Time, et time.Time, id int64, size int) (res *model.SettleOrders, offset int64, err error) {
  802. q := fmt.Sprintf(sqlGetSettleCompareRefunds, "?")
  803. if size > 200 || size <= 0 {
  804. size = 200
  805. }
  806. r, err := d.db.Query(ctx, q, bt.Format("2006-01-02"), et.Format("2006-01-02"), id, consts.RefundTxStatusSucc, size+1)
  807. if err != nil {
  808. if err == sql.ErrNoRows {
  809. err = nil
  810. }
  811. return
  812. }
  813. defer r.Close()
  814. res = &model.SettleOrders{}
  815. res.Data = make([]*model.SettleOrder, 0)
  816. for r.Next() {
  817. o := &model.SettleOrder{}
  818. if err = r.Scan(&o.RefID, &o.OrderID, &o.RefundApplyTime); err != nil {
  819. return
  820. }
  821. res.Data = append(res.Data, o)
  822. }
  823. l := len(res.Data)
  824. if l > size {
  825. res.Data = res.Data[:l-1]
  826. offset = res.Data[l-2].RefID
  827. }
  828. return
  829. }