Refactor: Remove deprecated gRPC service files and implement new API structure

- Deleted old gRPC service definitions in `game_grpc.pb.go` and `public.go`.
- Added new API server implementations for objectstory, player, and shop services.
- Introduced configuration files for new APIs in `etc/*.yaml`.
- Created main entry points for each service in `objectstory.go`, `player.go`, and `shop.go`.
- Removed unused user update handler and user API files.
- Added utility functions for context management and HTTP header parsing.
- Introduced PostgreSQL backup configuration in `backup/postgreSql.yaml`.
This commit is contained in:
wwweww
2026-02-28 18:35:56 +08:00
parent d2f33b4b96
commit 19cc7a778c
349 changed files with 42548 additions and 1453 deletions
+19
View File
@@ -0,0 +1,19 @@
Name: order-api
Host: 0.0.0.0
Port: 8888
Prometheus:
Host: 0.0.0.0
Port: 4001
Path: /metrics
# k8s://juwan/<service name>:8080
OrderRpcConf:
Target: k8s://juwan/order-rpc-svc:8080
PlayerRpcConf:
Target: k8s://juwan/player-rpc-svc:8080
ShopRpcConf:
Target: k8s://juwan/shop-rpc-svc:8080
+16
View File
@@ -0,0 +1,16 @@
// Code scaffolded by goctl. Safe to edit.
// goctl 1.9.2
package config
import (
"github.com/zeromicro/go-zero/rest"
"github.com/zeromicro/go-zero/zrpc"
)
type Config struct {
rest.RestConf
OrderRpcConf zrpc.RpcClientConf
PlayerRpcConf zrpc.RpcClientConf
ShopRpcConf zrpc.RpcClientConf
}
@@ -0,0 +1,32 @@
// Code scaffolded by goctl. Safe to edit.
// goctl 1.9.2
package order
import (
"net/http"
"github.com/zeromicro/go-zero/rest/httpx"
"juwan-backend/app/order/api/internal/logic/order"
"juwan-backend/app/order/api/internal/svc"
"juwan-backend/app/order/api/internal/types"
)
// 接单
func AcceptOrderHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.PathId
if err := httpx.Parse(r, &req); err != nil {
httpx.ErrorCtx(r.Context(), w, err)
return
}
l := order.NewAcceptOrderLogic(r.Context(), svcCtx)
resp, err := l.AcceptOrder(&req)
if err != nil {
httpx.ErrorCtx(r.Context(), w, err)
} else {
httpx.OkJsonCtx(r.Context(), w, resp)
}
}
}
@@ -0,0 +1,32 @@
// Code scaffolded by goctl. Safe to edit.
// goctl 1.9.2
package order
import (
"net/http"
"github.com/zeromicro/go-zero/rest/httpx"
"juwan-backend/app/order/api/internal/logic/order"
"juwan-backend/app/order/api/internal/svc"
"juwan-backend/app/order/api/internal/types"
)
// 取消订单
func CancelOrderHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.PathId
if err := httpx.Parse(r, &req); err != nil {
httpx.ErrorCtx(r.Context(), w, err)
return
}
l := order.NewCancelOrderLogic(r.Context(), svcCtx)
resp, err := l.CancelOrder(&req)
if err != nil {
httpx.ErrorCtx(r.Context(), w, err)
} else {
httpx.OkJsonCtx(r.Context(), w, resp)
}
}
}
@@ -0,0 +1,32 @@
// Code scaffolded by goctl. Safe to edit.
// goctl 1.9.2
package order
import (
"net/http"
"github.com/zeromicro/go-zero/rest/httpx"
"juwan-backend/app/order/api/internal/logic/order"
"juwan-backend/app/order/api/internal/svc"
"juwan-backend/app/order/api/internal/types"
)
// 确认结算
func ConfirmCloseOrderHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.PathId
if err := httpx.Parse(r, &req); err != nil {
httpx.ErrorCtx(r.Context(), w, err)
return
}
l := order.NewConfirmCloseOrderLogic(r.Context(), svcCtx)
resp, err := l.ConfirmCloseOrder(&req)
if err != nil {
httpx.ErrorCtx(r.Context(), w, err)
} else {
httpx.OkJsonCtx(r.Context(), w, resp)
}
}
}
@@ -0,0 +1,32 @@
// Code scaffolded by goctl. Safe to edit.
// goctl 1.9.2
package order
import (
"net/http"
"github.com/zeromicro/go-zero/rest/httpx"
"juwan-backend/app/order/api/internal/logic/order"
"juwan-backend/app/order/api/internal/svc"
"juwan-backend/app/order/api/internal/types"
)
// 创建并支付订单
func CreateAndPayOrderHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.CreateOrderReq
if err := httpx.Parse(r, &req); err != nil {
httpx.ErrorCtx(r.Context(), w, err)
return
}
l := order.NewCreateAndPayOrderLogic(r.Context(), svcCtx)
resp, err := l.CreateAndPayOrder(&req)
if err != nil {
httpx.ErrorCtx(r.Context(), w, err)
} else {
httpx.OkJsonCtx(r.Context(), w, resp)
}
}
}
@@ -0,0 +1,32 @@
// Code scaffolded by goctl. Safe to edit.
// goctl 1.9.2
package order
import (
"net/http"
"github.com/zeromicro/go-zero/rest/httpx"
"juwan-backend/app/order/api/internal/logic/order"
"juwan-backend/app/order/api/internal/svc"
"juwan-backend/app/order/api/internal/types"
)
// 创建订单
func CreateOrderHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.CreateOrderReq
if err := httpx.Parse(r, &req); err != nil {
httpx.ErrorCtx(r.Context(), w, err)
return
}
l := order.NewCreateOrderLogic(r.Context(), svcCtx)
resp, err := l.CreateOrder(&req)
if err != nil {
httpx.ErrorCtx(r.Context(), w, err)
} else {
httpx.OkJsonCtx(r.Context(), w, resp)
}
}
}
@@ -0,0 +1,32 @@
// Code scaffolded by goctl. Safe to edit.
// goctl 1.9.2
package order
import (
"net/http"
"github.com/zeromicro/go-zero/rest/httpx"
"juwan-backend/app/order/api/internal/logic/order"
"juwan-backend/app/order/api/internal/svc"
"juwan-backend/app/order/api/internal/types"
)
// 获取订单详情
func GetOrderHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.PathId
if err := httpx.Parse(r, &req); err != nil {
httpx.ErrorCtx(r.Context(), w, err)
return
}
l := order.NewGetOrderLogic(r.Context(), svcCtx)
resp, err := l.GetOrder(&req)
if err != nil {
httpx.ErrorCtx(r.Context(), w, err)
} else {
httpx.OkJsonCtx(r.Context(), w, resp)
}
}
}
@@ -0,0 +1,32 @@
// Code scaffolded by goctl. Safe to edit.
// goctl 1.9.2
package order
import (
"net/http"
"github.com/zeromicro/go-zero/rest/httpx"
"juwan-backend/app/order/api/internal/logic/order"
"juwan-backend/app/order/api/internal/svc"
"juwan-backend/app/order/api/internal/types"
)
// 获取订单列表
func ListOrdersHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.OrderListReq
if err := httpx.Parse(r, &req); err != nil {
httpx.ErrorCtx(r.Context(), w, err)
return
}
l := order.NewListOrdersLogic(r.Context(), svcCtx)
resp, err := l.ListOrders(&req)
if err != nil {
httpx.ErrorCtx(r.Context(), w, err)
} else {
httpx.OkJsonCtx(r.Context(), w, resp)
}
}
}
@@ -0,0 +1,32 @@
// Code scaffolded by goctl. Safe to edit.
// goctl 1.9.2
package order
import (
"net/http"
"github.com/zeromicro/go-zero/rest/httpx"
"juwan-backend/app/order/api/internal/logic/order"
"juwan-backend/app/order/api/internal/svc"
"juwan-backend/app/order/api/internal/types"
)
// 支付订单
func PayOrderHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.PathId
if err := httpx.Parse(r, &req); err != nil {
httpx.ErrorCtx(r.Context(), w, err)
return
}
l := order.NewPayOrderLogic(r.Context(), svcCtx)
resp, err := l.PayOrder(&req)
if err != nil {
httpx.ErrorCtx(r.Context(), w, err)
} else {
httpx.OkJsonCtx(r.Context(), w, resp)
}
}
}
@@ -0,0 +1,32 @@
// Code scaffolded by goctl. Safe to edit.
// goctl 1.9.2
package order
import (
"net/http"
"github.com/zeromicro/go-zero/rest/httpx"
"juwan-backend/app/order/api/internal/logic/order"
"juwan-backend/app/order/api/internal/svc"
"juwan-backend/app/order/api/internal/types"
)
// 再来一单
func ReorderHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.PathId
if err := httpx.Parse(r, &req); err != nil {
httpx.ErrorCtx(r.Context(), w, err)
return
}
l := order.NewReorderLogic(r.Context(), svcCtx)
resp, err := l.Reorder(&req)
if err != nil {
httpx.ErrorCtx(r.Context(), w, err)
} else {
httpx.OkJsonCtx(r.Context(), w, resp)
}
}
}
@@ -0,0 +1,32 @@
// Code scaffolded by goctl. Safe to edit.
// goctl 1.9.2
package order
import (
"net/http"
"github.com/zeromicro/go-zero/rest/httpx"
"juwan-backend/app/order/api/internal/logic/order"
"juwan-backend/app/order/api/internal/svc"
"juwan-backend/app/order/api/internal/types"
)
// 申请结算
func RequestCloseOrderHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.PathId
if err := httpx.Parse(r, &req); err != nil {
httpx.ErrorCtx(r.Context(), w, err)
return
}
l := order.NewRequestCloseOrderLogic(r.Context(), svcCtx)
resp, err := l.RequestCloseOrder(&req)
if err != nil {
httpx.ErrorCtx(r.Context(), w, err)
} else {
httpx.OkJsonCtx(r.Context(), w, resp)
}
}
}
+81
View File
@@ -0,0 +1,81 @@
// Code generated by goctl. DO NOT EDIT.
// goctl 1.9.2
package handler
import (
"net/http"
order "juwan-backend/app/order/api/internal/handler/order"
"juwan-backend/app/order/api/internal/svc"
"github.com/zeromicro/go-zero/rest"
)
func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
server.AddRoutes(
[]rest.Route{
{
// 获取订单列表
Method: http.MethodGet,
Path: "/",
Handler: order.ListOrdersHandler(serverCtx),
},
{
// 创建订单
Method: http.MethodPost,
Path: "/",
Handler: order.CreateOrderHandler(serverCtx),
},
{
// 获取订单详情
Method: http.MethodGet,
Path: "/:id",
Handler: order.GetOrderHandler(serverCtx),
},
{
// 接单
Method: http.MethodPost,
Path: "/:id/accept",
Handler: order.AcceptOrderHandler(serverCtx),
},
{
// 取消订单
Method: http.MethodPost,
Path: "/:id/cancel",
Handler: order.CancelOrderHandler(serverCtx),
},
{
// 确认结算
Method: http.MethodPost,
Path: "/:id/confirm-close",
Handler: order.ConfirmCloseOrderHandler(serverCtx),
},
{
// 支付订单
Method: http.MethodPost,
Path: "/:id/pay",
Handler: order.PayOrderHandler(serverCtx),
},
{
// 再来一单
Method: http.MethodPost,
Path: "/:id/reorder",
Handler: order.ReorderHandler(serverCtx),
},
{
// 申请结算
Method: http.MethodPost,
Path: "/:id/request-close",
Handler: order.RequestCloseOrderHandler(serverCtx),
},
{
// 创建并支付订单
Method: http.MethodPost,
Path: "/paid",
Handler: order.CreateAndPayOrderHandler(serverCtx),
},
},
rest.WithPrefix("/api/v1/orders"),
)
}
@@ -0,0 +1,36 @@
// Code scaffolded by goctl. Safe to edit.
// goctl 1.9.2
package order
import (
"context"
"juwan-backend/app/order/api/internal/svc"
"juwan-backend/app/order/api/internal/types"
"github.com/zeromicro/go-zero/core/logx"
)
type AcceptOrderLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
// 接单
func NewAcceptOrderLogic(ctx context.Context, svcCtx *svc.ServiceContext) *AcceptOrderLogic {
return &AcceptOrderLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *AcceptOrderLogic) AcceptOrder(req *types.PathId) (resp *types.EmptyResp, err error) {
if err = transitionOrderStatus(l.ctx, l.svcCtx, req.Id, "in_progress", true, false, false, false); err != nil {
return nil, err
}
return &types.EmptyResp{}, nil
}
@@ -0,0 +1,36 @@
// Code scaffolded by goctl. Safe to edit.
// goctl 1.9.2
package order
import (
"context"
"juwan-backend/app/order/api/internal/svc"
"juwan-backend/app/order/api/internal/types"
"github.com/zeromicro/go-zero/core/logx"
)
type CancelOrderLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
// 取消订单
func NewCancelOrderLogic(ctx context.Context, svcCtx *svc.ServiceContext) *CancelOrderLogic {
return &CancelOrderLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *CancelOrderLogic) CancelOrder(req *types.PathId) (resp *types.EmptyResp, err error) {
if err = transitionOrderStatus(l.ctx, l.svcCtx, req.Id, "cancelled", false, false, false, true); err != nil {
return nil, err
}
return &types.EmptyResp{}, nil
}
@@ -0,0 +1,36 @@
// Code scaffolded by goctl. Safe to edit.
// goctl 1.9.2
package order
import (
"context"
"juwan-backend/app/order/api/internal/svc"
"juwan-backend/app/order/api/internal/types"
"github.com/zeromicro/go-zero/core/logx"
)
type ConfirmCloseOrderLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
// 确认结算
func NewConfirmCloseOrderLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ConfirmCloseOrderLogic {
return &ConfirmCloseOrderLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *ConfirmCloseOrderLogic) ConfirmCloseOrder(req *types.PathId) (resp *types.EmptyResp, err error) {
if err = transitionOrderStatus(l.ctx, l.svcCtx, req.Id, "completed", false, true, true, false); err != nil {
return nil, err
}
return &types.EmptyResp{}, nil
}
@@ -0,0 +1,48 @@
// Code scaffolded by goctl. Safe to edit.
// goctl 1.9.2
package order
import (
"context"
"juwan-backend/app/order/rpc/orderservice"
"juwan-backend/app/order/api/internal/svc"
"juwan-backend/app/order/api/internal/types"
"github.com/zeromicro/go-zero/core/logx"
)
type CreateAndPayOrderLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
// 创建并支付订单
func NewCreateAndPayOrderLogic(ctx context.Context, svcCtx *svc.ServiceContext) *CreateAndPayOrderLogic {
return &CreateAndPayOrderLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *CreateAndPayOrderLogic) CreateAndPayOrder(req *types.CreateOrderReq) (resp *types.CreateOrderResp, err error) {
created, err := NewCreateOrderLogic(l.ctx, l.svcCtx).CreateOrder(req)
if err != nil {
return nil, err
}
if err = transitionOrderStatus(l.ctx, l.svcCtx, created.Order.Id, "pending_accept", false, false, false, false); err != nil {
return nil, err
}
latest, err := l.svcCtx.OrderRpc.GetOrdersById(l.ctx, &orderservice.GetOrdersByIdReq{Id: created.Order.Id})
if err != nil {
return nil, err
}
return &types.CreateOrderResp{Ok: true, Order: toAPIOrder(latest.GetOrders())}, nil
}
@@ -0,0 +1,128 @@
// Code scaffolded by goctl. Safe to edit.
// goctl 1.9.2
package order
import (
"context"
"encoding/json"
"errors"
"strconv"
"time"
"juwan-backend/app/order/rpc/orderservice"
"juwan-backend/app/player/rpc/playerservice"
"juwan-backend/common/utils/contextj"
"juwan-backend/app/order/api/internal/svc"
"juwan-backend/app/order/api/internal/types"
"github.com/zeromicro/go-zero/core/logx"
)
type CreateOrderLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
// 创建订单
func NewCreateOrderLogic(ctx context.Context, svcCtx *svc.ServiceContext) *CreateOrderLogic {
return &CreateOrderLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *CreateOrderLogic) CreateOrder(req *types.CreateOrderReq) (resp *types.CreateOrderResp, err error) {
if req.Quantity <= 0 {
return nil, errors.New("quantity must be greater than 0")
}
consumerID, err := contextj.UserIDFrom(l.ctx)
if err != nil {
return nil, err
}
serviceResp, err := l.svcCtx.PlayerRpc.GetPlayerServicesById(l.ctx, &playerservice.GetPlayerServicesByIdReq{Id: req.ServiceId})
if err != nil {
return nil, err
}
service := serviceResp.GetPlayerServices()
if service == nil {
return nil, errors.New("player service not found")
}
if req.PlayerId > 0 && service.GetPlayerId() != req.PlayerId {
return nil, errors.New("service does not belong to player")
}
playerID := service.GetPlayerId()
if req.PlayerId > 0 {
playerID = req.PlayerId
}
price := service.GetPrice()
totalPrice := price * float64(req.Quantity)
totalPriceStr := strconv.FormatFloat(totalPrice, 'f', 2, 64)
serviceSnapshot := types.PlayerService{
Id: req.ServiceId,
PlayerId: playerID,
GameId: service.GetGameId(),
Title: service.GetTitle(),
Description: service.GetDescription(),
Price: price,
Unit: service.GetUnit(),
RankRange: service.GetRankRange(),
Availability: service.GetAvailability(),
}
snapshotBytes, err := json.Marshal(serviceSnapshot)
if err != nil {
return nil, err
}
orderID := time.Now().UnixNano()
consumerName := strconv.FormatInt(consumerID, 10)
playerName := strconv.FormatInt(playerID, 10)
shopName := ""
if req.ShopId > 0 {
shopName = strconv.FormatInt(req.ShopId, 10)
}
now := time.Now().Unix()
status := "pending_payment"
searchText := consumerName + " " + playerName + " " + shopName + " " + req.Note
addReq := &orderservice.AddOrdersReq{
Id: orderID,
ConsumerId: consumerID,
ConsumerName: consumerName,
PlayerId: playerID,
PlayerName: playerName,
ServiceSnapshot: string(snapshotBytes),
Status: &status,
TotalPrice: totalPriceStr,
SearchText: &searchText,
CreatedAt: &now,
UpdatedAt: &now,
}
if req.ShopId > 0 {
addReq.ShopId = &req.ShopId
addReq.ShopName = &shopName
}
if req.Note != "" {
addReq.Note = &req.Note
}
if _, err = l.svcCtx.OrderRpc.AddOrders(l.ctx, addReq); err != nil {
return nil, err
}
created, err := l.svcCtx.OrderRpc.GetOrdersById(l.ctx, &orderservice.GetOrdersByIdReq{Id: orderID})
if err != nil {
return nil, err
}
return &types.CreateOrderResp{Ok: true, Order: toAPIOrder(created.GetOrders())}, nil
}
@@ -0,0 +1,40 @@
// Code scaffolded by goctl. Safe to edit.
// goctl 1.9.2
package order
import (
"context"
"juwan-backend/app/order/rpc/orderservice"
"juwan-backend/app/order/api/internal/svc"
"juwan-backend/app/order/api/internal/types"
"github.com/zeromicro/go-zero/core/logx"
)
type GetOrderLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
// 获取订单详情
func NewGetOrderLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetOrderLogic {
return &GetOrderLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *GetOrderLogic) GetOrder(req *types.PathId) (resp *types.Order, err error) {
out, err := l.svcCtx.OrderRpc.GetOrdersById(l.ctx, &orderservice.GetOrdersByIdReq{Id: req.Id})
if err != nil {
return nil, err
}
order := toAPIOrder(out.GetOrders())
return &order, nil
}
@@ -0,0 +1,114 @@
package order
import (
"context"
"encoding/json"
"strconv"
"time"
"juwan-backend/app/order/api/internal/svc"
"juwan-backend/app/order/api/internal/types"
"juwan-backend/app/order/rpc/orderservice"
"juwan-backend/common/utils/contextj"
)
func int64Ptr(v int64) *int64 {
return &v
}
func stringPtr(v string) *string {
return &v
}
func formatUnix(ts int64) string {
if ts <= 0 {
return ""
}
return time.Unix(ts, 0).UTC().Format(time.RFC3339)
}
func toAPIOrder(in *orderservice.Orders) types.Order {
order := types.Order{}
if in == nil {
return order
}
totalPrice, _ := strconv.ParseFloat(in.GetTotalPrice(), 64)
playerID := strconv.FormatInt(in.GetPlayerId(), 10)
service := types.PlayerService{}
_ = json.Unmarshal([]byte(in.GetServiceSnapshot()), &service)
order = types.Order{
Id: in.GetId(),
ConsumerId: in.GetConsumerId(),
ConsumerName: in.GetConsumerName(),
PlayerId: playerID,
PlayerName: in.GetPlayerName(),
ShopId: in.GetShopId(),
ShopName: in.GetShopName(),
Service: service,
Status: in.GetStatus(),
TotalPrice: totalPrice,
Note: in.GetNote(),
CreatedAt: formatUnix(in.GetCreatedAt()),
AcceptedAt: formatUnix(in.GetAcceptedAt()),
CompletedAt: formatUnix(in.GetCompletedAt()),
}
return order
}
func transitionOrderStatus(ctx context.Context, svcCtx *svc.ServiceContext, orderID int64, toStatus string, setAcceptedAt bool, setClosedAt bool, setCompletedAt bool, setCancelledAt bool) error {
current, err := svcCtx.OrderRpc.GetOrdersById(ctx, &orderservice.GetOrdersByIdReq{Id: orderID})
if err != nil {
return err
}
if current.GetOrders() == nil {
return nil
}
now := time.Now().Unix()
updateReq := &orderservice.UpdateOrdersReq{
Id: orderID,
Status: stringPtr(toStatus),
UpdatedAt: int64Ptr(now),
}
if setAcceptedAt {
updateReq.AcceptedAt = int64Ptr(now)
}
if setClosedAt {
updateReq.ClosedAt = int64Ptr(now)
}
if setCompletedAt {
updateReq.CompletedAt = int64Ptr(now)
}
if setCancelledAt {
updateReq.CancelledAt = int64Ptr(now)
}
if _, err = svcCtx.OrderRpc.UpdateOrders(ctx, updateReq); err != nil {
return err
}
fromStatus := current.Orders.GetStatus()
actorID, _ := contextj.UserIDFrom(ctx)
actorRole := "system"
if actorID > 0 {
actorRole = "user"
}
_, err = svcCtx.OrderRpc.AddOrderStateLogs(ctx, &orderservice.AddOrderStateLogsReq{
Id: time.Now().UnixNano(),
OrderId: orderID,
FromStatus: &fromStatus,
ToStatus: toStatus,
Action: "status_transition",
ActorId: actorID,
ActorRole: actorRole,
CreatedAt: &now,
})
if err != nil {
return err
}
return nil
}
@@ -0,0 +1,114 @@
// Code scaffolded by goctl. Safe to edit.
// goctl 1.9.2
package order
import (
"context"
"strings"
"juwan-backend/app/order/rpc/orderservice"
"juwan-backend/app/shop/rpc/shopservice"
"juwan-backend/common/utils/contextj"
"juwan-backend/app/order/api/internal/svc"
"juwan-backend/app/order/api/internal/types"
"github.com/zeromicro/go-zero/core/logx"
)
type ListOrdersLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
// 获取订单列表
func NewListOrdersLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ListOrdersLogic {
return &ListOrdersLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *ListOrdersLogic) ListOrders(req *types.OrderListReq) (resp *types.OrderListResp, err error) {
searchReq := &orderservice.SearchOrdersReq{
Page: req.Offset,
Limit: req.Limit,
}
if req.Status != "" {
searchReq.Status = &req.Status
}
role := strings.ToLower(req.Role)
if role != "" {
uid, uidErr := contextj.UserIDFrom(l.ctx)
if uidErr != nil {
return nil, uidErr
}
switch role {
case "consumer":
searchReq.ConsumerId = &uid
case "player":
searchReq.PlayerId = &uid
case "owner":
shops, shopErr := l.svcCtx.ShopRpc.SearchShops(l.ctx, &shopservice.SearchShopsReq{
Page: 0,
Limit: 100,
OwnerId: uid,
})
if shopErr != nil {
return nil, shopErr
}
items := make([]types.Order, 0)
for _, shop := range shops.GetShops() {
shopID := shop.GetId()
q := &orderservice.SearchOrdersReq{
Page: req.Offset,
Limit: req.Limit,
ShopId: &shopID,
}
if req.Status != "" {
q.Status = &req.Status
}
out, rpcErr := l.svcCtx.OrderRpc.SearchOrders(l.ctx, q)
if rpcErr != nil {
return nil, rpcErr
}
for _, item := range out.GetOrders() {
items = append(items, toAPIOrder(item))
}
}
return &types.OrderListResp{
Items: items,
Meta: types.PageMeta{
Total: int64(len(items)),
Offset: req.Offset,
Limit: req.Limit,
},
}, nil
}
}
out, err := l.svcCtx.OrderRpc.SearchOrders(l.ctx, searchReq)
if err != nil {
return nil, err
}
items := make([]types.Order, 0, len(out.GetOrders()))
for _, item := range out.GetOrders() {
items = append(items, toAPIOrder(item))
}
return &types.OrderListResp{
Items: items,
Meta: types.PageMeta{
Total: int64(len(items)),
Offset: req.Offset,
Limit: req.Limit,
},
}, nil
}
@@ -0,0 +1,36 @@
// Code scaffolded by goctl. Safe to edit.
// goctl 1.9.2
package order
import (
"context"
"juwan-backend/app/order/api/internal/svc"
"juwan-backend/app/order/api/internal/types"
"github.com/zeromicro/go-zero/core/logx"
)
type PayOrderLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
// 支付订单
func NewPayOrderLogic(ctx context.Context, svcCtx *svc.ServiceContext) *PayOrderLogic {
return &PayOrderLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *PayOrderLogic) PayOrder(req *types.PathId) (resp *types.EmptyResp, err error) {
if err = transitionOrderStatus(l.ctx, l.svcCtx, req.Id, "pending_accept", false, false, false, false); err != nil {
return nil, err
}
return &types.EmptyResp{}, nil
}
@@ -0,0 +1,81 @@
// Code scaffolded by goctl. Safe to edit.
// goctl 1.9.2
package order
import (
"context"
"time"
"juwan-backend/app/order/rpc/orderservice"
"juwan-backend/app/order/api/internal/svc"
"juwan-backend/app/order/api/internal/types"
"github.com/zeromicro/go-zero/core/logx"
)
type ReorderLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
// 再来一单
func NewReorderLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ReorderLogic {
return &ReorderLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *ReorderLogic) Reorder(req *types.PathId) (resp *types.CreateOrderResp, err error) {
oldOrderResp, err := l.svcCtx.OrderRpc.GetOrdersById(l.ctx, &orderservice.GetOrdersByIdReq{Id: req.Id})
if err != nil {
return nil, err
}
oldOrder := oldOrderResp.GetOrders()
if oldOrder == nil {
return nil, nil
}
newID := time.Now().UnixNano()
now := time.Now().Unix()
status := "pending_payment"
searchText := oldOrder.GetSearchText()
addReq := &orderservice.AddOrdersReq{
Id: newID,
ConsumerId: oldOrder.GetConsumerId(),
ConsumerName: oldOrder.GetConsumerName(),
PlayerId: oldOrder.GetPlayerId(),
PlayerName: oldOrder.GetPlayerName(),
ServiceSnapshot: oldOrder.GetServiceSnapshot(),
Status: &status,
TotalPrice: oldOrder.GetTotalPrice(),
SearchText: &searchText,
CreatedAt: &now,
UpdatedAt: &now,
}
if oldOrder.ShopId != nil {
addReq.ShopId = oldOrder.ShopId
}
if oldOrder.ShopName != nil {
addReq.ShopName = oldOrder.ShopName
}
if oldOrder.Note != nil {
addReq.Note = oldOrder.Note
}
if _, err = l.svcCtx.OrderRpc.AddOrders(l.ctx, addReq); err != nil {
return nil, err
}
created, err := l.svcCtx.OrderRpc.GetOrdersById(l.ctx, &orderservice.GetOrdersByIdReq{Id: newID})
if err != nil {
return nil, err
}
return &types.CreateOrderResp{Ok: true, Order: toAPIOrder(created.GetOrders())}, nil
}
@@ -0,0 +1,36 @@
// Code scaffolded by goctl. Safe to edit.
// goctl 1.9.2
package order
import (
"context"
"juwan-backend/app/order/api/internal/svc"
"juwan-backend/app/order/api/internal/types"
"github.com/zeromicro/go-zero/core/logx"
)
type RequestCloseOrderLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
// 申请结算
func NewRequestCloseOrderLogic(ctx context.Context, svcCtx *svc.ServiceContext) *RequestCloseOrderLogic {
return &RequestCloseOrderLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *RequestCloseOrderLogic) RequestCloseOrder(req *types.PathId) (resp *types.EmptyResp, err error) {
if err = transitionOrderStatus(l.ctx, l.svcCtx, req.Id, "pending_close", false, false, false, false); err != nil {
return nil, err
}
return &types.EmptyResp{}, nil
}
@@ -0,0 +1,29 @@
// Code scaffolded by goctl. Safe to edit.
// goctl 1.9.2
package svc
import (
"juwan-backend/app/order/rpc/orderservice"
"juwan-backend/app/player/rpc/playerservice"
"juwan-backend/app/shop/rpc/shopservice"
"juwan-backend/app/order/api/internal/config"
"github.com/zeromicro/go-zero/zrpc"
)
type ServiceContext struct {
Config config.Config
OrderRpc orderservice.OrderService
PlayerRpc playerservice.PlayerService
ShopRpc shopservice.ShopService
}
func NewServiceContext(c config.Config) *ServiceContext {
return &ServiceContext{
Config: c,
OrderRpc: orderservice.NewOrderService(zrpc.MustNewClient(c.OrderRpcConf)),
PlayerRpc: playerservice.NewPlayerService(zrpc.MustNewClient(c.PlayerRpcConf)),
ShopRpc: shopservice.NewShopService(zrpc.MustNewClient(c.ShopRpcConf)),
}
}
+95
View File
@@ -0,0 +1,95 @@
// Code generated by goctl. DO NOT EDIT.
// goctl 1.9.2
package types
type CreateOrderReq struct {
PlayerId int64 `json:"playerId"`
ShopId int64 `json:"shopId,optional"`
ServiceId int64 `json:"serviceId"`
Quantity int `json:"quantity"`
Note string `json:"note,optional"`
}
type CreateOrderResp struct {
Ok bool `json:"ok"`
Order Order `json:"order"`
}
type EmptyResp struct {
}
type Order struct {
Id int64 `json:"id"`
ConsumerId int64 `json:"consumerId"`
ConsumerName string `json:"consumerName"`
PlayerId string `json:"playerId"`
PlayerName string `json:"playerName"`
ShopId int64 `json:"shopId,optional"`
ShopName string `json:"shopName,optional"`
Service PlayerService `json:"service"`
Status string `json:"status"`
TotalPrice float64 `json:"totalPrice"`
Note string `json:"note,optional"`
CreatedAt string `json:"createdAt"`
AcceptedAt string `json:"acceptedAt,optional"`
CompletedAt string `json:"completedAt,optional"`
}
type OrderListReq struct {
PageReq
Role string `form:"role"`
Status string `form:"status,optional"`
}
type OrderListResp struct {
Items []Order `json:"items"`
Meta PageMeta `json:"meta"`
}
type PageMeta struct {
Total int64 `json:"total"`
Offset int64 `json:"offset"`
Limit int64 `json:"limit"`
}
type PageReq struct {
Offset int64 `form:"offset,default=0"`
Limit int64 `form:"limit,default=20"`
}
type PathId struct {
Id int64 `path:"id"`
}
type PlayerService struct {
Id int64 `json:"id"`
PlayerId int64 `json:"playerId"`
GameId int64 `json:"gameId"`
GameName string `json:"gameName"`
Title string `json:"title"`
Description string `json:"description"`
Price float64 `json:"price"`
Unit string `json:"unit"`
RankRange string `json:"rankRange,optional"`
Availability []string `json:"availability"`
}
type SimpleUser struct {
Id string `json:"id"`
Nickname string `json:"nickname"`
Avatar string `json:"avatar"`
}
type UserProfile struct {
Id string `json:"id"`
Username string `json:"username"`
Nickname string `json:"nickname"`
Avatar string `json:"avatar"`
Role string `json:"role"` // consumer, player, owner, admin
VerifiedRoles []string `json:"verifiedRoles"`
VerificationStatus map[string]string `json:"verificationStatus"`
Phone string `json:"phone,optional"`
Bio string `json:"bio,optional"`
CreatedAt string `json:"createdAt"`
}
+34
View File
@@ -0,0 +1,34 @@
// Code scaffolded by goctl. Safe to edit.
// goctl 1.9.2
package main
import (
"flag"
"fmt"
"juwan-backend/app/order/api/internal/config"
"juwan-backend/app/order/api/internal/handler"
"juwan-backend/app/order/api/internal/svc"
"github.com/zeromicro/go-zero/core/conf"
"github.com/zeromicro/go-zero/rest"
)
var configFile = flag.String("f", "etc/order-api.yaml", "the config file")
func main() {
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()
}