package dao import ( "errors" "fmt" "github.com/gin-gonic/gin" "github.com/jmoiron/sqlx" goproto "google.golang.org/protobuf/proto" "service/app/mix/conf" "service/bizcommon/util" "service/dbstruct" "service/library/logger" "service/library/mysqldb" "time" ) type Mysql struct { dbVas *sqlx.DB } func (m *Mysql) getDBVas() *sqlx.DB { return m.dbVas } func (m *Mysql) VasBegin(ctx *gin.Context) (tx *sqlx.Tx, err error) { tx, err = m.dbVas.BeginTxx(ctx, nil) if err != nil { logger.Error("beginx fail, err: %v", err) return } if tx == nil { err = errors.New("get tx fail") logger.Error("nil tx, err: %v", err) return } return } func (m *Mysql) DealTxCR(tx *sqlx.Tx, errIn error) (errOut error) { if errIn != nil { // 事务回滚 logger.Error("deal tx err, %v", errIn) errOut = tx.Rollback() if errOut != nil { logger.Error("tx rollback fail, err: %v", errOut) return } } else { // 提交事务 errOut = tx.Commit() if errOut != nil { logger.Error("tx commit fail, err: %v", errOut) return } } return } // mysql const ( DatabaseVas = "vas" TableOrder = "vas_order" // 订单表 TableWallet = "vas_wallet" // 钱包 TableCoinOrder = "vas_coin_order" // 金币订单 TableConsumeHistoryCost = "vas_ch_cost" // 消费明细 TableConsumeHistoryCharge = "vas_ch_charge" // 充值明细 TableConsumeHistoryIncome = "vas_ch_income" // 收入明细 TableConsumeHistoryWithdraw = "vas_ch_withdraw" // 提现明细 TableVasUserUnlock = "vas_user_unlock" // 用增解锁 ) func (m *Mysql) ChTableName(ch *dbstruct.ConsumeHistory) (string, error) { switch ch.GetType() { case dbstruct.CHTypeCost: return TableConsumeHistoryCost, nil case dbstruct.CHTypeCharge: return TableConsumeHistoryCharge, nil case dbstruct.CHTypeIncome: return TableConsumeHistoryIncome, nil case dbstruct.CHTypeWithdraw: return TableConsumeHistoryWithdraw, nil default: return "", errors.New(fmt.Sprintf("invalid ch type: %v", *ch.Type)) } } func NewMysql(cfg *conf.ConfigSt) (mysql *Mysql, err error) { mysql = new(Mysql) mysql.dbVas, err = mysqldb.NewMysqlDB(cfg.MixMysql, DatabaseVas) if err != nil { logger.Error("NewMysqlDB fail, cfg: %v, db: %v, err: %v", util.ToJson(cfg.MixMongo), DatabaseVas, err) return } mysql.dbVas.SetMaxOpenConns(20) mysql.dbVas.SetMaxIdleConns(10) err = mysql.dbVas.Ping() if err != nil { logger.Error("MysqlDB ping fail, cfg: %v, db: %v, err: %v", util.ToJson(cfg.MixMongo), DatabaseVas, err) return } return } // 创建订单 func (m *Mysql) CreateOrder(ctx *gin.Context, tx *sqlx.Tx, order *dbstruct.Order) error { var err error sqlStr := "insert into " + TableOrder + " (id, mid, uid, product_id, pay_type, pay_amount, " + " out_order_id, receipt_data, coins, order_status, order_from, " + " ct, ut, ext, b_did, b_ver, b_osver, b_dt, b_ch, b_model, b_nt, ip) " + " values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) " if tx != nil { _, err = tx.ExecContext(ctx, sqlStr, order.GetID(), order.GetMid(), order.GetUid(), order.GetProductId(), order.GetPayType(), order.GetPayAmount(), order.GetOutOrderID(), order.GetReceiptData(), order.GetCoins(), order.GetOrderStatus(), order.GetOrderFrom(), order.GetCt(), order.GetUt(), order.GetExt(), order.GetDid(), order.GetVersion(), order.GetOsVersion(), order.GetDevType(), order.GetChannel(), order.GetModel(), order.GetNetType(), order.GetIp(), ) } else { db := m.getDBVas() _, err = db.ExecContext(ctx, sqlStr, order.GetID(), order.GetMid(), order.GetUid(), order.GetProductId(), order.GetPayType(), order.GetPayAmount(), order.GetOutOrderID(), order.GetReceiptData(), order.GetCoins(), order.GetOrderStatus(), order.GetOrderFrom(), order.GetCt(), order.GetUt(), order.GetExt(), order.GetDid(), order.GetVersion(), order.GetOsVersion(), order.GetDevType(), order.GetChannel(), order.GetModel(), order.GetNetType(), order.GetIp(), ) } if err != nil { logger.Error("CreateOrder fail, order: %v, err: %v", order.ToString(), err) return err } return err } // 获取订单 func (m *Mysql) GetOrderById(ctx *gin.Context, tx *sqlx.Tx, id string) (order *dbstruct.Order, err error) { var tmpOrder dbstruct.Order if tx != nil { err = tx.GetContext(ctx, &tmpOrder, fmt.Sprintf("select * from %s where id = ?", TableOrder), id) } else { db := m.getDBVas() err = db.GetContext(ctx, &tmpOrder, fmt.Sprintf("select * from %s where id = ?", TableOrder), id) } if err != nil { return } order = &tmpOrder return } // 获取订单 func (m *Mysql) GetOrderByOutOrderId(ctx *gin.Context, tx *sqlx.Tx, outOrderId string) (order *dbstruct.Order, err error) { var tmpOrder dbstruct.Order if tx != nil { err = tx.GetContext(ctx, &tmpOrder, fmt.Sprintf("select * from %s where out_order_id = ?", TableOrder), outOrderId) } else { db := m.getDBVas() err = db.GetContext(ctx, &tmpOrder, fmt.Sprintf("select * from %s where out_order_id = ?", TableOrder), outOrderId) } if err != nil { return } order = &tmpOrder return } // 获取订单for update func (m *Mysql) GetOrderByIdForUpdate(ctx *gin.Context, tx *sqlx.Tx, id string) (order *dbstruct.Order, err error) { var tmpOrder dbstruct.Order err = tx.GetContext(ctx, &tmpOrder, fmt.Sprintf("select * from %s where id = ? for update", TableOrder), id) if err != nil { return } order = &tmpOrder return } // 更新订单状态 func (m *Mysql) UpdateOrderStatus(ctx *gin.Context, tx *sqlx.Tx, orderId string, preStatus, aftStatus int32) error { var err error sqlStr := "update " + TableOrder + " set order_status=? where id=? and order_status=?" if tx != nil { _, err = tx.ExecContext(ctx, sqlStr, aftStatus, orderId, preStatus) } else { db := m.getDBVas() _, err = db.ExecContext(ctx, sqlStr, aftStatus, orderId, preStatus) } if err != nil { logger.Error("UpdateOrderStatus fail, orderId: %v, preStatus: %v, aftStatus: %v, err: %v", orderId, preStatus, aftStatus, err) return err } return err } // 获取钱包 for update func (m *Mysql) GetWalletForUpdate(ctx *gin.Context, tx *sqlx.Tx, mid int64) (wallet *dbstruct.Wallet, err error) { var tmpWallet dbstruct.Wallet err = tx.GetContext(ctx, &tmpWallet, fmt.Sprintf("select * from %s where id = ? for update", TableWallet), mid) if err != nil { return } wallet = &tmpWallet return } // 新建钱包 func (m *Mysql) CreateWallet(ctx *gin.Context, tx *sqlx.Tx, mid int64) error { var err error sqlStr := "insert into " + TableWallet + " (id, coins, diamonds, withdraw_diamonds) " + " values (?, ?, ?, ?)" if tx != nil { _, err = tx.ExecContext(ctx, sqlStr, mid, 0, 0, 0) } else { db := m.getDBVas() _, err = db.ExecContext(ctx, sqlStr, mid, 0, 0, 0) } if err != nil { logger.Error("CreateWallet fail, mid: %v, err: %v", mid, err) return err } return nil } // 获取钱包 func (m *Mysql) GetWalletByMid(ctx *gin.Context, mid int64) (wallet *dbstruct.Wallet, err error) { var ( db = m.getDBVas() tmpWallet dbstruct.Wallet ) err = db.GetContext(ctx, &tmpWallet, fmt.Sprintf("select * from %s where id = ?", TableWallet), mid) if err != nil { return } wallet = &tmpWallet return } // 增加金币 func (m *Mysql) IncCoins(ctx *gin.Context, tx *sqlx.Tx, mid, coins int64) error { var err error sqlStr := "update " + TableWallet + " set coins = coins + ? where id = ?" if tx != nil { _, err = tx.ExecContext(ctx, sqlStr, coins, mid, ) } else { db := m.getDBVas() _, err = db.ExecContext(ctx, sqlStr, coins, mid, ) } if err != nil { logger.Error("IncCoins fail, mid: %v, coins: %v, err: %v", mid, coins, err) return err } return err } // 扣金币 func (m *Mysql) DecCoins(ctx *gin.Context, tx *sqlx.Tx, mid, coins int64) error { var err error sqlStr := "update " + TableWallet + " set coins = coins - ? where id = ?" if tx != nil { _, err = tx.ExecContext(ctx, sqlStr, coins, mid, ) } else { db := m.getDBVas() _, err = db.ExecContext(ctx, sqlStr, coins, mid, ) } if err != nil { logger.Error("IncCoins fail, mid: %v, coins: %v, err: %v", mid, coins, err) return err } return err } // 增加钻石 func (m *Mysql) IncDiamonds(ctx *gin.Context, tx *sqlx.Tx, mid, dias int64) error { var err error sqlStr := "update " + TableWallet + " set diamonds = diamonds + ? where id = ?" if tx != nil { _, err = tx.ExecContext(ctx, sqlStr, dias, mid, ) } else { db := m.getDBVas() _, err = db.ExecContext(ctx, sqlStr, dias, mid, ) } if err != nil { logger.Error("IncCoins fail, mid: %v, dias: %v, err: %v", mid, dias, err) return err } return err } // 创建金币订单 func (m *Mysql) CreateCoinOrder(ctx *gin.Context, tx *sqlx.Tx, order *dbstruct.CoinOrder) error { var err error sqlStr := "insert into " + TableCoinOrder + " (id, mid, uid, product_id, " + " coins, order_status, order_from, " + " ct, ut, ext, b_did, b_ver, b_osver, " + " b_dt, b_ch, b_model, b_nt, ip) " + " values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) " if tx != nil { _, err = tx.ExecContext(ctx, sqlStr, order.GetID(), order.GetMid(), order.GetUid(), order.GetProductId(), order.GetCoins(), order.GetOrderStatus(), order.GetOrderFrom(), order.GetCt(), order.GetUt(), order.GetExt(), order.GetDid(), order.GetVersion(), order.GetOsVersion(), order.GetDevType(), order.GetChannel(), order.GetModel(), order.GetNetType(), order.GetIp(), ) } else { db := m.getDBVas() _, err = db.ExecContext(ctx, sqlStr, order.GetID(), order.GetMid(), order.GetUid(), order.GetProductId(), order.GetCoins(), order.GetOrderStatus(), order.GetOrderFrom(), order.GetCt(), order.GetUt(), order.GetExt(), order.GetDid(), order.GetVersion(), order.GetOsVersion(), order.GetDevType(), order.GetChannel(), order.GetModel(), order.GetNetType(), order.GetIp(), ) } if err != nil { logger.Error("CreateCoinOrder fail, order: %v, err: %v", order.ToString(), err) return err } return err } // 获取金币订单 func (m *Mysql) GetCoinOrderById(ctx *gin.Context, tx *sqlx.Tx, id string) (order *dbstruct.CoinOrder, err error) { var tmpOrder dbstruct.CoinOrder if tx != nil { err = tx.GetContext(ctx, &tmpOrder, fmt.Sprintf("select * from %s where id = ?", TableCoinOrder), id) } else { db := m.getDBVas() err = db.GetContext(ctx, &tmpOrder, fmt.Sprintf("select * from %s where id = ?", TableCoinOrder), id) } if err != nil { return } order = &tmpOrder return } // 获取金币订单 for update func (m *Mysql) GetCoinOrderByIdForUpdate(ctx *gin.Context, tx *sqlx.Tx, id string) (order *dbstruct.CoinOrder, err error) { var tmpOrder dbstruct.CoinOrder err = tx.GetContext(ctx, &tmpOrder, fmt.Sprintf("select * from %s where id = ? for update", TableCoinOrder), id) if err != nil { return } order = &tmpOrder return } // 金币订单填写联系方式 func (m *Mysql) FillCoinOderContact(ctx *gin.Context, tx *sqlx.Tx, id, qq, wechat, phone, addr, note string) error { var err error sqlStr := "update " + TableCoinOrder + " set qq=?, wechat=?, phone=?, addr=?, note=?, order_status=? where id=?" if tx != nil { _, err = tx.ExecContext(ctx, sqlStr, qq, wechat, phone, addr, note, dbstruct.VasCoinOrderStatusWaitDeal, id, ) } else { db := m.getDBVas() _, err = db.ExecContext(ctx, sqlStr, qq, wechat, phone, addr, note, dbstruct.VasCoinOrderStatusWaitDeal, id, ) } if err != nil { return err } return nil } // todo 获取待结算的订单 func (m *Mysql) Get(ctx *gin.Context, tx *sqlx.Tx, id string) (order *dbstruct.CoinOrder, err error) { var tmpOrder dbstruct.CoinOrder err = tx.GetContext(ctx, &tmpOrder, fmt.Sprintf("select * from %s where id = ? for update", TableCoinOrder), id) if err != nil { return } order = &tmpOrder return } // 待添加微信的订单 func (m *Mysql) GetWaitWechatAddCoinOrders(ctx *gin.Context, tx *sqlx.Tx, mid int64, statusList []int32, offset, limit int) (list []*dbstruct.CoinOrder, err error) { list = make([]*dbstruct.CoinOrder, 0) sqlStr := fmt.Sprintf("select * from %s where uid=? and product_id=? and order_status in (%s) limit ? offset ?", TableCoinOrder, util.Convert2SqlArr(statusList)) if tx != nil { err = tx.SelectContext(ctx, &list, sqlStr, mid, dbstruct.ProductIdContactWechat, limit, offset) } else { db := m.getDBVas() err = db.SelectContext(ctx, &list, sqlStr, mid, dbstruct.ProductIdContactWechat, limit, offset) } if err != nil { return } return } // 确定推荐微信 func (m *Mysql) ConfirmAddWechat(ctx *gin.Context, tx *sqlx.Tx, coinOrderId string) (err error) { sqlStr := "update " + TableCoinOrder + " set order_status=? where id=? and order_status=?" if tx != nil { _, err = tx.ExecContext(ctx, sqlStr, dbstruct.VasCoinOrderStatusDeal, coinOrderId, dbstruct.VasCoinOrderStatusWaitDeal) } else { db := m.getDBVas() _, err = db.ExecContext(ctx, sqlStr, dbstruct.VasCoinOrderStatusDeal, coinOrderId, dbstruct.VasCoinOrderStatusWaitDeal) } if err != nil { return } return } // 创建消费历史 func (m *Mysql) CreateConsumeHistory(ctx *gin.Context, tx *sqlx.Tx, ch *dbstruct.ConsumeHistory) error { var ( timeNow = time.Now().Unix() tableName, err = m.ChTableName(ch) ) if err != nil { return err } sqlStr := "insert into " + tableName + " (mid, uid, did, `type`, stype, type_id, " + " `order_id`, `change`, `before`, `after`, `count`, ct) " + " values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) " if tx != nil { _, err = tx.ExecContext(ctx, sqlStr, ch.Mid, ch.Uid, ch.Did, ch.Type, ch.SType, ch.TypeId, ch.OrderId, ch.Change, ch.Before, ch.After, ch.Count, timeNow, //ch.GetMid(), ch.GetUid(), ch.GetDid(), ch.GetType(), ch.GetSType(), ch.GetTypeId(), //ch.GetOrderId(), ch.GetChange(), ch.GetBefore(), ch.GetAfter(), ch.GetCount(), timeNow, ) } else { db := m.getDBVas() _, err = db.ExecContext(ctx, sqlStr, ch.Mid, ch.Uid, ch.Did, ch.Type, ch.SType, ch.TypeId, ch.OrderId, ch.Change, ch.Before, ch.After, ch.Count, timeNow, ) } if err != nil { logger.Error("CreateConsumeHistory fail, ch: %v, err: %v", util.ToJson(ch), err) return err } return err } // 创建解锁记录 func (m *Mysql) CreateUserVasUnlock(ctx *gin.Context, tx *sqlx.Tx, uu *dbstruct.UserVasUnlock) error { var ( err error timeNow = time.Now().Unix() ) sqlStr := "insert into " + TableVasUserUnlock + " (mid, uid, product_id, ct, lock_type, status, means, order_id) " + " values (?, ?, ?, ?, ?, ?, ?, ?) " if tx != nil { _, err = tx.ExecContext(ctx, sqlStr, uu.Mid, uu.Uid, uu.ProductId, timeNow, uu.LockType, uu.Status, uu.Means, uu.OrderId, ) } else { db := m.getDBVas() _, err = db.ExecContext(ctx, sqlStr, uu.Mid, uu.Uid, uu.ProductId, timeNow, uu.LockType, uu.Status, uu.Means, uu.OrderId, ) } if err != nil { logger.Error("CreateCoinOrder fail, uu: %v, err: %v", util.ToJson(uu), err) return err } return err } // 获取解锁记录 func (m *Mysql) GetUserVasUnlock(ctx *gin.Context, tx *sqlx.Tx, mid, uid int64, productId string) (uu *dbstruct.UserVasUnlock, err error) { var uuTmp dbstruct.UserVasUnlock sqlStr := fmt.Sprintf("select * from %s where mid=? and uid=? and product_id=?", TableVasUserUnlock) fmt.Println(sqlStr) if tx != nil { err = tx.GetContext(ctx, &uuTmp, sqlStr, mid, uid, productId) } else { db := m.getDBVas() err = db.GetContext(ctx, &uuTmp, sqlStr, mid, uid, productId) } if err != nil { return } uu = &uuTmp return } // 获取解锁记录 func (m *Mysql) GetUnlockWechatList(ctx *gin.Context, tx *sqlx.Tx, mid int64, offset, limit int) (list []*dbstruct.UserVasUnlock, err error) { list = make([]*dbstruct.UserVasUnlock, 0) sqlStr := fmt.Sprintf("select * from %s where mid=? limit ? offset ? ", TableVasUserUnlock) if tx != nil { err = tx.SelectContext(ctx, &list, sqlStr, mid, limit, offset) } else { db := m.getDBVas() err = db.SelectContext(ctx, &list, sqlStr, mid, limit, offset) } if err != nil { return } return } // 获取消费历史 func (m *Mysql) GetUCHList(ctx *gin.Context, tx *sqlx.Tx, mid int64, typ int32, offset, limit int) (list []*dbstruct.ConsumeHistory, err error) { list = make([]*dbstruct.ConsumeHistory, 0) tableName, err := m.ChTableName(&dbstruct.ConsumeHistory{Type: goproto.Int32(typ)}) sqlStr := fmt.Sprintf("select * from %s where mid=? limit ? offset ?", tableName) if tx != nil { err = tx.SelectContext(ctx, &list, sqlStr, mid, limit, offset) } else { db := m.getDBVas() err = db.SelectContext(ctx, &list, sqlStr, mid, limit, offset) } if err != nil { return } return }