123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860 |
- package dao
- import (
- "context"
- "crypto/md5"
- "database/sql"
- "encoding/json"
- "errors"
- "fmt"
- "net/url"
- "strings"
- "time"
- "go-common/app/service/openplatform/ticket-sales/model"
- "go-common/app/service/openplatform/ticket-sales/model/consts"
- "go-common/library/cache/redis"
- xsql "go-common/library/database/sql"
- "go-common/library/ecode"
- "github.com/gogo/protobuf/types"
- )
- //订单相关常量
- const (
- cacheTimeout = 10
- DefaultOrderPSize = 20 //默认每页数量
- DefaultOrderOrderBy = "id desc" //默认排序
- //sqlGetUserOrders 查询用户订单列表
- sqlGetUserOrders = "SELECT %s FROM order_main WHERE uid=? AND is_deleted = 0 ORDER BY %s LIMIT %d,%d"
- //sqlGetUserItemOrders 查询用户已购买的某个项目订单
- sqlGetUserItemOrders = "SELECT %s FROM order_main WHERE uid=? AND item_id=? AND status IN (%s)"
- //sqlCountUserOrders 查询用户订单数量
- sqlCountUserOrders = "SELECT COUNT(*) FROM order_main WHERE uid=? AND is_deleted=0"
- //sqlGetOrders 查询订单列表
- sqlGetOrders = "SELECT %s FROM order_main WHERE order_id IN (%s)"
- //sqlInsertOrderMains 批量写入order_main
- sqlInsertOrderMains = "INSERT INTO order_main(%s) VALUES %s"
- //sqlGetOrderDetails 查询订单详情
- sqlGetOrderDetails = "SELECT %s FROM order_detail WHERE order_id IN (%s)"
- //sqlInsertOrderDetails 批量写入order_detail
- sqlInsertOrderDetails = "INSERT INTO order_detail(%s) VALUES %s"
- //sqlGetOrderSkus 查询order_sku
- sqlGetOrderSkus = "SELECT %s FROM order_sku WHERE order_id IN (%s)"
- //sqlInsertOrderSkus 批量写入order_sku
- sqlInsertOrderSkus = "INSERT INTO order_sku(%s) VALUES %s"
- //sqlGetBoughtSkus 获取已购买的sku
- sqlGetBoughtSkus = "SELECT `count` FROM order_sku WHERE order_id IN (%s) AND sku_id IN (%s)"
- //sqlGetOrderPayChs 获取支付流水
- sqlGetOrderPayChs = "SELECT %s FROM order_pay_charge WHERE order_id IN (%s) AND paid=1"
- //获取结算对账订单(0元单)
- 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 ?"
- //获取结算对帐退款单
- 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 ?"
- )
- //RawOrders 从db查询用户订单信息,包括以下情况
- //* 按照订单号查询
- //* 按照uid查分页
- //* 按照uid+商品id+状态查询列表
- func (d *Dao) RawOrders(ctx context.Context, req *model.OrderMainQuerier) (orders []*model.OrderMain, err error) {
- defer LogX(ctx, req, orders, err)
- o := new(model.OrderMain)
- sqls, args := pickOrderSQL(req, o.GetFields(nil))
- q := sqls[0]
- if q == "" {
- return
- }
- r, err := d.db.Query(ctx, q, args...)
- if err != nil {
- if err == sql.ErrNoRows {
- err = nil
- }
- return
- }
- defer r.Close()
- for r.Next() {
- vptrs := make(map[int]interface{})
- ptrs := o.GetPtrs(nil, vptrs)
- if err = r.Scan(ptrs...); err != nil {
- return
- }
- for k, v := range vptrs {
- json.Unmarshal([]byte(*ptrs[k].(*string)), v)
- }
- orders = append(orders, o)
- o = new(model.OrderMain)
- }
- return
- }
- //RawOrderCount 从db获取用户订单数目,当查询条件仅有uid时生效,否则返回0
- func (d *Dao) RawOrderCount(ctx context.Context, req *model.OrderMainQuerier) (cnt int64, err error) {
- defer LogX(ctx, req, cnt, err)
- sqls, args := pickOrderSQL(req, nil)
- q := sqls[1]
- if q == "" {
- return
- }
- r := d.db.QueryRow(ctx, q, args...)
- err = r.Scan(&cnt)
- //缓存回源逻辑0会被当成没命中缓存
- if cnt == 0 {
- cnt = -1
- }
- return
- }
- //RawOrderDetails 从db获取订单详细
- func (d *Dao) RawOrderDetails(ctx context.Context, oids []int64) (orders map[int64]*model.OrderDetail, err error) {
- defer LogX(ctx, oids, orders, err)
- lo := len(oids)
- if lo == 0 {
- return
- }
- a := make([]interface{}, lo)
- for k, v := range oids {
- a[k] = v
- }
- o := new(model.OrderDetail)
- f := o.GetFields(nil)
- q := fmt.Sprintf(sqlGetOrderDetails, "`"+strings.Join(f, "`,`")+"`", strings.Repeat(",?", lo)[1:])
- r, err := d.db.Query(ctx, q, a...)
- if err != nil {
- if err == sql.ErrNoRows {
- err = nil
- }
- return
- }
- defer r.Close()
- orders = make(map[int64]*model.OrderDetail, lo)
- for r.Next() {
- vptrs := make(map[int]interface{})
- ptrs := o.GetPtrs(nil, vptrs)
- if err = r.Scan(ptrs...); err != nil {
- return
- }
- for k, v := range vptrs {
- json.Unmarshal([]byte(*ptrs[k].(*string)), v)
- }
- o.Decrypt(d.c.Encrypt)
- orders[o.OrderID] = o
- o = new(model.OrderDetail)
- }
- return
- }
- //RawOrderSKUs 从db获取订单的sku
- func (d *Dao) RawOrderSKUs(ctx context.Context, oids []int64) (skus map[int64][]*model.OrderSKU, err error) {
- defer LogX(ctx, oids, skus, err)
- lo := len(oids)
- if lo == 0 {
- return
- }
- a := make([]interface{}, lo)
- for k, v := range oids {
- a[k] = v
- }
- o := new(model.OrderSKU)
- f := o.GetFields(nil)
- q := fmt.Sprintf(sqlGetOrderSkus, "`"+strings.Join(f, "`,`")+"`", strings.Repeat(",?", lo)[1:])
- r, err := d.db.Query(ctx, q, a...)
- if err != nil {
- if err == sql.ErrNoRows {
- err = nil
- }
- return
- }
- defer r.Close()
- skus = make(map[int64][]*model.OrderSKU, lo)
- for r.Next() {
- vptrs := make(map[int]interface{})
- ptrs := o.GetPtrs(nil, vptrs)
- if err = r.Scan(ptrs...); err != nil {
- return
- }
- for k, v := range vptrs {
- json.Unmarshal([]byte(*ptrs[k].(*string)), v)
- }
- skus[o.OrderID] = append(skus[o.OrderID], o)
- o = new(model.OrderSKU)
- }
- return
- }
- //RawBoughtCount 按照票种获取用户已购的订单票数
- func (d *Dao) RawBoughtCount(ctx context.Context, uid string, itemID int64, skuIDs []int64) (cnt int64, err error) {
- query := &model.OrderMainQuerier{
- UID: uid,
- ItemID: itemID,
- Status: []int16{consts.OrderStatusUnpaid, consts.OrderStatusPaid},
- }
- orders, err := d.RawOrders(ctx, query)
- if err != nil {
- return
- }
- //存在部分退款,要减去已退款票数
- pt := false
- lo := len(orders)
- oids := make([]int64, lo)
- for k, v := range orders {
- if v.RefundStatus == consts.RefundStatusPtRefunded {
- pt = true
- }
- cnt += v.Count
- oids[k] = v.OrderID
- }
- ls := len(skuIDs)
- //查具体sku的,要再次从order_sku表统计
- if ls > 0 && lo > 0 {
- cnt, err = d.rawBoughtSkusCnt(ctx, oids, skuIDs)
- if err != nil {
- return
- }
- }
- //部分退款的减去已退款张数
- if pt {
- var rCnt int64
- rCnt, err = d.rawRefundTicketCnt(ctx, oids)
- if err != nil {
- return
- }
- cnt -= rCnt
- }
- return
- }
- //rawBoughtSkusCnt 按照skuID统计用户购买数
- func (d *Dao) rawBoughtSkusCnt(ctx context.Context, oids []int64, skuIDs []int64) (cnt int64, err error) {
- lo := len(oids)
- ls := len(skuIDs)
- if lo == 0 || ls == 0 {
- err = ecode.RequestErr
- return
- }
- q := fmt.Sprintf(sqlGetBoughtSkus, strings.Repeat(",?", lo)[1:], strings.Repeat(",?", ls)[1:])
- a := make([]interface{}, lo+ls)
- for k, v := range oids {
- a[k] = v
- }
- for k, v := range skuIDs {
- a[k+lo] = v
- }
- r, err := d.db.Query(ctx, q, a...)
- if err != nil {
- return
- }
- defer r.Close()
- var c int64
- for r.Next() {
- if err = r.Scan(&c); err != nil {
- return
- }
- cnt += c
- }
- return
- }
- //RawOrderPayCharges 从db获取订单流水
- func (d *Dao) RawOrderPayCharges(ctx context.Context, oids []int64) (chs map[int64]*model.OrderPayCharge, err error) {
- defer LogX(ctx, oids, chs, err)
- lo := len(oids)
- if lo == 0 {
- return
- }
- a := make([]interface{}, lo)
- for k, v := range oids {
- a[k] = v
- }
- o := new(model.OrderPayCharge)
- f := o.GetFields(nil)
- q := fmt.Sprintf(sqlGetOrderPayChs, "`"+strings.Join(f, "`,`")+"`", strings.Repeat(",?", lo)[1:])
- r, err := d.db.Query(ctx, q, a...)
- if err != nil {
- if err == sql.ErrNoRows {
- err = nil
- }
- return
- }
- defer r.Close()
- chs = make(map[int64]*model.OrderPayCharge, lo)
- for r.Next() {
- ptrs := o.GetPtrs(&types.FieldMask{Paths: f}, nil)
- if err = r.Scan(ptrs...); err != nil {
- return
- }
- chs[o.OrderID] = o
- o = new(model.OrderPayCharge)
- }
- return
- }
- //CacheOrders 从缓存获取订单基础信息
- func (d *Dao) CacheOrders(ctx context.Context, req *model.OrderMainQuerier) (orders []*model.OrderMain, err error) {
- pool := d.redis.Get(ctx)
- defer func() {
- pool.Close()
- LogX(ctx, req, orders, err)
- }()
- var keys []interface{}
- if l := len(req.OrderID); l > 0 {
- keys = make([]interface{}, l)
- for k, v := range req.OrderID {
- keys[k] = fmt.Sprintf("%s:%d", model.CacheKeyOrderMn, v)
- }
- } else if key := oidCacheKey(req); key != "" {
- //如果查的是列表,先查出列表缓存的orderId,再根据orderId查订单信息
- var b []byte
- key = model.CacheKeyOrderList + ":" + key
- if b, err = redis.Bytes(pool.Do("GET", key)); err != nil {
- if err == redis.ErrNil {
- err = nil
- }
- return
- }
- s := string(b)
- LogX(ctx, []string{"GET", key}, s, err)
- oids := strings.Split(s, ",")
- keys = make([]interface{}, len(oids))
- for k, v := range oids {
- keys[k] = model.CacheKeyOrderMn + ":" + v
- }
- }
- if len(keys) == 0 {
- return
- }
- var data [][]byte
- if data, err = redis.ByteSlices(pool.Do("MGET", keys...)); err != nil {
- return
- }
- LogX(ctx, append([]interface{}{"MGET"}, keys...), data, err)
- for _, v := range data {
- if v != nil {
- o := &model.OrderMain{}
- orders = append(orders, o)
- json.Unmarshal(v, o)
- }
- }
- return
- }
- //CacheOrderCount 从缓存获取订单数目
- func (d *Dao) CacheOrderCount(ctx context.Context, req *model.OrderMainQuerier) (cnt int64, err error) {
- pool := d.redis.Get(ctx)
- defer func() {
- pool.Close()
- LogX(ctx, req, cnt, err)
- }()
- if key := oidCacheKey(req); key != "" {
- if cnt, err = redis.Int64(pool.Do("GET", model.CacheKeyOrderCnt+":"+key)); err == redis.ErrNil {
- err = nil
- }
- }
- return
- }
- //CacheOrderDetails 从缓存获取订单详细
- func (d *Dao) CacheOrderDetails(ctx context.Context, oids []int64) (orders map[int64]*model.OrderDetail, err error) {
- pool := d.redis.Get(ctx)
- defer func() {
- pool.Close()
- LogX(ctx, oids, orders, err)
- }()
- lo := len(oids)
- keys := make([]interface{}, lo)
- for k, v := range oids {
- keys[k] = fmt.Sprintf("%s:%d", model.CacheKeyOrderDt, v)
- }
- var data [][]byte
- if data, err = redis.ByteSlices(pool.Do("MGET", keys...)); err != nil {
- return
- }
- LogX(ctx, append([]interface{}{"MGET"}, keys...), data, nil)
- orders = make(map[int64]*model.OrderDetail, lo)
- for k, v := range oids {
- if data[k] == nil {
- continue
- }
- o := &model.OrderDetail{}
- if err = json.Unmarshal(data[k], o); err != nil {
- err = nil
- } else {
- orders[v] = o
- }
- }
- return
- }
- //CacheOrderSKUs 获取订单sku缓存
- func (d *Dao) CacheOrderSKUs(ctx context.Context, oids []int64) (skus map[int64][]*model.OrderSKU, err error) {
- pool := d.redis.Get(ctx)
- defer func() {
- pool.Close()
- LogX(ctx, oids, skus, err)
- }()
- lo := len(oids)
- keys := make([]interface{}, lo)
- for k, v := range oids {
- keys[k] = fmt.Sprintf("%s:%d", model.CacheKeyOrderSKU, v)
- }
- var data [][]byte
- if data, err = redis.ByteSlices(pool.Do("MGET", keys...)); err != nil {
- return
- }
- LogX(ctx, append([]interface{}{"MGET"}, keys...), data, nil)
- skus = make(map[int64][]*model.OrderSKU, lo)
- for k, v := range oids {
- if data[k] == nil {
- continue
- }
- o := []*model.OrderSKU{}
- if err = json.Unmarshal(data[k], &o); err != nil {
- err = nil
- } else {
- skus[v] = o
- }
- }
- return
- }
- //CacheOrderPayCharges 从缓存获取订单流水
- func (d *Dao) CacheOrderPayCharges(ctx context.Context, oids []int64) (chs map[int64]*model.OrderPayCharge, err error) {
- pool := d.redis.Get(ctx)
- defer func() {
- pool.Close()
- LogX(ctx, oids, chs, err)
- }()
- lo := len(oids)
- if lo == 0 {
- return
- }
- keys := make([]interface{}, lo)
- for k, v := range oids {
- keys[k] = fmt.Sprintf("%s:%d", model.CacheKeyOrderPayCh, v)
- }
- var data [][]byte
- if data, err = redis.ByteSlices(pool.Do("MGET", keys...)); err != nil {
- return
- }
- LogX(ctx, append([]interface{}{"MGET"}, keys...), data, nil)
- chs = make(map[int64]*model.OrderPayCharge, lo)
- for k, v := range oids {
- if data[k] == nil {
- continue
- }
- ch := &model.OrderPayCharge{}
- if err = json.Unmarshal(data[k], ch); err != nil {
- err = nil
- } else {
- chs[v] = ch
- }
- }
- return
- }
- //AddCacheOrders 设置订单基础信息缓存
- func (d *Dao) AddCacheOrders(ctx context.Context, req *model.OrderMainQuerier, res []*model.OrderMain) (err error) {
- pool := d.redis.Get(ctx)
- defer func() {
- pool.Flush()
- pool.Close()
- LogX(ctx, []interface{}{req, res}, nil, err)
- }()
- data := make([]interface{}, len(res)*2)
- var sOids string
- for k, v := range res {
- if sOids == "" {
- sOids = fmt.Sprintf("%d", v.OrderID)
- } else {
- sOids += fmt.Sprintf(",%d", v.OrderID)
- }
- b, _ := json.Marshal(v)
- data[k*2] = fmt.Sprintf("%s:%d", model.CacheKeyOrderMn, v.OrderID)
- data[k*2+1] = b
- }
- //设置列表orderID缓存
- if key := oidCacheKey(req); key != "" {
- arg := []interface{}{model.CacheKeyOrderList + ":" + key, cacheTimeout, sOids}
- LogX(ctx, append([]interface{}{"SETEX"}, arg...), nil, nil)
- if err = pool.Send("SETEX", arg...); err != nil {
- return
- }
- }
- LogX(ctx, append([]interface{}{"MSET"}, data...), nil, nil)
- if err = pool.Send("MSET", data...); err != nil {
- return
- }
- for i := 0; i < len(data); i += 2 {
- pool.Send("EXPIRE", data[i], cacheTimeout)
- }
- return
- }
- //AddCacheOrderCount 设置订单数目缓存
- func (d *Dao) AddCacheOrderCount(ctx context.Context, req *model.OrderMainQuerier, res int64) (err error) {
- pool := d.redis.Get(ctx)
- defer func() {
- pool.Close()
- LogX(ctx, []interface{}{req, res}, nil, err)
- }()
- if key := oidCacheKey(req); key != "" {
- _, err = pool.Do("SETEX", model.CacheKeyOrderCnt+":"+key, cacheTimeout, res)
- }
- return
- }
- //AddCacheOrderDetails 增加订单详细缓存
- func (d *Dao) AddCacheOrderDetails(ctx context.Context, orders map[int64]*model.OrderDetail) (err error) {
- pool := d.redis.Get(ctx)
- defer func() {
- pool.Flush()
- pool.Close()
- LogX(ctx, orders, nil, err)
- }()
- data := make([]interface{}, len(orders)*2)
- i := 0
- for k, v := range orders {
- key := fmt.Sprintf("%s:%d", model.CacheKeyOrderDt, k)
- var b []byte
- b, _ = json.Marshal(v)
- data[i] = key
- data[i+1] = b
- i += 2
- }
- LogX(ctx, append([]interface{}{"MSET"}, data...), nil, nil)
- if err = pool.Send("MSET", data...); err != nil {
- return
- }
- for i := 0; i < len(data); i += 2 {
- pool.Send("EXPIRE", data[i], cacheTimeout)
- }
- return
- }
- //AddCacheOrderSKUs 增加订单sku缓存
- func (d *Dao) AddCacheOrderSKUs(ctx context.Context, skus map[int64][]*model.OrderSKU) (err error) {
- pool := d.redis.Get(ctx)
- defer func() {
- pool.Flush()
- pool.Close()
- LogX(ctx, skus, nil, err)
- }()
- data := make([]interface{}, len(skus)*2)
- i := 0
- for k, v := range skus {
- key := fmt.Sprintf("%s:%d", model.CacheKeyOrderSKU, k)
- var b []byte
- b, err = json.Marshal(v)
- data[i] = key
- data[i+1] = b
- i += 2
- }
- LogX(ctx, append([]interface{}{"MSET"}, data...), nil, nil)
- if err = pool.Send("MSET", data...); err != nil {
- return
- }
- for i := 0; i < len(data); i += 2 {
- pool.Send("EXPIRE", data[i], cacheTimeout)
- }
- return
- }
- //AddCacheOrderPayCharges 增加订单流水缓存
- func (d *Dao) AddCacheOrderPayCharges(ctx context.Context, chs map[int64]*model.OrderPayCharge) (err error) {
- pool := d.redis.Get(ctx)
- defer func() {
- pool.Flush()
- pool.Close()
- LogX(ctx, chs, nil, err)
- }()
- data := make([]interface{}, len(chs)*2)
- i := 0
- for k, v := range chs {
- key := fmt.Sprintf("%s:%d", model.CacheKeyOrderPayCh, k)
- var b []byte
- b, _ = json.Marshal(v)
- data[i] = key
- data[i+1] = b
- i += 2
- }
- LogX(ctx, append([]interface{}{"MSET"}, data...), nil, nil)
- if err = pool.Send("MSET", data...); err != nil {
- return
- }
- for i := 0; i < len(data); i += 2 {
- pool.Send("EXPIRE", data[i], cacheTimeout)
- }
- return
- }
- //DelCacheOrders 删除订单相关缓存,如果是新增或删除订单,要删除这个uid的订单列表缓存
- func (d *Dao) DelCacheOrders(ctx context.Context, req *model.OrderMainQuerier) {
- pool := d.redis.Get(ctx)
- var ret interface{}
- defer func() {
- pool.Close()
- LogX(ctx, req, ret, nil)
- }()
- for _, v := range req.OrderID {
- ret, _ = pool.Do("DEL",
- fmt.Sprintf("%s:%d", model.CacheKeyOrderMn, v),
- fmt.Sprintf("%s:%d", model.CacheKeyOrderDt, v),
- fmt.Sprintf("%s:%d", model.CacheKeyOrderSKU, v),
- )
- }
- if key := oidCacheKey(req); key != "" {
- ret, _ = pool.Do("DEL", model.CacheKeyOrderList+":"+key, model.CacheKeyOrderCnt+":"+key)
- }
- }
- //TxInsertOrders 插入订单表,返回成功行数
- func (d *Dao) TxInsertOrders(tx *xsql.Tx, orders []*model.OrderMain) (cnt int64, err error) {
- lo := len(orders)
- if lo == 0 {
- return
- }
- f := orders[0].GetFields(&types.FieldMask{Paths: []string{"ctime", "mtime"}})
- lf := len(f)
- hlds := model.InsPlHlds(lf, lo)
- a := make([]interface{}, lf*lo)
- i := 0
- for _, o := range orders {
- vals := o.GetVals(&types.FieldMask{Paths: f}, true)
- copy(a[i:], vals)
- i += lf
- }
- r, err := tx.Exec(fmt.Sprintf(sqlInsertOrderMains, "`"+strings.Join(f, "`,`")+"`", hlds), a...)
- if err != nil {
- return
- }
- cnt, err = r.RowsAffected()
- return
- }
- //TxInsertOrderDetails 写入orderDetail表
- func (d *Dao) TxInsertOrderDetails(tx *xsql.Tx, orders []*model.OrderDetail) (cnt int64, err error) {
- for _, v := range orders {
- v.Encrypt(d.c.Encrypt)
- }
- lo := len(orders)
- if lo == 0 {
- return
- }
- f := orders[0].GetFields(&types.FieldMask{Paths: []string{"ctime", "mtime"}})
- lf := len(f)
- hlds := model.InsPlHlds(lf, lo)
- a := make([]interface{}, lf*lo)
- i := 0
- for _, o := range orders {
- vals := o.GetVals(&types.FieldMask{Paths: f}, true)
- copy(a[i:], vals)
- i += lf
- }
- r, err := tx.Exec(fmt.Sprintf(sqlInsertOrderDetails, "`"+strings.Join(f, "`,`")+"`", hlds), a...)
- if err != nil {
- cnt = 0
- return
- }
- cnt, err = r.RowsAffected()
- return
- }
- //TxInsertOrderSKUs 增加订单Sku
- func (d *Dao) TxInsertOrderSKUs(tx *xsql.Tx, orders []*model.OrderSKU) (cnt int64, err error) {
- lo := len(orders)
- if lo == 0 {
- return
- }
- f := orders[0].GetFields(&types.FieldMask{Paths: []string{"ctime", "mtime"}})
- lf := len(f)
- hlds := model.InsPlHlds(lf, lo)
- a := make([]interface{}, lf*lo)
- i := 0
- for _, o := range orders {
- vals := o.GetVals(&types.FieldMask{Paths: f}, true)
- copy(a[i:], vals)
- i += lf
- }
- r, err := tx.Exec(fmt.Sprintf(sqlInsertOrderSkus, "`"+strings.Join(f, "`,`")+"`", hlds), a...)
- if err != nil {
- cnt = 0
- return
- }
- cnt, err = r.RowsAffected()
- return
- }
- //OrderID 获取订单号的方法
- func (d *Dao) OrderID(ctx context.Context, n int) ([]int64, error) {
- if n <= 0 {
- return nil, nil
- }
- if _, ok := d.c.URLs["basecenter"]; !ok {
- return nil, errors.New("miss basecenter's url conf")
- }
- u := d.c.URLs["basecenter"]
- var res struct {
- Errno int32 `json:"errno"`
- Data []int64 `json:"data"`
- }
- uv := url.Values{}
- uv.Set("app_id", d.c.BaseCenter.AppID)
- uv.Set("app_token", d.c.BaseCenter.Token)
- uv.Set("count", fmt.Sprintf("%d", n))
- if err := d.httpClientR.Get(ctx, u+"/orderid/get", "", uv, &res); err != nil {
- return nil, err
- }
- if len(res.Data) == 0 {
- return nil, ecode.TicketGetOidFail
- }
- return res.Data, nil
- }
- //pickOrderSQL 查订单的sql,返回sqls:{0:查列表的sql, 1:查数量的sql}, args:需要代入的变量
- func pickOrderSQL(q *model.OrderMainQuerier, fields []string) (sqls []string, args []interface{}) {
- sqls = make([]string, 2)
- var f string
- if len(fields) > 0 {
- f = "`" + strings.Join(fields, "`,`") + "`"
- }
- if l := len(q.OrderID); l > 0 {
- if f != "" {
- sqls[0] = fmt.Sprintf(sqlGetOrders, f, strings.Repeat(",?", l)[1:])
- }
- args = make([]interface{}, len(q.OrderID))
- for k, v := range q.OrderID {
- args[k] = v
- }
- return
- }
- if l := len(q.Status); l > 0 && q.ItemID > 0 {
- if f != "" {
- sqls[0] = fmt.Sprintf(sqlGetUserItemOrders, f, strings.Repeat(",?", l)[1:])
- }
- args = make([]interface{}, 2+l)
- args[0] = q.UID
- args[1] = q.ItemID
- for k, v := range q.Status {
- args[k+2] = v
- }
- return
- }
- if q.OrderBy == "" {
- q.OrderBy = DefaultOrderOrderBy
- }
- if q.Limit == 0 {
- q.Limit = DefaultOrderPSize
- }
- if f != "" {
- sqls[0] = fmt.Sprintf(sqlGetUserOrders, f, q.OrderBy, q.Offset, q.Limit)
- }
- sqls[1] = sqlCountUserOrders
- args = []interface{}{q.UID}
- return
- }
- //oidCacheKey orderId列表的缓存key, 返回空不缓存列表
- func oidCacheKey(q *model.OrderMainQuerier) string {
- s := ""
- if len(q.OrderID) > 0 {
- return s
- }
- if q.OrderBy == "" {
- q.OrderBy = DefaultOrderOrderBy
- }
- if q.Limit == 0 {
- q.Limit = DefaultOrderPSize
- }
- //仅缓存第一页
- if q.Offset > 0 || q.Limit != DefaultOrderPSize || strings.ToLower(q.OrderBy) != DefaultOrderOrderBy {
- return ""
- }
- if q.UID != "" {
- s = "&uid=" + q.UID
- }
- if q.ItemID > 0 {
- s += fmt.Sprintf("&item_id=%d", q.ItemID)
- }
- fs := map[string][]int16{
- "status": q.Status,
- "sub_status": q.SubStatus,
- "refund_status": q.RefundStatus,
- }
- for k, v := range fs {
- if len(v) > 0 {
- s += fmt.Sprintf("&%s=%s", k, strings.Trim(strings.Join(strings.Fields(fmt.Sprint(v)), ","), "[]"))
- }
- }
- ls := len(s)
- if ls > 32 {
- return fmt.Sprintf("%x", md5.Sum([]byte(s[1:])))
- }
- if ls > 2 {
- return s[1:]
- }
- //空缓存key
- return "nil"
- }
- //RawGetSettleOrders 获取待结算订单
- func (d *Dao) RawGetSettleOrders(ctx context.Context, bt time.Time, et time.Time, id int64, size int) (res *model.SettleOrders, offset int64, err error) {
- q := fmt.Sprintf(sqlGetSettleCompareOrders, "?,?")
- if size > 200 || size <= 0 {
- size = 200
- }
- r, err := d.db.Query(ctx, q, bt.Format("2006-01-02"), et.Format("2006-01-02"), id, consts.OrderStatusPaid, consts.OrderStatusRefunded, size+1)
- if err != nil {
- if err == sql.ErrNoRows {
- err = nil
- }
- return
- }
- defer r.Close()
- res = &model.SettleOrders{}
- res.Data = make([]*model.SettleOrder, 0, size+1)
- for r.Next() {
- o := &model.SettleOrder{}
- if err = r.Scan(&o.ID, &o.OrderID); err != nil {
- return
- }
- res.Data = append(res.Data, o)
- }
- l := len(res.Data)
- if l > size {
- res.Data = res.Data[:l-1]
- offset = res.Data[l-2].ID
- }
- return
- }
- //RawGetSettleRefunds 获取待结算退款订单
- func (d *Dao) RawGetSettleRefunds(ctx context.Context, bt time.Time, et time.Time, id int64, size int) (res *model.SettleOrders, offset int64, err error) {
- q := fmt.Sprintf(sqlGetSettleCompareRefunds, "?")
- if size > 200 || size <= 0 {
- size = 200
- }
- r, err := d.db.Query(ctx, q, bt.Format("2006-01-02"), et.Format("2006-01-02"), id, consts.RefundTxStatusSucc, size+1)
- if err != nil {
- if err == sql.ErrNoRows {
- err = nil
- }
- return
- }
- defer r.Close()
- res = &model.SettleOrders{}
- res.Data = make([]*model.SettleOrder, 0)
- for r.Next() {
- o := &model.SettleOrder{}
- if err = r.Scan(&o.RefID, &o.OrderID, &o.RefundApplyTime); err != nil {
- return
- }
- res.Data = append(res.Data, o)
- }
- l := len(res.Data)
- if l > size {
- res.Data = res.Data[:l-1]
- offset = res.Data[l-2].RefID
- }
- return
- }
|