Files
slogan/server/styleagent/dao/payment_order_dao.go
T
admin a6de9ebd12 Add 'server/' from commit 'e64421295fff83acbb6d6ab3d3b27f3ef8368f00'
git-subtree-dir: server
git-subtree-mainline: c4e617ada7
git-subtree-split: e64421295f
2026-08-04 15:02:35 +08:00

95 lines
3.5 KiB
Go

package dao
import (
"context"
"slogan-agent/styleagent/consts"
"slogan-agent/styleagent/model/entity"
"github.com/gogf/gf/v2/database/gdb"
"github.com/gogf/gf/v2/frame/g"
)
var PaymentOrder = &paymentOrderDao{}
type paymentOrderDao struct{}
func init() {
ctx := context.Background()
_, err := dbPay().Exec(ctx, `CREATE TABLE IF NOT EXISTS `+consts.TableNamePaymentOrder+` (
id INTEGER PRIMARY KEY AUTOINCREMENT,
order_no TEXT NOT NULL UNIQUE,
user_id INTEGER NOT NULL DEFAULT 0,
plan_id INTEGER NOT NULL DEFAULT 0,
amount_fen INTEGER NOT NULL DEFAULT 0,
channel TEXT NOT NULL DEFAULT '',
status TEXT NOT NULL DEFAULT 'pending',
trade_no TEXT NOT NULL DEFAULT '',
notify_raw TEXT NOT NULL DEFAULT '',
paid_at DATETIME,
created_at DATETIME DEFAULT (datetime('now','localtime'))
)`)
if err != nil {
g.Log().Warningf(ctx, "create payment_order table failed: %v", err)
}
if _, err := dbPay().Exec(ctx, `CREATE INDEX IF NOT EXISTS idx_payment_order_user ON `+consts.TableNamePaymentOrder+`(user_id, created_at)`); err != nil {
g.Log().Warningf(ctx, "create index idx_payment_order_user failed: %v", err)
}
}
func (d *paymentOrderDao) Insert(ctx context.Context, order *entity.PaymentOrder) (int64, error) {
r, err := dbPay().Model(consts.TableNamePaymentOrder).Ctx(ctx).Data(g.Map{
"order_no": order.OrderNo, "user_id": order.UserId, "plan_id": order.PlanId,
"amount_fen": order.AmountFen, "channel": order.Channel, "status": order.Status,
}).Insert()
if err != nil {
return 0, err
}
return r.LastInsertId()
}
func (d *paymentOrderDao) GetByOrderNo(ctx context.Context, orderNo string) (*entity.PaymentOrder, error) {
var o *entity.PaymentOrder
err := dbPay().Model(consts.TableNamePaymentOrder).Ctx(ctx).
Where("order_no", orderNo).Scan(&o)
return o, err
}
// MarkPaid 状态机 pending→paid(只更新 pending 行,返回是否成功,回调并发安全)
func (d *paymentOrderDao) MarkPaid(ctx context.Context, orderNo, tradeNo, notifyRaw string) (bool, error) {
r, err := dbPay().Exec(ctx,
"UPDATE "+consts.TableNamePaymentOrder+" SET status=?, trade_no=?, notify_raw=?, paid_at=datetime('now','localtime') WHERE order_no=? AND status=?",
consts.PayStatusPaid, tradeNo, notifyRaw, orderNo, consts.PayStatusPending)
if err != nil {
return false, err
}
n, _ := r.RowsAffected()
return n > 0, nil
}
// ===== 事务版本(HandlePaidNotify 回调流程使用,保证订单状态与会员开通原子) =====
func (d *paymentOrderDao) GetByOrderNoTx(ctx context.Context, tx gdb.TX, orderNo string) (*entity.PaymentOrder, error) {
var o *entity.PaymentOrder
err := tx.Model(consts.TableNamePaymentOrder).Ctx(ctx).Where("order_no", orderNo).Scan(&o)
return o, err
}
func (d *paymentOrderDao) MarkPaidTx(ctx context.Context, tx gdb.TX, orderNo, tradeNo, notifyRaw string) (bool, error) {
r, err := tx.Ctx(ctx).Exec(
"UPDATE "+consts.TableNamePaymentOrder+" SET status=?, trade_no=?, notify_raw=?, paid_at=datetime('now','localtime') WHERE order_no=? AND status=?",
consts.PayStatusPaid, tradeNo, notifyRaw, orderNo, consts.PayStatusPending)
if err != nil {
return false, err
}
n, _ := r.RowsAffected()
return n > 0, nil
}
func (d *paymentOrderDao) GetByUser(ctx context.Context, userId int64) ([]*entity.PaymentOrder, error) {
var list []*entity.PaymentOrder
err := dbPay().Model(consts.TableNamePaymentOrder).Ctx(ctx).
Where("user_id", userId).OrderDesc("id").Limit(20).Scan(&list)
return list, err
}