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 CreatedAt time.Time `xorm:"created"` } 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, out_trade_no string, recharge_account string, account_type int64, status int64, transfer_status 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 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 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, out_trade_no string, recharge_account string, account_type int64, status int64, transfer_status 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 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 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) 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) 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 10 MINUTE)" err = m.GetDb().Where(sql, args...).OrderBy("created_at").Limit(limit).Find(&orders) return }