Add API for AI Agent
This commit is contained in:
@@ -0,0 +1,93 @@
|
||||
from typing import Optional
|
||||
from ninja import Router, Schema
|
||||
from django.db.models import Count
|
||||
from django.shortcuts import get_object_or_404
|
||||
from .models import Category, Product
|
||||
|
||||
router = Router()
|
||||
|
||||
class CategoryOut(Schema):
|
||||
id: int
|
||||
name: str
|
||||
product_count: int
|
||||
|
||||
class ImageInfo(Schema):
|
||||
url: str
|
||||
alt: str
|
||||
|
||||
class ProductListOut(Schema):
|
||||
id: int
|
||||
name: str
|
||||
sku: Optional[str] = None
|
||||
briefdesc: str
|
||||
price: float
|
||||
price_with_vat: float
|
||||
stock: int
|
||||
category_id: int
|
||||
category_name: str
|
||||
primary_image: Optional[ImageInfo] = None
|
||||
average_rating: float
|
||||
reviews_count: int
|
||||
|
||||
class ProductDetailOut(ProductListOut):
|
||||
description: str
|
||||
secondary_images: list[ImageInfo]
|
||||
|
||||
|
||||
def _image_info(img, request):
|
||||
if not img:
|
||||
return None
|
||||
return ImageInfo(
|
||||
url=request.build_absolute_uri(img.image.url),
|
||||
alt=img.alt or img.name,
|
||||
)
|
||||
|
||||
def _product_to_list_out(p, request):
|
||||
return ProductListOut(
|
||||
id=p.id,
|
||||
name=p.name,
|
||||
sku=p.sku,
|
||||
briefdesc=p.briefdesc,
|
||||
price=p.price,
|
||||
price_with_vat=p.get_price_with_vat(),
|
||||
stock=p.stock,
|
||||
category_id=p.category_id,
|
||||
category_name=p.category.name,
|
||||
primary_image=_image_info(p.primary_image, request),
|
||||
average_rating=p.get_average_rating(),
|
||||
reviews_count=p.get_reviews_count(),
|
||||
)
|
||||
|
||||
def _product_to_detail_out(p, request):
|
||||
base = _product_to_list_out(p, request)
|
||||
data = base.dict()
|
||||
data["description"] = p.description
|
||||
data["secondary_images"] = [
|
||||
_image_info(img, request) for img in p.secondary_images.all()
|
||||
]
|
||||
return ProductDetailOut(**data)
|
||||
|
||||
|
||||
@router.get("/categorias", response=list[CategoryOut])
|
||||
def listar_categorias(request):
|
||||
qs = Category.objects.annotate(product_count=Count("product"))
|
||||
return [
|
||||
CategoryOut(id=c.id, name=c.name, product_count=c.product_count)
|
||||
for c in qs
|
||||
]
|
||||
|
||||
@router.get("/productos", response=list[ProductListOut])
|
||||
def listar_productos(request, categoria_id: Optional[int] = None):
|
||||
qs = Product.objects.select_related("category", "primary_image")
|
||||
if categoria_id:
|
||||
qs = qs.filter(category_id=categoria_id)
|
||||
return [_product_to_list_out(p, request) for p in qs]
|
||||
|
||||
@router.get("/productos/{product_id}", response=ProductDetailOut)
|
||||
def detalle_producto(request, product_id: int):
|
||||
p = get_object_or_404(
|
||||
Product.objects.select_related("category", "primary_image")
|
||||
.prefetch_related("secondary_images"),
|
||||
id=product_id,
|
||||
)
|
||||
return _product_to_detail_out(p, request)
|
||||
@@ -318,3 +318,23 @@ p.price {
|
||||
overflow-wrap: break-word;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
:root {
|
||||
--chat--color--primary: #513CB0;
|
||||
--chat--color--primary-shade-50: #3f2a8f;
|
||||
--chat--color--primary--shade-100: #361DA7;
|
||||
--chat--color--secondary: #513CB0;
|
||||
--chat--color-secondary-shade-50: #3f2a8f;
|
||||
--chat--color--typing: #513CB0;
|
||||
--chat--color-dark: #101330;
|
||||
--chat--window--border-radius: 12px;
|
||||
--chat--toggle--background: #513CB0;
|
||||
--chat--toggle--hover--background: #3f2a8f;
|
||||
--chat--toggle--active--background: #361DA7;
|
||||
--chat--message--bot--background: #f0f0f0;
|
||||
--chat--message--user--background: #513CB0;
|
||||
--chat--header--background: #513CB0;
|
||||
--chat--input--send--button--color: #513CB0;
|
||||
--chat--input--send--button--color-hover: #3f2a8f;
|
||||
--chat--close--button--color-hover: #FC3F44;
|
||||
}
|
||||
|
||||
@@ -344,5 +344,27 @@
|
||||
});
|
||||
</script>
|
||||
{% endcache %}
|
||||
|
||||
<link href="https://cdn.jsdelivr.net/npm/@n8n/chat/dist/style.css" rel="stylesheet" />
|
||||
<script type="module">
|
||||
import { createChat } from 'https://cdn.jsdelivr.net/npm/@n8n/chat/dist/chat.bundle.es.js';
|
||||
|
||||
createChat({
|
||||
webhookUrl: 'https://n8n.elordenador.org/webhook/0e2cbe42-39d2-4e86-be62-c12542e246d4/chat',
|
||||
initialMessages: [
|
||||
'¡Hola! 👋',
|
||||
'Soy el asistente virtual de Comercialmeria. ¿En qué puedo ayudarte?'
|
||||
],
|
||||
i18n: {
|
||||
en: {
|
||||
title: 'Chat de Soporte',
|
||||
subtitle: 'Estamos aquí para ayudarte 24/7.',
|
||||
footer: '',
|
||||
getStarted: 'Nueva conversación',
|
||||
inputPlaceholder: 'Escribe tu mensaje...',
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user