491 lines
12 KiB
Go
491 lines
12 KiB
Go
package orders
|
||
|
||
import (
|
||
"encoding/json"
|
||
"errors"
|
||
"sync"
|
||
"time"
|
||
|
||
"github.com/qit-team/snow-core/db"
|
||
)
|
||
|
||
var (
|
||
once sync.Once
|
||
m *ordersModel
|
||
)
|
||
|
||
/**
|
||
* Orders
|
||
*/
|
||
type Orders struct {
|
||
Id int64 `xorm:"pk autoincr"` //注:使用getOne 或者ID() 需要设置主键
|
||
OrderNo string
|
||
MerchantId int64
|
||
ProductId int64
|
||
|
||
OutTradeNo string
|
||
RechargeAccount string
|
||
AccountType int64
|
||
Number int64
|
||
NotifyUrl string
|
||
ExtendParameter string
|
||
|
||
Status int64
|
||
TransferStatus int64
|
||
FailReason string
|
||
DeviceNo string
|
||
CreatedAt time.Time `xorm:"created"`
|
||
|
||
QueueNo int64
|
||
}
|
||
|
||
func (o *Orders) MarshalBinary() ([]byte, error) {
|
||
return json.Marshal(o)
|
||
}
|
||
|
||
/**
|
||
* 表名规则
|
||
* @wiki http://gobook.io/read/github.com/go-xorm/manual-zh-CN/chapter-02/3.tags.html
|
||
*/
|
||
func (m *Orders) TableName() string {
|
||
return "orders"
|
||
}
|
||
|
||
/**
|
||
* 私有化,防止被外部new
|
||
*/
|
||
type ordersModel struct {
|
||
db.Model //组合基础Model,集成基础Model的属性和方法
|
||
}
|
||
|
||
// 单例模式
|
||
func GetInstance() *ordersModel {
|
||
once.Do(func() {
|
||
m = new(ordersModel)
|
||
//m.DiName = "" //设置数据库实例连接,默认db.SingletonMain
|
||
})
|
||
return m
|
||
}
|
||
|
||
/**
|
||
* 查询主键ID的记录
|
||
* @param id 主键ID
|
||
* @return has 是否有记录
|
||
* @return err 错误信息
|
||
* @return orders 查询结果
|
||
*/
|
||
func (m *ordersModel) GetById(id int64) (orders *Orders, has bool, err error) {
|
||
orders = &Orders{}
|
||
has, err = m.GetDb().ID(id).Get(orders)
|
||
if err != nil || !has {
|
||
orders = nil
|
||
}
|
||
return
|
||
}
|
||
|
||
func (m *ordersModel) GetByOutTradeNo(out_trade_no string, merchant_id int64) (orders *Orders, has bool, err error) {
|
||
orders = &Orders{}
|
||
has, err = m.GetDb().Where("out_trade_no = ? and merchant_id = ?", out_trade_no, merchant_id).Get(orders)
|
||
if err != nil || !has {
|
||
orders = nil
|
||
}
|
||
return
|
||
}
|
||
|
||
func (m *ordersModel) Search(
|
||
id int64,
|
||
order_no string,
|
||
merchant_id int64,
|
||
product_id int64,
|
||
device_no string,
|
||
out_trade_no string,
|
||
recharge_account string,
|
||
account_type int64,
|
||
|
||
status int64,
|
||
transfer_status int64,
|
||
queue_no int64,
|
||
startTime string,
|
||
endTime string,
|
||
limit int,
|
||
page int) (orders []*Orders, err error) {
|
||
orders = make([]*Orders, 0)
|
||
sql := "1=1"
|
||
var args []interface{}
|
||
if id != 0 {
|
||
sql += " and id = ?"
|
||
args = append(args, id)
|
||
}
|
||
if order_no != "" {
|
||
sql += " and order_no = ?"
|
||
args = append(args, order_no)
|
||
}
|
||
if merchant_id != 0 {
|
||
sql += " and merchant_id = ?"
|
||
args = append(args, merchant_id)
|
||
}
|
||
if product_id != 0 {
|
||
sql += " and product_id = ?"
|
||
args = append(args, product_id)
|
||
}
|
||
if device_no != "" {
|
||
sql += " and device_no = ?"
|
||
args = append(args, device_no)
|
||
}
|
||
if out_trade_no != "" {
|
||
sql += " and out_trade_no = ?"
|
||
args = append(args, out_trade_no)
|
||
}
|
||
if recharge_account != "" {
|
||
sql += " and recharge_account = ?"
|
||
args = append(args, recharge_account)
|
||
}
|
||
if account_type != 0 {
|
||
sql += " and account_type = ?"
|
||
args = append(args, recharge_account)
|
||
}
|
||
if status != 0 {
|
||
sql += " and status = ?"
|
||
args = append(args, status)
|
||
}
|
||
if transfer_status != 0 {
|
||
sql += " and transfer_status = ?"
|
||
args = append(args, transfer_status)
|
||
}
|
||
if queue_no != 0 {
|
||
sql += " and queue_no = ?"
|
||
args = append(args, queue_no)
|
||
}
|
||
if startTime != "" && endTime != "" {
|
||
sql += " and created_at >= ? and created_at <= ?"
|
||
args = append(args, startTime, endTime)
|
||
}
|
||
err = m.GetDb().Where(sql, args...).OrderBy("created_at desc").Limit(limit, page).Find(&orders)
|
||
return
|
||
}
|
||
|
||
func (m *ordersModel) CountAll(
|
||
id int64,
|
||
order_no string,
|
||
merchant_id int64,
|
||
product_id int64,
|
||
device_no string,
|
||
out_trade_no string,
|
||
recharge_account string,
|
||
account_type int64,
|
||
|
||
status int64,
|
||
transfer_status int64,
|
||
queue_no int64,
|
||
startTime string,
|
||
endTime string,
|
||
) (res int64, err error) {
|
||
sql := "1=1"
|
||
var args []interface{}
|
||
if id != 0 {
|
||
sql += " and id = ?"
|
||
args = append(args, id)
|
||
}
|
||
if order_no != "" {
|
||
sql += " and order_no = ?"
|
||
args = append(args, order_no)
|
||
}
|
||
if merchant_id != 0 {
|
||
sql += " and merchant_id = ?"
|
||
args = append(args, merchant_id)
|
||
}
|
||
if product_id != 0 {
|
||
sql += " and merchant_id = ?"
|
||
args = append(args, product_id)
|
||
}
|
||
if device_no != "" {
|
||
sql += " and device_no = ?"
|
||
args = append(args, device_no)
|
||
}
|
||
if out_trade_no != "" {
|
||
sql += " and out_trade_no = ?"
|
||
args = append(args, out_trade_no)
|
||
}
|
||
if recharge_account != "" {
|
||
sql += " and recharge_account = ?"
|
||
args = append(args, recharge_account)
|
||
}
|
||
if account_type != 0 {
|
||
sql += " and account_type = ?"
|
||
args = append(args, recharge_account)
|
||
}
|
||
if status != 0 {
|
||
sql += " and status = ?"
|
||
args = append(args, status)
|
||
}
|
||
if transfer_status != 0 {
|
||
sql += " and transfer_status = ?"
|
||
args = append(args, transfer_status)
|
||
}
|
||
if queue_no != 0 {
|
||
sql += " and queue_no = ?"
|
||
args = append(args, queue_no)
|
||
}
|
||
if startTime != "" && endTime != "" {
|
||
sql += " and created_at >= ? and created_at <= ?"
|
||
args = append(args, startTime, endTime)
|
||
}
|
||
res, err = m.GetDb().Where(sql, args...).Table("orders").Count()
|
||
return
|
||
}
|
||
|
||
func (m *ordersModel) CountErrHour() (res int64, err error) {
|
||
res, err = m.GetDb().Where("(transfer_status = 4 or transfer_status = 5) and created_at >= NOW() + INTERVAL 7 HOUR").Table("orders").Count()
|
||
return
|
||
}
|
||
|
||
func (m *ordersModel) Create(orders *Orders) (affected int64, err error) {
|
||
orders.CreatedAt = time.Now()
|
||
affected, err = m.GetDb().Insert(orders)
|
||
return
|
||
}
|
||
|
||
func (m *ordersModel) Update(orders *Orders) (affected int64, err error) {
|
||
affected, err = m.GetDb().ID(orders.Id).Update(orders)
|
||
return
|
||
}
|
||
|
||
func (m *ordersModel) Delete(id int64) (affected int64, err error) {
|
||
affected, err = m.GetDb().ID(id).Delete(&Orders{})
|
||
return
|
||
}
|
||
|
||
func (m *ordersModel) GetIdleOrder() (orders *Orders, has bool, err error) {
|
||
orders = &Orders{}
|
||
|
||
session := m.GetDb().NewSession()
|
||
defer session.Close()
|
||
// add Begin() before any action
|
||
if err = session.Begin(); err != nil {
|
||
orders = nil
|
||
return
|
||
}
|
||
|
||
has, err = session.Where("transfer_status = 3").Limit(1).Get(orders)
|
||
if err != nil || !has {
|
||
orders = nil
|
||
return
|
||
}
|
||
orders.TransferStatus = 7 // 1.成功 2.充值中 3. 等待充值 4.充值失败 5.异常需要人工处理 6.取消订单 7.订单入队
|
||
affected, err := session.ID(orders.Id).Where("transfer_status = 3").Update(orders)
|
||
if err != nil || affected == 0 {
|
||
orders = nil
|
||
return
|
||
}
|
||
err = session.Commit()
|
||
return
|
||
}
|
||
|
||
func (m *ordersModel) OrderOutQueue(orderId int64) (err error) {
|
||
orders := &Orders{}
|
||
|
||
session := m.GetDb().NewSession()
|
||
defer session.Close()
|
||
// add Begin() before any action
|
||
if err = session.Begin(); err != nil {
|
||
orders = nil
|
||
return
|
||
}
|
||
|
||
orders = &Orders{}
|
||
has, err := session.ID(orderId).Get(orders)
|
||
if err != nil || !has {
|
||
orders = nil
|
||
return
|
||
}
|
||
|
||
if orders.TransferStatus != 7 {
|
||
err = errors.New("订单已取消或者未在队列中")
|
||
return
|
||
}
|
||
|
||
orders.TransferStatus = 2 // 1.成功 2.充值中 3. 等待充值 4.充值失败 5.异常需要人工处理 6.取消订单 7.订单入队
|
||
affected, err := session.ID(orders.Id).Where("transfer_status = 7").Update(orders)
|
||
if err != nil || affected == 0 {
|
||
orders = nil
|
||
return
|
||
}
|
||
err = session.Commit()
|
||
return
|
||
}
|
||
|
||
func (m *ordersModel) CancelOrder(orderId int64) (affected int64, err error) {
|
||
orders := &Orders{}
|
||
|
||
session := m.GetDb().NewSession()
|
||
defer session.Close()
|
||
// add Begin() before any action
|
||
if err = session.Begin(); err != nil {
|
||
orders = nil
|
||
return
|
||
}
|
||
|
||
orders = &Orders{}
|
||
has, err := session.ID(orderId).Get(orders)
|
||
if err != nil || !has {
|
||
orders = nil
|
||
return
|
||
}
|
||
|
||
orders.Status = 5
|
||
orders.TransferStatus = 6 // 1.成功 2.充值中 3. 等待充值 4.充值失败 5.异常需要人工处理 6.取消订单 7.订单入队
|
||
orders.FailReason = "订单取消"
|
||
affected, err = session.ForUpdate().ID(orders.Id).Where("transfer_status not in (1,2,4,5,6)").Update(orders)
|
||
if err != nil || affected == 0 {
|
||
err = errors.New("订单正在充值或者已经完成")
|
||
orders = nil
|
||
return
|
||
}
|
||
err = session.Commit()
|
||
if err != nil {
|
||
session.Rollback()
|
||
return
|
||
}
|
||
return
|
||
}
|
||
|
||
func (m *ordersModel) DangerousConfirm(orderId int64) (affected int64, err error) {
|
||
orders := &Orders{}
|
||
|
||
session := m.GetDb().NewSession()
|
||
defer session.Close()
|
||
// add Begin() before any action
|
||
if err = session.Begin(); err != nil {
|
||
orders = nil
|
||
return
|
||
}
|
||
|
||
orders = &Orders{}
|
||
has, err := session.ID(orderId).Get(orders)
|
||
if err != nil || !has {
|
||
orders = nil
|
||
return
|
||
}
|
||
|
||
orders.Status = 1
|
||
orders.TransferStatus = 1 // 1.成功 2.充值中 3. 等待充值 4.充值失败 5.异常需要人工处理 6.取消订单 7.订单入队
|
||
orders.FailReason = "风险确认"
|
||
affected, err = session.ForUpdate().ID(orders.Id).Where("transfer_status not in (1,4,6)").Update(orders)
|
||
if err != nil || affected == 0 {
|
||
err = errors.New("订单正在充值或者已经完成")
|
||
orders = nil
|
||
return
|
||
}
|
||
err = session.Commit()
|
||
if err != nil {
|
||
session.Rollback()
|
||
return
|
||
}
|
||
return
|
||
}
|
||
|
||
func (m *ordersModel) DangerousCancel(orderId int64) (affected int64, err error) {
|
||
orders := &Orders{}
|
||
|
||
session := m.GetDb().NewSession()
|
||
defer session.Close()
|
||
// add Begin() before any action
|
||
if err = session.Begin(); err != nil {
|
||
orders = nil
|
||
return
|
||
}
|
||
|
||
orders = &Orders{}
|
||
has, err := session.ID(orderId).Get(orders)
|
||
if err != nil || !has {
|
||
orders = nil
|
||
return
|
||
}
|
||
|
||
orders.Status = 5
|
||
orders.TransferStatus = 6 // 1.成功 2.充值中 3. 等待充值 4.充值失败 5.异常需要人工处理 6.取消订单 7.订单入队
|
||
orders.FailReason = "风险取消"
|
||
affected, err = session.ForUpdate().ID(orders.Id).Where("transfer_status not in (1,4,6)").Update(orders)
|
||
if err != nil || affected == 0 {
|
||
err = errors.New("订单正在充值或者已经完成")
|
||
orders = nil
|
||
return
|
||
}
|
||
err = session.Commit()
|
||
if err != nil {
|
||
session.Rollback()
|
||
return
|
||
}
|
||
return
|
||
}
|
||
|
||
func (m *ordersModel) SetDealingOrder(orders *Orders) (affected int64, err error) {
|
||
|
||
session := m.GetDb().NewSession()
|
||
defer session.Close()
|
||
// add Begin() before any action
|
||
if err = session.Begin(); err != nil {
|
||
orders = nil
|
||
return
|
||
}
|
||
|
||
has, err := session.Where("id = ? and merchant_id = ? and product_id = ? and transfer_status = 2",
|
||
orders.Id, orders.MerchantId, orders.ProductId).Get(&Orders{})
|
||
if err != nil || !has {
|
||
orders = nil
|
||
return
|
||
}
|
||
// 1.成功 2.充值中 3. 等待充值 4.充值失败 5.异常需要人工处理
|
||
affected, err = session.ID(orders.Id).Where("transfer_status = 2").Update(orders)
|
||
if err != nil || affected == 0 {
|
||
orders = nil
|
||
return
|
||
}
|
||
err = session.Commit()
|
||
return
|
||
}
|
||
|
||
func (m *ordersModel) GetTimeoutOrder(
|
||
limit int,
|
||
) (orders []*Orders, err error) {
|
||
orders = make([]*Orders, 0)
|
||
sql := "1=1"
|
||
var args []interface{}
|
||
sql += " and transfer_status not in (1,2,4,5,6)"
|
||
// sql += " and created_at <= DATE_SUB(NOW(), INTERVAL 3 MINUTE)"
|
||
sql += " and created_at <= DATE_SUB(DATE_ADD(NOW(),INTERVAL 8 HOUR), INTERVAL 3 MINUTE)"
|
||
err = m.GetDb().Where(sql, args...).OrderBy("created_at").Limit(limit).Find(&orders)
|
||
return
|
||
}
|
||
|
||
func (m *ordersModel) GetRechargeTimeoutOrder(
|
||
limit int,
|
||
) (orders []*Orders, err error) {
|
||
orders = make([]*Orders, 0)
|
||
sql := "1=1"
|
||
var args []interface{}
|
||
sql += " and transfer_status = 2"
|
||
sql += " and (fail_reason = '' or fail_reason IS NULL)"
|
||
// sql += " and created_at <= DATE_SUB(NOW(), INTERVAL 3 MINUTE)"
|
||
sql += " and created_at <= DATE_SUB(DATE_ADD(NOW(),INTERVAL 8 HOUR), INTERVAL 7 MINUTE)"
|
||
err = m.GetDb().Where(sql, args...).OrderBy("created_at").Limit(limit).Find(&orders)
|
||
return
|
||
}
|
||
|
||
func (m *ordersModel) SetOrderMobile(orders *Orders) (affected int64, err error) {
|
||
session := m.GetDb().NewSession()
|
||
defer session.Close()
|
||
// add Begin() before any action
|
||
if err = session.Begin(); err != nil {
|
||
orders = nil
|
||
return
|
||
}
|
||
affected, err = session.ID(orders.Id).Update(orders)
|
||
if err != nil || affected == 0 {
|
||
orders = nil
|
||
return
|
||
}
|
||
err = session.Commit()
|
||
return
|
||
}
|