diff --git a/Services/Media/PictureService.cs b/Services/Media/PictureService.cs
index 7119297..dbf541a 100644
--- a/Services/Media/PictureService.cs
+++ b/Services/Media/PictureService.cs
@@ -766,11 +766,31 @@ public class PictureService(
picture.Description = description.Trim();
}
+ // 只有当名称或描述发生变化时才更新嵌入向量
if (!string.IsNullOrWhiteSpace(name) || !string.IsNullOrWhiteSpace(description))
{
- var combinedText = $"{picture.Name}. {picture.Description}";
- var embedding = await embeddingService.GetEmbeddingAsync(combinedText);
- picture.Embedding = new Vector(embedding);
+ try
+ {
+ var combinedText = $"{picture.Name}. {picture.Description}";
+ var embedding = await embeddingService.GetEmbeddingAsync(combinedText);
+
+ // 只有在成功获取到非空嵌入向量时才更新
+ if (embedding != null && embedding.Length > 0)
+ {
+ picture.Embedding = new Vector(embedding);
+ }
+ else
+ {
+ // 记录获取到空向量的警告
+ Console.WriteLine($"警告: 图片 {pictureId} 的嵌入向量为空,跳过向量更新");
+ }
+ }
+ catch (Exception ex)
+ {
+ // 记录错误但不抛出异常,允许其他字段的更新继续进行
+ Console.WriteLine($"更新图片 {pictureId} 的嵌入向量时出错: {ex.Message}");
+ // 不设置 picture.Embedding,保持原值不变
+ }
}
if (tags != null)
diff --git a/Web/src/api/index.ts b/Web/src/api/index.ts
index 3ce6a2c..ce67681 100644
--- a/Web/src/api/index.ts
+++ b/Web/src/api/index.ts
@@ -24,7 +24,8 @@ export {
unfavoritePicture,
getUserFavorites,
uploadPicture,
- deleteMultiplePictures, // 添加导出删除图片函数
+ deleteMultiplePictures,
+ updatePicture,
} from './pictureApi';
// 导出Album API
diff --git a/Web/src/api/pictureApi.ts b/Web/src/api/pictureApi.ts
index 8ae62ed..eb67d83 100644
--- a/Web/src/api/pictureApi.ts
+++ b/Web/src/api/pictureApi.ts
@@ -1,4 +1,4 @@
-import type { PaginatedResult, PictureResponse, FilteredPicturesRequest, BaseResult } from './types';
+import type { PaginatedResult, PictureResponse, FilteredPicturesRequest, BaseResult, UpdatePictureRequest } from './types';
import { fetchApi, BASE_URL } from './fetchClient';
// 获取图片列表
@@ -196,3 +196,11 @@ export async function deleteMultiplePictures(pictureIds: number[]): Promise> {
+ return fetchApi('/picture/update_picture', {
+ method: 'POST',
+ body: JSON.stringify(request),
+ });
+}
+
diff --git a/Web/src/api/types.ts b/Web/src/api/types.ts
index c30a8c1..7d5374a 100644
--- a/Web/src/api/types.ts
+++ b/Web/src/api/types.ts
@@ -220,3 +220,10 @@ export interface UpdateUserRequest {
currentPassword?: string;
newPassword?: string;
}
+
+export interface UpdatePictureRequest {
+ id: number;
+ name?: string;
+ description?: string;
+ tags?: string[];
+}
diff --git a/Web/src/components/image/ImageGrid.tsx b/Web/src/components/image/ImageGrid.tsx
index ba9a3a0..7ef8832 100644
--- a/Web/src/components/image/ImageGrid.tsx
+++ b/Web/src/components/image/ImageGrid.tsx
@@ -8,6 +8,7 @@ import type { PictureResponse } from '../../api';
import { favoritePicture, unfavoritePicture, getPictures, deleteMultiplePictures } from '../../api';
import ImageViewer from './ImageViewer';
import ShareImageDialog from './ShareImageDialog';
+import EditImageDialog from './EditImageDialog';
import './ImageGrid.css';
import { useAuth } from '../../api/AuthContext';
@@ -159,6 +160,15 @@ const ImageGrid: React.FC = ({
y: 0,
});
+ // 添加编辑对话框状态
+ const [editDialogState, setEditDialogState] = useState<{
+ visible: boolean;
+ image: PictureResponse | null;
+ }>({
+ visible: false,
+ image: null
+ });
+
// 简化标志变量
const isUsingExternalData = !!dataSource;
@@ -354,7 +364,33 @@ const ImageGrid: React.FC = ({
});
};
- // 修改handleMenuAction中的分享处理
+ // 处理编辑图片
+ const handleEditImage = (image: PictureResponse) => {
+ setEditDialogState({
+ visible: true,
+ image
+ });
+ };
+
+ // 关闭编辑对话框
+ const handleCloseEditDialog = () => {
+ setEditDialogState({
+ ...editDialogState,
+ visible: false
+ });
+ };
+
+ // 处理图片更新成功
+ const handleImageUpdateSuccess = (updatedImage: PictureResponse) => {
+ // 更新本地图片列表中对应的图片
+ setImages(prevImages =>
+ prevImages.map(img =>
+ img.id === updatedImage.id ? { ...img, ...updatedImage } : img
+ )
+ );
+ };
+
+ // 修改handleMenuAction中的编辑处理
const handleMenuAction = (action: string) => {
if (!contextMenu.image) return;
@@ -366,7 +402,7 @@ const ImageGrid: React.FC = ({
handleDeleteImage(contextMenu.image);
break;
case 'edit':
- onEdit?.(contextMenu.image);
+ handleEditImage(contextMenu.image);
break;
case 'download':
onDownload?.(contextMenu.image);
@@ -497,7 +533,11 @@ const ImageGrid: React.FC = ({
className="custom-card-action-item"
onClick={(e) => {
e.stopPropagation();
- onEdit && onEdit(image);
+ if (onEdit) {
+ onEdit(image);
+ } else {
+ handleEditImage(image);
+ }
}}
>
@@ -686,6 +726,13 @@ const ImageGrid: React.FC = ({
onClose={handleCloseShareDialog}
image={shareDialogState.image}
/>
+
+
>
);
};