merchant.client.ticket.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337
  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. accountAmount, err := decimal.NewFromString(recharge.Amount)
  68. if err != nil {
  69. return err
  70. }
  71. clientAccount.ClientOpenID = clientOpenId
  72. clientAccount.MerchantOpenID = recharge.MerchantOpenID
  73. clientAccount.UpdatedAt = time.Now()
  74. clientAccount.CreatedAt = time.Now()
  75. err = tx.Table(clientAccount.TableName()).Create(&clientAccount).Error
  76. if err != nil {
  77. return err
  78. }
  79. //充值记录
  80. accountLog.Amount = accountAmount
  81. accountLog.AmountAfter = accountAmount
  82. accountLog.ClientOpenID = clientOpenId
  83. accountLog.MerchantOpenID = recharge.MerchantOpenID //充值商户
  84. accountLog.TransType = 1 //充值
  85. accountLog.Operator = operator //充值人员
  86. accountLog.PayTransID = recharge.ID
  87. accountLog.CreatedAt = time.Now()
  88. accountLog.UpdatedAt = time.Now()
  89. err = tx.Table(accountLog.TableName()).Create(&accountLog).Error
  90. if err != nil {
  91. return err
  92. }
  93. } else { //更新充值加钱,并且保存记录
  94. //var clientAccount MerchantRechargeClientAccount
  95. //clientAccount.MerchantOpenID = recharge.MerchantOpenID
  96. //clientAccount.ClientOpenID = clientOpenId
  97. //err = tx.Table(clientAccount.TableName()).Where("client_open_id = ? and merchant_open_id = ?",
  98. // clientOpenId, recharge.MerchantOpenID).First(&clientAccount).Error
  99. //if err != nil {
  100. // return err
  101. //}
  102. inAmount, err := decimal.NewFromString(recharge.Amount)
  103. if err != nil {
  104. return err
  105. }
  106. fmt.Println("inAmount = ", inAmount)
  107. amountPre := account.Amount
  108. amountAfter := account.Amount.Add(inAmount)
  109. result := tx.Table(account.TableName()).Model(&account).Where("id = ? and version = ? ", account.ID, account.Version).Updates(
  110. map[string]interface{}{
  111. "client_open_id": account.ClientOpenID,
  112. "merchant_open_id": account.MerchantOpenID,
  113. "amount": amountAfter,
  114. "version": account.Version + 1,
  115. "updated_at": tools.GetCurrntTimeStr()})
  116. if result.Error != nil {
  117. err = result.Error
  118. return err
  119. }
  120. if result.RowsAffected <= 0 {
  121. err = errors.New("金额充值失败,请重新再试。")
  122. return err
  123. }
  124. //充值记录
  125. accountLog.Amount = inAmount
  126. accountLog.AmountPre = amountPre
  127. accountLog.AmountAfter = amountAfter
  128. accountLog.ClientOpenID = clientOpenId
  129. accountLog.MerchantOpenID = recharge.MerchantOpenID //充值商户
  130. accountLog.TransType = 1 //充值
  131. accountLog.Operator = operator //充值人员
  132. accountLog.PayTransID = recharge.ID
  133. accountLog.CreatedAt = time.Now()
  134. accountLog.UpdatedAt = time.Now()
  135. err = tx.Table(accountLog.TableName()).Create(&accountLog).Error
  136. if err != nil {
  137. return err
  138. }
  139. }
  140. fmt.Println(recharge.CardProjectData)
  141. //充卡券
  142. err = json.Unmarshal([]byte(recharge.CardProjectData), &project)
  143. if err != nil {
  144. return err
  145. }
  146. for _, v := range project {
  147. var ticket MerchantClientTicket
  148. ticket.RechargeProjectName = v.ProjectName
  149. ticket.RechargeProjectQuantity = v.ProjectQuantity
  150. ticket.RechargeProjectID = v.ID
  151. ticket.MerchantOpenID = v.MerchantOpenID
  152. ticket.ClientOpenID = clientOpenId
  153. ticket.Operator = operator
  154. err = tx.Table(ticket.TableName()).Create(&ticket).Error
  155. if err != nil {
  156. return err
  157. }
  158. }
  159. return nil
  160. }
  161. // list 接口使用
  162. func (m *MerchantClientTicket) MerchantRechargeTicketList(pageSize int, pageIndex int) ([]MerchantClientTicket, int, error) {
  163. var doc []MerchantClientTicket
  164. table := orm.ShMysql.Table(m.TableName())
  165. table = table.Where("client_open_id = ? and merchant_open_id = ?", m.ClientOpenID, m.MerchantOpenID)
  166. var count int
  167. if err := table.Select("*").Order("id desc").Offset((pageIndex - 1) * pageSize).Limit(pageSize).Find(&doc).Error; err != nil {
  168. return nil, 0, err
  169. }
  170. table.Count(&count)
  171. return doc, count, nil
  172. }
  173. func (m *MerchantClientTicket) GetMerchantRechargeTicket() ([]MerchantClientTicket, error) {
  174. var doc []MerchantClientTicket
  175. table := orm.ShMysql.Table(m.TableName())
  176. table = table.Where("client_open_id = ? and merchant_open_id = ? and recharge_project_quantity > 0", m.ClientOpenID, m.MerchantOpenID)
  177. if err := table.Select("*").Order("id desc").Find(&doc).Error; err != nil {
  178. return nil, err
  179. }
  180. return doc, nil
  181. }
  182. func (m *MerchantClientTicket) CancelAccountTicket(data models.RechargeCancelRequest) error {
  183. var err error
  184. var rechargeAccount MerchantRechargeClientAccount
  185. var ticket MerchantClientTicket
  186. var accountLog MerchantRechargeClientAccountLog
  187. tx := orm.ShMysql.Begin()
  188. defer func() {
  189. if err != nil {
  190. tx.Rollback()
  191. } else {
  192. tx.Commit()
  193. }
  194. }()
  195. //扣除金额
  196. err = tx.Table("merchant_recharge_client_account").Select("*").Where("id = ?", data.AccountId).First(&rechargeAccount).Error
  197. if err != nil {
  198. return err
  199. }
  200. if data.CancelAmount != "" { //扣减账号金额
  201. cancelAmount, err := decimal.NewFromString(data.CancelAmount)
  202. if err != nil {
  203. return err
  204. }
  205. if rechargeAccount.Amount.Cmp(cancelAmount) < 0 {
  206. err = errors.New("金额不足")
  207. return err
  208. }
  209. amount := cancelAmount //交易金额
  210. amountPre := rechargeAccount.Amount //交易前
  211. amountAfter := rechargeAccount.Amount.Sub(cancelAmount) //交易后
  212. result := tx.Table("merchant_recharge_client_account").Model(&rechargeAccount).Where("id = ? and version = ? ", rechargeAccount.ID, rechargeAccount.Version).Updates(
  213. map[string]interface{}{
  214. "amount": amountAfter,
  215. "version": rechargeAccount.Version + 1,
  216. "updated_at": tools.GetCurrntTimeStr()})
  217. if result.Error != nil {
  218. err = result.Error
  219. return err
  220. }
  221. if result.RowsAffected <= 0 {
  222. err = errors.New("核销失败,请重新再试。")
  223. return err
  224. }
  225. //充值记录
  226. accountLog.Amount = amount
  227. accountLog.AmountPre = amountPre
  228. accountLog.AmountAfter = amountAfter
  229. accountLog.ClientOpenID = rechargeAccount.ClientOpenID
  230. accountLog.MerchantOpenID = rechargeAccount.MerchantOpenID //充值商户
  231. accountLog.TransType = 2 //消费
  232. accountLog.Operator = data.MerchantOpenId //充值人员
  233. accountLog.CreatedAt = time.Now()
  234. accountLog.UpdatedAt = time.Now()
  235. err = tx.Table(accountLog.TableName()).Create(&accountLog).Error
  236. if err != nil {
  237. return err
  238. }
  239. }
  240. //扣卡券
  241. for _, v := range data.ChargeMerchantCancel {
  242. if v.CancelQuantity == 0 {
  243. continue
  244. }
  245. //扣券
  246. ticketInfo := MerchantClientTicket{}
  247. err = tx.Table(ticket.TableName()).Select("*").Where("id = ?", v.TicketId).First(&ticketInfo).Error
  248. if err != nil {
  249. return err
  250. }
  251. if ticketInfo.RechargeProjectQuantity < v.CancelQuantity {
  252. err = errors.New("卡券数量不够")
  253. return err
  254. }
  255. version := ticketInfo.Version
  256. //quantity := v.CancelQuantity //交易前数量
  257. quantityAfter := ticketInfo.RechargeProjectQuantity - v.CancelQuantity //交易后数量
  258. result := tx.Table("merchant_client_ticket").Model(&ticketInfo).Where("id = ? and version = ? ", ticketInfo.ID, ticketInfo.Version).Updates(
  259. map[string]interface{}{
  260. "recharge_project_quantity": quantityAfter,
  261. "version": version + 1,
  262. "updated_at": tools.GetCurrntTimeStr()})
  263. if result.Error != nil {
  264. err = result.Error
  265. return err
  266. }
  267. if result.RowsAffected <= 0 {
  268. err = errors.New("核销失败,请重新再试。")
  269. return err
  270. }
  271. //扣券日志
  272. rechargeCancelLog := RechargeCancelLog{
  273. ClientOpenID: ticketInfo.ClientOpenID,
  274. MerchantOpenID: ticketInfo.MerchantOpenID,
  275. QuantityPre: ticketInfo.RechargeProjectQuantity,
  276. QuantityAfter: quantityAfter,
  277. Quantity: v.CancelQuantity,
  278. Operator: data.MerchantOpenId,
  279. RechargeID: v.TicketId,
  280. CreatedAt: time.Now(),
  281. UpdatedAt: time.Now(),
  282. }
  283. err = tx.Table(rechargeCancelLog.TableName()).Create(&rechargeCancelLog).Error
  284. if err != nil {
  285. return err
  286. }
  287. }
  288. return nil
  289. }