重构后端服务架构并优化前端错误处理

This commit is contained in:
ylweng
2025-09-12 01:21:43 +08:00
parent d550a8ed51
commit 3a48a67757
53 changed files with 3925 additions and 0 deletions

View File

@@ -0,0 +1,177 @@
package controllers
import (
"net/http"
"strconv"
"github.com/gin-gonic/gin"
"github.com/google/uuid"
"gorm.io/gorm"
"niumall-go/config"
"niumall-go/models"
)
// GetOrders retrieves a list of orders with pagination
func GetOrders(c *gin.Context) {
var orders []models.Order
skip, _ := strconv.Atoi(c.DefaultQuery("skip", "0"))
limit, _ := strconv.Atoi(c.DefaultQuery("limit", "100"))
if err := config.DB.Offset(skip).Limit(limit).Find(&orders).Error; err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, orders)
}
// GetOrderByID retrieves an order by ID
func GetOrderByID(c *gin.Context) {
id := c.Param("id")
var order models.Order
if err := config.DB.First(&order, id).Error; err != nil {
if err == gorm.ErrRecordNotFound {
c.JSON(http.StatusNotFound, gin.H{"error": "Order not found"})
return
}
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, order)
}
// CreateOrder creates a new order
func CreateOrder(c *gin.Context) {
var input models.Order
if err := c.ShouldBindJSON(&input); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
// Generate unique order number
orderNo := "ORD" + uuid.New().String()[:16]
// Create order
order := models.Order{
OrderNo: orderNo,
BuyerID: input.BuyerID,
SellerID: input.SellerID,
VarietyType: input.VarietyType,
WeightRange: input.WeightRange,
WeightActual: input.WeightActual,
PricePerUnit: input.PricePerUnit,
TotalPrice: input.TotalPrice,
AdvancePayment: input.AdvancePayment,
FinalPayment: input.FinalPayment,
Status: input.Status,
DeliveryAddress: input.DeliveryAddress,
DeliveryTime: input.DeliveryTime,
Remark: input.Remark,
}
if err := config.DB.Create(&order).Error; err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, order)
}
// UpdateOrder updates an order's information
func UpdateOrder(c *gin.Context) {
id := c.Param("id")
var order models.Order
// Check if order exists
if err := config.DB.First(&order, id).Error; err != nil {
if err == gorm.ErrRecordNotFound {
c.JSON(http.StatusNotFound, gin.H{"error": "Order not found"})
return
}
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
// Parse input
var input models.Order
if err := c.ShouldBindJSON(&input); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
// Update order fields
if input.BuyerID != 0 {
order.BuyerID = input.BuyerID
}
if input.SellerID != 0 {
order.SellerID = input.SellerID
}
if input.VarietyType != "" {
order.VarietyType = input.VarietyType
}
if input.WeightRange != "" {
order.WeightRange = input.WeightRange
}
if input.WeightActual != 0 {
order.WeightActual = input.WeightActual
}
if input.PricePerUnit != 0 {
order.PricePerUnit = input.PricePerUnit
}
if input.TotalPrice != 0 {
order.TotalPrice = input.TotalPrice
}
if input.AdvancePayment != 0 {
order.AdvancePayment = input.AdvancePayment
}
if input.FinalPayment != 0 {
order.FinalPayment = input.FinalPayment
}
if input.Status != "" {
order.Status = input.Status
}
if input.DeliveryAddress != "" {
order.DeliveryAddress = input.DeliveryAddress
}
if input.DeliveryTime != nil {
order.DeliveryTime = input.DeliveryTime
}
if input.Remark != "" {
order.Remark = input.Remark
}
// Save updated order
if err := config.DB.Save(&order).Error; err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, order)
}
// DeleteOrder deletes an order by ID
func DeleteOrder(c *gin.Context) {
id := c.Param("id")
var order models.Order
// Check if order exists
if err := config.DB.First(&order, id).Error; err != nil {
if err == gorm.ErrRecordNotFound {
c.JSON(http.StatusNotFound, gin.H{"error": "Order not found"})
return
}
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
// Delete order
if err := config.DB.Delete(&order).Error; err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, order)
}

View File

@@ -0,0 +1,153 @@
package controllers
import (
"net/http"
"strconv"
"github.com/gin-gonic/gin"
"github.com/google/uuid"
"gorm.io/gorm"
"niumall-go/config"
"niumall-go/models"
)
// GetPayments retrieves a list of payments with pagination
func GetPayments(c *gin.Context) {
var payments []models.Payment
skip, _ := strconv.Atoi(c.DefaultQuery("skip", "0"))
limit, _ := strconv.Atoi(c.DefaultQuery("limit", "100"))
if err := config.DB.Offset(skip).Limit(limit).Find(&payments).Error; err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, payments)
}
// GetPaymentByID retrieves a payment by ID
func GetPaymentByID(c *gin.Context) {
id := c.Param("id")
var payment models.Payment
if err := config.DB.First(&payment, id).Error; err != nil {
if err == gorm.ErrRecordNotFound {
c.JSON(http.StatusNotFound, gin.H{"error": "Payment not found"})
return
}
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, payment)
}
// CreatePayment creates a new payment
func CreatePayment(c *gin.Context) {
var input models.Payment
if err := c.ShouldBindJSON(&input); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
// Generate unique payment number
paymentNo := "PMT" + uuid.New().String()[:16]
// Create payment
payment := models.Payment{
PaymentNo: paymentNo,
OrderID: input.OrderID,
UserID: input.UserID,
Amount: input.Amount,
PaymentType: input.PaymentType,
PaymentMethod: input.PaymentMethod,
Status: input.Status,
TransactionID: input.TransactionID,
}
if err := config.DB.Create(&payment).Error; err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, payment)
}
// UpdatePayment updates a payment's information
func UpdatePayment(c *gin.Context) {
id := c.Param("id")
var payment models.Payment
// Check if payment exists
if err := config.DB.First(&payment, id).Error; err != nil {
if err == gorm.ErrRecordNotFound {
c.JSON(http.StatusNotFound, gin.H{"error": "Payment not found"})
return
}
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
// Parse input
var input models.Payment
if err := c.ShouldBindJSON(&input); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
// Update payment fields
if input.OrderID != 0 {
payment.OrderID = input.OrderID
}
if input.UserID != 0 {
payment.UserID = input.UserID
}
if input.Amount != 0 {
payment.Amount = input.Amount
}
if input.PaymentType != "" {
payment.PaymentType = input.PaymentType
}
if input.PaymentMethod != "" {
payment.PaymentMethod = input.PaymentMethod
}
if input.Status != "" {
payment.Status = input.Status
}
if input.TransactionID != "" {
payment.TransactionID = input.TransactionID
}
// Save updated payment
if err := config.DB.Save(&payment).Error; err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, payment)
}
// DeletePayment deletes a payment by ID
func DeletePayment(c *gin.Context) {
id := c.Param("id")
var payment models.Payment
// Check if payment exists
if err := config.DB.First(&payment, id).Error; err != nil {
if err == gorm.ErrRecordNotFound {
c.JSON(http.StatusNotFound, gin.H{"error": "Payment not found"})
return
}
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
// Delete payment
if err := config.DB.Delete(&payment).Error; err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, payment)
}

View File

@@ -0,0 +1,153 @@
package controllers
import (
"net/http"
"strconv"
"github.com/gin-gonic/gin"
"gorm.io/gorm"
"niumall-go/config"
"niumall-go/models"
"niumall-go/utils"
)
// GetUserByID retrieves a user by ID
func GetUserByID(c *gin.Context) {
id := c.Param("id")
var user models.User
if err := config.DB.First(&user, id).Error; err != nil {
if err == gorm.ErrRecordNotFound {
c.JSON(http.StatusNotFound, gin.H{"error": "User not found"})
return
}
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, user)
}
// GetUsers retrieves a list of users with pagination
func GetUsers(c *gin.Context) {
var users []models.User
skip, _ := strconv.Atoi(c.DefaultQuery("skip", "0"))
limit, _ := strconv.Atoi(c.DefaultQuery("limit", "100"))
if err := config.DB.Offset(skip).Limit(limit).Find(&users).Error; err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, users)
}
// UpdateUser updates a user's information
func UpdateUser(c *gin.Context) {
id := c.Param("id")
var user models.User
// Check if user exists
if err := config.DB.First(&user, id).Error; err != nil {
if err == gorm.ErrRecordNotFound {
c.JSON(http.StatusNotFound, gin.H{"error": "User not found"})
return
}
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
// Parse input
var input models.User
if err := c.ShouldBindJSON(&input); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
// Update user fields
if input.Username != "" {
user.Username = input.Username
}
if input.UserType != "" {
user.UserType = input.UserType
}
if input.Status != "" {
user.Status = input.Status
}
// Save updated user
if err := config.DB.Save(&user).Error; err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, user)
}
// DeleteUser deletes a user by ID
func DeleteUser(c *gin.Context) {
id := c.Param("id")
var user models.User
// Check if user exists
if err := config.DB.First(&user, id).Error; err != nil {
if err == gorm.ErrRecordNotFound {
c.JSON(http.StatusNotFound, gin.H{"error": "User not found"})
return
}
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
// Delete user
if err := config.DB.Delete(&user).Error; err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, user)
}
// Login handles user login and returns a JWT token
func Login(c *gin.Context) {
var input struct {
Username string `json:"username" binding:"required"`
Password string `json:"password" binding:"required"`
}
// Parse input
if err := c.ShouldBindJSON(&input); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
// Find user by username
var user models.User
if err := config.DB.Where("username = ?", input.Username).First(&user).Error; err != nil {
if err == gorm.ErrRecordNotFound {
c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid credentials"})
return
}
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
// Check password
if !utils.CheckPasswordHash(input.Password, user.Password) {
c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid credentials"})
return
}
// Generate JWT token
token, err := utils.GenerateJWT(user.UUID)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to generate token"})
return
}
c.JSON(http.StatusOK, gin.H{
"access_token": token,
"token_type": "bearer",
})
}