193 lines
5.9 KiB
C#
193 lines
5.9 KiB
C#
using HoneyBox.Core.Interfaces;
|
||
using HoneyBox.Model.Data;
|
||
using HoneyBox.Model.Entities;
|
||
using HoneyBox.Model.Models.Vip;
|
||
using Microsoft.EntityFrameworkCore;
|
||
using Microsoft.Extensions.Logging;
|
||
|
||
namespace HoneyBox.Core.Services;
|
||
|
||
/// <summary>
|
||
/// VIP服务实现
|
||
/// </summary>
|
||
public class VipService : IVipService
|
||
{
|
||
private readonly HoneyBoxDbContext _dbContext;
|
||
private readonly ILogger<VipService> _logger;
|
||
|
||
public VipService(HoneyBoxDbContext dbContext, ILogger<VipService> logger)
|
||
{
|
||
_dbContext = dbContext;
|
||
_logger = logger;
|
||
}
|
||
|
||
/// <inheritdoc />
|
||
public async Task<VipInfoResponse> GetVipInfoAsync(int userId)
|
||
{
|
||
// 获取用户信息
|
||
var user = await _dbContext.Users
|
||
.Where(u => u.Id == userId)
|
||
.Select(u => new { u.Id, u.Nickname, u.HeadImg, u.Vip })
|
||
.FirstOrDefaultAsync();
|
||
|
||
if (user == null)
|
||
{
|
||
throw new InvalidOperationException("用户不存在");
|
||
}
|
||
|
||
// 计算并更新VIP等级
|
||
var currentVip = await CalculateVipLevelAsync(userId, user.Vip);
|
||
|
||
// 获取所有VIP等级列表
|
||
var vipLevels = await _dbContext.VipLevels
|
||
.Where(v => v.DeletedAt == null)
|
||
.OrderBy(v => v.Level)
|
||
.ToListAsync();
|
||
|
||
// 获取最大VIP等级
|
||
var maxVipLevel = vipLevels.Any() ? vipLevels.Max(v => v.Level) : 0;
|
||
|
||
// 构建用户VIP信息
|
||
var userInfo = new VipUserInfoDto
|
||
{
|
||
Nickname = user.Nickname,
|
||
Headimg = user.HeadImg,
|
||
Vip = currentVip,
|
||
UpgradeMoney = "0",
|
||
LastVip = 0,
|
||
JinDu = 0,
|
||
Notice = string.Empty
|
||
};
|
||
|
||
// 如果未达到最高等级,计算升级进度
|
||
if (currentVip < maxVipLevel)
|
||
{
|
||
// 计算累计消费
|
||
var totalOrder = await GetTotalOrderConsumptionAsync(userId);
|
||
|
||
// 获取下一个VIP等级的条件
|
||
var nextLevel = vipLevels
|
||
.Where(v => v.Level > currentVip)
|
||
.OrderBy(v => v.Level)
|
||
.FirstOrDefault();
|
||
|
||
if (nextLevel != null)
|
||
{
|
||
var upgradeMoney = nextLevel.Number - totalOrder;
|
||
userInfo.UpgradeMoney = upgradeMoney > 0 ? upgradeMoney.ToString("F2") : "0";
|
||
userInfo.LastVip = nextLevel.Level;
|
||
|
||
// 计算进度百分比
|
||
if (totalOrder >= nextLevel.Number)
|
||
{
|
||
userInfo.JinDu = 100;
|
||
}
|
||
else if (nextLevel.Number > 0)
|
||
{
|
||
userInfo.JinDu = Math.Round((decimal)totalOrder / nextLevel.Number * 100, 2);
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
userInfo.UpgradeMoney = "0";
|
||
userInfo.LastVip = 0;
|
||
userInfo.JinDu = 100;
|
||
}
|
||
|
||
// 获取当前等级的提示信息
|
||
var currentLevelInfo = vipLevels.FirstOrDefault(v => v.Level == currentVip);
|
||
if (currentLevelInfo != null)
|
||
{
|
||
userInfo.Notice = currentLevelInfo.Title; // 使用标题作为提示信息
|
||
}
|
||
|
||
// 构建VIP等级列表DTO
|
||
var vipLevelDtos = vipLevels.Select(v => new VipLevelDto
|
||
{
|
||
Id = v.Id,
|
||
Level = v.Level,
|
||
Title = v.Title,
|
||
Imgurl = string.Empty, // SQL Server表中没有imgurl字段
|
||
Condition = v.Number,
|
||
Discount = 0, // SQL Server表中没有discount字段
|
||
Notice = v.Title
|
||
}).ToList();
|
||
|
||
return new VipInfoResponse
|
||
{
|
||
Userinfo = userInfo,
|
||
Data = vipLevelDtos
|
||
};
|
||
}
|
||
|
||
/// <inheritdoc />
|
||
public async Task<int> CalculateVipLevelAsync(int userId, int currentVip)
|
||
{
|
||
// 计算累计消费
|
||
var totalOrder = await GetTotalOrderConsumptionAsync(userId);
|
||
|
||
// 查找符合升级条件的最高等级
|
||
// 条件:等级 > 当前等级 且 升级条件 <= 累计消费
|
||
var newVipLevel = await _dbContext.VipLevels
|
||
.Where(v => v.DeletedAt == null)
|
||
.Where(v => v.Level > currentVip)
|
||
.Where(v => v.Number <= totalOrder)
|
||
.OrderByDescending(v => v.Level)
|
||
.FirstOrDefaultAsync();
|
||
|
||
if (newVipLevel != null)
|
||
{
|
||
// 更新用户VIP等级
|
||
var user = await _dbContext.Users.FindAsync(userId);
|
||
if (user != null)
|
||
{
|
||
user.Vip = (byte)newVipLevel.Level;
|
||
await _dbContext.SaveChangesAsync();
|
||
_logger.LogInformation("用户 {UserId} VIP等级从 {OldVip} 升级到 {NewVip}",
|
||
userId, currentVip, newVipLevel.Level);
|
||
}
|
||
return newVipLevel.Level;
|
||
}
|
||
|
||
return currentVip;
|
||
}
|
||
|
||
/// <inheritdoc />
|
||
public async Task<List<VipLevelDto>> GetVipLevelsAsync()
|
||
{
|
||
var vipLevels = await _dbContext.VipLevels
|
||
.Where(v => v.DeletedAt == null)
|
||
.OrderBy(v => v.Level)
|
||
.ToListAsync();
|
||
|
||
return vipLevels.Select(v => new VipLevelDto
|
||
{
|
||
Id = v.Id,
|
||
Level = v.Level,
|
||
Title = v.Title,
|
||
Imgurl = string.Empty,
|
||
Condition = v.Number,
|
||
Discount = 0,
|
||
Notice = v.Title
|
||
}).ToList();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取用户累计订单消费金额
|
||
/// </summary>
|
||
/// <param name="userId">用户ID</param>
|
||
/// <returns>累计消费金额</returns>
|
||
private async Task<decimal> GetTotalOrderConsumptionAsync(int userId)
|
||
{
|
||
// 计算累计消费:status=1(已支付)且 order_type<5
|
||
var totalOrder = await _dbContext.Orders
|
||
.Where(o => o.UserId == userId)
|
||
.Where(o => o.Status == 1)
|
||
.Where(o => o.OrderType < 5)
|
||
.SumAsync(o => o.OrderTotal);
|
||
|
||
return totalOrder;
|
||
}
|
||
}
|