diff --git a/apps/index/etc/index-api.dev.yaml b/apps/index/etc/index-api.dev.yaml new file mode 100644 index 0000000..0e489dd --- /dev/null +++ b/apps/index/etc/index-api.dev.yaml @@ -0,0 +1,8 @@ +Name: index-api +Host: 0.0.0.0 +Port: 10004 +SentinelRpc: + Etcd: + Hosts: + - 127.0.0.1:2379 + Key: sentinel.rpc diff --git a/apps/index/etc/index-api.yaml b/apps/index/etc/index-api.yaml new file mode 100644 index 0000000..f8bc966 --- /dev/null +++ b/apps/index/etc/index-api.yaml @@ -0,0 +1,8 @@ +Name: index-api +Host: 0.0.0.0 +Port: 10004 +SentinelRpc: + Etcd: + Hosts: + - tyapi_etcd:2379 + Key: sentinel.rpc diff --git a/apps/index/index.api b/apps/index/index.api new file mode 100644 index 0000000..db2faa7 --- /dev/null +++ b/apps/index/index.api @@ -0,0 +1,42 @@ +syntax = "v1" + +type ( + GetProductByIdReq { + ProductId int64 `path:"productId"` + } + GetProductByIdResp { + ProductItem + } + GetProductListReq { + Page int64 `form:"page"` + PageSize int64 `form:"pageSize"` + } + GetProductListResp { + Total int64 `json:"total"` + List []ProductItem `json:"list"` + } + ProductItem { + ProductId int64 `json:"productId"` + ProductName string `json:"productName"` + ProductCode string `json:"productCode"` + ProductDescription string `json:"productDescription"` + ProductContent string `json:"productContent"` + ProductGroup string `json:"productGroup"` + ProductPrice float64 `json:"productPrice"` + CreatedAt string `json:"createdAt"` + UpdatedAt string `json:"updatedAt"` + } +) + +@server ( + group: product + prefix: /api/index/product +) +service index-api { + @handler getProductById + get /:productId (GetProductByIdReq) returns (GetProductByIdResp) + + @handler getProductList + get /list (GetProductListReq) returns (GetProductListResp) +} + diff --git a/apps/index/index.go b/apps/index/index.go new file mode 100644 index 0000000..5026143 --- /dev/null +++ b/apps/index/index.go @@ -0,0 +1,46 @@ +package main + +import ( + "flag" + "fmt" + "os" + + "tianyuan-api/apps/index/internal/config" + "tianyuan-api/apps/index/internal/handler" + "tianyuan-api/apps/index/internal/svc" + + "github.com/zeromicro/go-zero/core/conf" + "github.com/zeromicro/go-zero/rest" +) + +func main() { + // 读取环境变量 ENV,默认为 "prod" + env := os.Getenv("ENV") + if env == "" { + env = "production" + } + + // 根据 ENV 加载不同的配置文件 + var defaultConfigFile string + if env == "development" { + defaultConfigFile = "etc/index-api.dev.yaml" // 开发环境配置 + } else { + defaultConfigFile = "etc/index-api.yaml" // 生产环境配置 + } + + // 允许通过命令行参数覆盖配置文件路径 + configFile := flag.String("f", defaultConfigFile, "the config file") + flag.Parse() + + var c config.Config + conf.MustLoad(*configFile, &c) + + server := rest.MustNewServer(c.RestConf) + defer server.Stop() + + ctx := svc.NewServiceContext(c) + handler.RegisterHandlers(server, ctx) + + fmt.Printf("Starting server at %s:%d...\n", c.Host, c.Port) + server.Start() +} diff --git a/apps/index/internal/config/config.go b/apps/index/internal/config/config.go new file mode 100644 index 0000000..0d075ea --- /dev/null +++ b/apps/index/internal/config/config.go @@ -0,0 +1,11 @@ +package config + +import ( + "github.com/zeromicro/go-zero/rest" + "github.com/zeromicro/go-zero/zrpc" +) + +type Config struct { + rest.RestConf + SentinelRpc zrpc.RpcClientConf +} diff --git a/apps/index/internal/handler/product/getproductbyidhandler.go b/apps/index/internal/handler/product/getproductbyidhandler.go new file mode 100644 index 0000000..6669449 --- /dev/null +++ b/apps/index/internal/handler/product/getproductbyidhandler.go @@ -0,0 +1,30 @@ +package product + +import ( + "net/http" + + "github.com/zeromicro/go-zero/rest/httpx" + "tianyuan-api/apps/index/internal/logic/product" + "tianyuan-api/apps/index/internal/svc" + "tianyuan-api/apps/index/internal/types" + + xhttp "github.com/zeromicro/x/http" +) + +func GetProductByIdHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + var req types.GetProductByIdReq + if err := httpx.Parse(r, &req); err != nil { + xhttp.JsonBaseResponseCtx(r.Context(), w, err) + return + } + + l := product.NewGetProductByIdLogic(r.Context(), svcCtx) + resp, err := l.GetProductById(&req) + if err != nil { + xhttp.JsonBaseResponseCtx(r.Context(), w, err) + } else { + xhttp.JsonBaseResponseCtx(r.Context(), w, resp) + } + } +} diff --git a/apps/index/internal/handler/product/getproductlisthandler.go b/apps/index/internal/handler/product/getproductlisthandler.go new file mode 100644 index 0000000..946c0eb --- /dev/null +++ b/apps/index/internal/handler/product/getproductlisthandler.go @@ -0,0 +1,30 @@ +package product + +import ( + "net/http" + + "github.com/zeromicro/go-zero/rest/httpx" + "tianyuan-api/apps/index/internal/logic/product" + "tianyuan-api/apps/index/internal/svc" + "tianyuan-api/apps/index/internal/types" + + xhttp "github.com/zeromicro/x/http" +) + +func GetProductListHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + var req types.GetProductListReq + if err := httpx.Parse(r, &req); err != nil { + xhttp.JsonBaseResponseCtx(r.Context(), w, err) + return + } + + l := product.NewGetProductListLogic(r.Context(), svcCtx) + resp, err := l.GetProductList(&req) + if err != nil { + xhttp.JsonBaseResponseCtx(r.Context(), w, err) + } else { + xhttp.JsonBaseResponseCtx(r.Context(), w, resp) + } + } +} diff --git a/apps/index/internal/handler/routes.go b/apps/index/internal/handler/routes.go new file mode 100644 index 0000000..4509853 --- /dev/null +++ b/apps/index/internal/handler/routes.go @@ -0,0 +1,31 @@ +// Code generated by goctl. DO NOT EDIT. +// goctl 1.7.2 + +package handler + +import ( + "net/http" + + product "tianyuan-api/apps/index/internal/handler/product" + "tianyuan-api/apps/index/internal/svc" + + "github.com/zeromicro/go-zero/rest" +) + +func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) { + server.AddRoutes( + []rest.Route{ + { + Method: http.MethodGet, + Path: "/:productId", + Handler: product.GetProductByIdHandler(serverCtx), + }, + { + Method: http.MethodGet, + Path: "/list", + Handler: product.GetProductListHandler(serverCtx), + }, + }, + rest.WithPrefix("/api/index/product"), + ) +} diff --git a/apps/index/internal/logic/product/getproductbyidlogic.go b/apps/index/internal/logic/product/getproductbyidlogic.go new file mode 100644 index 0000000..aa5787e --- /dev/null +++ b/apps/index/internal/logic/product/getproductbyidlogic.go @@ -0,0 +1,46 @@ +package product + +import ( + "context" + "tianyuan-api/apps/sentinel/client/product" + + "tianyuan-api/apps/index/internal/svc" + "tianyuan-api/apps/index/internal/types" + + "github.com/zeromicro/go-zero/core/logx" +) + +type GetProductByIdLogic struct { + logx.Logger + ctx context.Context + svcCtx *svc.ServiceContext +} + +func NewGetProductByIdLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetProductByIdLogic { + return &GetProductByIdLogic{ + Logger: logx.WithContext(ctx), + ctx: ctx, + svcCtx: svcCtx, + } +} + +func (l *GetProductByIdLogic) GetProductById(req *types.GetProductByIdReq) (resp *types.GetProductByIdResp, err error) { + productResp, err := l.svcCtx.ProductRpc.GetProductById(l.ctx, &product.GetRecordByIdRequest{ + Id: req.ProductId, + }) + if err != nil { + return nil, err + } + + return &types.GetProductByIdResp{ + ProductItem: types.ProductItem{ + ProductId: productResp.Id, + ProductName: productResp.ProductName, + ProductCode: productResp.ProductCode, + ProductDescription: productResp.ProductDescription, + ProductContent: productResp.ProductContent, + ProductGroup: productResp.ProductGroup, + ProductPrice: productResp.ProductPrice, + }, + }, nil +} diff --git a/apps/index/internal/logic/product/getproductlistlogic.go b/apps/index/internal/logic/product/getproductlistlogic.go new file mode 100644 index 0000000..fa57a60 --- /dev/null +++ b/apps/index/internal/logic/product/getproductlistlogic.go @@ -0,0 +1,51 @@ +package product + +import ( + "context" + "tianyuan-api/apps/sentinel/client/product" + + "tianyuan-api/apps/index/internal/svc" + "tianyuan-api/apps/index/internal/types" + + "github.com/zeromicro/go-zero/core/logx" +) + +type GetProductListLogic struct { + logx.Logger + ctx context.Context + svcCtx *svc.ServiceContext +} + +func NewGetProductListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetProductListLogic { + return &GetProductListLogic{ + Logger: logx.WithContext(ctx), + ctx: ctx, + svcCtx: svcCtx, + } +} + +func (l *GetProductListLogic) GetProductList(req *types.GetProductListReq) (resp *types.GetProductListResp, err error) { + productList, err := l.svcCtx.ProductRpc.GetProductPageList(l.ctx, &product.PageListRequest{Page: req.Page, PageSize: req.PageSize}) + if err != nil { + return nil, err + } + var list []types.ProductItem + + for _, p := range productList.Products { + list = append(list, types.ProductItem{ + ProductId: p.Id, + ProductName: p.ProductName, + ProductCode: p.ProductCode, + ProductDescription: p.ProductDescription, + ProductPrice: p.ProductPrice, + ProductGroup: p.ProductGroup, + CreatedAt: p.CreatedAt, + UpdatedAt: p.UpdatedAt, + }) + } + resp = &types.GetProductListResp{ + Total: productList.Total, + List: list, + } + return resp, nil +} diff --git a/apps/index/internal/svc/servicecontext.go b/apps/index/internal/svc/servicecontext.go new file mode 100644 index 0000000..70b35ac --- /dev/null +++ b/apps/index/internal/svc/servicecontext.go @@ -0,0 +1,20 @@ +package svc + +import ( + "github.com/zeromicro/go-zero/zrpc" + "tianyuan-api/apps/index/internal/config" + "tianyuan-api/apps/sentinel/sentinel" +) + +type ServiceContext struct { + Config config.Config + ProductRpc sentinel.ProductClient +} + +func NewServiceContext(c config.Config) *ServiceContext { + productRpc := sentinel.NewProductClient(zrpc.MustNewClient(c.SentinelRpc).Conn()) + return &ServiceContext{ + Config: c, + ProductRpc: productRpc, + } +} diff --git a/apps/index/internal/types/types.go b/apps/index/internal/types/types.go new file mode 100644 index 0000000..3652ee3 --- /dev/null +++ b/apps/index/internal/types/types.go @@ -0,0 +1,34 @@ +// Code generated by goctl. DO NOT EDIT. +// goctl 1.7.2 + +package types + +type GetProductByIdReq struct { + ProductId int64 `path:"productId"` +} + +type GetProductByIdResp struct { + ProductItem +} + +type GetProductListReq struct { + Page int64 `form:"page"` + PageSize int64 `form:"pageSize"` +} + +type GetProductListResp struct { + Total int64 `json:"total"` + List []ProductItem `json:"list"` +} + +type ProductItem struct { + ProductId int64 `json:"productId"` + ProductName string `json:"productName"` + ProductCode string `json:"productCode"` + ProductDescription string `json:"productDescription"` + ProductContent string `json:"productContent"` + ProductGroup string `json:"productGroup"` + ProductPrice float64 `json:"productPrice"` + CreatedAt string `json:"createdAt"` + UpdatedAt string `json:"updatedAt"` +}