Files
lunar-mini/server/internal/handler/pay.go
T
gouki 48255faa5b feat: 实现后端业务逻辑和Inertia.js管理后台
- 实现数据库连接和自动迁移
- 实现用户服务(登录、资料、JWT认证)
- 实现许愿服务(创建、列表、机器人许愿)
- 实现订单服务(创建、支付、状态管理)
- 实现JWT认证中间件
- 实现管理后台API(仪表盘、用户、订单、许愿、设置)
- 创建Inertia.js前端页面(Vue3 + Tailwind CSS)
- 修复Go模块依赖问题
2026-08-06 13:11:59 +00:00

149 lines
3.3 KiB
Go

package handler
import (
"net/http"
"github.com/gin-gonic/gin"
"github.com/gouki/lunar-server/internal/model"
"github.com/gouki/lunar-server/internal/service"
)
// CreateOrder 创建订单
func CreateOrder(c *gin.Context) {
userID, exists := c.Get("userID")
if !exists {
c.JSON(http.StatusUnauthorized, gin.H{
"code": 401,
"msg": "未授权",
})
return
}
var req struct {
Type string `json:"type" binding:"required"` // wish:许愿 vip:会员
ProductID uint `json:"productId" binding:"required"` // 商品ID
ProductName string `json:"productName" binding:"required"` // 商品名称
Amount int `json:"amount" binding:"required"` // 金额(分)
Content string `json:"content"` // 许愿内容(许愿类型需要)
}
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"code": 400,
"msg": "参数错误",
})
return
}
orderService := service.NewOrderService()
order := &model.Order{
UserID: userID.(uint),
Type: req.Type,
ProductID: req.ProductID,
ProductName: req.ProductName,
Amount: req.Amount,
}
if err := orderService.CreateOrder(order); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"code": 500,
"msg": "创建订单失败",
})
return
}
// 如果是许愿类型,创建许愿记录
if req.Type == "wish" && req.Content != "" {
wishService := service.NewWishService()
wish := &model.Wish{
UserID: userID.(uint),
TreeID: 1, // 默认许愿树
Content: req.Content,
Type: "paid",
Status: 1,
}
wishService.CreateWish(wish)
}
// 创建微信支付订单
payParams, err := orderService.CreateWechatPayOrder(order, "")
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"code": 500,
"msg": "创建支付订单失败",
})
return
}
c.JSON(http.StatusOK, gin.H{
"code": 0,
"msg": "success",
"data": gin.H{
"orderId": order.ID,
"orderNo": order.OrderNo,
"payParams": payParams,
},
})
}
// PayNotify 支付回调
func PayNotify(c *gin.Context) {
// TODO: 验证微信支付回调签名
var req struct {
OrderNo string `json:"orderNo"`
TransactionID string `json:"transactionId"`
Status string `json:"status"`
}
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"code": "FAIL",
"msg": "参数错误",
})
return
}
if req.Status == "SUCCESS" {
orderService := service.NewOrderService()
if err := orderService.HandlePayNotify(req.OrderNo, req.TransactionID); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"code": "FAIL",
"msg": "处理失败",
})
return
}
}
c.JSON(http.StatusOK, gin.H{
"code": "SUCCESS",
"msg": "OK",
})
}
// GetPayStatus 获取支付状态
func GetPayStatus(c *gin.Context) {
orderID := c.Param("orderId")
orderService := service.NewOrderService()
order, err := orderService.GetOrderByOrderNo(orderID)
if err != nil {
c.JSON(http.StatusNotFound, gin.H{
"code": 404,
"msg": "订单不存在",
})
return
}
c.JSON(http.StatusOK, gin.H{
"code": 0,
"msg": "success",
"data": gin.H{
"orderId": order.ID,
"orderNo": order.OrderNo,
"status": order.Status,
"payTime": order.PayTime,
},
})
}