merchant.client.ticket.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  1. package shanghu
  2. import (
  3. "duoduo/apis/shanghu/models"
  4. orm "duoduo/database"
  5. "duoduo/tools"
  6. "encoding/json"
  7. "errors"
  8. "fmt"
  9. "github.com/shopspring/decimal"
  10. "time"
  11. )
  12. type MerchantClientTicket struct {
  13. ID int64 `gorm:"column:id;type:bigint(20);primary_key" json:"id"`
  14. RechargeProjectID int64 `gorm:"column:recharge_project_id;type:bigint(20)" json:"recharge_project_id"` // 项目id
  15. RechargeProjectQuantity int `gorm:"column:recharge_project_quantity;type:int(11)" json:"recharge_project_quantity"` // 项目数量
  16. RechargeProjectName string `gorm:"column:recharge_project_name;type:varchar(255)" json:"recharge_project_name"` // 项目名
  17. MerchantOpenID string `gorm:"column:merchant_open_id;type:varchar(255)" json:"merchant_open_id"`
  18. ClientOpenID string `gorm:"column:client_open_id;type:varchar(255)" json:"client_open_id"`
  19. Operator string `gorm:"column:operator;type:varchar(255)" json:"operator"` // operator 操作人
  20. Version int `gorm:"column:version;type:int(11)" json:"version"` // 锁
  21. CreateBy int64 `gorm:"column:create_by;type:bigint(20)" json:"create_by"` // 创建者
  22. UpdateBy int64 `gorm:"column:update_by;type:bigint(20)" json:"update_by"` // 更新者
  23. CreatedAt time.Time `gorm:"column:created_at;type:datetime(3)" json:"created_at"` // 创建时间
  24. UpdatedAt time.Time `gorm:"column:updated_at;type:datetime(3)" json:"updated_at"` // 最后更新时间
  25. DeletedAt time.Time `gorm:"column:deleted_at;type:datetime(3);default:null" json:"deleted_at"` // 删除时间
  26. }
  27. func (m *MerchantClientTicket) TableName() string {
  28. return "merchant_client_ticket"
  29. }
  30. func (u *MerchantClientTicket) Create() (MerchantClientTicket, error) {
  31. var doc MerchantClientTicket
  32. var err error
  33. doc = *u
  34. err = orm.ShMysql.Table(u.TableName()).Create(&doc).Error
  35. if err != nil {
  36. return doc, err
  37. }
  38. return doc, nil
  39. }
  40. // 商家充值进来,卡的商家
  41. func (u *MerchantClientTicket) Recharge(recharge MerchantRecharge, clientOpenId string, operator string) error {
  42. var err error
  43. var account MerchantRechargeClientAccount
  44. var accountLog MerchantRechargeClientAccountLog
  45. var project []MerchantRechargeProject
  46. tx := orm.ShMysql.Begin()
  47. defer func() {
  48. if err != nil {
  49. tx.Rollback()
  50. } else {
  51. tx.Commit()
  52. }
  53. }()
  54. err = tx.Table("merchant_recharge_client_account").Where("client_open_id = ? and merchant_open_id = ?",
  55. clientOpenId, recharge.MerchantOpenID).First(&account).Error
  56. if err != nil && err.Error() != "record not found" {
  57. return err
  58. }
  59. fmt.Println("account = ", account)
  60. // 创建充值记录
  61. if account.ID == 0 {
  62. var clientAccount MerchantRechargeClientAccount
  63. clientAccount.Amount, err = decimal.NewFromString(recharge.Amount)
  64. if err != nil {
  65. return err
  66. }
  67. clientAccount.ClientOpenID = clientOpenId
  68. clientAccount.MerchantOpenID = recharge.MerchantOpenID
  69. clientAccount.UpdatedAt = time.Now()
  70. clientAccount.CreatedAt = time.Now()
  71. err = tx.Table(clientAccount.TableName()).Create(&clientAccount).Error
  72. if err != nil {
  73. return err
  74. }
  75. //充值记录
  76. accountLog.Amount = account.Amount
  77. accountLog.AmountAfter = account.Amount
  78. accountLog.ClientOpenID = clientOpenId
  79. accountLog.MerchantOpenID = recharge.MerchantOpenID //充值商户
  80. accountLog.TransType = 1 //充值
  81. accountLog.Operator = operator //充值人员
  82. accountLog.PayTransID = recharge.ID
  83. accountLog.CreatedAt = time.Now()
  84. accountLog.UpdatedAt = time.Now()
  85. err = tx.Table(accountLog.TableName()).Create(&accountLog).Error
  86. if err != nil {
  87. return err
  88. }
  89. } else { //更新充值加钱,并且保存记录
  90. //var clientAccount MerchantRechargeClientAccount
  91. //clientAccount.MerchantOpenID = recharge.MerchantOpenID
  92. //clientAccount.ClientOpenID = clientOpenId
  93. //err = tx.Table(clientAccount.TableName()).Where("client_open_id = ? and merchant_open_id = ?",
  94. // clientOpenId, recharge.MerchantOpenID).First(&clientAccount).Error
  95. //if err != nil {
  96. // return err
  97. //}
  98. inAmount, err := decimal.NewFromString(recharge.Amount)
  99. if err != nil {
  100. return err
  101. }
  102. fmt.Println("inAmount = ", inAmount)
  103. amountPre := account.Amount
  104. amountAfter := account.Amount.Add(inAmount)
  105. result := tx.Table(account.TableName()).Model(&account).Where("id = ? and version = ? ", account.ID, account.Version).Updates(
  106. map[string]interface{}{
  107. "client_open_id": account.ClientOpenID,
  108. "merchant_open_id": account.MerchantOpenID,
  109. "amount": amountAfter,
  110. "version": account.Version + 1,
  111. "updated_at": tools.GetCurrntTimeStr()})
  112. if result.Error != nil {
  113. err = result.Error
  114. return err
  115. }
  116. if result.RowsAffected <= 0 {
  117. err = errors.New("金额充值失败,请重新再试。")
  118. return err
  119. }
  120. //充值记录
  121. accountLog.Amount = inAmount
  122. accountLog.AmountPre = amountPre
  123. accountLog.AmountAfter = amountAfter
  124. accountLog.ClientOpenID = clientOpenId
  125. accountLog.MerchantOpenID = recharge.MerchantOpenID //充值商户
  126. accountLog.TransType = 1 //充值
  127. accountLog.Operator = operator //充值人员
  128. accountLog.PayTransID = recharge.ID
  129. accountLog.CreatedAt = time.Now()
  130. accountLog.UpdatedAt = time.Now()
  131. err = tx.Table(accountLog.TableName()).Create(&accountLog).Error
  132. if err != nil {
  133. return err
  134. }
  135. }
  136. fmt.Println(recharge.CardProjectData)
  137. //充卡券
  138. err = json.Unmarshal([]byte(recharge.CardProjectData), &project)
  139. if err != nil {
  140. return err
  141. }
  142. for _, v := range project {
  143. var ticket MerchantClientTicket
  144. ticket.RechargeProjectName = v.ProjectName
  145. ticket.RechargeProjectQuantity = v.ProjectQuantity
  146. ticket.RechargeProjectID = v.ID
  147. ticket.MerchantOpenID = v.MerchantOpenID
  148. ticket.ClientOpenID = clientOpenId
  149. ticket.Operator = operator
  150. err = tx.Table(ticket.TableName()).Create(&ticket).Error
  151. if err != nil {
  152. return err
  153. }
  154. }
  155. return nil
  156. }
  157. // list 接口使用
  158. func (m *MerchantClientTicket) MerchantRechargeTicketList(pageSize int, pageIndex int) ([]MerchantClientTicket, int, error) {
  159. var doc []MerchantClientTicket
  160. table := orm.ShMysql.Table(m.TableName())
  161. table = table.Where("client_open_id = ? and merchant_open_id = ?", m.ClientOpenID, m.MerchantOpenID)
  162. var count int
  163. if err := table.Select("*").Order("id desc").Offset((pageIndex - 1) * pageSize).Limit(pageSize).Find(&doc).Error; err != nil {
  164. return nil, 0, err
  165. }
  166. table.Count(&count)
  167. return doc, count, nil
  168. }
  169. func (m *MerchantClientTicket) GetMerchantRechargeTicket() ([]MerchantClientTicket, error) {
  170. var doc []MerchantClientTicket
  171. table := orm.ShMysql.Table(m.TableName())
  172. table = table.Where("client_open_id = ? and merchant_open_id = ? and recharge_project_quantity > 0", m.ClientOpenID, m.MerchantOpenID)
  173. if err := table.Select("*").Order("id desc").Find(&doc).Error; err != nil {
  174. return nil, err
  175. }
  176. return doc, nil
  177. }
  178. func (m *MerchantClientTicket) CancelAccountTicket(data models.RechargeCancelRequest) error {
  179. var err error
  180. var rechargeAccount MerchantRechargeClientAccount
  181. var ticket MerchantClientTicket
  182. var accountLog MerchantRechargeClientAccountLog
  183. tx := orm.ShMysql.Begin()
  184. defer func() {
  185. if err != nil {
  186. tx.Rollback()
  187. } else {
  188. tx.Commit()
  189. }
  190. }()
  191. //扣除金额
  192. err = tx.Table("merchant_recharge_client_account").Select("*").Where("id = ?", data.AccountId).First(&rechargeAccount).Error
  193. if err != nil {
  194. return err
  195. }
  196. if data.CancelAmount != "" { //扣减账号金额
  197. cancelAmount, err := decimal.NewFromString(data.CancelAmount)
  198. if err != nil {
  199. return err
  200. }
  201. if rechargeAccount.Amount.Cmp(cancelAmount) < 0 {
  202. err = errors.New("金额不足")
  203. return err
  204. }
  205. amount := cancelAmount //交易金额
  206. amountPre := rechargeAccount.Amount //交易前
  207. amountAfter := rechargeAccount.Amount.Sub(cancelAmount) //交易后
  208. result := tx.Table("merchant_recharge_client_account").Model(&rechargeAccount).Where("id = ? and version = ? ", rechargeAccount.ID, rechargeAccount.Version).Updates(
  209. map[string]interface{}{
  210. "amount": amountAfter,
  211. "version": rechargeAccount.Version + 1,
  212. "updated_at": tools.GetCurrntTimeStr()})
  213. if result.Error != nil {
  214. err = result.Error
  215. return err
  216. }
  217. if result.RowsAffected <= 0 {
  218. err = errors.New("核销失败,请重新再试。")
  219. return err
  220. }
  221. //充值记录
  222. accountLog.Amount = amount
  223. accountLog.AmountPre = amountPre
  224. accountLog.AmountAfter = amountAfter
  225. accountLog.ClientOpenID = rechargeAccount.ClientOpenID
  226. accountLog.MerchantOpenID = rechargeAccount.MerchantOpenID //充值商户
  227. accountLog.TransType = 2 //消费
  228. accountLog.Operator = data.MerchantOpenId //充值人员
  229. accountLog.CreatedAt = time.Now()
  230. accountLog.UpdatedAt = time.Now()
  231. err = tx.Table(accountLog.TableName()).Create(&accountLog).Error
  232. if err != nil {
  233. return err
  234. }
  235. }
  236. //扣卡券
  237. for _, v := range data.ChargeMerchantCancel {
  238. if v.CancelQuantity == 0 {
  239. continue
  240. }
  241. //扣券
  242. ticketInfo := MerchantClientTicket{}
  243. err = tx.Table(ticket.TableName()).Select("*").Where("id = ?", v.TicketId).First(&ticketInfo).Error
  244. if err != nil {
  245. return err
  246. }
  247. if ticketInfo.RechargeProjectQuantity < v.CancelQuantity {
  248. err = errors.New("卡券数量不够")
  249. return err
  250. }
  251. version := ticketInfo.Version
  252. //quantity := v.CancelQuantity //交易前数量
  253. quantityAfter := ticketInfo.RechargeProjectQuantity - v.CancelQuantity //交易后数量
  254. result := tx.Table("merchant_client_ticket").Model(&ticketInfo).Where("id = ? and version = ? ", ticketInfo.ID, ticketInfo.Version).Updates(
  255. map[string]interface{}{
  256. "recharge_project_quantity": quantityAfter,
  257. "version": version + 1,
  258. "updated_at": tools.GetCurrntTimeStr()})
  259. if result.Error != nil {
  260. err = result.Error
  261. return err
  262. }
  263. if result.RowsAffected <= 0 {
  264. err = errors.New("核销失败,请重新再试。")
  265. return err
  266. }
  267. //扣券日志
  268. rechargeCancelLog := RechargeCancelLog{
  269. ClientOpenID: ticketInfo.ClientOpenID,
  270. MerchantOpenID: ticketInfo.MerchantOpenID,
  271. QuantityPre: ticketInfo.RechargeProjectQuantity,
  272. QuantityAfter: quantityAfter,
  273. Quantity: v.CancelQuantity,
  274. Operator: data.MerchantOpenId,
  275. RechargeID: v.TicketId,
  276. CreatedAt: time.Now(),
  277. UpdatedAt: time.Now(),
  278. }
  279. err = tx.Table(rechargeCancelLog.TableName()).Create(&rechargeCancelLog).Error
  280. if err != nil {
  281. return err
  282. }
  283. }
  284. return nil
  285. }