feat(admin): 添加管理后台功能模块
- 新增管理员界面模板 admin.html - 实现管理员路由处理器 AdminHandler - 添加产品、分类、订单、数据库管理子模块 - 注册管理后台相关路由处理器 - 修改URL生成函数名为MustGenerateUrl并统一调用方式 - 更新购物车和订单处理中的URL生成方法调用 - 在主程序中配置管理后台路由别名
This commit is contained in:
8
32-platform/sportsstore/admin/categories_handler.go
Normal file
8
32-platform/sportsstore/admin/categories_handler.go
Normal file
@@ -0,0 +1,8 @@
|
||||
package admin
|
||||
|
||||
type CategoriesHandler struct {
|
||||
}
|
||||
|
||||
func (handler CategoriesHandler) GetData() string {
|
||||
return "This is the categories handler"
|
||||
}
|
||||
8
32-platform/sportsstore/admin/database_handler.go
Normal file
8
32-platform/sportsstore/admin/database_handler.go
Normal file
@@ -0,0 +1,8 @@
|
||||
package admin
|
||||
|
||||
type DatabaseHandler struct {
|
||||
}
|
||||
|
||||
func (handler DatabaseHandler) GetData() string {
|
||||
return "This is the database handler"
|
||||
}
|
||||
29
32-platform/sportsstore/admin/main_handler.go
Normal file
29
32-platform/sportsstore/admin/main_handler.go
Normal file
@@ -0,0 +1,29 @@
|
||||
package admin
|
||||
|
||||
import (
|
||||
"platform/http/actionresults"
|
||||
"platform/http/handing"
|
||||
"sportstore/store"
|
||||
)
|
||||
|
||||
var sectionNames = []string{"Products", "Categories", "Orders", "Database"}
|
||||
|
||||
type AdminHandler struct {
|
||||
handing.URLGenerator
|
||||
}
|
||||
|
||||
type AdminTemplateContext struct {
|
||||
Sections []string
|
||||
ActiveSection string
|
||||
SectionUrlFunc func(string) string
|
||||
}
|
||||
|
||||
func (handler AdminHandler) GetSection(section string) actionresults.ActionResult {
|
||||
return actionresults.NewTemplateAction("admin.html", AdminTemplateContext{
|
||||
Sections: sectionNames,
|
||||
ActiveSection: section,
|
||||
SectionUrlFunc: func(sec string) string {
|
||||
return store.MustGenerateUrl(handler.URLGenerator, AdminHandler.GetSection, sec)
|
||||
},
|
||||
})
|
||||
}
|
||||
8
32-platform/sportsstore/admin/orders_handler.go
Normal file
8
32-platform/sportsstore/admin/orders_handler.go
Normal file
@@ -0,0 +1,8 @@
|
||||
package admin
|
||||
|
||||
type OrdersHandler struct {
|
||||
}
|
||||
|
||||
func (handler OrdersHandler) GetData() string {
|
||||
return "This is the orders handler"
|
||||
}
|
||||
8
32-platform/sportsstore/admin/products_handler.go
Normal file
8
32-platform/sportsstore/admin/products_handler.go
Normal file
@@ -0,0 +1,8 @@
|
||||
package admin
|
||||
|
||||
type ProductsHandler struct {
|
||||
}
|
||||
|
||||
func (handler ProductsHandler) GetData() string {
|
||||
return "This is the products handler"
|
||||
}
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"platform/pipeline/basic"
|
||||
"platform/services"
|
||||
"platform/sessions"
|
||||
"sportstore/admin"
|
||||
"sportstore/models/repo"
|
||||
"sportstore/store"
|
||||
"sportstore/store/cart"
|
||||
@@ -33,8 +34,14 @@ func createPipeline() pipeline.RequestPipeline {
|
||||
handing.HandlerEntry{Prefix: "", Handler: store.CategoryHandler{}},
|
||||
handing.HandlerEntry{Prefix: "", Handler: store.CartHandler{}},
|
||||
handing.HandlerEntry{Prefix: "", Handler: store.OrderHandler{}},
|
||||
handing.HandlerEntry{Prefix: "admin", Handler: admin.AdminHandler{}},
|
||||
handing.HandlerEntry{Prefix: "admin", Handler: admin.ProductsHandler{}},
|
||||
handing.HandlerEntry{Prefix: "admin", Handler: admin.CategoriesHandler{}},
|
||||
handing.HandlerEntry{Prefix: "admin", Handler: admin.OrdersHandler{}},
|
||||
handing.HandlerEntry{Prefix: "admin", Handler: admin.DatabaseHandler{}},
|
||||
).AddMethodAlias("/", store.ProductHandler.GetProducts, 0, 1).
|
||||
AddMethodAlias("/products[/]?[A-z0-9]*?", store.ProductHandler.GetProducts, 0, 1),
|
||||
AddMethodAlias("/products[/]?[A-z0-9]*?", store.ProductHandler.GetProducts, 0, 1).
|
||||
AddMethodAlias("/admin[/]?", admin.AdminHandler.GetSection, ""),
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -28,9 +28,9 @@ type CardProductReference struct {
|
||||
func (handler CartHandler) GetCart() actionresults.ActionResult {
|
||||
context := CartTemplateContext{
|
||||
Cart: handler.Cart,
|
||||
ProductListUrl: mustGenerateUrl(handler.URLGenerator, ProductHandler.GetProducts, 0, 1),
|
||||
RemoveUrl: mustGenerateUrl(handler.URLGenerator, CartHandler.PostRemoveFromCart),
|
||||
CheckoutUrl: mustGenerateUrl(handler.URLGenerator, OrderHandler.GetCheckout),
|
||||
ProductListUrl: MustGenerateUrl(handler.URLGenerator, ProductHandler.GetProducts, 0, 1),
|
||||
RemoveUrl: MustGenerateUrl(handler.URLGenerator, CartHandler.PostRemoveFromCart),
|
||||
CheckoutUrl: MustGenerateUrl(handler.URLGenerator, OrderHandler.GetCheckout),
|
||||
}
|
||||
return actionresults.NewTemplateAction("cart.html", context)
|
||||
}
|
||||
@@ -38,7 +38,7 @@ func (handler CartHandler) GetCart() actionresults.ActionResult {
|
||||
func (handler CartHandler) GetWidget() actionresults.ActionResult {
|
||||
context := CartTemplateContext{
|
||||
Cart: handler.Cart,
|
||||
CartUrl: mustGenerateUrl(handler.URLGenerator, CartHandler.GetCart),
|
||||
CartUrl: MustGenerateUrl(handler.URLGenerator, CartHandler.GetCart),
|
||||
}
|
||||
return actionresults.NewTemplateAction("cart_widget.html", context)
|
||||
}
|
||||
@@ -46,10 +46,10 @@ func (handler CartHandler) GetWidget() actionresults.ActionResult {
|
||||
func (handler CartHandler) PostAddToCart(ref CardProductReference) actionresults.ActionResult {
|
||||
p := handler.Repository.GetProduct(ref.ID)
|
||||
handler.Cart.AddProduct(p)
|
||||
return actionresults.NewRedirectAction(mustGenerateUrl(handler.URLGenerator, CartHandler.GetCart))
|
||||
return actionresults.NewRedirectAction(MustGenerateUrl(handler.URLGenerator, CartHandler.GetCart))
|
||||
}
|
||||
|
||||
func (handler CartHandler) PostRemoveFromCart(ref CardProductReference) actionresults.ActionResult {
|
||||
handler.Cart.RemoveLineForProduct(ref.ID)
|
||||
return actionresults.NewRedirectAction(mustGenerateUrl(handler.URLGenerator, CartHandler.GetCart))
|
||||
return actionresults.NewRedirectAction(MustGenerateUrl(handler.URLGenerator, CartHandler.GetCart))
|
||||
}
|
||||
|
||||
@@ -27,11 +27,11 @@ func (handler CategoryHandler) GetButtons(selected int) actionresults.ActionResu
|
||||
|
||||
func (handler CategoryHandler) createCategoryUrlFunction() func(int) string {
|
||||
return func(category int) string {
|
||||
return mustGenerateUrl(handler.URLGenerator, ProductHandler.GetProducts, category, 1)
|
||||
return MustGenerateUrl(handler.URLGenerator, ProductHandler.GetProducts, category, 1)
|
||||
}
|
||||
}
|
||||
|
||||
func mustGenerateUrl(generator handing.URLGenerator, method interface{}, data ...interface{}) string {
|
||||
func MustGenerateUrl(generator handing.URLGenerator, method interface{}, data ...interface{}) string {
|
||||
url, err := generator.GenerateUrl(method, data...)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
|
||||
@@ -31,7 +31,7 @@ func (handler OrderHandler) GetCheckout() actionresults.ActionResult {
|
||||
if jsonData != nil {
|
||||
json.NewDecoder(strings.NewReader(jsonData.(string))).Decode(&context)
|
||||
}
|
||||
context.CancelUrl = mustGenerateUrl(handler.URLGenerator, CartHandler.GetCart)
|
||||
context.CancelUrl = MustGenerateUrl(handler.URLGenerator, CartHandler.GetCart)
|
||||
return actionresults.NewTemplateAction("checkout.html", context)
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ func (handler OrderHandler) PostCheckout(details models.ShippingDetails) actionr
|
||||
builder := strings.Builder{}
|
||||
json.NewEncoder(&builder).Encode(ctx)
|
||||
handler.Session.SetValue("checkout_details", builder.String())
|
||||
redirectUrl := mustGenerateUrl(handler.URLGenerator, OrderHandler.GetCheckout)
|
||||
redirectUrl := MustGenerateUrl(handler.URLGenerator, OrderHandler.GetCheckout)
|
||||
return actionresults.NewRedirectAction(redirectUrl)
|
||||
} else {
|
||||
handler.Session.SetValue("checkout_details", "")
|
||||
@@ -68,12 +68,12 @@ func (handler OrderHandler) PostCheckout(details models.ShippingDetails) actionr
|
||||
handler.Repository.SaveOrder(&order)
|
||||
handler.Cart.Reset()
|
||||
|
||||
targetUrl := mustGenerateUrl(handler.URLGenerator, OrderHandler.GetSummary, order.Id)
|
||||
targetUrl := MustGenerateUrl(handler.URLGenerator, OrderHandler.GetSummary, order.Id)
|
||||
return actionresults.NewRedirectAction(targetUrl)
|
||||
}
|
||||
|
||||
func (handler OrderHandler) GetSummary(orderId int) actionresults.ActionResult {
|
||||
targetUrl := mustGenerateUrl(handler.URLGenerator, ProductHandler.GetProducts, 0, 1)
|
||||
targetUrl := MustGenerateUrl(handler.URLGenerator, ProductHandler.GetProducts, 0, 1)
|
||||
return actionresults.NewTemplateAction("checkout_summary.html", struct {
|
||||
Id int
|
||||
TargetUrl string
|
||||
|
||||
@@ -35,14 +35,14 @@ func (handler ProductHandler) GetProducts(category, page int) actionresults.Acti
|
||||
PageNumbers: handler.generatePageNumbers(pageCount),
|
||||
PageUrlFunc: handler.createPageUrlFunction(category),
|
||||
SelectedCategory: category,
|
||||
AddToCartUrl: mustGenerateUrl(handler.URLGenerator, CartHandler.PostAddToCart),
|
||||
AddToCartUrl: MustGenerateUrl(handler.URLGenerator, CartHandler.PostAddToCart),
|
||||
}
|
||||
return actionresults.NewTemplateAction("product_list.html", context)
|
||||
}
|
||||
|
||||
func (handler ProductHandler) createPageUrlFunction(category int) func(int) string {
|
||||
return func(page int) string {
|
||||
return mustGenerateUrl(handler.URLGenerator, ProductHandler.GetProducts, category, page)
|
||||
return MustGenerateUrl(handler.URLGenerator, ProductHandler.GetProducts, category, page)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
43
32-platform/sportsstore/templates/admin.html
Normal file
43
32-platform/sportsstore/templates/admin.html
Normal file
@@ -0,0 +1,43 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ch">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"></meta>
|
||||
<title>Sports Store</title>
|
||||
<link rel="stylesheet" href="/files/bootstrap.min.css"/>
|
||||
</head>
|
||||
<body>
|
||||
{{ $context := . }}
|
||||
<div class="bg-info text-white p-2">
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col navbar-brand">Sports Store Administration</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row m-1 p-1">
|
||||
<div id="sidebar" class="col-3">
|
||||
<div class="d-grid gap-2">
|
||||
{{ range $context.Sections }}
|
||||
<a href="{{ call $context.SectionUrlFunc . }}"
|
||||
{{ if eq . $context.ActiveSection }}
|
||||
class="btn btn-info"
|
||||
{{ else }}
|
||||
class="btn btn-outline-info"
|
||||
{{ end }}
|
||||
> {{ . }}</a>
|
||||
{{ end }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-9">
|
||||
{{ if eq $context.ActiveSection "" }}
|
||||
<h6 class="p-2">
|
||||
Welcome to the SportStore Administrations Features
|
||||
</h6>
|
||||
{{ else }}
|
||||
{{ handler $context.ActiveSection "GetData" }}
|
||||
{{ end }}
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user