bilibili-backup/app/service/openplatform/ticket-sales/dao/order.go

861 lines
22 KiB
Go
Raw Permalink Normal View History

2019-04-22 10:59:20 +08:00
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
}