티스토리 뷰

반응형

📌 NestJS + Prisma + Next.js로 만드는 웹 애플리케이션 첫걸음 - 애자일 쇼핑몰 프로젝트 - 주문 내역 및 배송 상태 관리

1. 주문 내역 및 배송 상태 관리 개요

쇼핑몰 애플리케이션에서 주문 내역 조회 및 배송 상태 업데이트 기능은 매우 중요합니다.
사용자는 주문한 상품의 진행 상태를 확인할 수 있어야 하며, 관리자는 배송 상태를 업데이트할 수 있어야 합니다.

주문 관리 기능이 필요한 이유:

  • 사용자는 주문 내역을 조회하고 진행 상태를 확인할 수 있어야 함
  • 관리자는 주문을 처리하고 배송 상태를 업데이트해야 함
  • 배송 상태가 자동으로 갱신되며, 사용자에게 알림을 보낼 수 있어야 함

💡 이 챕터에서는 주문 내역을 조회하고 배송 상태를 관리하는 기능을 구현합니다.


2. 주문 내역 데이터베이스 모델링

2.1. 주문 및 배송 상태 데이터 모델

주문 상태는 pending(주문 완료), processing(처리 중), shipped(배송 중), delivered(배송 완료)로 구분됩니다.

💡 Prisma 주문 모델 추가 (prisma/schema.prisma)

model Order {
  id          Int      @id @default(autoincrement())
  userId      Int
  user        User     @relation(fields: [userId], references: [id])
  totalAmount Int
  status      String   @default("pending") // 주문 상태
  createdAt   DateTime @default(now())
  items       OrderItem[]
}

model OrderItem {
  id        Int      @id @default(autoincrement())
  orderId   Int
  order     Order    @relation(fields: [orderId], references: [id])
  productId Int
  product   Product  @relation(fields: [productId], references: [id])
  quantity  Int
  price     Int
}

이제 주문과 주문 항목(OrderItem) 관계를 설정했습니다.

2.2. 데이터베이스 마이그레이션 실행

npx prisma migrate dev --name add_order_management

데이터베이스 스키마가 업데이트되었습니다.


3. 백엔드(NestJS) - 주문 API 구현

3.1. 주문 생성 API (orders.controller.ts)

💡 사용자가 장바구니 상품을 주문하면 새로운 주문이 생성됩니다.

import { Controller, Post, Get, Body, Param, Patch } from '@nestjs/common';
import { OrdersService } from './orders.service';

@Controller('orders')
export class OrdersController {
  constructor(private readonly ordersService: OrdersService) {}

  @Post()
  async createOrder(@Body() orderData) {
    return this.ordersService.createOrder(orderData);
  }

  @Get(':userId')
  async getUserOrders(@Param('userId') userId: string) {
    return this.ordersService.getUserOrders(+userId);
  }

  @Patch(':orderId')
  async updateOrderStatus(@Param('orderId') orderId: string, @Body() { status }) {
    return this.ordersService.updateOrderStatus(+orderId, status);
  }
}

주문 생성, 사용자 주문 조회, 주문 상태 업데이트 API를 구현했습니다.


3.2. 주문 서비스 (orders.service.ts)

💡 Prisma를 사용하여 주문 데이터를 관리합니다.

import { Injectable } from '@nestjs/common';
import { PrismaService } from '../prisma/prisma.service';

@Injectable()
export class OrdersService {
  constructor(private prisma: PrismaService) {}

  async createOrder(orderData) {
    return this.prisma.order.create({
      data: {
        userId: orderData.userId,
        totalAmount: orderData.totalAmount,
        items: {
          create: orderData.items.map(item => ({
            productId: item.productId,
            quantity: item.quantity,
            price: item.price,
          })),
        },
      },
    });
  }

  async getUserOrders(userId: number) {
    return this.prisma.order.findMany({
      where: { userId },
      include: { items: true },
    });
  }

  async updateOrderStatus(orderId: number, status: string) {
    return this.prisma.order.update({
      where: { id: orderId },
      data: { status },
    });
  }
}

이제 주문을 생성하고 조회하며, 주문 상태를 변경할 수 있습니다.


4. 프론트엔드(Next.js) - 주문 내역 조회 및 관리

4.1. 사용자 주문 내역 조회

💡 사용자는 자신의 주문 내역을 확인할 수 있습니다.

import { useEffect, useState } from 'react';
import { api } from '../utils/api';
import { useAuth } from '../context/AuthContext';

export default function OrdersPage() {
  const { user } = useAuth();
  const [orders, setOrders] = useState([]);

  useEffect(() => {
    if (user) {
      api.get(`/orders/${user.id}`).then((res) => setOrders(res.data));
    }
  }, [user]);

  return (
    <div>
      <h1>주문 내역</h1>
      {orders.map((order) => (
        <div key={order.id}>
          <h2>주문 번호: {order.id}</h2>
          <p>총 금액: {order.totalAmount}원</p>
          <p>주문 상태: {order.status}</p>
        </div>
      ))}
    </div>
  );
}

사용자는 /orders 페이지에서 자신의 주문 내역을 조회할 수 있습니다.


4.2. 관리자 주문 상태 변경 기능

💡 관리자는 주문의 배송 상태를 변경할 수 있습니다.

export default function AdminOrders() {
  const [orders, setOrders] = useState([]);

  useEffect(() => {
    api.get('/orders').then((res) => setOrders(res.data));
  }, []);

  const updateOrderStatus = (orderId, status) => {
    api.patch(`/orders/${orderId}`, { status }).then(() => {
      setOrders(orders.map(order => order.id === orderId ? { ...order, status } : order));
    });
  };

  return (
    <div>
      <h1>관리자 주문 관리</h1>
      {orders.map((order) => (
        <div key={order.id}>
          <h2>주문 번호: {order.id}</h2>
          <p>현재 상태: {order.status}</p>
          <button onClick={() => updateOrderStatus(order.id, 'shipped')}>배송 중</button>
          <button onClick={() => updateOrderStatus(order.id, 'delivered')}>배송 완료</button>
        </div>
      ))}
    </div>
  );
}

관리자는 주문 상태를 shipped, delivered로 변경할 수 있습니다.


5. 주문 상태 변경 알림 기능 추가 (Next.js + WebSocket)

💡 WebSocket을 활용하여 주문 상태 변경 시 사용자에게 실시간 알림을 보낼 수 있습니다.

import { useEffect, useState } from 'react';

export default function OrderNotifications() {
  const [notifications, setNotifications] = useState([]);

  useEffect(() => {
    const ws = new WebSocket('ws://localhost:3000');

    ws.onmessage = (event) => {
      const data = JSON.parse(event.data);
      setNotifications([...notifications, data.message]);
    };

    return () => ws.close();
  }, [notifications]);

  return (
    <div>
      <h2>주문 상태 알림</h2>
      {notifications.map((note, index) => (
        <p key={index}>{note}</p>
      ))}
    </div>
  );
}

이제 주문 상태 변경 시 실시간 알림을 받을 수 있습니다.


🎯 마무리하며

이번 챕터에서는 사용자의 주문 내역 조회 및 주문 상태 관리를 구현하는 방법을 살펴봤습니다.
다음 단계에서는 5.4. 리뷰 및 평점 기능 구현을 다룰 예정입니다. 🚀

 

※ 이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
글 보관함
반응형