diff --git a/internal/biz/bo/multi_notify_data_bo.go b/internal/biz/bo/multi_notify_data_bo.go new file mode 100644 index 0000000..8f541cf --- /dev/null +++ b/internal/biz/bo/multi_notify_data_bo.go @@ -0,0 +1,21 @@ +package bo + +import "time" + +// MultiNotifyDataBo 领域实体Bo结构,字段和模型字段保持一致 +type MultiNotifyDataBo struct { + ID int64 + Source string + NotifyID string + OrderNo string + OutBizNo string + CouponID string + StockID string + ConsumeAmount int32 + ConsumeTime *time.Time + EventType string + OriginalData string + NoticeNum int32 + CreateTime *time.Time + UpdateTime *time.Time +} diff --git a/internal/biz/bo/multi_notify_log_bo.go b/internal/biz/bo/multi_notify_log_bo.go new file mode 100644 index 0000000..487ab23 --- /dev/null +++ b/internal/biz/bo/multi_notify_log_bo.go @@ -0,0 +1,27 @@ +package bo + +import "time" + +// MultiNotifyLogBo 领域实体Bo结构,字段和模型字段保持一致 +type MultiNotifyLogBo struct { + ID int64 + MultiNotifyDataID int64 + OrderNo string + OutBizNo string + CouponID string + ActivityNo string + StockID string + EventType string + Status string + ConsumeAmount int32 + ConsumeTime *time.Time + TransactionID string + RequestURL string + RequestStatus int32 + Request string + Response string + OrderCreateTime *time.Time + CouponCreateTime *time.Time + CreateTime *time.Time + UpdateTime *time.Time +} diff --git a/internal/biz/repo/multi_notify_data.go b/internal/biz/repo/multi_notify_data.go new file mode 100644 index 0000000..b0b9cc5 --- /dev/null +++ b/internal/biz/repo/multi_notify_data.go @@ -0,0 +1,14 @@ +package repo + +import ( + "context" + "voucher/internal/biz/bo" +) + +type MultiNotifyDataRepo interface { + FindNoticeNumZero(ctx context.Context, fun func(ctx context.Context, rows []*bo.MultiNotifyDataBo) error) error + Create(ctx context.Context, req *bo.MultiNotifyDataBo) (*bo.MultiNotifyDataBo, error) + GetByID(ctx context.Context, id int64) (*bo.MultiNotifyDataBo, error) + GetByNotifyID(ctx context.Context, notifyId string) (*bo.MultiNotifyDataBo, error) + AddNoticeNum(ctx context.Context, id int64) error +} diff --git a/internal/biz/repo/multi_notify_log.go b/internal/biz/repo/multi_notify_log.go new file mode 100644 index 0000000..a43f049 --- /dev/null +++ b/internal/biz/repo/multi_notify_log.go @@ -0,0 +1,13 @@ +package repo + +import ( + "context" + "voucher/internal/biz/bo" +) + +type MultiNotifyLogRepo interface { + Create(ctx context.Context, req *bo.MultiNotifyLogBo) (*bo.MultiNotifyLogBo, error) + GetByID(ctx context.Context, id int64) (*bo.MultiNotifyLogBo, error) + Success(ctx context.Context, id int64, response string) error + Fail(ctx context.Context, id int64, remark string) error +} diff --git a/internal/data/model/multi_notify_data.gen.go b/internal/data/model/multi_notify_data.gen.go new file mode 100644 index 0000000..f66a190 --- /dev/null +++ b/internal/data/model/multi_notify_data.gen.go @@ -0,0 +1,34 @@ +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. + +package model + +import ( + "time" +) + +const TableNameMultiNotifyDatum = "multi_notify_data" + +// MultiNotifyDatum mapped from table +type MultiNotifyDatum struct { + ID int64 `gorm:"column:id;primaryKey" json:"id"` + Source string `gorm:"column:source;not null;comment:来源" json:"source"` // 来源 + NotifyID string `gorm:"column:notify_id;not null;comment:回调通知id" json:"notify_id"` // 回调通知id + OrderNo string `gorm:"column:order_no;not null;comment:订单号" json:"order_no"` // 订单号 + OutBizNo string `gorm:"column:out_biz_no;not null;comment:外部业务号" json:"out_biz_no"` // 外部业务号 + CouponID string `gorm:"column:coupon_id;not null;comment:券id" json:"coupon_id"` // 券id + StockID string `gorm:"column:stock_id;not null;comment:微信批次号" json:"stock_id"` // 微信批次号 + ConsumeAmount int32 `gorm:"column:consume_amount;not null;comment:核销金额" json:"consume_amount"` // 核销金额 + ConsumeTime *time.Time `gorm:"column:consume_time;not null;comment:核销时间" json:"consume_time"` // 核销时间 + EventType string `gorm:"column:event_type;not null;comment:通知的类型" json:"event_type"` // 通知的类型 + OriginalData string `gorm:"column:original_data;not null;comment:微信回调通知原始数据" json:"original_data"` // 微信回调通知原始数据 + NoticeNum int32 `gorm:"column:notice_num;not null;comment:通知下游次数" json:"notice_num"` // 通知下游次数 + CreateTime *time.Time `gorm:"column:create_time;not null;comment:创建时间" json:"create_time"` // 创建时间 + UpdateTime *time.Time `gorm:"column:update_time;comment:修改时间" json:"update_time"` // 修改时间 +} + +// TableName MultiNotifyDatum's table name +func (*MultiNotifyDatum) TableName() string { + return TableNameMultiNotifyDatum +} diff --git a/internal/data/model/multi_notify_log.gen.go b/internal/data/model/multi_notify_log.gen.go new file mode 100644 index 0000000..8a459e2 --- /dev/null +++ b/internal/data/model/multi_notify_log.gen.go @@ -0,0 +1,40 @@ +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. + +package model + +import ( + "time" +) + +const TableNameMultiNotifyLog = "multi_notify_log" + +// MultiNotifyLog mapped from table +type MultiNotifyLog struct { + ID int64 `gorm:"column:id;primaryKey;autoIncrement:true" json:"id"` + MultiNotifyDataID int64 `gorm:"column:multi_notify_data_id;not null" json:"multi_notify_data_id"` + OrderNo string `gorm:"column:order_no;not null;comment:订单号" json:"order_no"` // 订单号 + OutBizNo string `gorm:"column:out_biz_no;not null;comment:外部请求号" json:"out_biz_no"` // 外部请求号 + CouponID string `gorm:"column:coupon_id;not null;comment:微信券id" json:"coupon_id"` // 微信券id + ActivityNo string `gorm:"column:activity_no;not null;comment:活动编号CMB开头" json:"activity_no"` // 活动编号CMB开头 + StockID string `gorm:"column:stock_id;not null;comment:微信批次号" json:"stock_id"` // 微信批次号 + EventType string `gorm:"column:event_type;not null;comment:通知类型 COUPON.USE" json:"event_type"` // 通知类型 COUPON.USE + Status string `gorm:"column:status;not null;comment:券状态" json:"status"` // 券状态 + ConsumeAmount int32 `gorm:"column:consume_amount;not null;comment:核销金额" json:"consume_amount"` // 核销金额 + ConsumeTime *time.Time `gorm:"column:consume_time;not null;comment:核销时间" json:"consume_time"` // 核销时间 + TransactionID string `gorm:"column:transaction_id;not null;comment:微信支付系统生成的订单号" json:"transaction_id"` // 微信支付系统生成的订单号 + RequestURL string `gorm:"column:request_url;not null;comment:请求地址" json:"request_url"` // 请求地址 + RequestStatus int32 `gorm:"column:request_status;not null;comment:请求状态" json:"request_status"` // 请求状态 + Request string `gorm:"column:request;not null;comment:请求数据" json:"request"` // 请求数据 + Response string `gorm:"column:response;not null;comment:响应结果" json:"response"` // 响应结果 + OrderCreateTime *time.Time `gorm:"column:order_create_time;not null;comment:券收单时间-蓝色兄弟" json:"order_create_time"` // 券收单时间-蓝色兄弟 + CouponCreateTime *time.Time `gorm:"column:coupon_create_time;not null;comment:券创建时间-微信侧" json:"coupon_create_time"` // 券创建时间-微信侧 + CreateTime *time.Time `gorm:"column:create_time;not null;comment:创建时间" json:"create_time"` // 创建时间 + UpdateTime *time.Time `gorm:"column:update_time;comment:修改时间" json:"update_time"` // 修改时间 +} + +// TableName MultiNotifyLog's table name +func (*MultiNotifyLog) TableName() string { + return TableNameMultiNotifyLog +} diff --git a/internal/data/repoimpl/multi_notify_data.go b/internal/data/repoimpl/multi_notify_data.go new file mode 100644 index 0000000..95ff99a --- /dev/null +++ b/internal/data/repoimpl/multi_notify_data.go @@ -0,0 +1,129 @@ +package repoimpl + +import ( + "context" + "gorm.io/gorm" + "time" + "voucher/internal/biz/bo" + "voucher/internal/biz/repo" + "voucher/internal/data" + "voucher/internal/data/model" +) + +// MultiNotifyDataRepoImpl . +type MultiNotifyDataRepoImpl struct { + Base[model.MultiNotifyDatum, bo.MultiNotifyDataBo] + db *data.Db +} + +// NewMultiNotifyDataRepoImpl . +func NewMultiNotifyDataRepoImpl(db *data.Db) repo.MultiNotifyDataRepo { + return &MultiNotifyDataRepoImpl{db: db} +} + +func (p *MultiNotifyDataRepoImpl) DB(ctx context.Context) *gorm.DB { + return p.db.DB(ctx).WithContext(ctx).Model(model.MultiNotifyDatum{}) +} + +func (p *MultiNotifyDataRepoImpl) FindNoticeNumZero(ctx context.Context, fun func(ctx context.Context, rows []*bo.MultiNotifyDataBo) error) error { + + tx := p.DB(ctx).Where("notice_num = 0") + tx.Order("id asc") // 显式清除排序,移除默认的 ORDER BY + tx.Limit(200) + + var results = make([]*model.MultiNotifyDatum, 0) + + result := tx.FindInBatches(&results, 50, func(tx *gorm.DB, batch int) error { + return fun(ctx, p.ToBos(results)) + }) + + if result.Error != nil { + return result.Error + } + + return nil +} + +func (p *MultiNotifyDataRepoImpl) Create(ctx context.Context, req *bo.MultiNotifyDataBo) (*bo.MultiNotifyDataBo, error) { + + now := time.Now() + + info := &model.MultiNotifyDatum{ + Source: req.Source, + NotifyID: req.NotifyID, + OrderNo: req.OrderNo, + OutBizNo: req.OutBizNo, + CouponID: req.CouponID, + StockID: req.StockID, + ConsumeAmount: req.ConsumeAmount, + ConsumeTime: req.ConsumeTime, + EventType: req.EventType, + OriginalData: req.OriginalData, + NoticeNum: 0, + CreateTime: &now, + } + + if err := p.DB(ctx).Create(info).Error; err != nil { + return nil, err + } + + return p.ToBo(info), nil +} + +func (p *MultiNotifyDataRepoImpl) GetByID(ctx context.Context, id int64) (*bo.MultiNotifyDataBo, error) { + + var item model.MultiNotifyDatum + + tx := p.DB(ctx).Where(model.MultiNotifyDatum{ID: id}).First(&item) + + if tx.Error != nil { + return nil, tx.Error + } + + if tx.RowsAffected == 0 { + return nil, gorm.ErrRecordNotFound + } + + return p.ToBo(&item), nil +} + +func (p *MultiNotifyDataRepoImpl) GetByNotifyID(ctx context.Context, notifyId string) (*bo.MultiNotifyDataBo, error) { + + var item model.MultiNotifyDatum + + tx := p.DB(ctx).Where(model.MultiNotifyDatum{NotifyID: notifyId}).First(&item) + + if tx.Error != nil { + return nil, tx.Error + } + + if tx.RowsAffected == 0 { + return nil, gorm.ErrRecordNotFound + } + + return p.ToBo(&item), nil +} + +func (p *MultiNotifyDataRepoImpl) AddNoticeNum(ctx context.Context, id int64) error { + + now := time.Now() + + u := map[string]interface{}{ + "notice_num": gorm.Expr("notice_num + ?", 1), + "update_time": &now, + } + + tx := p.DB(ctx). + Where("id = ?", id). + Updates(u) + + if tx.Error != nil { + return tx.Error + } + + if tx.RowsAffected == 0 { + return gorm.ErrRecordNotFound + } + + return nil +} diff --git a/internal/data/repoimpl/multi_notify_log.go b/internal/data/repoimpl/multi_notify_log.go new file mode 100644 index 0000000..4a4ccc9 --- /dev/null +++ b/internal/data/repoimpl/multi_notify_log.go @@ -0,0 +1,128 @@ +package repoimpl + +import ( + "context" + "fmt" + "gorm.io/gorm" + "time" + "unicode/utf8" + err2 "voucher/api/err" + "voucher/internal/biz/bo" + "voucher/internal/biz/repo" + "voucher/internal/biz/vo" + "voucher/internal/data" + "voucher/internal/data/model" +) + +// MultiNotifyLogRepoImpl . +type MultiNotifyLogRepoImpl struct { + Base[model.MultiNotifyLog, bo.MultiNotifyLogBo] + db *data.Db +} + +// NewMultiNotifyLogRepoImpl . +func NewMultiNotifyLogRepoImpl(db *data.Db) repo.MultiNotifyLogRepo { + return &MultiNotifyLogRepoImpl{db: db} +} + +func (p *MultiNotifyLogRepoImpl) DB(ctx context.Context) *gorm.DB { + return p.db.DB(ctx).WithContext(ctx).Model(model.MultiNotifyLog{}) +} + +func (p *MultiNotifyLogRepoImpl) Create(ctx context.Context, req *bo.MultiNotifyLogBo) (*bo.MultiNotifyLogBo, error) { + + now := time.Now() + + info := &model.MultiNotifyLog{ + MultiNotifyDataID: req.MultiNotifyDataID, + OrderNo: req.OrderNo, + OutBizNo: req.OutBizNo, + CouponID: req.CouponID, + ActivityNo: req.ActivityNo, + StockID: req.StockID, + EventType: req.EventType, + Status: req.Status, + ConsumeAmount: req.ConsumeAmount, + ConsumeTime: req.ConsumeTime, + TransactionID: req.TransactionID, + Request: req.Request, + RequestURL: req.RequestURL, + RequestStatus: vo.MultiNotifyLogStatusWait.GetValue(), + OrderCreateTime: req.OrderCreateTime, + CouponCreateTime: req.CouponCreateTime, + CreateTime: &now, + } + + if err := p.DB(ctx).Create(info).Error; err != nil { + return nil, err + } + + return p.ToBo(info), nil +} + +func (p *MultiNotifyLogRepoImpl) GetByID(ctx context.Context, id int64) (*bo.MultiNotifyLogBo, error) { + var item model.MultiNotifyLog + + tx := p.DB(ctx).Where(model.MultiNotifyLog{ID: id}).First(&item) + + if tx.Error != nil { + return nil, fmt.Errorf("b fail %w", tx.Error) + } + + if tx.RowsAffected == 0 { + return nil, err2.ErrorDbNotFound("数据不存在") + } + + return p.ToBo(&item), nil +} + +func (p *MultiNotifyLogRepoImpl) Success(ctx context.Context, id int64, response string) error { + + now := time.Now() + + res := p.DB(ctx). + Where(model.MultiNotifyLog{ + ID: id, + RequestStatus: vo.MultiNotifyLogStatusWait.GetValue(), + }). + Updates(model.MultiNotifyLog{ + RequestStatus: vo.MultiNotifyLogStatusSuccess.GetValue(), + Response: response, + UpdateTime: &now, + }) + + if res.Error != nil { + return res.Error + } + + return nil +} + +func (p *MultiNotifyLogRepoImpl) Fail(ctx context.Context, id int64, remark string) error { + + if utf8.RuneCountInString(remark) > 255 { + runes := []rune(remark) + if len(runes) > 255 { + remark = string(runes[:255]) + } + } + + now := time.Now() + + res := p.DB(ctx). + Where(model.MultiNotifyLog{ + ID: id, + RequestStatus: vo.MultiNotifyLogStatusWait.GetValue(), + }). + Updates(model.MultiNotifyLog{ + RequestStatus: vo.MultiNotifyLogStatusSuccess.GetValue(), + Response: remark, + UpdateTime: &now, + }) + + if res.Error != nil { + return res.Error + } + + return nil +}