初始化
This commit is contained in:
@@ -2,6 +2,7 @@ using Microsoft.EntityFrameworkCore;
|
||||
using FutureMailAPI.Data;
|
||||
using FutureMailAPI.Models;
|
||||
using FutureMailAPI.DTOs;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace FutureMailAPI.Services
|
||||
{
|
||||
@@ -382,6 +383,393 @@ namespace FutureMailAPI.Services
|
||||
return ApiResponse<bool>.SuccessResult(true, "邮件已撤销");
|
||||
}
|
||||
|
||||
// 存入胶囊相关方法实现
|
||||
public async Task<ApiResponse<SaveToCapsuleResponseDto>> SaveToCapsuleAsync(int userId, SaveToCapsuleDto saveToCapsuleDto)
|
||||
{
|
||||
// 验证收件人类型
|
||||
if (saveToCapsuleDto.RecipientType == RecipientTypeEnum.SPECIFIC && string.IsNullOrEmpty(saveToCapsuleDto.RecipientEmail))
|
||||
{
|
||||
return ApiResponse<SaveToCapsuleResponseDto>.ErrorResult("指定收件人时,收件人邮箱是必填项");
|
||||
}
|
||||
|
||||
// 验证发送时间
|
||||
if (saveToCapsuleDto.SendTime.HasValue && saveToCapsuleDto.SendTime.Value <= DateTime.UtcNow)
|
||||
{
|
||||
return ApiResponse<SaveToCapsuleResponseDto>.ErrorResult("发送时间必须是未来时间");
|
||||
}
|
||||
|
||||
// 创建邮件
|
||||
var mail = new SentMail
|
||||
{
|
||||
Title = saveToCapsuleDto.Title,
|
||||
Content = saveToCapsuleDto.Content,
|
||||
SenderId = userId,
|
||||
RecipientType = (int)saveToCapsuleDto.RecipientType,
|
||||
SentAt = DateTime.UtcNow,
|
||||
CreatedAt = DateTime.UtcNow,
|
||||
DeliveryTime = saveToCapsuleDto.SendTime ?? DateTime.UtcNow.AddDays(1), // 默认一天后发送
|
||||
Status = 0, // 草稿状态
|
||||
TriggerType = (int)saveToCapsuleDto.TriggerType,
|
||||
TriggerDetails = saveToCapsuleDto.TriggerCondition != null ? JsonSerializer.Serialize(saveToCapsuleDto.TriggerCondition) : null,
|
||||
Attachments = saveToCapsuleDto.Attachments != null ? JsonSerializer.Serialize(saveToCapsuleDto.Attachments) : null,
|
||||
IsEncrypted = saveToCapsuleDto.IsEncrypted,
|
||||
Theme = saveToCapsuleDto.CapsuleStyle
|
||||
};
|
||||
|
||||
// 如果是指定收件人,查找收件人ID
|
||||
if (saveToCapsuleDto.RecipientType == RecipientTypeEnum.SPECIFIC && !string.IsNullOrEmpty(saveToCapsuleDto.RecipientEmail))
|
||||
{
|
||||
var recipient = await _context.Users
|
||||
.FirstOrDefaultAsync(u => u.Email == saveToCapsuleDto.RecipientEmail);
|
||||
|
||||
if (recipient == null)
|
||||
{
|
||||
return ApiResponse<SaveToCapsuleResponseDto>.ErrorResult("收件人不存在");
|
||||
}
|
||||
|
||||
mail.RecipientId = recipient.Id;
|
||||
}
|
||||
|
||||
_context.SentMails.Add(mail);
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
// 创建时间胶囊
|
||||
var timeCapsule = new TimeCapsule
|
||||
{
|
||||
UserId = userId,
|
||||
SentMailId = mail.Id,
|
||||
Status = 0, // 草稿状态
|
||||
CreatedAt = DateTime.UtcNow,
|
||||
PositionX = 0.5f, // 默认位置
|
||||
PositionY = 0.5f,
|
||||
PositionZ = 0.5f,
|
||||
Style = saveToCapsuleDto.CapsuleStyle,
|
||||
GlowIntensity = 0.8f // 默认发光强度
|
||||
};
|
||||
|
||||
_context.TimeCapsules.Add(timeCapsule);
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
var response = new SaveToCapsuleResponseDto
|
||||
{
|
||||
Id = mail.Id,
|
||||
MailId = mail.Id.ToString(),
|
||||
CapsuleId = timeCapsule.Id.ToString(),
|
||||
Status = "DRAFT",
|
||||
CreatedAt = mail.CreatedAt
|
||||
};
|
||||
|
||||
return ApiResponse<SaveToCapsuleResponseDto>.SuccessResult(response, "邮件已存入胶囊");
|
||||
}
|
||||
|
||||
public async Task<ApiResponse<PagedResponse<CapsuleMailListResponseDto>>> GetCapsuleMailsAsync(int userId, MailListQueryDto queryDto)
|
||||
{
|
||||
var query = _context.SentMails
|
||||
.Where(m => m.SenderId == userId && m.Status == 0) // 只查询草稿状态的邮件
|
||||
.Include(m => m.Sender)
|
||||
.Include(m => m.Recipient)
|
||||
.Include(m => m.TimeCapsule)
|
||||
.AsQueryable();
|
||||
|
||||
// 应用筛选条件
|
||||
if (queryDto.Status.HasValue)
|
||||
{
|
||||
query = query.Where(m => m.Status == queryDto.Status.Value);
|
||||
}
|
||||
|
||||
if (queryDto.RecipientType.HasValue)
|
||||
{
|
||||
query = query.Where(m => m.RecipientType == queryDto.RecipientType.Value);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(queryDto.Keyword))
|
||||
{
|
||||
query = query.Where(m => m.Title.Contains(queryDto.Keyword) || m.Content.Contains(queryDto.Keyword));
|
||||
}
|
||||
|
||||
if (queryDto.StartDate.HasValue)
|
||||
{
|
||||
query = query.Where(m => m.SentAt >= queryDto.StartDate.Value);
|
||||
}
|
||||
|
||||
if (queryDto.EndDate.HasValue)
|
||||
{
|
||||
query = query.Where(m => m.SentAt <= queryDto.EndDate.Value);
|
||||
}
|
||||
|
||||
// 排序
|
||||
query = query.OrderByDescending(m => m.SentAt);
|
||||
|
||||
// 分页
|
||||
var totalCount = await query.CountAsync();
|
||||
var mails = await query
|
||||
.Skip((queryDto.PageIndex - 1) * queryDto.PageSize)
|
||||
.Take(queryDto.PageSize)
|
||||
.ToListAsync();
|
||||
|
||||
var mailDtos = mails.Select(MapToCapsuleMailListResponseDto).ToList();
|
||||
|
||||
var pagedResponse = new PagedResponse<CapsuleMailListResponseDto>(
|
||||
mailDtos, queryDto.PageIndex, queryDto.PageSize, totalCount);
|
||||
|
||||
return ApiResponse<PagedResponse<CapsuleMailListResponseDto>>.SuccessResult(pagedResponse);
|
||||
}
|
||||
|
||||
public async Task<ApiResponse<CapsuleMailDetailResponseDto>> GetCapsuleMailByIdAsync(int userId, int mailId)
|
||||
{
|
||||
var mail = await _context.SentMails
|
||||
.Include(m => m.Sender)
|
||||
.Include(m => m.Recipient)
|
||||
.Include(m => m.TimeCapsule)
|
||||
.FirstOrDefaultAsync(m => m.Id == mailId && m.SenderId == userId);
|
||||
|
||||
if (mail == null)
|
||||
{
|
||||
return ApiResponse<CapsuleMailDetailResponseDto>.ErrorResult("邮件不存在");
|
||||
}
|
||||
|
||||
var mailDto = MapToCapsuleMailDetailResponseDto(mail);
|
||||
|
||||
return ApiResponse<CapsuleMailDetailResponseDto>.SuccessResult(mailDto);
|
||||
}
|
||||
|
||||
public async Task<ApiResponse<CapsuleMailDetailResponseDto>> UpdateCapsuleMailAsync(int userId, int mailId, UpdateCapsuleMailDto updateDto)
|
||||
{
|
||||
var mail = await _context.SentMails
|
||||
.Include(m => m.Sender)
|
||||
.Include(m => m.Recipient)
|
||||
.Include(m => m.TimeCapsule)
|
||||
.FirstOrDefaultAsync(m => m.Id == mailId && m.SenderId == userId);
|
||||
|
||||
if (mail == null)
|
||||
{
|
||||
return ApiResponse<CapsuleMailDetailResponseDto>.ErrorResult("邮件不存在");
|
||||
}
|
||||
|
||||
// 检查邮件状态,只有草稿状态的邮件才能编辑
|
||||
if (mail.Status != 0)
|
||||
{
|
||||
return ApiResponse<CapsuleMailDetailResponseDto>.ErrorResult("只有草稿状态的邮件才能编辑");
|
||||
}
|
||||
|
||||
// 更新邮件信息
|
||||
if (!string.IsNullOrEmpty(updateDto.Title))
|
||||
{
|
||||
mail.Title = updateDto.Title;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(updateDto.Content))
|
||||
{
|
||||
mail.Content = updateDto.Content;
|
||||
}
|
||||
|
||||
if (updateDto.RecipientType.HasValue)
|
||||
{
|
||||
mail.RecipientType = (int)updateDto.RecipientType.Value;
|
||||
|
||||
// 如果是指定收件人,查找收件人ID
|
||||
if (updateDto.RecipientType.Value == RecipientTypeEnum.SPECIFIC && !string.IsNullOrEmpty(updateDto.RecipientEmail))
|
||||
{
|
||||
var recipient = await _context.Users
|
||||
.FirstOrDefaultAsync(u => u.Email == updateDto.RecipientEmail);
|
||||
|
||||
if (recipient == null)
|
||||
{
|
||||
return ApiResponse<CapsuleMailDetailResponseDto>.ErrorResult("收件人不存在");
|
||||
}
|
||||
|
||||
mail.RecipientId = recipient.Id;
|
||||
}
|
||||
}
|
||||
|
||||
if (updateDto.SendTime.HasValue)
|
||||
{
|
||||
if (updateDto.SendTime.Value <= DateTime.UtcNow)
|
||||
{
|
||||
return ApiResponse<CapsuleMailDetailResponseDto>.ErrorResult("发送时间必须是未来时间");
|
||||
}
|
||||
|
||||
mail.DeliveryTime = updateDto.SendTime.Value;
|
||||
}
|
||||
|
||||
if (updateDto.TriggerType.HasValue)
|
||||
{
|
||||
mail.TriggerType = (int)updateDto.TriggerType.Value;
|
||||
}
|
||||
|
||||
if (updateDto.TriggerCondition != null)
|
||||
{
|
||||
mail.TriggerDetails = JsonSerializer.Serialize(updateDto.TriggerCondition);
|
||||
}
|
||||
|
||||
if (updateDto.Attachments != null)
|
||||
{
|
||||
mail.Attachments = JsonSerializer.Serialize(updateDto.Attachments);
|
||||
}
|
||||
|
||||
if (updateDto.IsEncrypted.HasValue)
|
||||
{
|
||||
mail.IsEncrypted = updateDto.IsEncrypted.Value;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(updateDto.CapsuleStyle))
|
||||
{
|
||||
mail.Theme = updateDto.CapsuleStyle;
|
||||
|
||||
// 更新时间胶囊样式
|
||||
if (mail.TimeCapsule != null)
|
||||
{
|
||||
mail.TimeCapsule.Style = updateDto.CapsuleStyle;
|
||||
}
|
||||
}
|
||||
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
var mailResponse = MapToCapsuleMailDetailResponseDto(mail);
|
||||
|
||||
return ApiResponse<CapsuleMailDetailResponseDto>.SuccessResult(mailResponse, "胶囊邮件更新成功");
|
||||
}
|
||||
|
||||
public async Task<ApiResponse<bool>> RevokeCapsuleMailAsync(int userId, int mailId)
|
||||
{
|
||||
var mail = await _context.SentMails
|
||||
.Include(m => m.TimeCapsule)
|
||||
.FirstOrDefaultAsync(m => m.Id == mailId && m.SenderId == userId);
|
||||
|
||||
if (mail == null)
|
||||
{
|
||||
return ApiResponse<bool>.ErrorResult("邮件不存在");
|
||||
}
|
||||
|
||||
// 检查邮件状态,只有草稿或待投递状态的邮件才能撤销
|
||||
if (mail.Status > 1)
|
||||
{
|
||||
return ApiResponse<bool>.ErrorResult("已投递的邮件不能撤销");
|
||||
}
|
||||
|
||||
// 更新邮件状态为已撤销
|
||||
mail.Status = 4; // 4-已撤销
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
// 更新相关的时间胶囊状态
|
||||
if (mail.TimeCapsule != null)
|
||||
{
|
||||
mail.TimeCapsule.Status = 3; // 3-已撤销
|
||||
await _context.SaveChangesAsync();
|
||||
}
|
||||
|
||||
return ApiResponse<bool>.SuccessResult(true, "胶囊邮件已撤销");
|
||||
}
|
||||
|
||||
private static CapsuleMailListResponseDto MapToCapsuleMailListResponseDto(SentMail mail)
|
||||
{
|
||||
return new CapsuleMailListResponseDto
|
||||
{
|
||||
MailId = mail.Id.ToString(),
|
||||
Title = mail.Title,
|
||||
Sender = MapToUserInfoDto(mail.Sender),
|
||||
Recipient = mail.Recipient != null ? MapToUserInfoDto(mail.Recipient) : new UserInfoDto(),
|
||||
SendTime = mail.SentAt,
|
||||
DeliveryTime = mail.DeliveryTime,
|
||||
Status = mail.Status switch
|
||||
{
|
||||
0 => "DRAFT",
|
||||
1 => "PENDING",
|
||||
2 => "DELIVERING",
|
||||
3 => "DELIVERED",
|
||||
_ => "UNKNOWN"
|
||||
},
|
||||
HasAttachments = !string.IsNullOrEmpty(mail.Attachments),
|
||||
IsEncrypted = mail.IsEncrypted,
|
||||
CapsuleStyle = mail.Theme ?? "default",
|
||||
Countdown = mail.Status == 1 ? (int)(mail.DeliveryTime - DateTime.UtcNow).TotalSeconds : null
|
||||
};
|
||||
}
|
||||
|
||||
private static CapsuleMailDetailResponseDto MapToCapsuleMailDetailResponseDto(SentMail mail)
|
||||
{
|
||||
List<AttachmentDto> attachments = new List<AttachmentDto>();
|
||||
|
||||
if (!string.IsNullOrEmpty(mail.Attachments))
|
||||
{
|
||||
try
|
||||
{
|
||||
var attachmentList = JsonSerializer.Deserialize<List<object>>(mail.Attachments);
|
||||
if (attachmentList != null)
|
||||
{
|
||||
attachments = attachmentList.Select(a => new AttachmentDto
|
||||
{
|
||||
Id = Guid.NewGuid().ToString(),
|
||||
Type = "IMAGE", // 默认类型,实际应根据数据解析
|
||||
Url = a.ToString() ?? "",
|
||||
Size = 0 // 默认大小,实际应根据数据解析
|
||||
}).ToList();
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// 解析失败时忽略附件
|
||||
}
|
||||
}
|
||||
|
||||
object? triggerCondition = null;
|
||||
if (!string.IsNullOrEmpty(mail.TriggerDetails))
|
||||
{
|
||||
try
|
||||
{
|
||||
triggerCondition = JsonSerializer.Deserialize<object>(mail.TriggerDetails);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// 解析失败时忽略触发条件
|
||||
}
|
||||
}
|
||||
|
||||
return new CapsuleMailDetailResponseDto
|
||||
{
|
||||
MailId = mail.Id.ToString(),
|
||||
Title = mail.Title,
|
||||
Content = mail.Content,
|
||||
Sender = MapToUserInfoDto(mail.Sender),
|
||||
Recipient = mail.Recipient != null ? MapToUserInfoDto(mail.Recipient) : new UserInfoDto(),
|
||||
SendTime = mail.SentAt,
|
||||
CreatedAt = mail.CreatedAt,
|
||||
DeliveryTime = mail.DeliveryTime,
|
||||
Status = mail.Status switch
|
||||
{
|
||||
0 => "DRAFT",
|
||||
1 => "PENDING",
|
||||
2 => "DELIVERING",
|
||||
3 => "DELIVERED",
|
||||
_ => "UNKNOWN"
|
||||
},
|
||||
TriggerType = mail.TriggerType switch
|
||||
{
|
||||
0 => "TIME",
|
||||
1 => "LOCATION",
|
||||
2 => "EVENT",
|
||||
_ => "UNKNOWN"
|
||||
},
|
||||
TriggerCondition = triggerCondition,
|
||||
Attachments = attachments,
|
||||
IsEncrypted = mail.IsEncrypted,
|
||||
CapsuleStyle = mail.Theme ?? "default",
|
||||
CanEdit = mail.Status == 0, // 只有草稿状态可编辑
|
||||
CanRevoke = mail.Status <= 1 // 草稿或待投递状态可撤销
|
||||
};
|
||||
}
|
||||
|
||||
private static UserInfoDto MapToUserInfoDto(User user)
|
||||
{
|
||||
return new UserInfoDto
|
||||
{
|
||||
UserId = user.Id,
|
||||
Username = user.Username,
|
||||
Avatar = user.Avatar ?? "",
|
||||
Email = user.Email
|
||||
};
|
||||
}
|
||||
|
||||
private async Task<SentMailResponseDto> GetSentMailWithDetailsAsync(int mailId)
|
||||
{
|
||||
var mail = await _context.SentMails
|
||||
@@ -471,5 +859,70 @@ namespace FutureMailAPI.Services
|
||||
_ => "未知"
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发送至未来 - 将草稿状态的邮件设置为在未来特定时间自动发送
|
||||
/// </summary>
|
||||
/// <param name="userId">用户ID</param>
|
||||
/// <param name="sendToFutureDto">发送至未来请求DTO</param>
|
||||
/// <returns>发送至未来响应DTO</returns>
|
||||
public async Task<ApiResponse<SendToFutureResponseDto>> SendToFutureAsync(int userId, SendToFutureDto sendToFutureDto)
|
||||
{
|
||||
// 检查投递时间是否在未来
|
||||
if (sendToFutureDto.DeliveryTime <= DateTime.UtcNow)
|
||||
{
|
||||
return ApiResponse<SendToFutureResponseDto>.ErrorResult("投递时间必须是未来时间");
|
||||
}
|
||||
|
||||
// 查找邮件
|
||||
var mail = await _context.SentMails
|
||||
.Include(m => m.Sender)
|
||||
.FirstOrDefaultAsync(m => m.Id == sendToFutureDto.MailId && m.SenderId == userId);
|
||||
|
||||
if (mail == null)
|
||||
{
|
||||
return ApiResponse<SendToFutureResponseDto>.ErrorResult("邮件不存在");
|
||||
}
|
||||
|
||||
// 检查邮件是否为草稿状态
|
||||
if (mail.Status != 0)
|
||||
{
|
||||
return ApiResponse<SendToFutureResponseDto>.ErrorResult("只有草稿状态的邮件可以设置为发送至未来");
|
||||
}
|
||||
|
||||
// 更新邮件状态和投递时间
|
||||
mail.DeliveryTime = sendToFutureDto.DeliveryTime;
|
||||
mail.Status = 1; // 设置为已发送(待投递)状态
|
||||
mail.SentAt = DateTime.UtcNow; // 设置发送时间为当前时间
|
||||
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
// 创建时间胶囊
|
||||
var timeCapsule = new TimeCapsule
|
||||
{
|
||||
UserId = userId,
|
||||
SentMailId = mail.Id,
|
||||
PositionX = 0,
|
||||
PositionY = 0,
|
||||
PositionZ = 0,
|
||||
Status = 1, // 漂浮中
|
||||
Type = 0 // 普通
|
||||
};
|
||||
|
||||
_context.TimeCapsules.Add(timeCapsule);
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
// 构建响应
|
||||
var response = new SendToFutureResponseDto
|
||||
{
|
||||
MailId = mail.Id,
|
||||
Title = mail.Title,
|
||||
DeliveryTime = mail.DeliveryTime,
|
||||
Status = GetStatusText(mail.Status),
|
||||
SentAt = mail.SentAt
|
||||
};
|
||||
|
||||
return ApiResponse<SendToFutureResponseDto>.SuccessResult(response, "邮件已设置为发送至未来");
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user