diff --git a/app/(admin)/settings/admin-settings-client.tsx b/app/(admin)/settings/admin-settings-client.tsx
index f459f57..12e6909 100644
--- a/app/(admin)/settings/admin-settings-client.tsx
+++ b/app/(admin)/settings/admin-settings-client.tsx
@@ -3550,8 +3550,26 @@ export function AdminSettingsClient() {
placeholder="留空使用默认地址"
disabled={!angleEditConfig.enabled}
/>
-
- 默认: huggingface.co/fal/Qwen-Image-Edit-2511-Multiple-Angles-LoRA
+
+
+ 默认地址(推荐使用,无需修改):
+
+
+ huggingface.co/fal/Qwen-Image-Edit-2511-Multiple-Angles-LoRA/resolve/main/qwen-image-edit-2511-multiple-angles-lora.safetensors
+
+
diff --git a/components/chat.tsx b/components/chat.tsx
index dc7c33a..a162260 100644
--- a/components/chat.tsx
+++ b/components/chat.tsx
@@ -115,6 +115,7 @@ export function Chat({
const [isProcessingEnhance, setIsProcessingEnhance] = useState(false);
const [isProcessingRmbg, setIsProcessingRmbg] = useState(false);
const [isProcessingExtend, setIsProcessingExtend] = useState(false);
+ const [isProcessingAngleEdit, setIsProcessingAngleEdit] = useState(false);
const currentModelIdRef = useRef(currentModelId);
// 🆕 视频参数状态
@@ -951,6 +952,60 @@ export function Chat({
}
};
+ // 处理角度编辑完成
+ const handleImageAngleEdit = async (resultUrl: string) => {
+ const messageId = generateUUID();
+
+ // 构造图片Markdown(使用与其他处理功能相同的格式)
+ const imageMarkdown = ``;
+
+ // 创建最终消息
+ const finalMessage: ChatMessage = {
+ id: messageId,
+ role: "assistant",
+ parts: [{ type: "text", text: imageMarkdown }],
+ metadata: {
+ createdAt: new Date().toISOString(),
+ },
+ } as ChatMessage;
+
+ // 添加消息
+ setMessages((prev) => [...prev, finalMessage]);
+
+ // 滚动到底部
+ setTimeout(() => {
+ const messagesContainer = document.querySelector('[role="log"]');
+ if (messagesContainer) {
+ messagesContainer.scrollTo({
+ top: messagesContainer.scrollHeight,
+ behavior: "smooth",
+ });
+ }
+ }, 100);
+
+ // 保存消息到数据库
+ try {
+ await fetch("/api/messages", {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/json",
+ },
+ body: JSON.stringify({
+ chatId: id,
+ message: {
+ id: messageId,
+ role: "assistant",
+ parts: [{ type: "text", text: imageMarkdown }],
+ attachments: [],
+ createdAt: new Date().toISOString(),
+ },
+ }),
+ });
+ } catch (saveError) {
+ console.error("[Chat] Failed to save angle edit message:", saveError);
+ }
+ };
+
useAutoResume({
autoResume,
initialMessages,
@@ -983,9 +1038,11 @@ export function Chat({
onImageEnhance={handleImageEnhance}
onImageRmbg={handleImageRmbg}
onImageExtend={handleImageExtend}
+ onImageAngleEdit={handleImageAngleEdit}
isProcessingEnhance={isProcessingEnhance}
isProcessingRmbg={isProcessingRmbg}
isProcessingExtend={isProcessingExtend}
+ isProcessingAngleEdit={isProcessingAngleEdit}
pendingGeneration={pendingGeneration}
imageCount={imageParams?.imageCount || 1}
/>
diff --git a/components/elements/response.tsx b/components/elements/response.tsx
index f4a4a7e..d52e5f9 100644
--- a/components/elements/response.tsx
+++ b/components/elements/response.tsx
@@ -12,13 +12,15 @@ type ResponseProps = ComponentProps & {
onImageEnhance?: (imageUrl: string) => void;
onImageRmbg?: (imageUrl: string) => void;
onImageExtend?: (imageUrl: string) => void;
+ onImageAngleEdit?: (imageUrl: string) => void;
isProcessingEnhance?: boolean;
isProcessingRmbg?: boolean;
isProcessingExtend?: boolean;
+ isProcessingAngleEdit?: boolean;
};
export const Response = memo(
- ({ className, onImageEdit, onDrawingComplete, onImageEnhance, onImageRmbg, onImageExtend, isProcessingEnhance, isProcessingRmbg, isProcessingExtend, ...props }: ResponseProps) => (
+ ({ className, onImageEdit, onDrawingComplete, onImageEnhance, onImageRmbg, onImageExtend, onImageAngleEdit, isProcessingEnhance, isProcessingRmbg, isProcessingExtend, isProcessingAngleEdit, ...props }: ResponseProps) => (
*:first-child]:mt-0 [&>*:last-child]:mb-0 [&_code]:whitespace-pre-wrap [&_code]:break-words [&_pre]:max-w-full [&_pre]:overflow-x-auto",
@@ -37,9 +39,11 @@ export const Response = memo(
onImageEnhance={onImageEnhance}
onImageRmbg={onImageRmbg}
onImageExtend={onImageExtend}
+ onImageAngleEdit={onImageAngleEdit}
isProcessingEnhance={isProcessingEnhance}
isProcessingRmbg={isProcessingRmbg}
isProcessingExtend={isProcessingExtend}
+ isProcessingAngleEdit={isProcessingAngleEdit}
/>;
},
video: ({ src, alt }: { src?: string; alt?: string }) => {
@@ -59,9 +63,11 @@ export const Response = memo(
prevProps.onImageEnhance === nextProps.onImageEnhance &&
prevProps.onImageRmbg === nextProps.onImageRmbg &&
prevProps.onImageExtend === nextProps.onImageExtend &&
+ prevProps.onImageAngleEdit === nextProps.onImageAngleEdit &&
prevProps.isProcessingEnhance === nextProps.isProcessingEnhance &&
prevProps.isProcessingRmbg === nextProps.isProcessingRmbg &&
- prevProps.isProcessingExtend === nextProps.isProcessingExtend
+ prevProps.isProcessingExtend === nextProps.isProcessingExtend &&
+ prevProps.isProcessingAngleEdit === nextProps.isProcessingAngleEdit
);
Response.displayName = "Response";
diff --git a/components/message.tsx b/components/message.tsx
index f68866a..75f2f29 100644
--- a/components/message.tsx
+++ b/components/message.tsx
@@ -151,9 +151,11 @@ const PurePreviewMessage = ({
onImageEnhance,
onImageRmbg,
onImageExtend,
+ onImageAngleEdit,
isProcessingEnhance,
isProcessingRmbg,
isProcessingExtend,
+ isProcessingAngleEdit,
}: {
chatId: string;
message: ChatMessage;
@@ -169,9 +171,11 @@ const PurePreviewMessage = ({
onImageEnhance?: (imageUrl: string) => void;
onImageRmbg?: (imageUrl: string) => void;
onImageExtend?: (imageUrl: string) => void;
+ onImageAngleEdit?: (imageUrl: string) => void;
isProcessingEnhance?: boolean;
isProcessingRmbg?: boolean;
isProcessingExtend?: boolean;
+ isProcessingAngleEdit?: boolean;
}) => {
const [mode, setMode] = useState<"view" | "edit">("view");
@@ -305,9 +309,11 @@ const PurePreviewMessage = ({
onImageEnhance={onImageEnhance}
onImageRmbg={onImageRmbg}
onImageExtend={onImageExtend}
+ onImageAngleEdit={onImageAngleEdit}
isProcessingEnhance={isProcessingEnhance}
isProcessingRmbg={isProcessingRmbg}
isProcessingExtend={isProcessingExtend}
+ isProcessingAngleEdit={isProcessingAngleEdit}
>
{sanitizeText(part.content)}
diff --git a/components/messages.tsx b/components/messages.tsx
index fc4bd5c..775a5ab 100644
--- a/components/messages.tsx
+++ b/components/messages.tsx
@@ -40,9 +40,11 @@ type MessagesProps = {
onImageEnhance?: (imageUrl: string) => void;
onImageRmbg?: (imageUrl: string) => void;
onImageExtend?: (imageUrl: string) => void;
+ onImageAngleEdit?: (imageUrl: string) => void;
isProcessingEnhance?: boolean;
isProcessingRmbg?: boolean;
isProcessingExtend?: boolean;
+ isProcessingAngleEdit?: boolean;
pendingGeneration?: PendingGeneration | null; // 🆕 持久化的生成状态
imageCount?: number; // 🆕 用户选择的图片数量
};
@@ -62,9 +64,11 @@ function PureMessages({
onImageEnhance,
onImageRmbg,
onImageExtend,
+ onImageAngleEdit,
isProcessingEnhance = false,
isProcessingRmbg = false,
isProcessingExtend = false,
+ isProcessingAngleEdit = false,
pendingGeneration,
imageCount = 1,
}: MessagesProps) {
@@ -246,9 +250,11 @@ function PureMessages({
onImageEnhance={onImageEnhance}
onImageRmbg={onImageRmbg}
onImageExtend={onImageExtend}
+ onImageAngleEdit={onImageAngleEdit}
isProcessingEnhance={isProcessingEnhance}
isProcessingRmbg={isProcessingRmbg}
isProcessingExtend={isProcessingExtend}
+ isProcessingAngleEdit={isProcessingAngleEdit}
/>
))}
diff --git a/系统性能诊断与解决方案.md b/系统性能诊断与解决方案.md
index 036aec0..16c77ba 100644
--- a/系统性能诊断与解决方案.md
+++ b/系统性能诊断与解决方案.md
@@ -142,3 +142,4 @@ pmset -g
+