|
@@ -0,0 +1,332 @@
|
|
|
+package shanghu
|
|
|
+
|
|
|
+import (
|
|
|
+ "duoduo/apis/shanghu/models"
|
|
|
+ orm "duoduo/database"
|
|
|
+ "duoduo/tools"
|
|
|
+ "encoding/json"
|
|
|
+ "errors"
|
|
|
+ "fmt"
|
|
|
+ "github.com/shopspring/decimal"
|
|
|
+ "time"
|
|
|
+)
|
|
|
+
|
|
|
+type MerchantClientTicket struct {
|
|
|
+ ID int64 `gorm:"column:id;type:bigint(20);primary_key" json:"id"`
|
|
|
+ RechargeProjectID int64 `gorm:"column:recharge_project_id;type:bigint(20)" json:"recharge_project_id"` // 项目id
|
|
|
+ RechargeProjectQuantity int `gorm:"column:recharge_project_quantity;type:int(11)" json:"recharge_project_quantity"` // 项目数量
|
|
|
+ RechargeProjectName string `gorm:"column:recharge_project_name;type:varchar(255)" json:"recharge_project_name"` // 项目名
|
|
|
+ MerchantOpenID string `gorm:"column:merchant_open_id;type:varchar(255)" json:"merchant_open_id"`
|
|
|
+ ClientOpenID string `gorm:"column:client_open_id;type:varchar(255)" json:"client_open_id"`
|
|
|
+ Operator string `gorm:"column:operator;type:varchar(255)" json:"operator"` // operator 操作人
|
|
|
+ Version int `gorm:"column:version;type:int(11)" json:"version"` // 锁
|
|
|
+ CreateBy int64 `gorm:"column:create_by;type:bigint(20)" json:"create_by"` // 创建者
|
|
|
+ UpdateBy int64 `gorm:"column:update_by;type:bigint(20)" json:"update_by"` // 更新者
|
|
|
+ CreatedAt time.Time `gorm:"column:created_at;type:datetime(3)" json:"created_at"` // 创建时间
|
|
|
+ UpdatedAt time.Time `gorm:"column:updated_at;type:datetime(3)" json:"updated_at"` // 最后更新时间
|
|
|
+ DeletedAt time.Time `gorm:"column:deleted_at;type:datetime(3);default:null" json:"deleted_at"` // 删除时间
|
|
|
+}
|
|
|
+
|
|
|
+func (m *MerchantClientTicket) TableName() string {
|
|
|
+ return "merchant_client_ticket"
|
|
|
+}
|
|
|
+
|
|
|
+func (u *MerchantClientTicket) Create() (MerchantClientTicket, error) {
|
|
|
+ var doc MerchantClientTicket
|
|
|
+ var err error
|
|
|
+
|
|
|
+ doc = *u
|
|
|
+ err = orm.ShMysql.Table(u.TableName()).Create(&doc).Error
|
|
|
+ if err != nil {
|
|
|
+ return doc, err
|
|
|
+ }
|
|
|
+
|
|
|
+ return doc, nil
|
|
|
+}
|
|
|
+
|
|
|
+// 商家充值进来,卡的商家
|
|
|
+func (u *MerchantClientTicket) Recharge(recharge MerchantRecharge, clientOpenId string, operator string) error {
|
|
|
+ var err error
|
|
|
+ var account MerchantRechargeClientAccount
|
|
|
+ var accountLog MerchantRechargeClientAccountLog
|
|
|
+ var project []MerchantRechargeProject
|
|
|
+
|
|
|
+ tx := orm.ShMysql.Begin()
|
|
|
+ defer func() {
|
|
|
+ if err != nil {
|
|
|
+ tx.Rollback()
|
|
|
+ } else {
|
|
|
+ tx.Commit()
|
|
|
+ }
|
|
|
+ }()
|
|
|
+
|
|
|
+ err = tx.Table("merchant_recharge_client_account").Where("client_open_id = ? and merchant_open_id = ?",
|
|
|
+ clientOpenId, recharge.MerchantOpenID).First(&account).Error
|
|
|
+ if err != nil && err.Error() != "record not found" {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+
|
|
|
+ fmt.Println("account = ", account)
|
|
|
+
|
|
|
+ // 创建充值记录
|
|
|
+ if account.ID == 0 {
|
|
|
+ var clientAccount MerchantRechargeClientAccount
|
|
|
+ clientAccount.Amount, err = decimal.NewFromString(recharge.Amount)
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ clientAccount.ClientOpenID = clientOpenId
|
|
|
+ clientAccount.MerchantOpenID = recharge.MerchantOpenID
|
|
|
+ clientAccount.UpdatedAt = time.Now()
|
|
|
+ clientAccount.CreatedAt = time.Now()
|
|
|
+ err = tx.Table(clientAccount.TableName()).Create(&clientAccount).Error
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+
|
|
|
+ //充值记录
|
|
|
+ accountLog.Amount = account.Amount
|
|
|
+ accountLog.AmountAfter = account.Amount
|
|
|
+ accountLog.ClientOpenID = clientOpenId
|
|
|
+ accountLog.MerchantOpenID = recharge.MerchantOpenID //充值商户
|
|
|
+ accountLog.TransType = 1 //充值
|
|
|
+ accountLog.Operator = operator //充值人员
|
|
|
+ accountLog.PayTransID = recharge.ID
|
|
|
+ accountLog.CreatedAt = time.Now()
|
|
|
+ accountLog.UpdatedAt = time.Now()
|
|
|
+ err = tx.Table(accountLog.TableName()).Create(&accountLog).Error
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+
|
|
|
+ } else { //更新充值加钱,并且保存记录
|
|
|
+ //var clientAccount MerchantRechargeClientAccount
|
|
|
+ //clientAccount.MerchantOpenID = recharge.MerchantOpenID
|
|
|
+ //clientAccount.ClientOpenID = clientOpenId
|
|
|
+ //err = tx.Table(clientAccount.TableName()).Where("client_open_id = ? and merchant_open_id = ?",
|
|
|
+ // clientOpenId, recharge.MerchantOpenID).First(&clientAccount).Error
|
|
|
+ //if err != nil {
|
|
|
+ // return err
|
|
|
+ //}
|
|
|
+
|
|
|
+ inAmount, err := decimal.NewFromString(recharge.Amount)
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ fmt.Println("inAmount = ", inAmount)
|
|
|
+ amountPre := account.Amount
|
|
|
+ amountAfter := account.Amount.Add(inAmount)
|
|
|
+
|
|
|
+ result := tx.Table(account.TableName()).Model(&account).Where("id = ? and version = ? ", account.ID, account.Version).Updates(
|
|
|
+ map[string]interface{}{
|
|
|
+ "client_open_id": account.ClientOpenID,
|
|
|
+ "merchant_open_id": account.MerchantOpenID,
|
|
|
+ "amount": amountAfter,
|
|
|
+ "version": account.Version + 1,
|
|
|
+ "updated_at": tools.GetCurrntTimeStr()})
|
|
|
+ if result.Error != nil {
|
|
|
+ err = result.Error
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ if result.RowsAffected <= 0 {
|
|
|
+ err = errors.New("金额充值失败,请重新再试。")
|
|
|
+ return err
|
|
|
+ }
|
|
|
+
|
|
|
+ //充值记录
|
|
|
+ accountLog.Amount = inAmount
|
|
|
+ accountLog.AmountPre = amountPre
|
|
|
+ accountLog.AmountAfter = amountAfter
|
|
|
+ accountLog.ClientOpenID = clientOpenId
|
|
|
+ accountLog.MerchantOpenID = recharge.MerchantOpenID //充值商户
|
|
|
+ accountLog.TransType = 1 //充值
|
|
|
+ accountLog.Operator = operator //充值人员
|
|
|
+ accountLog.PayTransID = recharge.ID
|
|
|
+ accountLog.CreatedAt = time.Now()
|
|
|
+ accountLog.UpdatedAt = time.Now()
|
|
|
+
|
|
|
+ err = tx.Table(accountLog.TableName()).Create(&accountLog).Error
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ fmt.Println(recharge.CardProjectData)
|
|
|
+ //充卡券
|
|
|
+ err = json.Unmarshal([]byte(recharge.CardProjectData), &project)
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+
|
|
|
+ for _, v := range project {
|
|
|
+ var ticket MerchantClientTicket
|
|
|
+
|
|
|
+ ticket.RechargeProjectName = v.ProjectName
|
|
|
+ ticket.RechargeProjectQuantity = v.ProjectQuantity
|
|
|
+ ticket.RechargeProjectID = v.ID
|
|
|
+ ticket.MerchantOpenID = v.MerchantOpenID
|
|
|
+ ticket.ClientOpenID = clientOpenId
|
|
|
+ ticket.Operator = operator
|
|
|
+
|
|
|
+ err = tx.Table(ticket.TableName()).Create(&ticket).Error
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return nil
|
|
|
+}
|
|
|
+
|
|
|
+// list 接口使用
|
|
|
+func (m *MerchantClientTicket) MerchantRechargeTicketList(pageSize int, pageIndex int) ([]MerchantClientTicket, int, error) {
|
|
|
+ var doc []MerchantClientTicket
|
|
|
+
|
|
|
+ table := orm.ShMysql.Table(m.TableName())
|
|
|
+
|
|
|
+ table = table.Where("client_open_id = ? and merchant_open_id = ?", m.ClientOpenID, m.MerchantOpenID)
|
|
|
+ var count int
|
|
|
+ if err := table.Select("*").Order("id desc").Offset((pageIndex - 1) * pageSize).Limit(pageSize).Find(&doc).Error; err != nil {
|
|
|
+ return nil, 0, err
|
|
|
+ }
|
|
|
+ table.Count(&count)
|
|
|
+ return doc, count, nil
|
|
|
+}
|
|
|
+
|
|
|
+func (m *MerchantClientTicket) GetMerchantRechargeTicket() ([]MerchantClientTicket, error) {
|
|
|
+
|
|
|
+ var doc []MerchantClientTicket
|
|
|
+
|
|
|
+ table := orm.ShMysql.Table(m.TableName())
|
|
|
+
|
|
|
+ table = table.Where("client_open_id = ? and merchant_open_id = ? and recharge_project_quantity > 0", m.ClientOpenID, m.MerchantOpenID)
|
|
|
+ if err := table.Select("*").Order("id desc").Find(&doc).Error; err != nil {
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+ return doc, nil
|
|
|
+}
|
|
|
+
|
|
|
+func (m *MerchantClientTicket) CancelAccountTicket(data models.RechargeCancelRequest) error {
|
|
|
+ var err error
|
|
|
+ var rechargeAccount MerchantRechargeClientAccount
|
|
|
+ var ticket MerchantClientTicket
|
|
|
+ var accountLog MerchantRechargeClientAccountLog
|
|
|
+ tx := orm.ShMysql.Begin()
|
|
|
+ defer func() {
|
|
|
+ if err != nil {
|
|
|
+ tx.Rollback()
|
|
|
+ } else {
|
|
|
+ tx.Commit()
|
|
|
+ }
|
|
|
+ }()
|
|
|
+
|
|
|
+ //扣除金额
|
|
|
+ err = tx.Table("merchant_recharge_client_account").Select("*").Where("id = ?", data.AccountId).First(&rechargeAccount).Error
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ if data.CancelAmount != "" { //扣减账号金额
|
|
|
+ cancelAmount, err := decimal.NewFromString(data.CancelAmount)
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+
|
|
|
+ if rechargeAccount.Amount.Cmp(cancelAmount) < 0 {
|
|
|
+ err = errors.New("金额不足")
|
|
|
+ return err
|
|
|
+ }
|
|
|
+
|
|
|
+ amount := cancelAmount //交易金额
|
|
|
+ amountPre := rechargeAccount.Amount //交易前
|
|
|
+ amountAfter := rechargeAccount.Amount.Sub(cancelAmount) //交易后
|
|
|
+
|
|
|
+ result := tx.Table("merchant_recharge_client_account").Model(&rechargeAccount).Where("id = ? and version = ? ", rechargeAccount.ID, rechargeAccount.Version).Updates(
|
|
|
+ map[string]interface{}{
|
|
|
+ "amount": amountAfter,
|
|
|
+ "version": rechargeAccount.Version + 1,
|
|
|
+ "updated_at": tools.GetCurrntTimeStr()})
|
|
|
+
|
|
|
+ if result.Error != nil {
|
|
|
+ err = result.Error
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ if result.RowsAffected <= 0 {
|
|
|
+ err = errors.New("核销失败,请重新再试。")
|
|
|
+ return err
|
|
|
+ }
|
|
|
+
|
|
|
+ //充值记录
|
|
|
+ accountLog.Amount = amount
|
|
|
+ accountLog.AmountPre = amountPre
|
|
|
+ accountLog.AmountAfter = amountAfter
|
|
|
+ accountLog.ClientOpenID = rechargeAccount.ClientOpenID
|
|
|
+ accountLog.MerchantOpenID = rechargeAccount.MerchantOpenID //充值商户
|
|
|
+ accountLog.TransType = 2 //消费
|
|
|
+ accountLog.Operator = data.MerchantOpenId //充值人员
|
|
|
+ accountLog.CreatedAt = time.Now()
|
|
|
+ accountLog.UpdatedAt = time.Now()
|
|
|
+
|
|
|
+ err = tx.Table(accountLog.TableName()).Create(&accountLog).Error
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ //扣卡券
|
|
|
+ for _, v := range data.ChargeMerchantCancel {
|
|
|
+ if v.CancelQuantity == 0 {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ //扣券
|
|
|
+ ticketInfo := MerchantClientTicket{}
|
|
|
+ err = tx.Table(ticket.TableName()).Select("*").Where("id = ?", v.TicketId).First(&ticketInfo).Error
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+
|
|
|
+ if ticketInfo.RechargeProjectQuantity < v.CancelQuantity {
|
|
|
+ err = errors.New("卡券数量不够")
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ version := ticketInfo.Version
|
|
|
+ //quantity := v.CancelQuantity //交易前数量
|
|
|
+ quantityAfter := ticketInfo.RechargeProjectQuantity - v.CancelQuantity //交易后数量
|
|
|
+
|
|
|
+ result := tx.Table("merchant_client_ticket").Model(&ticketInfo).Where("id = ? and version = ? ", ticketInfo.ID, ticketInfo.Version).Updates(
|
|
|
+ map[string]interface{}{
|
|
|
+ "recharge_project_quantity": quantityAfter,
|
|
|
+ "version": version + 1,
|
|
|
+ "updated_at": tools.GetCurrntTimeStr()})
|
|
|
+
|
|
|
+ if result.Error != nil {
|
|
|
+ err = result.Error
|
|
|
+ return err
|
|
|
+ }
|
|
|
+
|
|
|
+ if result.RowsAffected <= 0 {
|
|
|
+ err = errors.New("核销失败,请重新再试。")
|
|
|
+ return err
|
|
|
+ }
|
|
|
+
|
|
|
+ //扣券日志
|
|
|
+ rechargeCancelLog := RechargeCancelLog{
|
|
|
+ ClientOpenID: ticketInfo.ClientOpenID,
|
|
|
+ MerchantOpenID: ticketInfo.MerchantOpenID,
|
|
|
+ QuantityPre: ticketInfo.RechargeProjectQuantity,
|
|
|
+ QuantityAfter: quantityAfter,
|
|
|
+ Quantity: v.CancelQuantity,
|
|
|
+ Operator: data.MerchantOpenId,
|
|
|
+ RechargeID: v.TicketId,
|
|
|
+ CreatedAt: time.Now(),
|
|
|
+ UpdatedAt: time.Now(),
|
|
|
+ }
|
|
|
+
|
|
|
+ err = tx.Table(rechargeCancelLog.TableName()).Create(&rechargeCancelLog).Error
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ return nil
|
|
|
+}
|