Middle+
Implémenter la méthode grpc-serveur AddItemAndOrder: 1. Ajouter des produits au panier 2. Il est obligatoire d'informer les consommateurs potentiels du fait de la création du panier via le broker de messages. 3. Lors de la modification de la composition du panier, il faut recalculer basket.Total = somme(quantité * prix) 4. Tous les éléments du panier doivent être uniques par la clé ProductID 5. Pour passer la commande, il faut changer son statut en ordered 6. Aucune modification ne doit être apportée aux paniers déjà commandés Il y a une table où toutes les colonnes sont de type entier. Dans le code, il y a une requête: select * from t1 where a > ? and b = ? and c != ? order by a;
sobes.tech IA
Réponse de l'IA
Ниже пример реализации метода gRPC-сервера AddItemAndOrder на Go, учитывающего все требования:
func (s *Server) AddItemAndOrder(ctx context.Context, req *pb.AddItemAndOrderRequest) (*pb.AddItemAndOrderResponse, error) {
basketID := req.GetBasketId()
newItems := req.GetItems() // список товаров для добавления
// Получаем корзину из БД
basket, err := s.store.GetBasket(ctx, basketID)
if err != nil {
return nil, err
}
if basket.Status == "ordered" {
return nil, status.Errorf(codes.FailedPrecondition, "Нельзя изменять оформленную корзину")
}
// Создаем карту для уникальности по ProductID
itemsMap := make(map[int32]*pb.Item)
for _, item := range basket.Items {
itemsMap[item.ProductId] = item
}
// Добавляем/обновляем товары
for _, newItem := range newItems {
itemsMap[newItem.ProductId] = newItem
}
// Пересчитываем total
var total int32 = 0
var updatedItems []*pb.Item
for _, item := range itemsMap {
total += item.Count * item.Price
updatedItems = append(updatedItems, item)
}
// Обновляем корзину
basket.Items = updatedItems
basket.Total = total
// Если в запросе есть флаг оформления, меняем статус
if req.GetOrder() {
basket.Status = "ordered"
}
// Сохраняем изменения
err = s.store.UpdateBasket(ctx, basket)
if err != nil {
return nil, err
}
// Если корзина оформлена, публикуем событие в брокер сообщений
if basket.Status == "ordered" {
err = s.messageBroker.Publish("basket_ordered", basket)
if err != nil {
return nil, err
}
}
return &pb.AddItemAndOrderResponse{Basket: basket}, nil
}
В этом примере:
- Все товары уникальны по ProductID благодаря карте
itemsMap. - При изменении состава корзины пересчитывается
Total. - Статус меняется на
orderedпри оформлении. - Изменения в оформленную корзину запрещены.
- После оформления публикуется событие в брокер сообщений.
По поводу SQL-запроса:
select * from t1 where a > ? and b = ? and c != ? order by a;
Это пример параметризованного запроса, где ? — плейсхолдеры для значений. Такой подход помогает избежать SQL-инъекций и улучшает читаемость кода.