Commit b28e8fcb authored by AI-甘富林's avatar AI-甘富林

前端代码修复

parent 99f78a49
...@@ -12,6 +12,7 @@ import { ScrollArea } from '@/components/ui/scroll-area'; ...@@ -12,6 +12,7 @@ import { ScrollArea } from '@/components/ui/scroll-area';
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar'; import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar';
import { Loader2, Send, Bot, User, Sparkles, Brain, ChevronDown, ChevronUp } from 'lucide-react'; import { Loader2, Send, Bot, User, Sparkles, Brain, ChevronDown, ChevronUp } from 'lucide-react';
import { supabase } from '@/integrations/supabase/client'; import { supabase } from '@/integrations/supabase/client';
import { generateUUID } from '@/utils/idGenerator';
import { DynamicRenderer, type UISchema, type RenderContext } from '@/ai/genui'; import { DynamicRenderer, type UISchema, type RenderContext } from '@/ai/genui';
import { toast } from 'sonner'; import { toast } from 'sonner';
import { cn } from '@/lib/utils'; import { cn } from '@/lib/utils';
...@@ -111,7 +112,7 @@ export function ServiceGenUIChat({ onAction, className }: ServiceGenUIChatProps) ...@@ -111,7 +112,7 @@ export function ServiceGenUIChat({ onAction, className }: ServiceGenUIChatProps)
if (!messageText.trim() || isLoading) return; if (!messageText.trim() || isLoading) return;
const userMessage: Message = { const userMessage: Message = {
id: crypto.randomUUID(), id: generateUUID(),
role: 'user', role: 'user',
content: messageText, content: messageText,
timestamp: new Date(), timestamp: new Date(),
...@@ -146,7 +147,7 @@ export function ServiceGenUIChat({ onAction, className }: ServiceGenUIChatProps) ...@@ -146,7 +147,7 @@ export function ServiceGenUIChat({ onAction, className }: ServiceGenUIChatProps)
Math.min(80, 50 + Math.random() * 30); Math.min(80, 50 + Math.random() * 30);
const assistantMessage: Message = { const assistantMessage: Message = {
id: data.message_id || crypto.randomUUID(), id: data.message_id || generateUUID(),
role: 'assistant', role: 'assistant',
content: data.answer || '', content: data.answer || '',
ui_schema: data.ui_schema, ui_schema: data.ui_schema,
...@@ -172,7 +173,7 @@ export function ServiceGenUIChat({ onAction, className }: ServiceGenUIChatProps) ...@@ -172,7 +173,7 @@ export function ServiceGenUIChat({ onAction, className }: ServiceGenUIChatProps)
// 添加错误消息 // 添加错误消息
setMessages(prev => [...prev, { setMessages(prev => [...prev, {
id: crypto.randomUUID(), id: generateUUID(),
role: 'assistant', role: 'assistant',
content: '抱歉,处理请求时出现错误,请稍后重试。', content: '抱歉,处理请求时出现错误,请稍后重试。',
timestamp: new Date(), timestamp: new Date(),
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
*/ */
import { useState, useEffect, useCallback, useRef } from "react"; import { useState, useEffect, useCallback, useRef } from "react";
import { generateUUID } from '@/utils/idGenerator';
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input"; import { Input } from "@/components/ui/input";
...@@ -63,7 +64,7 @@ export function ServiceGenUIDashboard({ className }: ServiceGenUIDashboardProps) ...@@ -63,7 +64,7 @@ export function ServiceGenUIDashboard({ className }: ServiceGenUIDashboardProps)
if (!messageText.trim() || isLoading) return; if (!messageText.trim() || isLoading) return;
const userMessage: Message = { const userMessage: Message = {
id: crypto.randomUUID(), id: generateUUID(),
role: 'user', role: 'user',
content: messageText, content: messageText,
timestamp: new Date(), timestamp: new Date(),
...@@ -97,7 +98,7 @@ export function ServiceGenUIDashboard({ className }: ServiceGenUIDashboardProps) ...@@ -97,7 +98,7 @@ export function ServiceGenUIDashboard({ className }: ServiceGenUIDashboardProps)
if (error) throw error; if (error) throw error;
const assistantMessage: Message = { const assistantMessage: Message = {
id: data.message_id || crypto.randomUUID(), id: data.message_id || generateUUID(),
role: 'assistant', role: 'assistant',
content: data.answer || '处理完成', content: data.answer || '处理完成',
ui_schema: data.ui_schema, ui_schema: data.ui_schema,
...@@ -115,7 +116,7 @@ export function ServiceGenUIDashboard({ className }: ServiceGenUIDashboardProps) ...@@ -115,7 +116,7 @@ export function ServiceGenUIDashboard({ className }: ServiceGenUIDashboardProps)
toast.error("请求失败,请重试"); toast.error("请求失败,请重试");
const errorMessage: Message = { const errorMessage: Message = {
id: crypto.randomUUID(), id: generateUUID(),
role: 'assistant', role: 'assistant',
content: '抱歉,处理请求时出现错误,请稍后重试。', content: '抱歉,处理请求时出现错误,请稍后重试。',
timestamp: new Date(), timestamp: new Date(),
......
...@@ -12,6 +12,7 @@ import { ScrollArea } from '@/components/ui/scroll-area'; ...@@ -12,6 +12,7 @@ import { ScrollArea } from '@/components/ui/scroll-area';
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar'; import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar';
import { Loader2, Send, Bot, User, Brain } from 'lucide-react'; import { Loader2, Send, Bot, User, Brain } from 'lucide-react';
import { supabase } from '@/integrations/supabase/client'; import { supabase } from '@/integrations/supabase/client';
import { generateUUID } from '@/utils/idGenerator';
import { DynamicRenderer, type UISchema, type RenderContext } from '@/ai/genui'; import { DynamicRenderer, type UISchema, type RenderContext } from '@/ai/genui';
import { toast } from 'sonner'; import { toast } from 'sonner';
import { cn } from '@/lib/utils'; import { cn } from '@/lib/utils';
...@@ -118,7 +119,7 @@ export function ManagerGenUIChat({ onAction, className }: ManagerGenUIChatProps) ...@@ -118,7 +119,7 @@ export function ManagerGenUIChat({ onAction, className }: ManagerGenUIChatProps)
if (!messageText.trim() || isLoading) return; if (!messageText.trim() || isLoading) return;
const userMessage: Message = { const userMessage: Message = {
id: crypto.randomUUID(), id: generateUUID(),
role: 'user', role: 'user',
content: messageText, content: messageText,
timestamp: new Date(), timestamp: new Date(),
...@@ -155,7 +156,7 @@ export function ManagerGenUIChat({ onAction, className }: ManagerGenUIChatProps) ...@@ -155,7 +156,7 @@ export function ManagerGenUIChat({ onAction, className }: ManagerGenUIChatProps)
Math.min(80, 50 + Math.random() * 30); Math.min(80, 50 + Math.random() * 30);
const assistantMessage: Message = { const assistantMessage: Message = {
id: data.message_id || crypto.randomUUID(), id: data.message_id || generateUUID(),
role: 'assistant', role: 'assistant',
content: data.answer || '好的,让我为您展示相关数据。', content: data.answer || '好的,让我为您展示相关数据。',
ui_schema: data.ui_schema, ui_schema: data.ui_schema,
...@@ -179,7 +180,7 @@ export function ManagerGenUIChat({ onAction, className }: ManagerGenUIChatProps) ...@@ -179,7 +180,7 @@ export function ManagerGenUIChat({ onAction, className }: ManagerGenUIChatProps)
toast.error('发送失败,请重试'); toast.error('发送失败,请重试');
setMessages(prev => [...prev, { setMessages(prev => [...prev, {
id: crypto.randomUUID(), id: generateUUID(),
role: 'assistant', role: 'assistant',
content: '抱歉,处理请求时出现错误,请稍后重试。', content: '抱歉,处理请求时出现错误,请稍后重试。',
timestamp: new Date(), timestamp: new Date(),
......
...@@ -12,6 +12,7 @@ import { ScrollArea } from '@/components/ui/scroll-area'; ...@@ -12,6 +12,7 @@ import { ScrollArea } from '@/components/ui/scroll-area';
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar'; import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar';
import { Loader2, Send, Bot, User, Brain } from 'lucide-react'; import { Loader2, Send, Bot, User, Brain } from 'lucide-react';
import { supabase } from '@/integrations/supabase/client'; import { supabase } from '@/integrations/supabase/client';
import { generateUUID } from '@/utils/idGenerator';
import { DynamicRenderer, type UISchema, type RenderContext } from '@/ai/genui'; import { DynamicRenderer, type UISchema, type RenderContext } from '@/ai/genui';
import { toast } from 'sonner'; import { toast } from 'sonner';
import { cn } from '@/lib/utils'; import { cn } from '@/lib/utils';
...@@ -118,7 +119,7 @@ export function MarketingGenUIChat({ onAction, className }: MarketingGenUIChatPr ...@@ -118,7 +119,7 @@ export function MarketingGenUIChat({ onAction, className }: MarketingGenUIChatPr
if (!messageText.trim() || isLoading) return; if (!messageText.trim() || isLoading) return;
const userMessage: Message = { const userMessage: Message = {
id: crypto.randomUUID(), id: generateUUID(),
role: 'user', role: 'user',
content: messageText, content: messageText,
timestamp: new Date(), timestamp: new Date(),
...@@ -155,7 +156,7 @@ export function MarketingGenUIChat({ onAction, className }: MarketingGenUIChatPr ...@@ -155,7 +156,7 @@ export function MarketingGenUIChat({ onAction, className }: MarketingGenUIChatPr
Math.min(80, 50 + Math.random() * 30); Math.min(80, 50 + Math.random() * 30);
const assistantMessage: Message = { const assistantMessage: Message = {
id: data.message_id || crypto.randomUUID(), id: data.message_id || generateUUID(),
role: 'assistant', role: 'assistant',
content: data.answer || '好的,让我为您展示相关数据。', content: data.answer || '好的,让我为您展示相关数据。',
ui_schema: data.ui_schema, ui_schema: data.ui_schema,
...@@ -179,7 +180,7 @@ export function MarketingGenUIChat({ onAction, className }: MarketingGenUIChatPr ...@@ -179,7 +180,7 @@ export function MarketingGenUIChat({ onAction, className }: MarketingGenUIChatPr
toast.error('发送失败,请重试'); toast.error('发送失败,请重试');
setMessages(prev => [...prev, { setMessages(prev => [...prev, {
id: crypto.randomUUID(), id: generateUUID(),
role: 'assistant', role: 'assistant',
content: '抱歉,处理请求时出现错误,请稍后重试。', content: '抱歉,处理请求时出现错误,请稍后重试。',
timestamp: new Date(), timestamp: new Date(),
......
...@@ -11,6 +11,7 @@ import { ScrollArea } from '@/components/ui/scroll-area'; ...@@ -11,6 +11,7 @@ import { ScrollArea } from '@/components/ui/scroll-area';
import { Avatar, AvatarFallback } from '@/components/ui/avatar'; import { Avatar, AvatarFallback } from '@/components/ui/avatar';
import { Loader2, Send, Bot, User, Sparkles } from 'lucide-react'; import { Loader2, Send, Bot, User, Sparkles } from 'lucide-react';
import { supabase } from '@/integrations/supabase/client'; import { supabase } from '@/integrations/supabase/client';
import { generateUUID } from '@/utils/idGenerator';
import { DynamicRenderer, type UISchema, type RenderContext } from '@/ai/genui'; import { DynamicRenderer, type UISchema, type RenderContext } from '@/ai/genui';
import { toast } from 'sonner'; import { toast } from 'sonner';
import { cn } from '@/lib/utils'; import { cn } from '@/lib/utils';
...@@ -64,7 +65,7 @@ export function ProductGenUIChat({ onAction, className }: ProductGenUIChatProps) ...@@ -64,7 +65,7 @@ export function ProductGenUIChat({ onAction, className }: ProductGenUIChatProps)
if (!messageText.trim()) return; if (!messageText.trim()) return;
const userMessage: Message = { const userMessage: Message = {
id: crypto.randomUUID(), id: generateUUID(),
role: 'user', role: 'user',
content: messageText, content: messageText,
timestamp: new Date(), timestamp: new Date(),
...@@ -95,7 +96,7 @@ export function ProductGenUIChat({ onAction, className }: ProductGenUIChatProps) ...@@ -95,7 +96,7 @@ export function ProductGenUIChat({ onAction, className }: ProductGenUIChatProps)
}); });
const assistantMessage: Message = { const assistantMessage: Message = {
id: data.message_id || crypto.randomUUID(), id: data.message_id || generateUUID(),
role: 'assistant', role: 'assistant',
content: data.answer || '', content: data.answer || '',
ui_schema: data.ui_schema, ui_schema: data.ui_schema,
...@@ -115,7 +116,7 @@ export function ProductGenUIChat({ onAction, className }: ProductGenUIChatProps) ...@@ -115,7 +116,7 @@ export function ProductGenUIChat({ onAction, className }: ProductGenUIChatProps)
toast.error('发送失败,请重试'); toast.error('发送失败,请重试');
setMessages(prev => [...prev, { setMessages(prev => [...prev, {
id: crypto.randomUUID(), id: generateUUID(),
role: 'assistant', role: 'assistant',
content: '抱歉,处理请求时出现错误,请稍后重试。', content: '抱歉,处理请求时出现错误,请稍后重试。',
timestamp: new Date(), timestamp: new Date(),
......
...@@ -306,6 +306,7 @@ export default function ShopPage() { ...@@ -306,6 +306,7 @@ export default function ShopPage() {
// AI response handler // AI response handler
const simulateAIResponse = useCallback(async (userMessage: string) => { const simulateAIResponse = useCallback(async (userMessage: string) => {
setIsAiTyping(true); setIsAiTyping(true);
console.log('🔍 [Shop AI] simulateAIResponse start — products in state:', products.length, 'user:', user?.id || 'anonymous');
const streamMsgId = `ai_${Date.now()}`; const streamMsgId = `ai_${Date.now()}`;
// 先插入一个占位消息,后续流式更新 // 先插入一个占位消息,后续流式更新
...@@ -326,12 +327,10 @@ export default function ShopPage() { ...@@ -326,12 +327,10 @@ export default function ShopPage() {
let currentProducts = products; let currentProducts = products;
if (currentProducts.length === 0) { if (currentProducts.length === 0) {
currentProducts = await fetchProducts(); currentProducts = await fetchProducts();
console.log('🔍 [Shop AI] fetchProducts retry returned:', currentProducts.length, 'products');
} }
if (currentProducts.length === 0) { // 商品目录可以为空,AI Edge Function 使用 service_role 自行查询数据库
throw new Error('产品数据加载失败');
}
const catalog = currentProducts.map(p => ({ const catalog = currentProducts.map(p => ({
id: p.id, id: p.id,
name: p.name, name: p.name,
...@@ -343,15 +342,16 @@ export default function ShopPage() { ...@@ -343,15 +342,16 @@ export default function ShopPage() {
// ─── 流式接收 AI 回复文字 ─── // ─── 流式接收 AI 回复文字 ───
let fullContent = ''; let fullContent = '';
console.log('🔍 [Shop AI] About to call callCozeEdge — catalog size:', catalog.length);
const { data: intentCard } = await callCozeEdge({ const { data: intentCard } = await callCozeEdge({
message: userMessage, message: userMessage,
userId: user?.id || 'anonymous', userId: user?.id || 'anonymous',
product: { product: currentProducts.length > 0 ? {
id: currentProducts[0].id, id: currentProducts[0].id,
title: currentProducts[0].name, title: currentProducts[0].name,
description: currentProducts[0].description || '', description: currentProducts[0].description || '',
price: Number(currentProducts[0].price) price: Number(currentProducts[0].price)
}, } : undefined,
catalog, catalog,
onText: (text: string) => { onText: (text: string) => {
fullContent += text; fullContent += text;
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
*/ */
import { supabase } from '@/integrations/supabase/client'; import { supabase } from '@/integrations/supabase/client';
import { generateUUID } from '@/utils/idGenerator';
const SUPABASE_URL = import.meta.env.VITE_SUPABASE_URL; const SUPABASE_URL = import.meta.env.VITE_SUPABASE_URL;
const SUPABASE_ANON_KEY = import.meta.env.VITE_SUPABASE_PUBLISHABLE_KEY; const SUPABASE_ANON_KEY = import.meta.env.VITE_SUPABASE_PUBLISHABLE_KEY;
...@@ -99,7 +100,7 @@ export async function callCozeEdge( ...@@ -99,7 +100,7 @@ export async function callCozeEdge(
status: number; status: number;
error?: string; error?: string;
}> { }> {
const traceId = crypto.randomUUID(); const traceId = generateUUID();
const requestBody = { const requestBody = {
message: options.message, message: options.message,
...@@ -119,6 +120,9 @@ export async function callCozeEdge( ...@@ -119,6 +120,9 @@ export async function callCozeEdge(
const { data: { session } } = await supabase.auth.getSession(); const { data: { session } } = await supabase.auth.getSession();
console.log('🔍 [CHAT CLIENT] Fetching:', `${SUPABASE_URL}/functions/v1/dify-chat-stream`);
console.log('🔍 [CHAT CLIENT] Auth mode:', session?.access_token ? 'session token' : 'anon key');
// 单次调用 + 超时保护(65秒) // 单次调用 + 超时保护(65秒)
const invokePromise = fetch(`${SUPABASE_URL}/functions/v1/dify-chat-stream`, { const invokePromise = fetch(`${SUPABASE_URL}/functions/v1/dify-chat-stream`, {
method: 'POST', method: 'POST',
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
*/ */
import { supabase } from '@/integrations/supabase/client'; import { supabase } from '@/integrations/supabase/client';
import { generateUUID } from '@/utils/idGenerator';
interface CozeStreamOptions { interface CozeStreamOptions {
message: string; message: string;
...@@ -59,7 +60,7 @@ export async function streamCozeChat( ...@@ -59,7 +60,7 @@ export async function streamCozeChat(
options: CozeStreamOptions, options: CozeStreamOptions,
callbacks: CozeStreamCallbacks callbacks: CozeStreamCallbacks
): Promise<void> { ): Promise<void> {
const traceId = crypto.randomUUID(); const traceId = generateUUID();
// 获取 Supabase session // 获取 Supabase session
const { data: { session } } = await supabase.auth.getSession(); const { data: { session } } = await supabase.auth.getSession();
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
import { supabase } from '@/integrations/supabase/client'; import { supabase } from '@/integrations/supabase/client';
import type { CozeStreamCallbacks } from '@/utils/cozeStreamClient'; import type { CozeStreamCallbacks } from '@/utils/cozeStreamClient';
import { generateUUID } from '@/utils/idGenerator';
interface DifyStreamOptions { interface DifyStreamOptions {
message: string; message: string;
...@@ -30,7 +31,7 @@ export async function streamDifyChat( ...@@ -30,7 +31,7 @@ export async function streamDifyChat(
options: DifyStreamOptions, options: DifyStreamOptions,
callbacks: CozeStreamCallbacks callbacks: CozeStreamCallbacks
): Promise<void> { ): Promise<void> {
const traceId = crypto.randomUUID(); const traceId = generateUUID();
const { data: { session } } = await supabase.auth.getSession(); const { data: { session } } = await supabase.auth.getSession();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment