Files
sale/backend/internal/api/routes/routes.go
T
admin 3a898e8aa0 fix: 全面修复项目问题
后端修复:
- 验证码存储与校验机制
- 订单创建事务+库存扣减
- GetStats字段名错误
- VerifyEmail改为POST
- 供应商更新字段白名单
- 文件删除安全检查
- 抽奖安全随机数
- 用户管理CRUD
- 订单取消/确认收货
- 工单回复
- Toggle返回新数据
- 移除死代码

前端修复:
- 404兜底路由
- 401软跳转
- API层统一
- 面包屑补充banners
- 国际化完善
- 购物车并行删除
- 退出清理购物车
- 供应商Dashboard数据
- 工单详情页
- 订单取消/确认收货
2026-05-06 09:55:01 +08:00

242 lines
7.9 KiB
Go

package routes
import (
"net/http"
"sale/internal/api/handlers"
"sale/internal/api/middlewares"
"github.com/gin-gonic/gin"
)
func SetupRoutes(r *gin.Engine) {
authHandler := handlers.NewAuthHandler()
categoryHandler := handlers.NewCategoryHandler()
brandHandler := handlers.NewBrandHandler()
productHandler := handlers.NewProductHandler()
cartHandler := handlers.NewCartHandler()
orderHandler := handlers.NewOrderHandler()
addressHandler := handlers.NewAddressHandler()
lotteryHandler := handlers.NewLotteryHandler()
ticketHandler := handlers.NewTicketHandler()
systemHandler := handlers.NewSystemHandler()
supplierHandler := handlers.NewSupplierHandler()
inventoryHandler := handlers.NewInventoryHandler()
articleHandler := handlers.NewArticleHandler()
uploadHandler := handlers.NewUploadHandler()
bannerHandler := handlers.NewBannerHandler()
r.Use(middlewares.CORSMiddleware())
api := r.Group("/api")
{
api.GET("/installed", authHandler.CheckInstalled)
api.POST("/install", authHandler.Install)
auth := api.Group("/auth")
{
auth.POST("/register", authHandler.Register)
auth.POST("/login", authHandler.Login)
auth.POST("/forgot-password", authHandler.ForgotPassword)
auth.POST("/reset-password", authHandler.ResetPassword)
auth.POST("/verify-email", authHandler.VerifyEmail)
}
articles := api.Group("/articles")
{
articles.GET("", articleHandler.List)
articles.GET("/:id", articleHandler.GetByID)
// 采集 API(管理员权限)
articles.POST("/crawl-ribenyan", articleHandler.CrawlRibenyan)
}
api.GET("/banners", bannerHandler.List)
api.GET("/categories", categoryHandler.List)
api.GET("/brands", brandHandler.List)
api.GET("/products", productHandler.List)
api.GET("/products/:id", productHandler.GetByID)
api.GET("/lotteries", lotteryHandler.List)
api.GET("/lotteries/:id", lotteryHandler.GetByID)
api.GET("/settings/public", systemHandler.GetPublicSettings)
authed := api.Group("")
authed.Use(middlewares.AuthMiddleware())
{
authed.POST("/upload", uploadHandler.UploadImage)
authed.POST("/upload/multiple", uploadHandler.UploadMultiple)
authed.DELETE("/upload/:filename", uploadHandler.DeleteImage)
users := authed.Group("/users")
{
users.GET("/profile", authHandler.GetProfile)
users.PUT("/profile", authHandler.UpdateProfile)
users.PUT("/password", authHandler.ChangePassword)
users.POST("/send-verify-code", authHandler.SendVerifyCode)
}
addresses := authed.Group("/users/addresses")
{
addresses.GET("", addressHandler.List)
addresses.POST("", addressHandler.Create)
addresses.PUT("/:id", addressHandler.Update)
addresses.DELETE("/:id", addressHandler.Delete)
addresses.PUT("/:id/default", addressHandler.SetDefault)
}
carts := authed.Group("/cart")
{
carts.GET("", cartHandler.List)
carts.POST("", cartHandler.Add)
carts.PUT("/:id", cartHandler.Update)
carts.DELETE("/:id", cartHandler.Delete)
}
orders := authed.Group("/orders")
{
orders.GET("", orderHandler.List)
orders.GET("/:id", orderHandler.GetByID)
orders.POST("", orderHandler.Create)
orders.POST("/:id/refund", orderHandler.Refund)
orders.PUT("/:id/cancel", orderHandler.CancelOrder)
orders.PUT("/:id/confirm-receipt", orderHandler.ConfirmReceipt)
}
lotteries := authed.Group("/lotteries")
{
lotteries.POST("/:id/register", lotteryHandler.Register)
}
tickets := authed.Group("/tickets")
{
tickets.GET("", ticketHandler.List)
tickets.POST("", ticketHandler.Create)
tickets.GET("/:id", ticketHandler.GetByID)
tickets.POST("/:id/reply", ticketHandler.Reply)
}
supplier := authed.Group("/supplier")
supplier.Use(middlewares.RoleMiddleware("supplier", "admin"))
{
supplier.GET("/orders", orderHandler.List)
supplier.GET("/orders/:id", orderHandler.GetByID)
supplier.PUT("/orders/:id/confirm", orderHandler.ConfirmOrder)
supplier.PUT("/orders/:id/ship", orderHandler.ShipOrder)
supplier.GET("/inventory", inventoryHandler.SupplierList)
supplier.PUT("/inventory/:id", inventoryHandler.Update)
}
admin := authed.Group("/admin")
admin.Use(middlewares.RoleMiddleware("admin"))
{
admin.GET("/stats", systemHandler.GetStats)
admin.GET("/users", authHandler.AdminGetUsers)
admin.PUT("/users/:id", authHandler.AdminUpdateUser)
admin.DELETE("/users/:id", authHandler.AdminDeleteUser)
adminCategories := admin.Group("/categories")
{
adminCategories.POST("", categoryHandler.Create)
adminCategories.PUT("/:id", categoryHandler.Update)
adminCategories.DELETE("/:id", categoryHandler.Delete)
}
adminBrands := admin.Group("/brands")
{
adminBrands.GET("", brandHandler.List)
adminBrands.POST("", brandHandler.Create)
adminBrands.PUT("/:id", brandHandler.Update)
adminBrands.DELETE("/:id", brandHandler.Delete)
}
adminProducts := admin.Group("/products")
{
adminProducts.GET("", productHandler.AdminList)
adminProducts.POST("", productHandler.Create)
adminProducts.PUT("/:id", productHandler.Update)
adminProducts.DELETE("/:id", productHandler.Delete)
adminProducts.POST("/:id/custom-fields", productHandler.AddCustomField)
}
adminOrders := admin.Group("/orders")
{
adminOrders.GET("", orderHandler.AdminList)
adminOrders.GET("/export", orderHandler.Export)
adminOrders.PUT("/:id/refund", orderHandler.ProcessRefund)
}
adminLotteries := admin.Group("/lotteries")
{
adminLotteries.POST("", lotteryHandler.Create)
adminLotteries.PUT("/:id", lotteryHandler.Update)
adminLotteries.DELETE("/:id", lotteryHandler.Delete)
adminLotteries.POST("/:id/prizes", lotteryHandler.AddPrize)
adminLotteries.POST("/:id/draw", lotteryHandler.Draw)
}
adminTickets := admin.Group("/tickets")
{
adminTickets.GET("", ticketHandler.AdminList)
adminTickets.PUT("/:id", ticketHandler.Update)
adminTickets.PUT("/:id/assign", ticketHandler.Assign)
}
admin.GET("/settings", systemHandler.GetSettings)
admin.PUT("/settings", systemHandler.UpdateSettings)
admin.PUT("/settings/smtp", systemHandler.UpdateSMTP)
admin.PUT("/settings/payment", systemHandler.UpdatePayment)
adminSuppliers := admin.Group("/suppliers")
{
adminSuppliers.GET("", supplierHandler.List)
adminSuppliers.POST("", supplierHandler.Create)
adminSuppliers.PUT("/:id", supplierHandler.Update)
adminSuppliers.DELETE("/:id", supplierHandler.Delete)
adminSuppliers.POST("/:id/authorize", supplierHandler.Authorize)
}
admin.GET("/inventory", inventoryHandler.AdminList)
adminArticles := admin.Group("/articles")
{
adminArticles.GET("", articleHandler.AdminList)
adminArticles.POST("", articleHandler.Create)
adminArticles.PUT("/:id", articleHandler.Update)
adminArticles.DELETE("/:id", articleHandler.Delete)
adminArticles.PUT("/:id/pin", articleHandler.TogglePin)
}
adminBanners := admin.Group("/banners")
{
adminBanners.GET("", bannerHandler.AdminList)
adminBanners.POST("", bannerHandler.Create)
adminBanners.PUT("/:id", bannerHandler.Update)
adminBanners.DELETE("/:id", bannerHandler.Delete)
adminBanners.PUT("/:id/toggle", bannerHandler.ToggleActive)
}
}
}
}
// Serve uploads
r.Static("/uploads", "./uploads")
// Serve frontend static assets (CSS, JS, images, etc.)
r.StaticFS("/assets", http.Dir("./static/assets"))
// SPA fallback - serve index.html for all other routes (Vue Router History Mode)
// This must be the last route to catch all unmatched paths
r.NoRoute(func(c *gin.Context) {
path := c.Request.URL.Path
// For root and SPA routes, serve index.html
// API requests will return 404 if not found
if path == "/" || path == "/favicon.ico" || path == "/icons.svg" || path == "/favicon.svg" ||
len(path) > 4 && path[:4] != "/api/" {
c.File("/app/static/index.html")
} else {
// API routes - let them return 404 if not found
c.AbortWithStatus(404)
}
})
}