123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515 |
- package pendant
- import (
- "bytes"
- "context"
- "database/sql"
- "fmt"
- "time"
- "go-common/app/service/main/usersuit/model"
- xsql "go-common/library/database/sql"
- "go-common/library/log"
- "go-common/library/xstr"
- "github.com/pkg/errors"
- )
- const (
- _getGroupOnlineSQL = "SELECT id,name,rank,status,image,image_model,frequency_limit,time_limit FROM pendant_group WHERE status = 1 or id in (30,31) ORDER BY rank"
- _getGroupByIDSQL = "SELECT id,name,rank,status,image,image_model,frequency_limit,time_limit FROM pendant_group where id = ?"
- _selGIDRefPIDSQL = "SELECT gid,pid FROM pendant_group_ref"
- _getPendantInfoSQL = "SELECT id,name,image,image_model,status FROM pendant_info"
- _getPendantInfoByIDSQL = "SELECT id,name,image,image_model,status FROM pendant_info where id = ? limit 1"
- _getPendantInfosSQL = "SELECT id,name,image,image_model,status,rank FROM pendant_info ORDER BY rank"
- _getPendantPriceSQL = "SELECT pid,type,price FROM pendant_price where pid = ? "
- _getOrderHistorySQL = "SELECT mid,order_id,pay_id,appid,status,pid,time_length,cost,buy_time,is_callback,callback_time,pay_type FROM user_pendant_order WHERE %s"
- _getUserPackageSQL = "SELECT mid,pid,expires,type,status,is_vip FROM user_pendant_pkg WHERE mid = ? AND pid = ? "
- _getUserPackageByMidSQL = "SELECT mid,pid,expires,type,status,is_vip FROM user_pendant_pkg WHERE mid = ? AND expires >= ? AND status > 0 ORDER BY mtime DESC"
- _countOrderHistorySQL = "SELECT count(1) FROM user_pendant_order WHERE %s"
- _getPendantEquipByMidSQL = "SELECT mid,pid,expires FROM user_pendant_equip WHERE mid = ? and expires >= ?"
- _getPendantEquipByMidsSQL = "SELECT mid,pid,expires FROM user_pendant_equip WHERE mid IN (%s) and expires >= ?"
- _insertPendantPackageSQL = "INSERT INTO user_pendant_pkg(mid,pid,expires,type,status,is_vip) VALUES (?,?,?,?,?,?)"
- _insertOrderHistory = "INSERT INTO user_pendant_order(mid,order_id,pay_id,appid,status,pid,time_length,cost,buy_time,is_callback,callback_time,pay_type) VALUES(?,?,?,?,?,?,?,?,?,?,?,?)"
- _insertOperationSQL = "INSERT INTO pendant_grant_history(mid,pid,source_type,operator_name,operator_action) VALUES (?,?,?,?,?)"
- _insertEquipSQL = "INSERT INTO user_pendant_equip(mid,pid,expires) VALUES (?,?,?) ON DUPLICATE KEY UPDATE pid=VALUES(pid),expires=VALUES(expires)"
- _updatePackageSQL = "UPDATE user_pendant_pkg %s WHERE mid=? AND pid=?"
- _updatePackageExpireSQL = "UPDATE user_pendant_pkg SET status=0 WHERE mid=? AND expires<?"
- _updateOrderInfoSQL = "UPDATE user_pendant_order SET status=?,pay_id=?,is_callback=?,callback_time=? WHERE order_id=?"
- _updateEquipMIDSQL = "UPDATE user_pendant_equip SET pid=0,expires=0 WHERE mid=?"
- )
- //PendantGroupInfo return all group info
- func (d *Dao) PendantGroupInfo(c context.Context) (res []*model.PendantGroupInfo, err error) {
- var row *xsql.Rows
- res = make([]*model.PendantGroupInfo, 0)
- if row, err = d.db.Query(c, _getGroupOnlineSQL); err != nil {
- log.Error("PendantGroupInfo query error %v", err)
- return
- }
- defer row.Close()
- for row.Next() {
- info := new(model.PendantGroupInfo)
- if err = row.Scan(&info.ID, &info.Name, &info.Rank, &info.Status, &info.Image, &info.ImageModel, &info.FrequencyLimit, &info.TimeLimit); err != nil {
- log.Error("PendantGroupInfo scan error %v", err)
- return
- }
- res = append(res, info)
- }
- return
- }
- // GroupByID return group info by id
- func (d *Dao) GroupByID(c context.Context, gid int64) (res *model.PendantGroupInfo, err error) {
- var row *xsql.Row
- res = new(model.PendantGroupInfo)
- row = d.db.QueryRow(c, _getGroupByIDSQL, gid)
- if err = row.Scan(&res.ID, &res.Name, &res.Rank, &res.Status, &res.Image, &res.ImageModel, &res.FrequencyLimit, &res.TimeLimit); err != nil {
- if err == xsql.ErrNoRows {
- res = nil
- err = nil
- return
- }
- log.Error("PendantGroupInfo scan error %v", err)
- return
- }
- return
- }
- // GIDRefPID gid relation of pid .
- func (d *Dao) GIDRefPID(c context.Context) (gidMap map[int64][]int64, pidMap map[int64]int64, err error) {
- var rows *xsql.Rows
- if rows, err = d.db.Query(c, _selGIDRefPIDSQL); err != nil {
- err = errors.WithStack(err)
- return
- }
- defer rows.Close()
- gidMap = make(map[int64][]int64)
- pidMap = make(map[int64]int64)
- for rows.Next() {
- var gid, pid int64
- if err = rows.Scan(&gid, &pid); err != nil {
- if err == xsql.ErrNoRows {
- gidMap = nil
- pidMap = nil
- err = nil
- return
- }
- err = errors.WithStack(err)
- return
- }
- pidMap[pid] = gid
- gidMap[gid] = append(gidMap[gid], pid)
- }
- return
- }
- // PendantList return pendant info
- func (d *Dao) PendantList(c context.Context) (res []*model.Pendant, err error) {
- var (
- row *xsql.Rows
- )
- res = make([]*model.Pendant, 0)
- if row, err = d.db.Query(c, _getPendantInfosSQL); err != nil {
- log.Error("PendantInfo query error %v", err)
- return
- }
- defer row.Close()
- for row.Next() {
- info := new(model.Pendant)
- if err = row.Scan(&info.ID, &info.Name, &info.Image, &info.ImageModel, &info.Status, &info.Rank); err != nil {
- log.Error("PendantInfo scan error %v", err)
- return
- }
- res = append(res, info)
- }
- return
- }
- // Pendants return pendant info by ids
- func (d *Dao) Pendants(c context.Context, pids []int64) (res []*model.Pendant, err error) {
- var (
- row *xsql.Rows
- bf bytes.Buffer
- )
- res = make([]*model.Pendant, 0)
- bf.WriteString(_getPendantInfoSQL)
- bf.WriteString(" where id in(")
- bf.WriteString(xstr.JoinInts(pids))
- bf.WriteString(") and status = 1 ORDER BY rank")
- if row, err = d.db.Query(c, bf.String()); err != nil {
- log.Error("Pendants query error %v", err)
- return
- }
- defer row.Close()
- for row.Next() {
- info := new(model.Pendant)
- if err = row.Scan(&info.ID, &info.Name, &info.Image, &info.ImageModel, &info.Status); err != nil {
- log.Error("Pendants scan error %v", err)
- return
- }
- res = append(res, info)
- }
- return
- }
- // PendantInfo return pendant info by id
- func (d *Dao) PendantInfo(c context.Context, pid int64) (res *model.Pendant, err error) {
- var (
- row *xsql.Row
- )
- res = new(model.Pendant)
- row = d.db.QueryRow(c, _getPendantInfoByIDSQL, pid)
- if err = row.Scan(&res.ID, &res.Name, &res.Image, &res.ImageModel, &res.Status); err != nil {
- if err == xsql.ErrNoRows {
- res = nil
- err = nil
- return
- }
- log.Error("Pendant scan error %v", err)
- return
- }
- return
- }
- // PendantPrice return pendant price
- func (d *Dao) PendantPrice(c context.Context, pid int64) (res map[int64]*model.PendantPrice, err error) {
- var row *xsql.Rows
- res = make(map[int64]*model.PendantPrice)
- if row, err = d.db.Query(c, _getPendantPriceSQL, pid); err != nil {
- log.Error("PendantPrice query error %v", err)
- return
- }
- defer row.Close()
- for row.Next() {
- info := new(model.PendantPrice)
- if err = row.Scan(&info.Pid, &info.Type, &info.Price); err != nil {
- log.Error("PendantPrice scan error %v", err)
- return
- }
- res[info.Type] = info
- }
- return
- }
- // getOrderInfoSQL return a sql string
- func (d *Dao) getOrderInfoSQL(c context.Context, arg *model.ArgOrderHistory, tp string) (sql string, values []interface{}) {
- values = make([]interface{}, 0, 5)
- var cond bytes.Buffer
- cond.WriteString("mid = ?")
- values = append(values, arg.Mid)
- if arg.OrderID != "" {
- cond.WriteString(" AND order_id = ?")
- values = append(values, arg.OrderID)
- }
- if arg.Pid != 0 {
- cond.WriteString(" AND pid = ?")
- values = append(values, arg.Pid)
- }
- if arg.Status != 0 {
- cond.WriteString(" AND status = ?")
- values = append(values, arg.Status)
- }
- if arg.PayType != 0 {
- cond.WriteString(" AND pay_type = ?")
- values = append(values, arg.PayType)
- }
- if arg.PayID != "" {
- cond.WriteString(" AND pay_id = ?")
- values = append(values, arg.PayID)
- }
- if arg.StartTime != 0 {
- cond.WriteString(" AND buy_time >= ?")
- values = append(values, arg.StartTime)
- }
- if arg.EndTime != 0 {
- cond.WriteString(" AND buy_time <= ?")
- values = append(values, arg.EndTime)
- }
- if tp == "info" {
- cond.WriteString(" order by buy_time DESC LIMIT ?,20")
- values = append(values, (arg.Page-1)*20)
- sql = fmt.Sprintf(_getOrderHistorySQL, cond.String())
- } else if tp == "count" {
- sql = fmt.Sprintf(_countOrderHistorySQL, cond.String())
- }
- return
- }
- // OrderInfo return order info
- func (d *Dao) OrderInfo(c context.Context, arg *model.ArgOrderHistory) (res []*model.PendantOrderInfo, count int64, err error) {
- sqlstr, values := d.getOrderInfoSQL(c, arg, "info")
- var (
- row *xsql.Rows
- r *xsql.Row
- )
- res = make([]*model.PendantOrderInfo, 0)
- if row, err = d.db.Query(c, sqlstr, values...); err != nil {
- log.Error("PendantOrderInfo query error %v", err)
- return
- }
- defer row.Close()
- cstr, values2 := d.getOrderInfoSQL(c, arg, "count")
- r = d.db.QueryRow(c, cstr, values2...)
- for row.Next() {
- info := new(model.PendantOrderInfo)
- if err = row.Scan(&info.Mid, &info.OrderID, &info.PayID, &info.AppID, &info.Stauts, &info.Pid, &info.TimeLength, &info.Cost, &info.BuyTime, &info.IsCallback, &info.CallbackTime, &info.PayType); err != nil {
- log.Error("PendantOrderInfo scan error %v", err)
- return
- }
- if info.PayType == 3 {
- info.PayPrice = info.PayPrice / 100
- }
- res = append(res, info)
- }
- err = r.Scan(&count)
- if err == xsql.ErrNoRows {
- res = nil
- err = nil
- return
- }
- return
- }
- // OrderInfoByID return order info by order id
- func (d *Dao) OrderInfoByID(c context.Context, orderID string) (res *model.PendantOrderInfo, err error) {
- row := d.db.QueryRow(c, fmt.Sprintf(_getOrderHistorySQL, "order_id=?"), orderID)
- res = new(model.PendantOrderInfo)
- if err = row.Scan(&res.Mid, &res.OrderID, &res.PayID, &res.AppID, &res.Stauts, &res.Pid, &res.TimeLength, &res.Cost, &res.BuyTime, &res.IsCallback, &res.CallbackTime, &res.PayType); err != nil {
- if err == xsql.ErrNoRows {
- res = nil
- err = nil
- return
- }
- log.Error("OrderInfoByID scan error %v", err)
- return
- }
- return
- }
- // AddOrderInfo add order log
- func (d *Dao) AddOrderInfo(c context.Context, arg *model.PendantOrderInfo) (id int64, err error) {
- var res sql.Result
- if res, err = d.db.Exec(c, _insertOrderHistory, arg.Mid, arg.OrderID, arg.PayID, arg.AppID, arg.Stauts, arg.Pid, arg.TimeLength, arg.Cost, arg.BuyTime, arg.IsCallback, arg.CallbackTime, arg.PayType); err != nil {
- log.Error("AddOrderInfo insert error %v", err)
- return
- }
- return res.LastInsertId()
- }
- // TxAddOrderInfo add order log
- func (d *Dao) TxAddOrderInfo(c context.Context, arg *model.PendantOrderInfo, tx *xsql.Tx) (id int64, err error) {
- var res sql.Result
- if res, err = tx.Exec(_insertOrderHistory, arg.Mid, arg.OrderID, arg.PayID, arg.AppID, arg.Stauts, arg.Pid, arg.TimeLength, arg.Cost, arg.BuyTime, arg.IsCallback, arg.CallbackTime, arg.PayType); err != nil {
- log.Error("TxAddOrderInfo insert error %v", err)
- return
- }
- return res.LastInsertId()
- }
- // UpdateOrderInfo update order info
- func (d *Dao) UpdateOrderInfo(c context.Context, arg *model.PendantOrderInfo) (id int64, err error) {
- var res sql.Result
- if res, err = d.db.Exec(c, _updateOrderInfoSQL, arg.Stauts, arg.PayID, arg.IsCallback, arg.CallbackTime, arg.OrderID); err != nil {
- log.Error("UpdateOrderInfo update error %v", err)
- return
- }
- return res.LastInsertId()
- }
- // TxUpdateOrderInfo update order info
- func (d *Dao) TxUpdateOrderInfo(c context.Context, arg *model.PendantOrderInfo, tx *xsql.Tx) (id int64, err error) {
- var res sql.Result
- if res, err = tx.Exec(_updateOrderInfoSQL, arg.Stauts, arg.PayID, arg.IsCallback, arg.CallbackTime, arg.OrderID); err != nil {
- log.Error("UpdateOrderInfo update error %v", err)
- return
- }
- return res.LastInsertId()
- }
- // PackageByMid get pendant in user's package
- func (d *Dao) PackageByMid(c context.Context, mid int64) (res []*model.PendantPackage, err error) {
- var (
- row *xsql.Rows
- t = time.Now().Unix()
- )
- res = make([]*model.PendantPackage, 0)
- if row, err = d.db.Query(c, _getUserPackageByMidSQL, mid, t); err != nil {
- log.Error("Package query error %v", err)
- return
- }
- defer row.Close()
- for row.Next() {
- info := new(model.PendantPackage)
- if err = row.Scan(&info.Mid, &info.Pid, &info.Expires, &info.Type, &info.Status, &info.IsVIP); err != nil {
- log.Error("Package scan error %v", err)
- return
- }
- res = append(res, info)
- }
- return
- }
- // PackageByID get pendant in user's package
- func (d *Dao) PackageByID(c context.Context, mid, pid int64) (res *model.PendantPackage, err error) {
- var row *xsql.Row
- res = new(model.PendantPackage)
- row = d.db.QueryRow(c, _getUserPackageSQL, mid, pid)
- if err = row.Scan(&res.Mid, &res.Pid, &res.Expires, &res.Type, &res.Status, &res.IsVIP); err != nil {
- if err == xsql.ErrNoRows {
- res = nil
- err = nil
- return
- }
- log.Error("Package scan error %v", err)
- return
- }
- return
- }
- // EquipByMid obtain pendant equiped
- func (d *Dao) EquipByMid(c context.Context, mid, t int64) (res *model.PendantEquip, noRow bool, err error) {
- var row *xsql.Row
- res = new(model.PendantEquip)
- row = d.db.QueryRow(c, _getPendantEquipByMidSQL, mid, t)
- if err = row.Scan(&res.Mid, &res.Pid, &res.Expires); err != nil {
- if err == xsql.ErrNoRows {
- noRow = true
- res = nil
- err = nil
- return
- }
- err = errors.WithStack(err)
- }
- return
- }
- // EquipByMids obtain equipss by mids .
- func (d *Dao) EquipByMids(c context.Context, mids []int64, t int64) (res map[int64]*model.PendantEquip, err error) {
- res = make(map[int64]*model.PendantEquip)
- rows, err := d.db.Query(c, fmt.Sprintf(_getPendantEquipByMidsSQL, xstr.JoinInts(mids)), t)
- if err != nil {
- err = errors.WithStack(err)
- return
- }
- defer rows.Close()
- for rows.Next() {
- pe := &model.PendantEquip{}
- if err = rows.Scan(&pe.Mid, &pe.Pid, &pe.Expires); err != nil {
- if err == xsql.ErrNoRows {
- err = nil
- return
- }
- err = errors.WithStack(err)
- }
- if _, ok := res[pe.Mid]; !ok {
- res[pe.Mid] = pe
- }
- }
- err = rows.Err()
- return
- }
- // AddEquip add equip
- func (d *Dao) AddEquip(c context.Context, arg *model.PendantEquip) (n int64, err error) {
- var res sql.Result
- if res, err = d.db.Exec(c, _insertEquipSQL, arg.Mid, arg.Pid, arg.Expires); err != nil {
- return 0, err
- }
- return res.RowsAffected()
- }
- // UpEquipMID uninstall user pid by mid.
- func (d *Dao) UpEquipMID(c context.Context, mid int64) (n int64, err error) {
- var res sql.Result
- if res, err = d.db.Exec(c, _updateEquipMIDSQL, mid); err != nil {
- return 0, err
- }
- return res.RowsAffected()
- }
- // TxUpdatePackageInfo update package info
- func (d *Dao) TxUpdatePackageInfo(c context.Context, arg *model.PendantPackage, tx *xsql.Tx) (n int64, err error) {
- var (
- bf bytes.Buffer
- values = make([]interface{}, 0, 4)
- res sql.Result
- )
- if arg.Status != 0 && arg.Expires != 0 {
- bf.WriteString("SET status=?,expires=?,type=?")
- values = append(values, arg.Status)
- values = append(values, arg.Expires)
- values = append(values, arg.Type)
- } else if arg.Status != 0 {
- bf.WriteString("SET status=?,type=?")
- values = append(values, arg.Status)
- values = append(values, arg.Type)
- } else if arg.Expires != 0 {
- bf.WriteString("SET expires=?,type=?")
- values = append(values, arg.Expires)
- values = append(values, arg.Type)
- }
- values = append(values, arg.Mid)
- values = append(values, arg.Pid)
- if res, err = tx.Exec(fmt.Sprintf(_updatePackageSQL, bf.String()), values...); err != nil {
- log.Error("TxUpdatePackageInfo update error %v", err)
- return
- }
- return res.RowsAffected()
- }
- // CheckPackageExpire check expire items and update
- func (d *Dao) CheckPackageExpire(c context.Context, mid, expires int64) (rows int64, err error) {
- var res sql.Result
- if res, err = d.db.Exec(c, _updatePackageExpireSQL, mid, expires); err != nil {
- log.Error("CheckPackageExpire error %v", err)
- return
- }
- return res.RowsAffected()
- }
- // BeginTran begin a tx.
- func (d *Dao) BeginTran(c context.Context) (res *xsql.Tx, err error) {
- if res, err = d.db.Begin(c); err != nil || res == nil {
- log.Error("BeginTran error %v", err)
- return
- }
- return
- }
- // TxAddPackage add a pendant in package
- func (d *Dao) TxAddPackage(c context.Context, arg *model.PendantPackage, tx *xsql.Tx) (id int64, err error) {
- var res sql.Result
- if res, err = tx.Exec(_insertPendantPackageSQL, arg.Mid, arg.Pid, arg.Expires, arg.Type, arg.Status, arg.IsVIP); err != nil {
- log.Error("TxAddPackage insert error %v", err)
- return
- }
- return res.LastInsertId()
- }
- // TxAddHistory add a history of operation
- func (d *Dao) TxAddHistory(c context.Context, arg *model.PendantHistory, tx *xsql.Tx) (id int64, err error) {
- var res sql.Result
- if res, err = tx.Exec(_insertOperationSQL, arg.Mid, arg.Pid, arg.SourceType, arg.OperatorName, arg.OperatorAction); err != nil {
- log.Error("TxAddHistory insert error %v", err)
- return
- }
- return res.LastInsertId()
- }
|