2023-12-21 22:17:40 +08:00
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 )
2023-12-25 01:02:06 +08:00
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
}
2023-12-21 22:17:40 +08:00
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
}
2023-12-29 14:16:37 +08:00
// 获取订单
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
}
2023-12-21 22:17:40 +08:00
// 获取钱包 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 +
2024-01-01 12:19:42 +08:00
" (id, coins, diamonds, withdraw_diamonds) " +
" values (?, ?, ?, ?)"
2023-12-21 22:17:40 +08:00
if tx != nil {
2024-01-01 12:19:42 +08:00
_ , err = tx . ExecContext ( ctx , sqlStr , mid , 0 , 0 , 0 )
2023-12-21 22:17:40 +08:00
} else {
db := m . getDBVas ( )
2024-01-01 12:19:42 +08:00
_ , err = db . ExecContext ( ctx , sqlStr , mid , 0 , 0 , 0 )
2023-12-21 22:17:40 +08:00
}
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
}
2023-12-29 14:16:37 +08:00
// 获取金币订单
2023-12-21 22:17:40 +08:00
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 )
2023-12-30 14:52:53 +08:00
sqlStr := fmt . Sprintf ( "select * from %s where uid=? and product_id=? and order_status in (%s) limit ? offset ?" , TableCoinOrder , util . Convert2SqlArr ( statusList ) )
2023-12-21 22:17:40 +08:00
if tx != nil {
2023-12-30 14:42:40 +08:00
err = tx . SelectContext ( ctx , & list , sqlStr , mid , dbstruct . ProductIdContactWechat , limit , offset )
2023-12-21 22:17:40 +08:00
} else {
db := m . getDBVas ( )
2023-12-30 14:42:40 +08:00
err = db . SelectContext ( ctx , & list , sqlStr , mid , dbstruct . ProductIdContactWechat , limit , offset )
2023-12-21 22:17:40 +08:00
}
if err != nil {
return
}
2023-12-24 00:02:22 +08:00
2023-12-21 22:17:40 +08:00
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
}