개발 일지

elder menu 음성인식 - 메뉴

만식 2024. 6. 3. 19:52

 

  • 오류 1: views.py의 orderbot에서 잘 넘겨준 재주천 메뉴를 화면에 띄우기 위한 과정에서 발생
    • 구체적으로, displayRecommendations()에서의 axios get요청이 잘 넘어가서 response도 받아오는데, 해당 response의 내용은 비어있었음
    • 그래서 orderbot의 get요청에 대해 print문을 찍어보니, 들어온 get요청에 대한 parameter값이 빈 값이었음
    • 하지만 보내는 쪽인 axios에서는 parameter값인 responseText, recommend_menu가 잘 넘어가고 있는 것은 console.log문을 통해 확인함
function displayRecommendations(recommended_menu, responseText) {
    // Log recommended_menu parameter before making the axios request
    console.log("Calling axios.get with parameters:", { params: { recommended_menu: recommended_menu } });

    axios.get('/orders/orderbot/', { params: { recommended_menu: recommended_menu } })
        .then(response => {
            const menuData = response.data.recommends;
            console.log("response>>>>>>>>>>", response);
            console.log("response.data>>>>>", response.data);
            console.log("menuData>>>>>", menuData);
            recommendations.innerHTML = '';
  • 문제해결:
    • 해결 시도(1): axios get요청의 parameter부분이 문제라는 판단 하에 params를 recommended_menu, recommended_menu_string 등으로 고쳐보았으나 결과에는 변함이 없었음(화면, 터미널상, console.log상)
    • 해결 시도(2): 터미널상에 찍히는 request요청 결과에서 차이를 발견함
    → elder_start.html에서부터 넘어올 때의 recommended_menu에 값이 들어있는 형식과 현재 elder_menu.html에서 시작할 때의 recommended_menu값이 달랐음
##elder_start에서 넘어올 때 (aibot)
[31/May/2024 03:08:17] "GET /orders/orderbot/?recommended_menu[]=%EC%95%84%EC%9D%B4%EC%8A%A4+%EC%95%84%EB%A9%94%EB%A6%AC%EC%B9%B4%EB%85%B8&recommended_menu[]=%EC%95%84%EB%A9%94%EB%A6%AC%EC%B9%B4%EB%85%B8&recommended_menu[]=%EC%B9%B4%ED%8E%98%EB%9D%BC%EB%96%BC HTTP/1.1" 200 17
##elder_menu 내에서 처리될 때 (orderbot)
"GET /orders/orderbot/?recommended_menu=[%22%EC%95%84%EC%9D%B4%EC%8A%A4+%EC%95%84%EB%A9%94%EB%A6%AC%EC%B9%B4%EB%85%B8%22,%22%EC%95%84%EB%A9%94%EB%A6%AC%EC%B9%B4%EB%85%B8%22,%22%EC%B9%B4%ED%8E%98%EB%9D%BC%EB%96%BC%22] HTTP/1.1" 200 414

 

cosole.log에서도 아래와 같이 parameter가 다른 형식으로 axios요청이 보내지고 있는 것을 다시 확인할 수 있었다

elder_start에서 넘어올 때 (aibot)
elder_menu 내에서 처리될 때 (orderbot)

그 결과, orderbot으로 처리될 때도 aibot에서와 마찬가지로 axios요청 시의 recommended_menu형식을 동일하게 해 주면 오류가 해결될 것으로 예상함

  axios.get('/orders/orderbot/', { params: { recommended_menu: JSON.stringify(recommended_menu) } })

위와 같이 고쳐주니 오류해결됨!

 

  • 오류2: 이제 axios의 get요청으로 MenuData는 잘 가져와지는데,

popupImage is not defined이라는 오류메시지가 뜸

  • 해결방법: displayRecommendations()내에 popupImage는 잘 선언되어 있어서, 코드에서 popupImage를 다루고 있는 부분을 찾던 중 코드 맨 앞의 조회 부분이 문제일 수 있다고 판단함
    • popupImage를 조회해서 가져오는 부분을 elder_menu.html의 코드 전역에서 접근하여 쓸 수 있도록 document.addEventListener('DOMContentLoaded', function() {} 밖으로 아래 코드들을 빼줌 → 문제 해결!
## 오류메시지에서는 popupImage만 언급되었지만, 혹시 몰라 popup에 관련된 것들은 다 빼줌
const popupOverlay = document.getElementById('popup-overlay');
const popupContainer = document.getElementById('popup-container');
const popupImage = document.getElementById('popup-image');
const popupName = document.getElementById('popup-name');
const popupPrice = document.getElementById('popup-price');
const closePopup = document.getElementById('closePopup');

 

 

배포 - docker를 이용한 postgreSQL 구현

  • docker를 이용한 postgreSQL 구현

→ 구현 중 오류 : app/manage.py를 찾을 수 없음.

→ 해결 : 작성한 코드 중 web부분을 지우고 단계별로 구현

# docker-compose.yml
version: '3'

services:
  db:
    image: postgres
    environment:
      POSTGRES_DB: mydatabase
      POSTGRES_USER: myuser
      POSTGRES_PASSWORD: mypassword
    ports:
      - "5432:5432"


# setting.py
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'mydatabase',
        'USER': 'myuser',
        'PASSWORD': 'mypassword',
        'HOST': 'localhost',
        'PORT': '5432',
    }
}

 

db저장 - 장바구니 데이터 베이스 문제

 

- 장바구니에 담긴 데이터를 데이터 베이스에 저장하는 방식에서 언어가 변경이 된 상태에서 저장을 했을시에 메뉴의 명이 번역이 된 상태로 저장이 되어 버려 메뉴 표기에 문제가 발생

 

selected_items :  [{'name': '冰茶', 'count': 2}, {'name': '热巧克力', 'count': 2}, {'name': '草莓拿铁', 'count': 1}]

 

  • 나중에 주문이 완료된 내역을 확인시에 메뉴가 복잡하게 보일 가능성이 존재하다고 판단
  • 해결방안 : 주문완료 대시보드에 메뉴를 표기하는 방법으로 name을 사용하는 것이 아닌 메뉴의 id 값을 추가하여 조회로 가져올 때에는 id로 조회를 해서 가져올 수 있도록 결정
menu_items = user_menus.filter(food_name=recommend)
            for menu_item in menu_items:
                recommended_list.append({
                    "menu_id": menu_item.id,  # id 값 추가
                    "food_name": menu_item.food_name,
                    "price": menu_item.price,
                    "img_url": menu_item.img.url
                })

 

    # 자바스크립트에도 menuId 추가
    const selectedItemsArray = Object.entries(selectedItems).map(([name, item]) => {
        return {name: name, count: item.count, menuId: item.menuId};  // 선택된 항목 배열로 변환
    });

 

    def post(self, request):
        try:
            # 요청의 본문을 한 번만 읽어서 사용
            user = request.user
            data = request.data
            selected_items = data.get('items', [])
            total_price = data.get('total_price', 0)
            print("selected_items : ", selected_items)
            # 오늘 날짜를 가져옵니다.
            today = datetime.now().date()

            # 오늘 생성된 마지막 주문을 가져옵니다.
            last_order = Order.objects.filter(store=user, created_at__date=today).order_by('-id').first()
            if last_order:
                order_number = last_order.order_number + 1
            else:
                order_number = 1

            # 새 주문을 생성합니다.
            new_order = Order.objects.create(
                order_number=order_number,
                order_menu=selected_items,
                total_price=total_price,
                status="A",
                store=user
            )
            return Response({'order_number': new_order.order_number}, status=201)
        except json.JSONDecodeError:
            return Response({'error': 'Invalid JSON'}, status=400)

id를 추가함으로써 조회시 id로 조회할 수 있도록 함

  • 결과 : 데이터 베이스에 저장이 되는 값에 id가 포함이 됨
selected_items :  [{'name': '冰茶', 'count': 2, 'menuId': 5}, {'name': '热巧克力', 'count': 2, 'menuId': 6}, 
{'name': '草莓拿铁', 'count': 1, 'menuId': 3}, {'name': '拿铁咖啡', 'count': 1, 'menuId': 2}, 
{'name': '橙子汽水', 'count': 1, 'menuId': 4}]

 

🫠 6.03 추가적인 문제 발생

  • 문제점 : id로 조회후 가져오는 방법을 사용 시 조회를 위해서 데이터 베이스 접근이 빈번히 발생하는 문제가 생김
  • 해결방안 : id로 가져오는 것이 아닌 처음부터 한글명을 함께 포함시켜 데이터 베이스에 저장을 하는 방안으로 변경
    def get(request):
        # GET 요청을 처리하는 메소드입니다.
        # 추천 메뉴를 반환합니다.
        user = request.user
        recommended_menu = request.GET.get('recommended_menu', '[]')
        # JSON 문자열을 파싱하여 리스트로 변환
        recommended_menu = json.loads(recommended_menu)
        # 현재 사용자가 작성한 모든 메뉴의 store를 가져옵니다.
        user_menus = Menu.objects.filter(store=user)
        # 추천 메뉴를 가져옵니다.
        recommended_list = []
        for recommend in recommended_menu:
            menus = user_menus.filter(food_name=recommend)
            for menu in menus:
                recommended_list.append({
                    "food_name_ko": getattr(menu, 'food_name_ko', ''),
                    "food_name": menu.food_name,
                    "price": menu.price,
                    "img_url": menu.img.url
                })

        return Response({'recommends': recommended_list})

 

function appendRecommendedMenuItems(container, items) {
    items.forEach(menu => {
        const menuItem = `
            <div class="menu-item card recommended" onclick="addItem('${menu.food_name}', ${menu.price}, '${menu.img_url}', this, '${menu.food_name_ko}')">
                <img src="${menu.img_url}" alt="${menu.food_name}" class="card-img-top">
                <div class="card-body text-center">
                    <h5 class="card-title text-primary">${menu.food_name}</h5>
                    <p class="card-text text-muted">${menu.price}${won}</p>
                </div>
            </div>
        `;
        container.append(menuItem);
    });
}

function addItem(name, price, imgUrl, element, food_name_ko) {
    if (!selectedItems[name]) {
        selectedItems[name] = {price: price, count: 1, imgUrl: imgUrl, food_name_ko: food_name_ko};  // 새로운 항목 추가
    } else {
        selectedItems[name].count += 1;  // 기존 항목의 수량 증가
    }
    updateSelectedItemsList();  // 선택된 항목 목록 업데이트
}

 

결과 : 목록을 한 번만 조회함으로 한글 메뉴를 가져올 수 있는 방안이 보완됨

selected_items :  [{'name': '苺ラテ', 'count': 1, 'food_name_ko': '딸기 라떼'}, {'name': 'ホットチョコレート', 'count': 1, 'food_name_ko': '핫 초코'}, {'name': 'アイスティー', 'count': 1, 'food_name_ko': '아이스 티カフェラテ', 'count': 1, 'food_name_ko': '카페 라떼'}]