fix: 修复评价争议参与者 ID 映射
This commit is contained in:
@@ -14,3 +14,6 @@ DisputeRpcConf:
|
|||||||
OrderRpcConf:
|
OrderRpcConf:
|
||||||
Endpoints:
|
Endpoints:
|
||||||
- order-rpc:8080
|
- order-rpc:8080
|
||||||
|
PlayerRpcConf:
|
||||||
|
Endpoints:
|
||||||
|
- player-rpc:8080
|
||||||
|
|||||||
@@ -9,4 +9,5 @@ type Config struct {
|
|||||||
rest.RestConf
|
rest.RestConf
|
||||||
DisputeRpcConf zrpc.RpcClientConf
|
DisputeRpcConf zrpc.RpcClientConf
|
||||||
OrderRpcConf zrpc.RpcClientConf
|
OrderRpcConf zrpc.RpcClientConf
|
||||||
|
PlayerRpcConf zrpc.RpcClientConf
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,11 +53,16 @@ func (l *CreateDisputeLogic) CreateDispute(req *types.CreateDisputeReq) (resp *t
|
|||||||
return nil, errors.New("order status does not allow disputes")
|
return nil, errors.New("order status does not allow disputes")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
consumerID, playerUserID, err := orderParticipantUserIDs(l.ctx, l.svcCtx, order)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
var respondentID int64
|
var respondentID int64
|
||||||
if uid == order.GetConsumerId() {
|
if uid == consumerID {
|
||||||
respondentID = order.GetPlayerId()
|
respondentID = playerUserID
|
||||||
} else if uid == order.GetPlayerId() {
|
} else if uid == playerUserID {
|
||||||
respondentID = order.GetConsumerId()
|
respondentID = consumerID
|
||||||
} else {
|
} else {
|
||||||
return nil, errors.New("not a participant of this order")
|
return nil, errors.New("not a participant of this order")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,7 +44,11 @@ func (l *GetOrderDisputeLogic) GetOrderDispute(req *types.DisputePathId) (resp *
|
|||||||
if order == nil {
|
if order == nil {
|
||||||
return nil, errors.New("order not found")
|
return nil, errors.New("order not found")
|
||||||
}
|
}
|
||||||
if uid != order.GetConsumerId() && uid != order.GetPlayerId() {
|
consumerID, playerUserID, err := orderParticipantUserIDs(l.ctx, l.svcCtx, order)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if uid != consumerID && uid != playerUserID {
|
||||||
return nil, errors.New("not a participant of this order")
|
return nil, errors.New("not a participant of this order")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,13 +1,18 @@
|
|||||||
package dispute
|
package dispute
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"juwan-backend/app/dispute/api/internal/svc"
|
||||||
"juwan-backend/app/dispute/api/internal/types"
|
"juwan-backend/app/dispute/api/internal/types"
|
||||||
"juwan-backend/app/dispute/rpc/disputeservice"
|
"juwan-backend/app/dispute/rpc/disputeservice"
|
||||||
|
"juwan-backend/app/order/rpc/orderservice"
|
||||||
|
"juwan-backend/app/player/rpc/playerservice"
|
||||||
)
|
)
|
||||||
|
|
||||||
func formatUnix(ts int64) string {
|
func formatUnix(ts int64) string {
|
||||||
@@ -95,3 +100,18 @@ func detailsJSON(values map[string]any) string {
|
|||||||
}
|
}
|
||||||
return string(b)
|
return string(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func orderParticipantUserIDs(ctx context.Context, svcCtx *svc.ServiceContext, order *orderservice.Orders) (int64, int64, error) {
|
||||||
|
if order == nil {
|
||||||
|
return 0, 0, errors.New("order not found")
|
||||||
|
}
|
||||||
|
playerResp, err := svcCtx.PlayerRpc.GetPlayersById(ctx, &playerservice.GetPlayersByIdReq{Id: order.GetPlayerId()})
|
||||||
|
if err != nil {
|
||||||
|
return 0, 0, err
|
||||||
|
}
|
||||||
|
player := playerResp.GetPlayers()
|
||||||
|
if player == nil || player.GetUserId() <= 0 {
|
||||||
|
return 0, 0, errors.New("player not found")
|
||||||
|
}
|
||||||
|
return order.GetConsumerId(), player.GetUserId(), nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"juwan-backend/app/dispute/api/internal/config"
|
"juwan-backend/app/dispute/api/internal/config"
|
||||||
"juwan-backend/app/dispute/rpc/disputeservice"
|
"juwan-backend/app/dispute/rpc/disputeservice"
|
||||||
"juwan-backend/app/order/rpc/orderservice"
|
"juwan-backend/app/order/rpc/orderservice"
|
||||||
|
"juwan-backend/app/player/rpc/playerservice"
|
||||||
|
|
||||||
"github.com/zeromicro/go-zero/zrpc"
|
"github.com/zeromicro/go-zero/zrpc"
|
||||||
)
|
)
|
||||||
@@ -12,6 +13,7 @@ type ServiceContext struct {
|
|||||||
Config config.Config
|
Config config.Config
|
||||||
DisputeRpc disputeservice.DisputeService
|
DisputeRpc disputeservice.DisputeService
|
||||||
OrderRpc orderservice.OrderService
|
OrderRpc orderservice.OrderService
|
||||||
|
PlayerRpc playerservice.PlayerService
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewServiceContext(c config.Config) *ServiceContext {
|
func NewServiceContext(c config.Config) *ServiceContext {
|
||||||
@@ -19,5 +21,6 @@ func NewServiceContext(c config.Config) *ServiceContext {
|
|||||||
Config: c,
|
Config: c,
|
||||||
DisputeRpc: disputeservice.NewDisputeService(zrpc.MustNewClient(c.DisputeRpcConf)),
|
DisputeRpc: disputeservice.NewDisputeService(zrpc.MustNewClient(c.DisputeRpcConf)),
|
||||||
OrderRpc: orderservice.NewOrderService(zrpc.MustNewClient(c.OrderRpcConf)),
|
OrderRpc: orderservice.NewOrderService(zrpc.MustNewClient(c.OrderRpcConf)),
|
||||||
|
PlayerRpc: playerservice.NewPlayerService(zrpc.MustNewClient(c.PlayerRpcConf)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,3 +14,6 @@ ReviewRpcConf:
|
|||||||
OrderRpcConf:
|
OrderRpcConf:
|
||||||
Endpoints:
|
Endpoints:
|
||||||
- order-rpc:8080
|
- order-rpc:8080
|
||||||
|
PlayerRpcConf:
|
||||||
|
Endpoints:
|
||||||
|
- player-rpc:8080
|
||||||
|
|||||||
@@ -9,4 +9,5 @@ type Config struct {
|
|||||||
rest.RestConf
|
rest.RestConf
|
||||||
ReviewRpcConf zrpc.RpcClientConf
|
ReviewRpcConf zrpc.RpcClientConf
|
||||||
OrderRpcConf zrpc.RpcClientConf
|
OrderRpcConf zrpc.RpcClientConf
|
||||||
|
PlayerRpcConf zrpc.RpcClientConf
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,10 +5,13 @@ package review
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
|
|
||||||
|
"juwan-backend/app/order/rpc/orderservice"
|
||||||
"juwan-backend/app/review/api/internal/svc"
|
"juwan-backend/app/review/api/internal/svc"
|
||||||
"juwan-backend/app/review/api/internal/types"
|
"juwan-backend/app/review/api/internal/types"
|
||||||
reviewpb "juwan-backend/app/review/rpc/pb"
|
reviewpb "juwan-backend/app/review/rpc/pb"
|
||||||
|
"juwan-backend/common/utils/contextj"
|
||||||
|
|
||||||
"github.com/zeromicro/go-zero/core/logx"
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
)
|
)
|
||||||
@@ -29,11 +32,30 @@ func NewGetOrderReviewsLogic(ctx context.Context, svcCtx *svc.ServiceContext) *G
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (l *GetOrderReviewsLogic) GetOrderReviews(req *types.GetOrderReviewsReq) (resp *types.ReviewListResp, err error) {
|
func (l *GetOrderReviewsLogic) GetOrderReviews(req *types.GetOrderReviewsReq) (resp *types.ReviewListResp, err error) {
|
||||||
|
uid, err := contextj.UserIDFrom(l.ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
orderResp, err := l.svcCtx.OrderRpc.GetOrdersById(l.ctx, &orderservice.GetOrdersByIdReq{Id: req.Id})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
order := orderResp.GetOrders()
|
||||||
|
consumerID, playerUserID, err := orderParticipantUserIDs(l.ctx, l.svcCtx, order)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if uid != consumerID && uid != playerUserID {
|
||||||
|
return nil, errors.New("not a participant of this order")
|
||||||
|
}
|
||||||
|
|
||||||
orderId := req.Id
|
orderId := req.Id
|
||||||
|
sealed := false
|
||||||
result, err := l.svcCtx.ReviewRpc.SearchReviews(l.ctx, &reviewpb.SearchReviewsReq{
|
result, err := l.svcCtx.ReviewRpc.SearchReviews(l.ctx, &reviewpb.SearchReviewsReq{
|
||||||
Offset: 0,
|
Offset: 0,
|
||||||
Limit: 10,
|
Limit: 10,
|
||||||
OrderId: &orderId,
|
OrderId: &orderId,
|
||||||
|
Sealed: &sealed,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|||||||
@@ -1,8 +1,13 @@
|
|||||||
package review
|
package review
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"juwan-backend/app/order/rpc/orderservice"
|
||||||
|
"juwan-backend/app/player/rpc/playerservice"
|
||||||
|
"juwan-backend/app/review/api/internal/svc"
|
||||||
"juwan-backend/app/review/api/internal/types"
|
"juwan-backend/app/review/api/internal/types"
|
||||||
reviewpb "juwan-backend/app/review/rpc/pb"
|
reviewpb "juwan-backend/app/review/rpc/pb"
|
||||||
)
|
)
|
||||||
@@ -26,3 +31,18 @@ func toAPIReview(r *reviewpb.Reviews) types.Review {
|
|||||||
CreatedAt: formatUnix(r.GetCreatedAt()),
|
CreatedAt: formatUnix(r.GetCreatedAt()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func orderParticipantUserIDs(ctx context.Context, svcCtx *svc.ServiceContext, order *orderservice.Orders) (int64, int64, error) {
|
||||||
|
if order == nil {
|
||||||
|
return 0, 0, errors.New("order not found")
|
||||||
|
}
|
||||||
|
playerResp, err := svcCtx.PlayerRpc.GetPlayersById(ctx, &playerservice.GetPlayersByIdReq{Id: order.GetPlayerId()})
|
||||||
|
if err != nil {
|
||||||
|
return 0, 0, err
|
||||||
|
}
|
||||||
|
player := playerResp.GetPlayers()
|
||||||
|
if player == nil || player.GetUserId() <= 0 {
|
||||||
|
return 0, 0, errors.New("player not found")
|
||||||
|
}
|
||||||
|
return order.GetConsumerId(), player.GetUserId(), nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -46,13 +46,18 @@ func (l *SubmitReviewLogic) SubmitReview(req *types.SubmitReviewReq) (resp *type
|
|||||||
return nil, errors.New("order is not in pending_review status")
|
return nil, errors.New("order is not in pending_review status")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
consumerID, playerUserID, err := orderParticipantUserIDs(l.ctx, l.svcCtx, order)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
var fromUserId, toUserId int64
|
var fromUserId, toUserId int64
|
||||||
if uid == order.GetConsumerId() {
|
if uid == consumerID {
|
||||||
fromUserId = order.GetConsumerId()
|
fromUserId = consumerID
|
||||||
toUserId = order.GetPlayerId()
|
toUserId = playerUserID
|
||||||
} else if uid == order.GetPlayerId() {
|
} else if uid == playerUserID {
|
||||||
fromUserId = order.GetPlayerId()
|
fromUserId = playerUserID
|
||||||
toUserId = order.GetConsumerId()
|
toUserId = consumerID
|
||||||
} else {
|
} else {
|
||||||
return nil, errors.New("not a participant of this order")
|
return nil, errors.New("not a participant of this order")
|
||||||
}
|
}
|
||||||
@@ -82,22 +87,28 @@ func (l *SubmitReviewLogic) SubmitReview(req *types.SubmitReviewReq) (resp *type
|
|||||||
now := time.Now().Unix()
|
now := time.Now().Unix()
|
||||||
sealed := false
|
sealed := false
|
||||||
for _, r := range existing.GetReviews() {
|
for _, r := range existing.GetReviews() {
|
||||||
_, _ = l.svcCtx.ReviewRpc.UpdateReviews(l.ctx, &reviewpb.UpdateReviewsReq{
|
_, err = l.svcCtx.ReviewRpc.UpdateReviews(l.ctx, &reviewpb.UpdateReviewsReq{
|
||||||
Id: r.GetId(),
|
Id: r.GetId(),
|
||||||
Sealed: &sealed,
|
Sealed: &sealed,
|
||||||
UnsealedAt: &now,
|
UnsealedAt: &now,
|
||||||
})
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
completedStatus := "completed"
|
completedStatus := "completed"
|
||||||
completedAt := now
|
completedAt := now
|
||||||
updatedAt := now
|
updatedAt := now
|
||||||
_, _ = l.svcCtx.OrderRpc.UpdateOrders(l.ctx, &orderservice.UpdateOrdersReq{
|
_, err = l.svcCtx.OrderRpc.UpdateOrders(l.ctx, &orderservice.UpdateOrdersReq{
|
||||||
Id: req.Id,
|
Id: req.Id,
|
||||||
Status: &completedStatus,
|
Status: &completedStatus,
|
||||||
CompletedAt: &completedAt,
|
CompletedAt: &completedAt,
|
||||||
UpdatedAt: &updatedAt,
|
UpdatedAt: &updatedAt,
|
||||||
})
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return &types.EmptyResp{}, nil
|
return &types.EmptyResp{}, nil
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package svc
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"juwan-backend/app/order/rpc/orderservice"
|
"juwan-backend/app/order/rpc/orderservice"
|
||||||
|
"juwan-backend/app/player/rpc/playerservice"
|
||||||
"juwan-backend/app/review/api/internal/config"
|
"juwan-backend/app/review/api/internal/config"
|
||||||
"juwan-backend/app/review/rpc/reviewservice"
|
"juwan-backend/app/review/rpc/reviewservice"
|
||||||
|
|
||||||
@@ -12,6 +13,7 @@ type ServiceContext struct {
|
|||||||
Config config.Config
|
Config config.Config
|
||||||
ReviewRpc reviewservice.ReviewService
|
ReviewRpc reviewservice.ReviewService
|
||||||
OrderRpc orderservice.OrderService
|
OrderRpc orderservice.OrderService
|
||||||
|
PlayerRpc playerservice.PlayerService
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewServiceContext(c config.Config) *ServiceContext {
|
func NewServiceContext(c config.Config) *ServiceContext {
|
||||||
@@ -19,5 +21,6 @@ func NewServiceContext(c config.Config) *ServiceContext {
|
|||||||
Config: c,
|
Config: c,
|
||||||
ReviewRpc: reviewservice.NewReviewService(zrpc.MustNewClient(c.ReviewRpcConf)),
|
ReviewRpc: reviewservice.NewReviewService(zrpc.MustNewClient(c.ReviewRpcConf)),
|
||||||
OrderRpc: orderservice.NewOrderService(zrpc.MustNewClient(c.OrderRpcConf)),
|
OrderRpc: orderservice.NewOrderService(zrpc.MustNewClient(c.OrderRpcConf)),
|
||||||
|
PlayerRpc: playerservice.NewPlayerService(zrpc.MustNewClient(c.PlayerRpcConf)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -954,7 +954,7 @@ def phase8_order(s_consumer: Session, s_actor: Session, player_id, service_id, s
|
|||||||
return order_id
|
return order_id
|
||||||
|
|
||||||
|
|
||||||
def phase8b_review(s_consumer: Session, order_id, player_id):
|
def phase8b_review(s_consumer: Session, order_id, player_user_id):
|
||||||
print("\n=== Phase 8b: Reviews ===")
|
print("\n=== Phase 8b: Reviews ===")
|
||||||
if not order_id:
|
if not order_id:
|
||||||
skip("Review flow", "No pending_review order id")
|
skip("Review flow", "No pending_review order id")
|
||||||
@@ -971,20 +971,26 @@ def phase8b_review(s_consumer: Session, order_id, player_id):
|
|||||||
code, body, _ = s_consumer.get(f"{GATEWAY}/api/v1/orders/{order_id}/reviews")
|
code, body, _ = s_consumer.get(f"{GATEWAY}/api/v1/orders/{order_id}/reviews")
|
||||||
report(f"GET /orders/{order_id}/reviews", code, body)
|
report(f"GET /orders/{order_id}/reviews", code, body)
|
||||||
if code == 200:
|
if code == 200:
|
||||||
|
items = pick_items(body)
|
||||||
report_check(
|
report_check(
|
||||||
f"GET /orders/{order_id}/reviews shape",
|
f"GET /orders/{order_id}/reviews shape",
|
||||||
isinstance(pick_items(body), list) and isinstance(body.get("meta"), dict),
|
isinstance(items, list) and isinstance(body.get("meta"), dict),
|
||||||
|
body,
|
||||||
|
)
|
||||||
|
report_check(
|
||||||
|
f"GET /orders/{order_id}/reviews hides sealed review",
|
||||||
|
len(items) == 0,
|
||||||
body,
|
body,
|
||||||
)
|
)
|
||||||
|
|
||||||
code, body, _ = s_consumer.get(f"{GATEWAY}/api/v1/reviews?limit=20")
|
code, body, _ = s_consumer.get(f"{GATEWAY}/api/v1/reviews?limit=20")
|
||||||
report("GET /reviews?limit=20", code, body)
|
report("GET /reviews?limit=20", code, body)
|
||||||
|
|
||||||
if player_id:
|
if player_user_id:
|
||||||
code, body, _ = s_consumer.get(
|
code, body, _ = s_consumer.get(
|
||||||
f"{GATEWAY}/api/v1/users/{player_id}/reviews?limit=20",
|
f"{GATEWAY}/api/v1/users/{player_user_id}/reviews?limit=20",
|
||||||
)
|
)
|
||||||
report(f"GET /users/{player_id}/reviews?limit=20", code, body)
|
report(f"GET /users/{player_user_id}/reviews?limit=20", code, body)
|
||||||
|
|
||||||
|
|
||||||
def phase8c_dispute(s_consumer: Session, s_actor: Session, player_id, service_id, shop_id):
|
def phase8c_dispute(s_consumer: Session, s_actor: Session, player_id, service_id, shop_id):
|
||||||
@@ -1053,16 +1059,15 @@ def phase8c_dispute(s_consumer: Session, s_actor: Session, player_id, service_id
|
|||||||
code, body, _ = s_actor.post(
|
code, body, _ = s_actor.post(
|
||||||
f"{GATEWAY}/api/v1/disputes/{dispute_id}/response",
|
f"{GATEWAY}/api/v1/disputes/{dispute_id}/response",
|
||||||
json_body={
|
json_body={
|
||||||
"reason": "test respondent guard",
|
"reason": "test respondent response",
|
||||||
"evidence": ["http://example.com/response.jpg"],
|
"evidence": ["http://example.com/response.jpg"],
|
||||||
},
|
},
|
||||||
headers=s_actor.csrf_headers(),
|
headers=s_actor.csrf_headers(),
|
||||||
)
|
)
|
||||||
report(
|
report(
|
||||||
f"POST /disputes/{dispute_id}/response (expect participant check)",
|
f"POST /disputes/{dispute_id}/response",
|
||||||
code,
|
code,
|
||||||
body,
|
body,
|
||||||
expect_status=(400, 403, 500),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
code, body, _ = s_consumer.post(
|
code, body, _ = s_consumer.post(
|
||||||
@@ -1481,7 +1486,7 @@ def main():
|
|||||||
shop_id = phase7_shop(s_user, s_consumer, user_id, invited_player_id)
|
shop_id = phase7_shop(s_user, s_consumer, user_id, invited_player_id)
|
||||||
|
|
||||||
order_id = phase8_order(s_consumer, s_user, player_id, service_id, shop_id)
|
order_id = phase8_order(s_consumer, s_user, player_id, service_id, shop_id)
|
||||||
phase8b_review(s_consumer, order_id, player_id)
|
phase8b_review(s_consumer, order_id, user_id)
|
||||||
phase8c_dispute(s_consumer, s_user, player_id, service_id, shop_id)
|
phase8c_dispute(s_consumer, s_user, player_id, service_id, shop_id)
|
||||||
phase8d_notifications(s_consumer)
|
phase8d_notifications(s_consumer)
|
||||||
phase8e_search_and_favorites(s_consumer, consumer_user_id, player_id, shop_id)
|
phase8e_search_and_favorites(s_consumer, consumer_user_id, player_id, shop_id)
|
||||||
|
|||||||
Reference in New Issue
Block a user