allowance.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. package dao
  2. import (
  3. "bytes"
  4. "context"
  5. xsql "database/sql"
  6. "fmt"
  7. "go-common/app/service/main/coupon/model"
  8. "go-common/library/database/sql"
  9. "strconv"
  10. "time"
  11. "github.com/pkg/errors"
  12. )
  13. const (
  14. _couponAllowanceNoStartCheckSQL = "SELECT id,coupon_token,mid,state,start_time,expire_time,origin,ver,batch_token,order_no,amount,full_amount,ctime,mtime FROM coupon_allowance_info_%02d WHERE mid = ? AND expire_time > ? AND state = ?;"
  15. _couponByOrderNOSQL = "SELECT id,coupon_token,mid,state,start_time,expire_time,origin,ver,batch_token,order_no,amount,full_amount,ctime,mtime,remark FROM coupon_allowance_info_%02d WHERE order_no = ?;"
  16. _couponUsableAllowanceSQL = "SELECT id,coupon_token,mid,state,start_time,expire_time,origin,ver,batch_token,order_no,amount,full_amount,ctime,mtime FROM coupon_allowance_info_%02d WHERE mid = ? AND expire_time > ? AND start_time < ? AND state = ?;"
  17. _couponAllowanceByTokenSQL = "SELECT id,coupon_token,mid,state,start_time,expire_time,origin,ver,batch_token,order_no,amount,full_amount,ctime,mtime FROM coupon_allowance_info_%02d WHERE coupon_token = ?;"
  18. _updateCouponAllowanceInUseSQL = "UPDATE coupon_allowance_info_%02d SET state =?, order_no = ?, remark = ?, ver =ver+1 WHERE coupon_token = ? AND ver = ?;"
  19. _updateCouponAllowanceToUseSQL = "UPDATE coupon_allowance_info_%02d SET state =?, order_no = ?, ver =ver+1 WHERE coupon_token = ? AND ver = ? AND state = ?;"
  20. _getCouponByOrderNoSQL = "SELECT mid,coupon_token,order_no,amount,full_amount,state,ver FROM coupon_allowance_info_%02d WHERE order_no = ?"
  21. _addCouponAllowanceChangeLogSQL = "INSERT INTO coupon_allowance_change_log_%02d (coupon_token,order_no,mid,state,ctime, change_type) VALUES(?,?,?,?,?,?);"
  22. _batchAllowanceCountByMid = "SELECT COUNT(1) FROM coupon_allowance_info_%02d WHERE mid = ? AND batch_token = ?;"
  23. _batchAddAllowanceCouponSQL = "INSERT INTO coupon_allowance_info_%02d(coupon_token,mid,state,start_time,expire_time,origin,batch_token,amount,full_amount,ctime,app_id) VALUES "
  24. _addAllowanceCouponSQL = "INSERT INTO coupon_allowance_info_%02d(coupon_token,mid,state,start_time,expire_time,origin,batch_token,amount,full_amount,app_id) VALUES (?,?,?,?,?,?,?,?,?,?)"
  25. _couponAllowancePageNotUsedSQL = "SELECT id,coupon_token,mid,state,start_time,expire_time,origin,ver,batch_token,order_no,amount,full_amount,ctime,mtime,remark FROM coupon_allowance_info_%02d WHERE mid = ? AND (state = 0 OR state = 1) AND expire_time > ? AND start_time < ? AND ctime > ? ORDER BY id DESC"
  26. _couponAllowancePageUsedSQL = "SELECT id,coupon_token,mid,state,start_time,expire_time,origin,ver,batch_token,order_no,amount,full_amount,ctime,mtime,remark FROM coupon_allowance_info_%02d WHERE mid = ? AND state = 2 AND ctime > ? ORDER BY id DESC "
  27. _couponAllowancePageExpireSQL = "SELECT id,coupon_token,mid,state,start_time,expire_time,origin,ver,batch_token,order_no,amount,full_amount,ctime,mtime,remark FROM coupon_allowance_info_%02d WHERE mid = ? AND state <> 2 AND expire_time < ? AND ctime > ? ORDER BY id DESC "
  28. )
  29. func hitAllowanceInfo(mid int64) int64 {
  30. return mid % 10
  31. }
  32. func hitAllowanceChangeLog(mid int64) int64 {
  33. return mid % 10
  34. }
  35. // ByStateAndExpireAllowances query by coupon state and expire .
  36. func (d *Dao) ByStateAndExpireAllowances(c context.Context, mid int64, state int8, t int64) (res []*model.CouponAllowanceInfo, err error) {
  37. var rows *sql.Rows
  38. if rows, err = d.db.Query(c, fmt.Sprintf(_couponAllowanceNoStartCheckSQL, hitAllowanceInfo(mid)), mid, t, state); err != nil {
  39. err = errors.WithStack(err)
  40. return
  41. }
  42. defer rows.Close()
  43. for rows.Next() {
  44. r := &model.CouponAllowanceInfo{}
  45. if err = rows.Scan(&r.ID, &r.CouponToken, &r.Mid, &r.State, &r.StartTime, &r.ExpireTime, &r.Origin, &r.Ver, &r.BatchToken,
  46. &r.OrderNO, &r.Amount, &r.FullAmount, &r.CTime, &r.MTime); err != nil {
  47. err = errors.WithStack(err)
  48. res = nil
  49. return
  50. }
  51. res = append(res, r)
  52. }
  53. err = rows.Err()
  54. return
  55. }
  56. // AllowanceByOrderNO query coupon by orderno.
  57. func (d *Dao) AllowanceByOrderNO(c context.Context, mid int64, orderNO string) (r *model.CouponAllowanceInfo, err error) {
  58. var row *sql.Row
  59. r = &model.CouponAllowanceInfo{}
  60. row = d.db.QueryRow(c, fmt.Sprintf(_couponByOrderNOSQL, hitAllowanceInfo(mid)), orderNO)
  61. if err = row.Scan(&r.ID, &r.CouponToken, &r.Mid, &r.State, &r.StartTime, &r.ExpireTime, &r.Origin, &r.Ver, &r.BatchToken,
  62. &r.OrderNO, &r.Amount, &r.FullAmount, &r.CTime, &r.MTime, &r.Remark); err != nil {
  63. if err == sql.ErrNoRows {
  64. err = nil
  65. r = nil
  66. return
  67. }
  68. err = errors.WithStack(err)
  69. return
  70. }
  71. return
  72. }
  73. // UsableAllowances usable allowance .
  74. func (d *Dao) UsableAllowances(c context.Context, mid int64, state int8, t int64) (res []*model.CouponAllowanceInfo, err error) {
  75. var rows *sql.Rows
  76. if rows, err = d.db.Query(c, fmt.Sprintf(_couponUsableAllowanceSQL, hitAllowanceInfo(mid)), mid, t, t, state); err != nil {
  77. err = errors.WithStack(err)
  78. return
  79. }
  80. defer rows.Close()
  81. for rows.Next() {
  82. r := &model.CouponAllowanceInfo{}
  83. if err = rows.Scan(&r.ID, &r.CouponToken, &r.Mid, &r.State, &r.StartTime, &r.ExpireTime, &r.Origin, &r.Ver, &r.BatchToken,
  84. &r.OrderNO, &r.Amount, &r.FullAmount, &r.CTime, &r.MTime); err != nil {
  85. err = errors.WithStack(err)
  86. res = nil
  87. return
  88. }
  89. res = append(res, r)
  90. }
  91. err = rows.Err()
  92. return
  93. }
  94. // AllowanceByToken query coupon by token.
  95. func (d *Dao) AllowanceByToken(c context.Context, mid int64, token string) (r *model.CouponAllowanceInfo, err error) {
  96. var row *sql.Row
  97. r = &model.CouponAllowanceInfo{}
  98. row = d.db.QueryRow(c, fmt.Sprintf(_couponAllowanceByTokenSQL, hitAllowanceInfo(mid)), token)
  99. if err = row.Scan(&r.ID, &r.CouponToken, &r.Mid, &r.State, &r.StartTime, &r.ExpireTime, &r.Origin, &r.Ver, &r.BatchToken,
  100. &r.OrderNO, &r.Amount, &r.FullAmount, &r.CTime, &r.MTime); err != nil {
  101. if err == sql.ErrNoRows {
  102. err = nil
  103. r = nil
  104. return
  105. }
  106. err = errors.WithStack(err)
  107. return
  108. }
  109. return
  110. }
  111. // UpdateAllowanceCouponInUse update coupon in use.
  112. func (d *Dao) UpdateAllowanceCouponInUse(c context.Context, tx *sql.Tx, cp *model.CouponAllowanceInfo) (a int64, err error) {
  113. var res xsql.Result
  114. if res, err = tx.Exec(fmt.Sprintf(_updateCouponAllowanceInUseSQL, hitAllowanceInfo(cp.Mid)), cp.State, cp.OrderNO, cp.Remark, cp.CouponToken, cp.Ver); err != nil {
  115. err = errors.WithStack(err)
  116. return
  117. }
  118. if a, err = res.RowsAffected(); err != nil {
  119. err = errors.WithStack(err)
  120. return
  121. }
  122. return
  123. }
  124. // UpdateAllowanceCouponToUse update coupon in use.
  125. func (d *Dao) UpdateAllowanceCouponToUse(c context.Context, tx *sql.Tx, cp *model.CouponAllowanceInfo) (a int64, err error) {
  126. var res xsql.Result
  127. if res, err = tx.Exec(fmt.Sprintf(_updateCouponAllowanceToUseSQL, hitAllowanceInfo(cp.Mid)), cp.State, cp.OrderNO, cp.CouponToken, cp.Ver, model.InUse); err != nil {
  128. err = errors.WithStack(err)
  129. return
  130. }
  131. if a, err = res.RowsAffected(); err != nil {
  132. err = errors.WithStack(err)
  133. return
  134. }
  135. return
  136. }
  137. // UpdateAllowanceCouponToUsed update coupon in used.
  138. func (d *Dao) UpdateAllowanceCouponToUsed(c context.Context, tx *sql.Tx, cp *model.CouponAllowanceInfo) (a int64, err error) {
  139. var res xsql.Result
  140. if res, err = tx.Exec(fmt.Sprintf(_updateCouponAllowanceToUseSQL, hitAllowanceInfo(cp.Mid)), cp.State, cp.OrderNO, cp.CouponToken, cp.Ver, model.NotUsed); err != nil {
  141. err = errors.WithStack(err)
  142. return
  143. }
  144. if a, err = res.RowsAffected(); err != nil {
  145. err = errors.WithStack(err)
  146. return
  147. }
  148. return
  149. }
  150. //InsertCouponAllowanceHistory insert coupon history .
  151. func (d *Dao) InsertCouponAllowanceHistory(c context.Context, tx *sql.Tx, l *model.CouponAllowanceChangeLog) (a int64, err error) {
  152. var res xsql.Result
  153. if res, err = tx.Exec(fmt.Sprintf(_addCouponAllowanceChangeLogSQL, hitAllowanceChangeLog(l.Mid)), l.CouponToken, l.OrderNO, l.Mid, l.State, l.Ctime, l.ChangeType); err != nil {
  154. err = errors.WithStack(err)
  155. return
  156. }
  157. if a, err = res.RowsAffected(); err != nil {
  158. err = errors.WithStack(err)
  159. }
  160. return
  161. }
  162. // CountByAllowanceBranchToken get user count by bratch token.
  163. func (d *Dao) CountByAllowanceBranchToken(c context.Context, mid int64, token string) (count int64, err error) {
  164. row := d.db.QueryRow(c, fmt.Sprintf(_batchAllowanceCountByMid, hitAllowanceInfo(mid)), mid, token)
  165. if err = row.Scan(&count); err != nil {
  166. err = errors.WithStack(err)
  167. }
  168. return
  169. }
  170. // GetCouponByOrderNo .
  171. func (d *Dao) GetCouponByOrderNo(c context.Context, mid int64, orderNo string) (res *model.CouponAllowanceInfo, err error) {
  172. res = &model.CouponAllowanceInfo{}
  173. row := d.db.QueryRow(c, fmt.Sprintf(_getCouponByOrderNoSQL, hitAllowanceInfo(mid)), orderNo)
  174. if err = row.Scan(&res.Mid, &res.CouponToken, &res.OrderNO, &res.Amount, &res.FullAmount, &res.State, &res.Ver); err != nil {
  175. err = errors.WithStack(err)
  176. }
  177. return
  178. }
  179. //TxAddAllowanceCoupon tx add lowance coupon
  180. func (d *Dao) TxAddAllowanceCoupon(tx *sql.Tx, cp *model.CouponAllowanceInfo) (err error) {
  181. if _, err = tx.Exec(fmt.Sprintf(_addAllowanceCouponSQL, hitAllowanceInfo(cp.Mid)), cp.CouponToken, cp.Mid, cp.State, cp.StartTime, cp.ExpireTime, cp.Origin, cp.BatchToken, cp.Amount, cp.FullAmount, cp.AppID); err != nil {
  182. err = errors.WithStack(err)
  183. }
  184. return
  185. }
  186. // BatchAddAllowanceCoupon batch add allowance coupon.
  187. func (d *Dao) BatchAddAllowanceCoupon(c context.Context, tx *sql.Tx, mid int64, cps []*model.CouponAllowanceInfo) (a int64, err error) {
  188. var (
  189. buf bytes.Buffer
  190. res xsql.Result
  191. sql string
  192. )
  193. buf.WriteString(fmt.Sprintf(_batchAddAllowanceCouponSQL, hitAllowanceInfo(mid)))
  194. for _, v := range cps {
  195. buf.WriteString("('")
  196. buf.WriteString(v.CouponToken)
  197. buf.WriteString("',")
  198. buf.WriteString(strconv.FormatInt(v.Mid, 10))
  199. buf.WriteString(",")
  200. buf.WriteString(fmt.Sprintf("%d", v.State))
  201. buf.WriteString(",")
  202. buf.WriteString(strconv.FormatInt(v.StartTime, 10))
  203. buf.WriteString(",")
  204. buf.WriteString(strconv.FormatInt(v.ExpireTime, 10))
  205. buf.WriteString(",")
  206. buf.WriteString(fmt.Sprintf("%d", v.Origin))
  207. buf.WriteString(",'")
  208. buf.WriteString(v.BatchToken)
  209. buf.WriteString("',")
  210. buf.WriteString(fmt.Sprintf("%f", v.Amount))
  211. buf.WriteString(",")
  212. buf.WriteString(fmt.Sprintf("%f", v.FullAmount))
  213. buf.WriteString(",'")
  214. buf.WriteString(v.CTime.Time().Format("2006-01-02 15:04:05"))
  215. buf.WriteString("',")
  216. buf.WriteString(strconv.FormatInt(v.AppID, 10))
  217. buf.WriteString("),")
  218. }
  219. sql = buf.String()
  220. if res, err = tx.Exec(sql[0 : len(sql)-1]); err != nil {
  221. err = errors.WithStack(err)
  222. return
  223. }
  224. if a, err = res.RowsAffected(); err != nil {
  225. err = errors.WithStack(err)
  226. }
  227. return
  228. }
  229. // AllowanceList list.
  230. func (d *Dao) AllowanceList(c context.Context, mid int64, state int8, t int64, stime time.Time) (res []*model.CouponAllowanceInfo, err error) {
  231. var rows *sql.Rows
  232. switch state {
  233. case model.NotUsed:
  234. rows, err = d.db.Query(c, fmt.Sprintf(_couponAllowancePageNotUsedSQL, hitAllowanceInfo(mid)), mid, t, t, stime)
  235. case model.Used:
  236. rows, err = d.db.Query(c, fmt.Sprintf(_couponAllowancePageUsedSQL, hitAllowanceInfo(mid)), mid, stime)
  237. case model.Expire:
  238. rows, err = d.db.Query(c, fmt.Sprintf(_couponAllowancePageExpireSQL, hitAllowanceInfo(mid)), mid, t, stime)
  239. default:
  240. return
  241. }
  242. if err != nil {
  243. err = errors.WithStack(err)
  244. return
  245. }
  246. defer rows.Close()
  247. for rows.Next() {
  248. r := new(model.CouponAllowanceInfo)
  249. if err = rows.Scan(&r.ID, &r.CouponToken, &r.Mid, &r.State, &r.StartTime, &r.ExpireTime, &r.Origin, &r.Ver, &r.BatchToken, &r.OrderNO, &r.Amount, &r.FullAmount,
  250. &r.CTime, &r.MTime, &r.Remark); err != nil {
  251. err = errors.WithStack(err)
  252. res = nil
  253. return
  254. }
  255. res = append(res, r)
  256. }
  257. err = rows.Err()
  258. return
  259. }