168 lines
5.0 KiB
Go
168 lines
5.0 KiB
Go
package app
|
||
|
||
import (
|
||
"fmt"
|
||
|
||
"git.echol.cn/loser/lckt/global"
|
||
"git.echol.cn/loser/lckt/model/app"
|
||
"git.echol.cn/loser/lckt/model/app/request"
|
||
"git.echol.cn/loser/lckt/model/user"
|
||
"git.echol.cn/loser/lckt/utils/wechat"
|
||
"github.com/gin-gonic/gin"
|
||
"go.uber.org/zap"
|
||
)
|
||
|
||
type OrderService struct{}
|
||
|
||
// Pay 发起支付
|
||
func (s *OrderService) Pay(p request.PayReq, ctx *gin.Context) (interface{}, error) {
|
||
order := app.Order{}
|
||
err := global.GVA_DB.Where("id = ? AND order_no = ?", p.OrderId, p.OrderNo).First(&order).Error
|
||
if err != nil {
|
||
global.GVA_LOG.Error("查询订单失败", zap.Error(err))
|
||
return "", err
|
||
}
|
||
|
||
if order.Status == 3 {
|
||
global.GVA_LOG.Error("订单已过期", zap.Int64("order_id", int64(order.ID)))
|
||
return "", fmt.Errorf("订单已过期")
|
||
}
|
||
|
||
if p.Mode == "h5" {
|
||
payConf, err := wechat.H5Pay(&order, ctx)
|
||
if err != nil {
|
||
global.GVA_LOG.Error("微信支付订单失败", zap.Error(err))
|
||
return "", err
|
||
}
|
||
return payConf, nil
|
||
} else if p.Mode == "jsapi" {
|
||
payConf, err := wechat.JSAPIPay(&order, ctx)
|
||
if err != nil {
|
||
global.GVA_LOG.Error("微信支付订单失败", zap.Error(err))
|
||
return "", err
|
||
}
|
||
return payConf, nil
|
||
}
|
||
|
||
return "", nil
|
||
}
|
||
|
||
func (s *OrderService) Create(o *app.Order) (*app.Order, error) {
|
||
// 生成订单号
|
||
o.OrderNo = wechat.GenerateOrderNum()
|
||
|
||
// 查询订单商品价格
|
||
price := 0
|
||
if o.OrderType == 1 {
|
||
err := global.GVA_DB.Table("article").Select("price").Where("id = ?", o.ArticleId).Scan(&price).Error
|
||
if err != nil {
|
||
global.GVA_LOG.Error("查询商品价格失败", zap.Error(err))
|
||
return nil, err
|
||
}
|
||
} else {
|
||
err := global.GVA_DB.Table("lckt_vip").Select("price").Where("id = ?", o.ArticleId).Scan(&price).Error
|
||
if err != nil {
|
||
global.GVA_LOG.Error("查询VIP价格失败", zap.Error(err))
|
||
return nil, err
|
||
}
|
||
}
|
||
o.Price = int64(price)
|
||
o.Status = 1 // 设置订单状态为未付款
|
||
// 设置openid
|
||
openId := ""
|
||
err := global.GVA_DB.Table("app_user").Where("id = ?", o.UserId).Select("open_id").Scan(&openId).Error
|
||
if err != nil {
|
||
global.GVA_LOG.Error("查询用户OpenID失败,请检查微信是否绑定", zap.Error(err))
|
||
return nil, fmt.Errorf("查询用户OpenID失败,请检查微信是否绑定")
|
||
}
|
||
o.OpenId = openId
|
||
|
||
err = global.GVA_DB.Create(&o).Error
|
||
if err != nil {
|
||
global.GVA_LOG.Error("创建订单失败", zap.Error(err))
|
||
return nil, err
|
||
}
|
||
return o, nil
|
||
}
|
||
|
||
func (s *OrderService) GetOrderDetail(id string) (order app.Order, err error) {
|
||
err = global.GVA_DB.Where("id = ?", id).First(&order).Error
|
||
if err != nil {
|
||
global.GVA_LOG.Error("获取订单详情失败", zap.Error(err))
|
||
return app.Order{}, err
|
||
}
|
||
return order, nil
|
||
}
|
||
|
||
func (s *OrderService) BalancePay(p request.BalancePay) error {
|
||
order := app.Order{}
|
||
err := global.GVA_DB.Where("id = ? AND order_no = ?", p.OrderId, p.OrderNo).First(&order).Error
|
||
if err != nil {
|
||
global.GVA_LOG.Error("查询订单失败", zap.Error(err))
|
||
return err
|
||
}
|
||
|
||
if order.Status != 1 {
|
||
global.GVA_LOG.Error("订单状态错误,无法支付", zap.Int("status", order.Status))
|
||
return err
|
||
}
|
||
// 检查用户余额是否足够
|
||
var user user.User
|
||
err = global.GVA_DB.Where("id = ?", p.UserId).Select("id,balance").First(&user).Error
|
||
if err != nil {
|
||
global.GVA_LOG.Error("查询用户信息失败", zap.Error(err))
|
||
return err
|
||
}
|
||
|
||
// 将订单价格从分转换为元(保持精度)
|
||
orderPriceInYuan := float64(order.Price) / 100.0
|
||
|
||
// 检查用户余额是否足够(使用float64进行比较,避免精度丢失)
|
||
if user.Balance < float32(orderPriceInYuan) {
|
||
global.GVA_LOG.Error("用户余额不足",
|
||
zap.Float32("balance", user.Balance),
|
||
zap.Float64("order_price_yuan", orderPriceInYuan),
|
||
zap.Int64("order_price_cent", order.Price))
|
||
return fmt.Errorf("用户余额不足")
|
||
}
|
||
|
||
// 扣除用户余额(保持精度)
|
||
newBalance := user.Balance - float32(orderPriceInYuan)
|
||
err = global.GVA_DB.Model(&user).Where("id = ?", p.UserId).Update("balance", newBalance).Error
|
||
if err != nil {
|
||
global.GVA_LOG.Error("扣除用户余额失败", zap.Error(err))
|
||
return err
|
||
}
|
||
// 更新订单状态为已付款
|
||
order.Status = 2
|
||
err = global.GVA_DB.Model(&order).Where("id = ?", order.ID).Update("status", 2).Error
|
||
if err != nil {
|
||
global.GVA_LOG.Error("更新订单状态失败", zap.Error(err))
|
||
return err
|
||
}
|
||
|
||
global.GVA_LOG.Info("余额支付成功", zap.Int64("user_id", int64(p.UserId)), zap.String("order_no", order.OrderNo))
|
||
return nil
|
||
}
|
||
|
||
func (s *OrderService) GetOrderList(p request.GetOrderList, id uint) (orders []app.Order, total int64, err error) {
|
||
limit := p.PageSize
|
||
offset := p.PageSize * (p.Page - 1)
|
||
|
||
db := global.GVA_DB.Model(&app.Order{}).Where("user_id = ?", id)
|
||
if p.Keyword != "" {
|
||
db = db.Where("title LIKE ? ", "%"+p.Keyword+"%")
|
||
}
|
||
if p.Status != 0 {
|
||
db = db.Where("status = ?", p.Status)
|
||
}
|
||
|
||
err = db.Count(&total).Error
|
||
err = db.Limit(limit).Offset(offset).Order("created_at desc").Find(&orders).Error
|
||
if err != nil {
|
||
global.GVA_LOG.Error("获取订单列表失败", zap.Error(err))
|
||
return nil, 0, err
|
||
}
|
||
return
|
||
}
|