takecash.go 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. package balance_model
  2. import (
  3. "fmt"
  4. "time"
  5. "github.com/astaxie/beego"
  6. "github.com/astaxie/beego/orm"
  7. "fohow.com/cache"
  8. )
  9. const (
  10. take_cash_orders_tablename = "take_cash_orders"
  11. ORDER_ID_PREFIX_TX = "TX" //提现
  12. //状态:提现失败(pay_state:0,audit_state:2), 提现中(pay_state:0,audit_state:0,1), 已完成(pay_state:1, audit_state:1)
  13. STATE_CN_REJECTED = "提现失败"
  14. STATE_CN_IN_PROGRESS = "提现中"
  15. STATE_CN_SUCESS = "已完成"
  16. TAKE_CASH_LIMIT = 1 //每天提现次数限制
  17. AUTOTAKE_STATE = int64(1) //自动提现状态
  18. REAL_STATE = int64(0) //强制检验
  19. TAKE_CASH_TIMEOUT_REMARK = "超时未确认,请您重新提现!"
  20. )
  21. type TakeCashOrder struct {
  22. Id int64 `orm:"column(id);pk" json:"id"` // int(11)
  23. WxUId int64 `orm:"column(wx_uid)" json:"wx_uid"` // int(11)
  24. OrderId string `orm:"column(order_id)" json:"order_id"` // varchar(64)
  25. TradeNo string `orm:"column(trade_no);null" json:"trade_no"` // varchar(64)
  26. Count int64 `orm:"column(count);null" json:"count"` // bigint(20)
  27. FeiCount int64 `orm:"column(fei_count)" json:"fei_count"` // int(11)
  28. FreeCount int64 `orm:"column(free_count)" json:"free_count"` // int(11)
  29. Fee int64 `orm:"column(fee);null" json:"fee"` // bigint(20)
  30. State int64 `orm:"column(pay_state);null" json:"pay_state"` // tinyint(1)
  31. RealState int64 `orm:"column(real_state);null" json:"-"` // tinyint(1)
  32. AuditState int64 `orm:"column(audit_state);null" json:"audit_state"` // tinyint(1)
  33. PaiedAt int64 `orm:"column(paied_at);null" json:"paied_at"` // int(11)
  34. Remark string `orm:"column(remark);null" json:"remark"` // varchar(255)
  35. ExpcPayAt time.Time `orm:"column(expc_pay_at);null;auto_now_add;type(datetime)" json:"expc_pay_at"` // datetime
  36. //银行信息
  37. BankName string `orm:"column(bank_name)" json:"bank_name"`
  38. BankAccount string `orm:"column(bank_account)" json:"bank_account"`
  39. AccountName string `orm:"column(account_name)" json:"account_name"`
  40. CreatedAt time.Time `orm:"column(created_at);null;auto_now_add;type(datetime)" json:"created_at"` // datetime
  41. UpdatedAt time.Time `orm:"column(updated_at);null;auto_now;type(datetime)" json:"updated_at"` // datetime
  42. }
  43. func (self *TakeCashOrder) TableName() string {
  44. return take_cash_orders_tablename
  45. }
  46. func (self *TakeCashOrder) Create(wxUId, count, feiCount, freeCount int64) (item *TakeCashOrder) {
  47. oId := createOrderId(ORDER_ID_PREFIX_TX)
  48. item = &TakeCashOrder{
  49. Count: count,
  50. FeiCount: feiCount,
  51. FreeCount: freeCount,
  52. WxUId: wxUId,
  53. OrderId: oId,
  54. RealState: REAL_STATE,
  55. }
  56. id, err := orm.NewOrm().Insert(item)
  57. if err != nil {
  58. beego.BeeLogger.Error("Create TakeCashOrder err=[%s]", err)
  59. return nil
  60. }
  61. item.Id = id
  62. return item
  63. }
  64. func (self *TakeCashOrder) Save() error {
  65. if _, err := orm.NewOrm().Update(self); err != nil {
  66. beego.BeeLogger.Error("Save take cash order id=[%d] .err=[%s]", self.Id, err)
  67. return err
  68. }
  69. return nil
  70. }
  71. // 状态值中文
  72. func (self *TakeCashOrder) GetStateCn() string {
  73. stateCn := ""
  74. switch self.State {
  75. case 0:
  76. switch self.AuditState {
  77. case 0:
  78. stateCn = STATE_CN_IN_PROGRESS
  79. case 1:
  80. stateCn = STATE_CN_IN_PROGRESS
  81. case 2:
  82. stateCn = STATE_CN_REJECTED
  83. }
  84. case 1:
  85. switch self.AuditState {
  86. case 1:
  87. stateCn = STATE_CN_SUCESS
  88. }
  89. case 2:
  90. stateCn = STATE_CN_REJECTED
  91. }
  92. return stateCn
  93. }
  94. func GetTakeCashOrderByOId(oId string, useCache bool) *TakeCashOrder {
  95. k := fmt.Sprintf("balance_model.GetTakeCashOrderByOId[%s]", oId)
  96. if useCache {
  97. if order, ok := cache.Cache.Get(k).(*TakeCashOrder); ok {
  98. return order
  99. }
  100. }
  101. order := new(TakeCashOrder)
  102. o := orm.NewOrm()
  103. err := o.QueryTable(order).Filter("order_id", oId).Limit(1).One(order)
  104. if err != nil {
  105. beego.Debug("GetOrderByOrderId is not found err=[%s], oId=%s", err, oId)
  106. return nil
  107. } else {
  108. cache.Cache.Put(k, order, 5*time.Minute)
  109. return order
  110. }
  111. }
  112. func GetTakeCashOrderById(id int64, useCache bool) *TakeCashOrder {
  113. k := fmt.Sprintf("balance_model.GetTakeCashOrderById[%d]", id)
  114. if useCache {
  115. if order, ok := cache.Cache.Get(k).(*TakeCashOrder); ok {
  116. return order
  117. }
  118. }
  119. order := new(TakeCashOrder)
  120. o := orm.NewOrm()
  121. err := o.QueryTable(order).Filter("id", id).Limit(1).One(order)
  122. if err != nil {
  123. beego.Debug("GetTakeCashOrderById is not found err=[%s], id=%d", err, id)
  124. return nil
  125. } else {
  126. cache.Cache.Put(k, order, 5*time.Minute)
  127. return order
  128. }
  129. }
  130. // 获取某人的提现流列表
  131. func GetTakeCashOrderListByWxUId(wxUId, page, perPage int64, useCache bool) (list []*TakeCashOrder) {
  132. k := fmt.Sprintf("balance_model.GetTakeCashOrderListByWxUId.wxUId(%d).page(%d).perPage(%d)", wxUId, page, perPage)
  133. if useCache {
  134. if s, ok := cache.Cache.Get(k).([]*TakeCashOrder); ok {
  135. return s
  136. }
  137. }
  138. order := new(TakeCashOrder)
  139. qs := orm.NewOrm().QueryTable(order)
  140. qs = qs.Filter("wx_uid", wxUId)
  141. if _, err := qs.OrderBy("-created_at", "-id").
  142. Limit(perPage, (page-1)*perPage).All(&list); err != nil {
  143. beego.BeeLogger.Debug("get GetTakeCashOrderListByWxUId with wxUId=%d, err=[%s]", wxUId, err)
  144. return nil
  145. }
  146. cache.Cache.Put(k, list, 5*time.Minute)
  147. return list
  148. }
  149. // 获取某人的提现流列表总条数
  150. func GetTakeCashOrderCountByWxUId(wxUId int64, useCache bool) int64 {
  151. k := fmt.Sprintf("balance_model.GetTakeCashOrderCountByWxUId.wxUId(%d)", wxUId)
  152. if useCache {
  153. if s, ok := cache.Cache.Get(k).(int64); ok {
  154. return s
  155. }
  156. }
  157. item := new(TakeCashOrder)
  158. o := orm.NewOrm()
  159. count, _ := o.QueryTable(item).Filter("wx_uid", wxUId).Count()
  160. if count > 0 {
  161. cache.Cache.Put(k, count, 5*time.Minute)
  162. }
  163. return count
  164. }
  165. func GetTakeCashOrderListByWxUIdAndTime(wxUId int64, now time.Time, useCache bool) (list []*TakeCashOrder) {
  166. k := fmt.Sprintf("balance_model.GetTakeCashOrderListByWxUIdAndTime.wxUId(%d).nowDay(%s)", wxUId, now.Format("2006-01-02"))
  167. if useCache {
  168. if s, ok := cache.Cache.Get(k).([]*TakeCashOrder); ok {
  169. return s
  170. }
  171. }
  172. qs := orm.NewOrm()
  173. sql :=
  174. `
  175. SELECT
  176. *
  177. FROM
  178. take_cash_orders
  179. WHERE
  180. wx_uid = ?
  181. AND DATE_FORMAT(
  182. DATE_ADD(created_at, INTERVAL 8 HOUR),
  183. '%Y-%m-%d'
  184. ) = ?
  185. LIMIT ?;
  186. `
  187. if _, err := qs.Raw(sql, wxUId, now.Format("2006-01-02")).QueryRows(&list); err != nil {
  188. beego.BeeLogger.Debug("get GetTakeCashOrderListByWxUIdAndTime with wxUId=%d, err=[%s]", wxUId, err)
  189. return nil
  190. }
  191. if len(list) > 0 {
  192. cache.Cache.Put(k, list, 5*time.Minute)
  193. }
  194. return list
  195. }
  196. // 取正在提现的订单列表
  197. func GetAllTakingCashOrders() (list []*TakeCashOrder) {
  198. sql := fmt.Sprintf("select * from %s where pay_state=? and audit_state=? and expc_pay_at < ?", take_cash_orders_tablename)
  199. if _, err := orm.NewOrm().Raw(sql, 0, 1, time.Now().Add(-8*time.Hour)).QueryRows(&list); err != nil {
  200. return nil
  201. }
  202. return list
  203. }
  204. // 取超过24小时仍未完成的提现订单,避免继续审核或继续等待已过期的微信确认收款。
  205. func GetTimeoutTakingCashOrders(limit int) (list []*TakeCashOrder) {
  206. if limit <= 0 {
  207. limit = 100
  208. }
  209. sql := fmt.Sprintf("SELECT * FROM %s WHERE pay_state=? AND audit_state=? AND created_at < DATE_SUB(NOW(), INTERVAL 24 HOUR) ORDER BY created_at ASC, id ASC LIMIT ?", take_cash_orders_tablename)
  210. if _, err := orm.NewOrm().Raw(sql, 0, 1, limit).QueryRows(&list); err != nil {
  211. beego.BeeLogger.Error("GetTimeoutTakingCashOrders err=[%s]", err)
  212. return nil
  213. }
  214. return list
  215. }
  216. func MarkTakeCashOrderTimeout(orderId string) (bool, error) {
  217. tbn := new(TakeCashOrder).TableName()
  218. sql := fmt.Sprintf("UPDATE `%s` SET `pay_state`=2, `remark`=?, `updated_at`=NOW() WHERE `order_id`=? AND `pay_state`=0 AND `audit_state`=1 LIMIT 1", tbn)
  219. res, err := orm.NewOrm().Raw(sql, TAKE_CASH_TIMEOUT_REMARK, orderId).Exec()
  220. if err != nil {
  221. beego.BeeLogger.Error("MarkTakeCashOrderTimeout order_id=[%s] err=[%s]", orderId, err)
  222. return false, err
  223. }
  224. rows, err := res.RowsAffected()
  225. if err != nil {
  226. beego.BeeLogger.Error("MarkTakeCashOrderTimeout rows affected order_id=[%s] err=[%s]", orderId, err)
  227. return false, err
  228. }
  229. return rows > 0, nil
  230. }
  231. // 充值账户余额
  232. func GetTakeFeeBalance(wxUId int64) int64 {
  233. type Ret struct {
  234. Count int64
  235. }
  236. ret := &Ret{}
  237. o := orm.NewOrm()
  238. tbn := new(TakeCashOrder).TableName()
  239. sql := fmt.Sprintf("SELECT sum(`free_count`) as count FROM `%s` WHERE wx_uid=?;", tbn)
  240. err := o.Raw(sql, wxUId).QueryRow(ret)
  241. if err != nil {
  242. beego.BeeLogger.Error("GetTakeFeeBalance, wxUser:%d err=[%s]", wxUId, err)
  243. return 0
  244. }
  245. if ret.Count < 0 {
  246. return 0
  247. }
  248. return ret.Count
  249. }