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
@@ -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
}