feat(image): add permission setting to EditImageDialog

This commit is contained in:
ShiYu
2025-06-12 00:10:07 +08:00
parent 853efaa2fe
commit d4bf9493c1
6 changed files with 50 additions and 23 deletions

View File

@@ -1,4 +1,3 @@
using System.Text.Json.Serialization;
using Foxel.Controllers;
using Foxel.Models;
using Foxel.Models.DataBase;
@@ -8,8 +7,7 @@ using Foxel.Services.Media;
using Foxel.Services.Storage;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using System.Text.Json; // Added for JsonSerializer in GetTelegramFile if it were kept
using Foxel.Services.Configuration; // Added for IConfigService
using Foxel.Services.Configuration;
namespace Foxel.Api;
@@ -17,8 +15,6 @@ namespace Foxel.Api;
[Route("api/picture")]
public class PictureController(IPictureService pictureService, IStorageService storageService, ILogger<PictureController> logger, IConfigService configuration) : BaseApiController
{
private readonly ILogger<PictureController> _logger = logger;
[HttpGet("get_pictures")]
public async Task<ActionResult<PaginatedResult<PictureResponse>>> GetPictures(
[FromQuery] FilteredPicturesRequest request)
@@ -203,8 +199,8 @@ public class PictureController(IPictureService pictureService, IStorageService s
if (currentUserId == null)
return Error<PictureResponse>("无法识别用户信息");
var (picture, ownerId) = await pictureService.UpdatePictureAsync(
request.Id, request.Name, request.Description, request.Tags);
(PictureResponse picture, int? ownerId) = await pictureService.UpdatePictureAsync(
request.Id, request.Name, request.Description, request.Tags, (PermissionType?)request.Permission);
// 权限验证
if (ownerId.HasValue && ownerId.Value != currentUserId.Value)
@@ -281,7 +277,7 @@ public class PictureController(IPictureService pictureService, IStorageService s
var picture = await pictureService.GetPictureByIdAsync(pictureId);
if (picture == null)
{
_logger.LogWarning("GetPictureFile: Picture with ID {PictureId} not found.", pictureId);
logger.LogWarning("GetPictureFile: Picture with ID {PictureId} not found.", pictureId);
return NotFound("Picture not found.");
}
var currentUserId = GetUserIdFromCookie();
@@ -289,7 +285,7 @@ public class PictureController(IPictureService pictureService, IStorageService s
{
if (currentUserId == null || picture.UserId != currentUserId.Value)
{
_logger.LogWarning("GetPictureFile: User {UserId} forbidden to access picture {PictureId}.", currentUserId, pictureId);
logger.LogWarning("GetPictureFile: User {UserId} forbidden to access picture {PictureId}.", currentUserId, pictureId);
return Forbid();
}
}
@@ -302,7 +298,7 @@ public class PictureController(IPictureService pictureService, IStorageService s
if (string.IsNullOrEmpty(tempFilePath) || !System.IO.File.Exists(tempFilePath))
{
_logger.LogError("GetPictureFile: Failed to download file or file not found at temp path for picture ID {PictureId}. TempPath: {TempPath}", pictureId, tempFilePath);
logger.LogError("GetPictureFile: Failed to download file or file not found at temp path for picture ID {PictureId}. TempPath: {TempPath}", pictureId, tempFilePath);
return StatusCode(500, "Failed to retrieve file from storage.");
}
// 4. 确定内容类型
@@ -313,27 +309,27 @@ public class PictureController(IPictureService pictureService, IStorageService s
}
catch (KeyNotFoundException knfEx)
{
_logger.LogWarning(knfEx, "GetPictureFile: Resource not found for picture ID {PictureId}.", pictureId);
logger.LogWarning(knfEx, "GetPictureFile: Resource not found for picture ID {PictureId}.", pictureId);
return NotFound($"Resource related to picture ID {pictureId} not found.");
}
catch (FileNotFoundException fnfEx)
{
_logger.LogWarning(fnfEx, "GetPictureFile: File not found in storage for picture ID {PictureId}.", pictureId);
logger.LogWarning(fnfEx, "GetPictureFile: File not found in storage for picture ID {PictureId}.", pictureId);
return NotFound("File not found in storage.");
}
catch (NotImplementedException niEx)
{
_logger.LogError(niEx, "GetPictureFile: DownloadFileAsync not implemented for the storage provider of picture ID {PictureId}.", pictureId);
logger.LogError(niEx, "GetPictureFile: DownloadFileAsync not implemented for the storage provider of picture ID {PictureId}.", pictureId);
return StatusCode(501, "File download is not supported for this storage type.");
}
catch (InvalidOperationException ioEx)
{
_logger.LogError(ioEx, "GetPictureFile: Invalid operation for picture ID {PictureId}.", pictureId);
logger.LogError(ioEx, "GetPictureFile: Invalid operation for picture ID {PictureId}.", pictureId);
return StatusCode(500, $"Error processing file request: {ioEx.Message}");
}
catch (Exception ex)
{
_logger.LogError(ex, "GetPictureFile: Error getting file for picture ID {PictureId}", pictureId);
logger.LogError(ex, "GetPictureFile: Error getting file for picture ID {PictureId}", pictureId);
return StatusCode(500, "An error occurred while retrieving the file.");
}
}

View File

@@ -1,6 +1,13 @@
namespace Foxel.Models.Request.Picture;
using System.Collections.Generic; // Required for List<string>
public record UpdatePictureRequestWithId : UpdatePictureRequest
namespace Foxel.Models.Request.Picture
{
public int Id { get; set; }
public class UpdatePictureRequestWithId
{
public int Id { get; set; }
public string? Name { get; set; }
public string? Description { get; set; }
public List<string>? Tags { get; set; }
public int? Permission { get; set; } // Added Permission property
}
}

View File

@@ -44,7 +44,7 @@ public interface IPictureService
/// <returns>每个图片ID对应的删除结果、可能的错误信息和所有者ID</returns>
Task<Dictionary<int, (bool Success, string? ErrorMessage, int? UserId)>> DeleteMultiplePicturesAsync(
List<int> pictureIds);
/// <summary>
/// 更新图片信息
/// </summary>
@@ -52,12 +52,14 @@ public interface IPictureService
/// <param name="name">新标题(可选)</param>
/// <param name="description">新描述(可选)</param>
/// <param name="tags">新标签(可选)</param>
/// <param name="permission">权限</param>
/// <returns>更新后的图片视图模型和所有者ID</returns>
Task<(PictureResponse Picture, int? UserId)> UpdatePictureAsync(
int pictureId,
string? name = null,
string? description = null,
List<string>? tags = null);
List<string>? tags = null,
PermissionType? permission = null);
/// <summary>
/// 收藏图片

View File

@@ -788,7 +788,8 @@ public class PictureService(
int pictureId,
string? name = null,
string? description = null,
List<string>? tags = null)
List<string>? tags = null,
PermissionType? permission = null)
{
await using var dbContext = await contextFactory.CreateDbContextAsync();
@@ -813,6 +814,11 @@ public class PictureService(
picture.Description = description.Trim();
}
if (permission.HasValue)
{
picture.Permission = permission.Value;
}
// 只有当名称或描述发生变化时才更新嵌入向量
if (!string.IsNullOrWhiteSpace(name) || !string.IsNullOrWhiteSpace(description))
{

View File

@@ -88,6 +88,7 @@ export interface UpdatePictureRequest {
name?: string;
description?: string;
tags?: string[];
permission?: number;
}
// 获取图片列表

View File

@@ -28,7 +28,8 @@ const EditImageDialog: React.FC<EditImageDialogProps> = ({
form.setFieldsValue({
name: image.name,
description: image.description,
tags: image.tags || []
tags: image.tags || [],
permission: image.permission === undefined ? 0 : image.permission // Default to Public if undefined
});
}
}, [visible, image, form]);
@@ -45,7 +46,8 @@ const EditImageDialog: React.FC<EditImageDialogProps> = ({
id: image.id,
name: values.name,
description: values.description,
tags: values.tags
tags: values.tags,
permission: values.permission
});
if (result.success) {
@@ -165,6 +167,19 @@ const EditImageDialog: React.FC<EditImageDialogProps> = ({
))}
</Select>
</Form.Item>
<Form.Item
name="permission"
label="权限设置"
rules={[{ required: true, message: '请选择权限' }]}
>
<Select placeholder="选择权限">
<Option value={0}></Option>
<Option value={1}></Option>
<Option value={2}></Option>
</Select>
</Form.Item>
<Form.Item className="edit-form-actions">
<Button onClick={onClose} style={{ marginRight: 8 }}></Button>
<Button