bilibili-backup/app/service/openplatform/ticket-sales/dao/order.go
2019-04-22 02:59:20 +00:00

861 lines
22 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
}