Sobes.tech
Назад к вопросам
Middle+
4

Реализовать метод grpc-сервера AddItemAndOrder: 1. Добавить товары в корзину 2. Обязательно сообщить возможным потребителям о факте оформления корзины через брокер сообщений. 3. При изменении состава корзины надо пересчитывать basket.Total=sum(count*price) 4. Все элементы корзины должны быть уникальны по ключу ProductID 5. Для оформления корзины необходимо сменить ее статус на ordered 6. В оформленные корзины изменения вносить нельзя Есть таблица, где все колонки integer. В коде есть запрос: select * from t1 where a > ? and b = ? and c != ? order by a;

Компании, где спрашивали
КуперКупер

Ответ от нейросети

sobes.tech AI

Ниже пример реализации метода 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-инъекций и улучшает читаемость кода.