package service import ( e "errors" "github.com/xuri/excelize/v2" "gold-shop/errors" "gold-shop/global" "gold-shop/model" "gold-shop/request" "gold-shop/request/manage" "gold-shop/utils" "gold-shop/utils/excel" "gold-shop/utils/payment" "gold-shop/utils/result" "gorm.io/gorm" "time" ) var PaymentService = paymentService{} type paymentService struct { } func (paymentService) GetUserPayments(userID, page, pageSize int) ([]model.Payment, int64) { payments := make([]model.Payment, pageSize) offset := (page - 1) * pageSize var total int64 global.DB.Where("user_id", userID).Offset(offset).Limit(pageSize).Find(&payments) global.DB.Model(&model.Payment{}).Where("user_id", userID).Count(&total) return payments, total } func (s paymentService) Payment(userID int, paymentRequest request.PaymentRequest) (result.Data, error) { p, err := s.createPayment(userID, paymentRequest) if err != nil { return nil, err } data := result.Data{} if paymentRequest.PayType == "wxOfficial" { data, err = s.wxPayment(paymentRequest, p) } else if paymentRequest.PayType == "transfer" { data, err = s.transferPayment(paymentRequest, p) } else { err = errors.NewBusinessError("payType参数错误") } if err != nil { p.Status = 2 p.ErrorMessage = err.Error() global.DB.Save(p) return nil, err } p.Status = 1 global.DB.Save(p) return data, nil } func (s paymentService) wxPayment(paymentRequest request.PaymentRequest, p *model.Payment) (result.Data, error) { param := payment.WxPayParam{} param.Remark = "payment" param.OrderId = utils.GenerateNo("payment") param.OpenId = paymentRequest.OpenID param.Amount = paymentRequest.Amount param.NotifyUrl = "" res, err := payment.PayApi.WxPay(param) if err != nil { return nil, err } if res.Status != payment.Success { return nil, errors.NewBusinessError(res.Message) } data := result.Data{ "paySign": res.PaySign, "package": res.Package, "signType": res.PaySignType, "nonceStr": res.NonceStr, "appId": res.AppId, "timeStamp": res.Timestamp, } return data, nil } func (s paymentService) transferPayment(paymentRequest request.PaymentRequest, p *model.Payment) (result.Data, error) { param := payment.TransferPayParam{} param.Remark = "payment" param.OrderId = utils.GenerateNo("payment") param.Amount = paymentRequest.Amount param.NotifyUrl = "" res, err := payment.PayApi.TransferPay(param) if err != nil { return nil, err } if res.Status != payment.Success { return nil, errors.NewBusinessError(res.Message) } data := result.Data{ "payeeAccountName": res.PayeeAccountName, "payeeBankName": res.PayeeBankName, "payeeCardNo": res.PayeeCardNo, "orderID": res.OrderID, "outOrderID": res.OutOrderID, } return data, nil } func (paymentService) createPayment(userID int, paymentRequest request.PaymentRequest) (*model.Payment, error) { p := model.Payment{} p.PaymentNo = utils.GenerateNo("payment") p.Amount = paymentRequest.Amount p.OpenID = paymentRequest.OpenID p.PayType = paymentRequest.PayType p.Status = 0 p.UserID = userID err := global.DB.Save(&p).Error if err != nil { return nil, errors.NewBusinessError("保存数据失败") } return &p, nil } func (s *paymentService) buildQuery(req manage.PaymentQueryRequest) *gorm.DB { tx := global.DB if req.Mobile != "" { var userIds []int global.DB.Model(&model.User{}).Where("mobile", req.Mobile).Pluck("id", &userIds) tx = tx.Where("user_id", userIds) } if req.PaymentNo != "" { tx = tx.Where("payment_no", req.PaymentNo) } if req.Status != "" { tx = tx.Where("status", req.Status) } if req.UserID != 0 { tx = tx.Where("user_id", req.UserID) } return tx } func (s *paymentService) GetPayments(req manage.PaymentQueryRequest) ([]model.Payment, int64) { payments := make([]model.Payment, req.PageSize) offset := (req.Page - 1) * req.PageSize var total int64 tx := s.buildQuery(req) tx.Preload("User").Order("id desc").Offset(offset).Limit(req.PageSize).Find(&payments) tx.Model(&model.Order{}).Count(&total) return payments, total } func (s *paymentService) GeneratePaymentsExcel(req manage.PaymentQueryRequest) *excelize.File { pageSize := 200 lastID := 0 tx := s.buildQuery(req) f := excel.NewFile() headers := []string{"支付订单号", "用户手机号", "金额", "支付状态", "支付时间"} excel.SetSimpleHeaders(headers, "Sheet1", f) for { payments := make([]model.Payment, pageSize) tx.Preload("User").Where("id > ?", lastID).Limit(pageSize).Find(&payments) count := len(payments) if count == 0 { break } s.buildPaymentsExcel(payments, "Sheet1", f) lastIndex := count - 1 lastID = payments[lastIndex].ID } return f } func (paymentService) buildPaymentsExcel(payments []model.Payment, sheet string, f *excelize.File) { row := 2 for _, p := range payments { col := 0 f.SetCellValue(sheet, excel.CellKey(row, &col), p.PaymentNo) f.SetCellValue(sheet, excel.CellKey(row, &col), p.User.Mobile) f.SetCellValue(sheet, excel.CellKey(row, &col), p.Amount) f.SetCellValue(sheet, excel.CellKey(row, &col), p.GetStatusText()) f.SetCellValue(sheet, excel.CellKey(row, &col), p.CreatedAt.Format(time.DateTime)) row++ } } func (s paymentService) AfterTransferPayNotify(req request.TransferPayNotifyRequest) error { pm := &model.Payment{} err := global.DB.Where("payment_no", req.OutOrderID).First(&pm).Error if err != nil && e.Is(err, gorm.ErrRecordNotFound) { return errors.NewBusinessError("记录不存在") } if req.PayStatus == "1" { pm.Status = 1 pm.PayerCardNo = req.PayerCardNo pm.PayerAccountName = req.PayerAccountName } else { pm.Status = 2 } err = global.DB.Save(&pm).Error return err }