refactor: 统一权益系统命名 VIP -> Equity
后端更改: - 重命名数据库表: vip_levels -> equity_levels, vip_level_rewards -> equity_level_rewards, user_vip_rewards -> user_equity_rewards - 重命名实体类: VipLevel -> EquityLevel, VipLevelReward -> EquityLevelReward, UserVipReward -> UserEquityReward - 重命名 DTO: VipInfoResponse -> EquityInfoResponse, VipUserInfoDto -> EquityUserInfoDto, VipLevelDto -> EquityLevelDto - 重命名服务: VipService -> EquityService, IVipService -> IEquityService - 更新 API 端点: /vip_list -> /equity_list - 移动命名空间: Models/Vip -> Models/Equity - 删除重复的 VipController (与 QyLevelController 功能重复) - 删除未使用的 equity_levels 和 equity_level_prizes 旧表实体 前端更改: - 更新 API 调用: getVipList -> getEquityList - 更新 vip.vue 页面使用新的 API 函数 保持兼容: - JSON 响应字段名保持不变 (vip, last_vip, jin_du 等) - 用户表 vip 字段保持不变
This commit is contained in:
parent
799fb29e0e
commit
2550f6d4c2
|
|
@ -40,11 +40,11 @@ export const updateUserInfo = async (data) => {
|
|||
};
|
||||
|
||||
/**
|
||||
* 获取VIP等级列表
|
||||
* @returns {Promise} VIP列表
|
||||
* 获取权益等级列表
|
||||
* @returns {Promise} 权益等级列表
|
||||
*/
|
||||
export const getVipList = async () => {
|
||||
return await RequestManager.get('/vip_list', {}, true);
|
||||
export const getEquityList = async () => {
|
||||
return await RequestManager.get('/equity_list', {}, true);
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import { getVipList } from '@/common/server/user.js';
|
||||
import { getEquityList } from '@/common/server/user.js';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
|
|
@ -61,7 +61,7 @@
|
|||
methods: {
|
||||
async getData() {
|
||||
// 模拟接口
|
||||
const res = await getVipList();
|
||||
const res = await getEquityList();
|
||||
if (res.status == 1) {
|
||||
this.userinfo = res.data.userinfo
|
||||
this.config = res.data.data
|
||||
|
|
|
|||
|
|
@ -1,233 +0,0 @@
|
|||
-- =============================================
|
||||
-- 权益等级表创建脚本
|
||||
-- 用于福利与任务管理模块
|
||||
-- =============================================
|
||||
|
||||
-- 创建权益等级表
|
||||
IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[equity_levels]') AND type in (N'U'))
|
||||
BEGIN
|
||||
CREATE TABLE [dbo].[equity_levels] (
|
||||
[id] INT IDENTITY(1,1) NOT NULL,
|
||||
[level] INT NOT NULL,
|
||||
[title] NVARCHAR(100) NOT NULL,
|
||||
[required_points] INT NOT NULL DEFAULT 0,
|
||||
[created_at] DATETIME2 DEFAULT GETDATE(),
|
||||
[updated_at] DATETIME2 DEFAULT GETDATE(),
|
||||
[deleted_at] DATETIME2 NULL,
|
||||
CONSTRAINT [pk_equity_levels] PRIMARY KEY CLUSTERED ([id] ASC)
|
||||
);
|
||||
|
||||
-- 添加表注释
|
||||
EXEC sp_addextendedproperty
|
||||
@name = N'MS_Description',
|
||||
@value = N'权益等级表,存储用户权益等级配置',
|
||||
@level0type = N'SCHEMA', @level0name = N'dbo',
|
||||
@level1type = N'TABLE', @level1name = N'equity_levels';
|
||||
|
||||
-- 添加列注释
|
||||
EXEC sp_addextendedproperty @name = N'MS_Description', @value = N'主键ID',
|
||||
@level0type = N'SCHEMA', @level0name = N'dbo',
|
||||
@level1type = N'TABLE', @level1name = N'equity_levels',
|
||||
@level2type = N'COLUMN', @level2name = N'id';
|
||||
|
||||
EXEC sp_addextendedproperty @name = N'MS_Description', @value = N'等级',
|
||||
@level0type = N'SCHEMA', @level0name = N'dbo',
|
||||
@level1type = N'TABLE', @level1name = N'equity_levels',
|
||||
@level2type = N'COLUMN', @level2name = N'level';
|
||||
|
||||
EXEC sp_addextendedproperty @name = N'MS_Description', @value = N'等级名称',
|
||||
@level0type = N'SCHEMA', @level0name = N'dbo',
|
||||
@level1type = N'TABLE', @level1name = N'equity_levels',
|
||||
@level2type = N'COLUMN', @level2name = N'title';
|
||||
|
||||
EXEC sp_addextendedproperty @name = N'MS_Description', @value = N'所需欧气值',
|
||||
@level0type = N'SCHEMA', @level0name = N'dbo',
|
||||
@level1type = N'TABLE', @level1name = N'equity_levels',
|
||||
@level2type = N'COLUMN', @level2name = N'required_points';
|
||||
|
||||
EXEC sp_addextendedproperty @name = N'MS_Description', @value = N'创建时间',
|
||||
@level0type = N'SCHEMA', @level0name = N'dbo',
|
||||
@level1type = N'TABLE', @level1name = N'equity_levels',
|
||||
@level2type = N'COLUMN', @level2name = N'created_at';
|
||||
|
||||
EXEC sp_addextendedproperty @name = N'MS_Description', @value = N'更新时间',
|
||||
@level0type = N'SCHEMA', @level0name = N'dbo',
|
||||
@level1type = N'TABLE', @level1name = N'equity_levels',
|
||||
@level2type = N'COLUMN', @level2name = N'updated_at';
|
||||
|
||||
EXEC sp_addextendedproperty @name = N'MS_Description', @value = N'删除时间(软删除)',
|
||||
@level0type = N'SCHEMA', @level0name = N'dbo',
|
||||
@level1type = N'TABLE', @level1name = N'equity_levels',
|
||||
@level2type = N'COLUMN', @level2name = N'deleted_at';
|
||||
|
||||
-- 创建索引
|
||||
CREATE INDEX [ix_equity_levels_level] ON [dbo].[equity_levels] ([level]);
|
||||
CREATE INDEX [ix_equity_levels_deleted_at] ON [dbo].[equity_levels] ([deleted_at]);
|
||||
|
||||
PRINT '权益等级表 equity_levels 创建成功';
|
||||
END
|
||||
ELSE
|
||||
BEGIN
|
||||
PRINT '权益等级表 equity_levels 已存在';
|
||||
END
|
||||
GO
|
||||
|
||||
-- 创建权益等级奖品表
|
||||
IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[equity_level_prizes]') AND type in (N'U'))
|
||||
BEGIN
|
||||
CREATE TABLE [dbo].[equity_level_prizes] (
|
||||
[id] INT IDENTITY(1,1) NOT NULL,
|
||||
[qy_level_id] INT NOT NULL,
|
||||
[qy_level] INT NOT NULL,
|
||||
[type] TINYINT NOT NULL DEFAULT 2,
|
||||
[title] NVARCHAR(255) NULL,
|
||||
[coupon_id] INT NULL,
|
||||
[z_num] INT NULL DEFAULT 0,
|
||||
[man_price] DECIMAL(10,2) NULL DEFAULT 0,
|
||||
[jian_price] DECIMAL(10,2) NULL DEFAULT 0,
|
||||
[effective_day] INT NULL DEFAULT 0,
|
||||
[jiang_price] DECIMAL(10,2) NULL DEFAULT 0,
|
||||
[money] DECIMAL(10,2) NULL DEFAULT 0,
|
||||
[sc_money] DECIMAL(10,2) NULL DEFAULT 0,
|
||||
[probability] DECIMAL(5,2) NULL DEFAULT 0,
|
||||
[imgurl] NVARCHAR(500) NULL,
|
||||
[prize_code] NVARCHAR(100) NULL,
|
||||
[shang_id] INT NULL,
|
||||
[sort] INT NULL DEFAULT 0,
|
||||
[created_at] DATETIME2 DEFAULT GETDATE(),
|
||||
[updated_at] DATETIME2 DEFAULT GETDATE(),
|
||||
[deleted_at] DATETIME2 NULL,
|
||||
CONSTRAINT [pk_equity_level_prizes] PRIMARY KEY CLUSTERED ([id] ASC),
|
||||
CONSTRAINT [fk_equity_level_prizes_equity_levels] FOREIGN KEY ([qy_level_id])
|
||||
REFERENCES [dbo].[equity_levels] ([id]) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
-- 添加表注释
|
||||
EXEC sp_addextendedproperty
|
||||
@name = N'MS_Description',
|
||||
@value = N'权益等级奖品表,存储各等级对应的奖品配置',
|
||||
@level0type = N'SCHEMA', @level0name = N'dbo',
|
||||
@level1type = N'TABLE', @level1name = N'equity_level_prizes';
|
||||
|
||||
-- 添加列注释
|
||||
EXEC sp_addextendedproperty @name = N'MS_Description', @value = N'主键ID',
|
||||
@level0type = N'SCHEMA', @level0name = N'dbo',
|
||||
@level1type = N'TABLE', @level1name = N'equity_level_prizes',
|
||||
@level2type = N'COLUMN', @level2name = N'id';
|
||||
|
||||
EXEC sp_addextendedproperty @name = N'MS_Description', @value = N'权益等级ID',
|
||||
@level0type = N'SCHEMA', @level0name = N'dbo',
|
||||
@level1type = N'TABLE', @level1name = N'equity_level_prizes',
|
||||
@level2type = N'COLUMN', @level2name = N'qy_level_id';
|
||||
|
||||
EXEC sp_addextendedproperty @name = N'MS_Description', @value = N'权益等级',
|
||||
@level0type = N'SCHEMA', @level0name = N'dbo',
|
||||
@level1type = N'TABLE', @level1name = N'equity_level_prizes',
|
||||
@level2type = N'COLUMN', @level2name = N'qy_level';
|
||||
|
||||
EXEC sp_addextendedproperty @name = N'MS_Description', @value = N'奖品类型:1-优惠券 2-实物奖品',
|
||||
@level0type = N'SCHEMA', @level0name = N'dbo',
|
||||
@level1type = N'TABLE', @level1name = N'equity_level_prizes',
|
||||
@level2type = N'COLUMN', @level2name = N'type';
|
||||
|
||||
EXEC sp_addextendedproperty @name = N'MS_Description', @value = N'奖品标题',
|
||||
@level0type = N'SCHEMA', @level0name = N'dbo',
|
||||
@level1type = N'TABLE', @level1name = N'equity_level_prizes',
|
||||
@level2type = N'COLUMN', @level2name = N'title';
|
||||
|
||||
EXEC sp_addextendedproperty @name = N'MS_Description', @value = N'优惠券ID',
|
||||
@level0type = N'SCHEMA', @level0name = N'dbo',
|
||||
@level1type = N'TABLE', @level1name = N'equity_level_prizes',
|
||||
@level2type = N'COLUMN', @level2name = N'coupon_id';
|
||||
|
||||
EXEC sp_addextendedproperty @name = N'MS_Description', @value = N'优惠券数量',
|
||||
@level0type = N'SCHEMA', @level0name = N'dbo',
|
||||
@level1type = N'TABLE', @level1name = N'equity_level_prizes',
|
||||
@level2type = N'COLUMN', @level2name = N'z_num';
|
||||
|
||||
EXEC sp_addextendedproperty @name = N'MS_Description', @value = N'满减门槛',
|
||||
@level0type = N'SCHEMA', @level0name = N'dbo',
|
||||
@level1type = N'TABLE', @level1name = N'equity_level_prizes',
|
||||
@level2type = N'COLUMN', @level2name = N'man_price';
|
||||
|
||||
EXEC sp_addextendedproperty @name = N'MS_Description', @value = N'减免金额',
|
||||
@level0type = N'SCHEMA', @level0name = N'dbo',
|
||||
@level1type = N'TABLE', @level1name = N'equity_level_prizes',
|
||||
@level2type = N'COLUMN', @level2name = N'jian_price';
|
||||
|
||||
EXEC sp_addextendedproperty @name = N'MS_Description', @value = N'有效天数',
|
||||
@level0type = N'SCHEMA', @level0name = N'dbo',
|
||||
@level1type = N'TABLE', @level1name = N'equity_level_prizes',
|
||||
@level2type = N'COLUMN', @level2name = N'effective_day';
|
||||
|
||||
EXEC sp_addextendedproperty @name = N'MS_Description', @value = N'奖品价值',
|
||||
@level0type = N'SCHEMA', @level0name = N'dbo',
|
||||
@level1type = N'TABLE', @level1name = N'equity_level_prizes',
|
||||
@level2type = N'COLUMN', @level2name = N'jiang_price';
|
||||
|
||||
EXEC sp_addextendedproperty @name = N'MS_Description', @value = N'兑换价格',
|
||||
@level0type = N'SCHEMA', @level0name = N'dbo',
|
||||
@level1type = N'TABLE', @level1name = N'equity_level_prizes',
|
||||
@level2type = N'COLUMN', @level2name = N'money';
|
||||
|
||||
EXEC sp_addextendedproperty @name = N'MS_Description', @value = N'市场参考价',
|
||||
@level0type = N'SCHEMA', @level0name = N'dbo',
|
||||
@level1type = N'TABLE', @level1name = N'equity_level_prizes',
|
||||
@level2type = N'COLUMN', @level2name = N'sc_money';
|
||||
|
||||
EXEC sp_addextendedproperty @name = N'MS_Description', @value = N'中奖概率(0-100)',
|
||||
@level0type = N'SCHEMA', @level0name = N'dbo',
|
||||
@level1type = N'TABLE', @level1name = N'equity_level_prizes',
|
||||
@level2type = N'COLUMN', @level2name = N'probability';
|
||||
|
||||
EXEC sp_addextendedproperty @name = N'MS_Description', @value = N'奖品图片URL',
|
||||
@level0type = N'SCHEMA', @level0name = N'dbo',
|
||||
@level1type = N'TABLE', @level1name = N'equity_level_prizes',
|
||||
@level2type = N'COLUMN', @level2name = N'imgurl';
|
||||
|
||||
EXEC sp_addextendedproperty @name = N'MS_Description', @value = N'奖品编码',
|
||||
@level0type = N'SCHEMA', @level0name = N'dbo',
|
||||
@level1type = N'TABLE', @level1name = N'equity_level_prizes',
|
||||
@level2type = N'COLUMN', @level2name = N'prize_code';
|
||||
|
||||
EXEC sp_addextendedproperty @name = N'MS_Description', @value = N'奖品等级ID',
|
||||
@level0type = N'SCHEMA', @level0name = N'dbo',
|
||||
@level1type = N'TABLE', @level1name = N'equity_level_prizes',
|
||||
@level2type = N'COLUMN', @level2name = N'shang_id';
|
||||
|
||||
EXEC sp_addextendedproperty @name = N'MS_Description', @value = N'排序',
|
||||
@level0type = N'SCHEMA', @level0name = N'dbo',
|
||||
@level1type = N'TABLE', @level1name = N'equity_level_prizes',
|
||||
@level2type = N'COLUMN', @level2name = N'sort';
|
||||
|
||||
EXEC sp_addextendedproperty @name = N'MS_Description', @value = N'创建时间',
|
||||
@level0type = N'SCHEMA', @level0name = N'dbo',
|
||||
@level1type = N'TABLE', @level1name = N'equity_level_prizes',
|
||||
@level2type = N'COLUMN', @level2name = N'created_at';
|
||||
|
||||
EXEC sp_addextendedproperty @name = N'MS_Description', @value = N'更新时间',
|
||||
@level0type = N'SCHEMA', @level0name = N'dbo',
|
||||
@level1type = N'TABLE', @level1name = N'equity_level_prizes',
|
||||
@level2type = N'COLUMN', @level2name = N'updated_at';
|
||||
|
||||
EXEC sp_addextendedproperty @name = N'MS_Description', @value = N'删除时间(软删除)',
|
||||
@level0type = N'SCHEMA', @level0name = N'dbo',
|
||||
@level1type = N'TABLE', @level1name = N'equity_level_prizes',
|
||||
@level2type = N'COLUMN', @level2name = N'deleted_at';
|
||||
|
||||
-- 创建索引
|
||||
CREATE INDEX [ix_equity_level_prizes_qy_level_id] ON [dbo].[equity_level_prizes] ([qy_level_id]);
|
||||
CREATE INDEX [ix_equity_level_prizes_type] ON [dbo].[equity_level_prizes] ([type]);
|
||||
CREATE INDEX [ix_equity_level_prizes_deleted_at] ON [dbo].[equity_level_prizes] ([deleted_at]);
|
||||
CREATE INDEX [ix_equity_level_prizes_sort] ON [dbo].[equity_level_prizes] ([sort]);
|
||||
|
||||
PRINT '权益等级奖品表 equity_level_prizes 创建成功';
|
||||
END
|
||||
ELSE
|
||||
BEGIN
|
||||
PRINT '权益等级奖品表 equity_level_prizes 已存在';
|
||||
END
|
||||
GO
|
||||
|
||||
PRINT '权益等级表创建脚本执行完成';
|
||||
GO
|
||||
|
|
@ -1,74 +0,0 @@
|
|||
using HoneyBox.Admin.Business.Attributes;
|
||||
using HoneyBox.Admin.Business.Models;
|
||||
using HoneyBox.Admin.Business.Models.User;
|
||||
using HoneyBox.Admin.Business.Services.Interfaces;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace HoneyBox.Admin.Business.Controllers;
|
||||
|
||||
/// <summary>
|
||||
/// VIP等级管理控制器
|
||||
/// </summary>
|
||||
[Route("api/admin/business/vip")]
|
||||
public class VipController : BusinessControllerBase
|
||||
{
|
||||
private readonly IUserBusinessService _userService;
|
||||
|
||||
public VipController(IUserBusinessService userService)
|
||||
{
|
||||
_userService = userService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取VIP等级列表
|
||||
/// </summary>
|
||||
/// <returns>VIP等级列表</returns>
|
||||
[HttpGet]
|
||||
[BusinessPermission("vip:list")]
|
||||
public async Task<IActionResult> GetVipLevels()
|
||||
{
|
||||
try
|
||||
{
|
||||
var result = await _userService.GetVipLevelsAsync();
|
||||
return Ok(result);
|
||||
}
|
||||
catch (BusinessException ex)
|
||||
{
|
||||
return Error(ex.Code, ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新VIP等级
|
||||
/// </summary>
|
||||
/// <param name="id">VIP等级ID</param>
|
||||
/// <param name="request">更新请求</param>
|
||||
/// <returns>操作结果</returns>
|
||||
[HttpPut("{id:int}")]
|
||||
[BusinessPermission("vip:edit")]
|
||||
public async Task<IActionResult> UpdateVipLevel(int id, [FromBody] VipLevelUpdateRequest request)
|
||||
{
|
||||
if (!ModelState.IsValid)
|
||||
{
|
||||
var errors = ModelState.Values
|
||||
.SelectMany(v => v.Errors)
|
||||
.Select(e => e.ErrorMessage)
|
||||
.FirstOrDefault();
|
||||
return ValidationError(errors ?? "参数验证失败");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var result = await _userService.UpdateVipLevelAsync(id, request);
|
||||
if (result)
|
||||
{
|
||||
return Ok("VIP等级更新成功");
|
||||
}
|
||||
return Error(BusinessErrorCodes.InternalError, "更新失败");
|
||||
}
|
||||
catch (BusinessException ex)
|
||||
{
|
||||
return Error(ex.Code, ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -92,9 +92,9 @@ public class UserListResponse
|
|||
public decimal Diamond { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// VIP等级
|
||||
/// 权益等级
|
||||
/// </summary>
|
||||
public int VipLevel { get; set; }
|
||||
public int EquityLevel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 注册时间
|
||||
|
|
|
|||
|
|
@ -1,59 +0,0 @@
|
|||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace HoneyBox.Admin.Business.Models.User;
|
||||
|
||||
/// <summary>
|
||||
/// VIP等级响应
|
||||
/// </summary>
|
||||
public class VipLevelDto
|
||||
{
|
||||
/// <summary>
|
||||
/// ID
|
||||
/// </summary>
|
||||
public int Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// VIP等级
|
||||
/// </summary>
|
||||
public int Level { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 等级名称
|
||||
/// </summary>
|
||||
public string Title { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 升级所需数量
|
||||
/// </summary>
|
||||
public int Number { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 创建时间
|
||||
/// </summary>
|
||||
public DateTime CreatedAt { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 更新时间
|
||||
/// </summary>
|
||||
public DateTime UpdatedAt { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// VIP等级更新请求
|
||||
/// </summary>
|
||||
public class VipLevelUpdateRequest
|
||||
{
|
||||
/// <summary>
|
||||
/// 等级名称
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "请输入等级名称")]
|
||||
[MaxLength(50, ErrorMessage = "等级名称最多50个字符")]
|
||||
public string Title { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 升级所需数量
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "请输入升级所需数量")]
|
||||
[Range(0, int.MaxValue, ErrorMessage = "升级所需数量必须大于等于0")]
|
||||
public int Number { get; set; }
|
||||
}
|
||||
|
|
@ -93,24 +93,6 @@ public interface IUserBusinessService
|
|||
|
||||
#endregion
|
||||
|
||||
#region VIP管理
|
||||
|
||||
/// <summary>
|
||||
/// 获取VIP等级列表
|
||||
/// </summary>
|
||||
/// <returns>VIP等级列表</returns>
|
||||
Task<List<VipLevelDto>> GetVipLevelsAsync();
|
||||
|
||||
/// <summary>
|
||||
/// 更新VIP等级
|
||||
/// </summary>
|
||||
/// <param name="id">VIP等级ID</param>
|
||||
/// <param name="request">更新请求</param>
|
||||
/// <returns>是否成功</returns>
|
||||
Task<bool> UpdateVipLevelAsync(int id, VipLevelUpdateRequest request);
|
||||
|
||||
#endregion
|
||||
|
||||
#region 统计功能
|
||||
|
||||
/// <summary>
|
||||
|
|
|
|||
|
|
@ -39,8 +39,8 @@ public class QyLevelService : IQyLevelService
|
|||
/// <inheritdoc />
|
||||
public async Task<PagedResult<QyLevelResponse>> GetQyLevelsAsync(QyLevelListRequest request)
|
||||
{
|
||||
// 使用 VipLevels 表(与用户端 API 保持一致)
|
||||
var query = _dbContext.VipLevels
|
||||
// 使用 EquityLevels 表
|
||||
var query = _dbContext.EquityLevels
|
||||
.AsNoTracking()
|
||||
.Where(e => e.DeletedAt == null && e.Level > 0);
|
||||
|
||||
|
|
@ -58,7 +58,7 @@ public class QyLevelService : IQyLevelService
|
|||
.Take(request.PageSize)
|
||||
.ToListAsync();
|
||||
|
||||
var list = items.Select(MapVipLevelToResponse).ToList();
|
||||
var list = items.Select(MapEquityLevelToResponse).ToList();
|
||||
|
||||
return PagedResult<QyLevelResponse>.Create(list, total, request.Page, request.PageSize);
|
||||
}
|
||||
|
|
@ -67,17 +67,17 @@ public class QyLevelService : IQyLevelService
|
|||
/// <inheritdoc />
|
||||
public async Task<QyLevelResponse?> GetQyLevelByIdAsync(int id)
|
||||
{
|
||||
var entity = await _dbContext.VipLevels
|
||||
var entity = await _dbContext.EquityLevels
|
||||
.AsNoTracking()
|
||||
.FirstOrDefaultAsync(e => e.Id == id && e.DeletedAt == null);
|
||||
|
||||
return entity == null ? null : MapVipLevelToResponse(entity);
|
||||
return entity == null ? null : MapEquityLevelToResponse(entity);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<bool> UpdateQyLevelAsync(int id, QyLevelUpdateRequest request)
|
||||
{
|
||||
var entity = await _dbContext.VipLevels
|
||||
var entity = await _dbContext.EquityLevels
|
||||
.FirstOrDefaultAsync(e => e.Id == id && e.DeletedAt == null);
|
||||
|
||||
if (entity == null)
|
||||
|
|
@ -108,7 +108,7 @@ public class QyLevelService : IQyLevelService
|
|||
public async Task<PagedResult<QyLevelPrizeResponse>> GetQyLevelPrizesAsync(int qyLevelId, QyLevelPrizeListRequest request)
|
||||
{
|
||||
// 验证权益等级是否存在
|
||||
var qyLevel = await _dbContext.VipLevels
|
||||
var qyLevel = await _dbContext.EquityLevels
|
||||
.AsNoTracking()
|
||||
.FirstOrDefaultAsync(e => e.Id == qyLevelId && e.DeletedAt == null);
|
||||
|
||||
|
|
@ -117,10 +117,10 @@ public class QyLevelService : IQyLevelService
|
|||
throw new BusinessException(BusinessErrorCodes.NotFound, "权益等级不存在");
|
||||
}
|
||||
|
||||
// 使用 VipLevelRewards 表
|
||||
var query = _dbContext.VipLevelRewards
|
||||
// 使用 EquityLevelRewards 表
|
||||
var query = _dbContext.EquityLevelRewards
|
||||
.AsNoTracking()
|
||||
.Where(p => p.VipLevelId == qyLevelId && p.DeletedAt == null);
|
||||
.Where(p => p.EquityLevelId == qyLevelId && p.DeletedAt == null);
|
||||
|
||||
// 按奖品类型筛选
|
||||
if (request.Type.HasValue)
|
||||
|
|
@ -157,7 +157,7 @@ public class QyLevelService : IQyLevelService
|
|||
.ToDictionaryAsync(c => c.Id)
|
||||
: new Dictionary<int, Coupon>();
|
||||
|
||||
var list = items.Select(p => MapVipLevelRewardToResponse(p, qyLevel.Level, coupons)).ToList();
|
||||
var list = items.Select(p => MapEquityLevelRewardToResponse(p, qyLevel.Level, coupons)).ToList();
|
||||
|
||||
return PagedResult<QyLevelPrizeResponse>.Create(list, total, request.Page, request.PageSize);
|
||||
}
|
||||
|
|
@ -165,7 +165,7 @@ public class QyLevelService : IQyLevelService
|
|||
/// <inheritdoc />
|
||||
public async Task<QyLevelPrizeResponse?> GetQyLevelPrizeByIdAsync(int prizeId)
|
||||
{
|
||||
var entity = await _dbContext.VipLevelRewards
|
||||
var entity = await _dbContext.EquityLevelRewards
|
||||
.AsNoTracking()
|
||||
.FirstOrDefaultAsync(p => p.Id == prizeId && p.DeletedAt == null);
|
||||
|
||||
|
|
@ -175,9 +175,9 @@ public class QyLevelService : IQyLevelService
|
|||
}
|
||||
|
||||
// 获取等级信息
|
||||
var qyLevel = await _dbContext.VipLevels
|
||||
var qyLevel = await _dbContext.EquityLevels
|
||||
.AsNoTracking()
|
||||
.FirstOrDefaultAsync(e => e.Id == entity.VipLevelId);
|
||||
.FirstOrDefaultAsync(e => e.Id == entity.EquityLevelId);
|
||||
var level = qyLevel?.Level ?? 0;
|
||||
|
||||
// 如果是优惠券类型,获取优惠券信息
|
||||
|
|
@ -193,7 +193,7 @@ public class QyLevelService : IQyLevelService
|
|||
}
|
||||
}
|
||||
|
||||
return MapVipLevelRewardToResponse(entity, level, coupons);
|
||||
return MapEquityLevelRewardToResponse(entity, level, coupons);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -201,7 +201,7 @@ public class QyLevelService : IQyLevelService
|
|||
public async Task<int> CreateQyLevelPrizeAsync(int qyLevelId, QyLevelPrizeCreateRequest request)
|
||||
{
|
||||
// 验证权益等级是否存在
|
||||
var qyLevel = await _dbContext.VipLevels
|
||||
var qyLevel = await _dbContext.EquityLevels
|
||||
.AsNoTracking()
|
||||
.FirstOrDefaultAsync(e => e.Id == qyLevelId && e.DeletedAt == null);
|
||||
|
||||
|
|
@ -213,9 +213,9 @@ public class QyLevelService : IQyLevelService
|
|||
// 验证请求
|
||||
ValidatePrizeCreateRequest(request);
|
||||
|
||||
var entity = new VipLevelReward
|
||||
var entity = new EquityLevelReward
|
||||
{
|
||||
VipLevelId = qyLevelId,
|
||||
EquityLevelId = qyLevelId,
|
||||
Type = (byte)request.Type,
|
||||
Title = request.Title,
|
||||
CouponId = request.CouponId,
|
||||
|
|
@ -230,7 +230,7 @@ public class QyLevelService : IQyLevelService
|
|||
UpdatedAt = DateTime.Now
|
||||
};
|
||||
|
||||
_dbContext.VipLevelRewards.Add(entity);
|
||||
_dbContext.EquityLevelRewards.Add(entity);
|
||||
await _dbContext.SaveChangesAsync();
|
||||
|
||||
_logger.LogInformation("创建权益等级奖品成功: Id={Id}, QyLevelId={QyLevelId}, Type={Type}",
|
||||
|
|
@ -242,7 +242,7 @@ public class QyLevelService : IQyLevelService
|
|||
/// <inheritdoc />
|
||||
public async Task<bool> UpdateQyLevelPrizeAsync(int prizeId, QyLevelPrizeUpdateRequest request)
|
||||
{
|
||||
var entity = await _dbContext.VipLevelRewards
|
||||
var entity = await _dbContext.EquityLevelRewards
|
||||
.FirstOrDefaultAsync(p => p.Id == prizeId && p.DeletedAt == null);
|
||||
|
||||
if (entity == null)
|
||||
|
|
@ -275,7 +275,7 @@ public class QyLevelService : IQyLevelService
|
|||
/// <inheritdoc />
|
||||
public async Task<bool> DeleteQyLevelPrizeAsync(int prizeId)
|
||||
{
|
||||
var entity = await _dbContext.VipLevelRewards
|
||||
var entity = await _dbContext.EquityLevelRewards
|
||||
.FirstOrDefaultAsync(p => p.Id == prizeId && p.DeletedAt == null);
|
||||
|
||||
if (entity == null)
|
||||
|
|
@ -469,9 +469,9 @@ public class QyLevelService : IQyLevelService
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将 VipLevel 实体映射为响应模型
|
||||
/// 将 EquityLevel 实体映射为响应模型
|
||||
/// </summary>
|
||||
private static QyLevelResponse MapVipLevelToResponse(VipLevel entity)
|
||||
private static QyLevelResponse MapEquityLevelToResponse(EquityLevel entity)
|
||||
{
|
||||
return new QyLevelResponse
|
||||
{
|
||||
|
|
@ -485,15 +485,15 @@ public class QyLevelService : IQyLevelService
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将 VipLevelReward 实体映射为奖品响应模型
|
||||
/// 将 EquityLevelReward 实体映射为奖品响应模型
|
||||
/// </summary>
|
||||
private static QyLevelPrizeResponse MapVipLevelRewardToResponse(VipLevelReward entity, int qyLevel, Dictionary<int, Coupon> coupons)
|
||||
private static QyLevelPrizeResponse MapEquityLevelRewardToResponse(EquityLevelReward entity, int qyLevel, Dictionary<int, Coupon> coupons)
|
||||
{
|
||||
var typeValue = (int)entity.Type;
|
||||
var response = new QyLevelPrizeResponse
|
||||
{
|
||||
Id = entity.Id,
|
||||
QyLevelId = entity.VipLevelId,
|
||||
QyLevelId = entity.EquityLevelId,
|
||||
QyLevel = qyLevel,
|
||||
Type = typeValue,
|
||||
TypeName = PrizeTypeNames.GetValueOrDefault(typeValue, "未知"),
|
||||
|
|
|
|||
|
|
@ -88,7 +88,7 @@ public class UserBusinessService : IUserBusinessService
|
|||
Balance = user.Money,
|
||||
Integral = user.Integral,
|
||||
Diamond = user.Score,
|
||||
VipLevel = user.Vip,
|
||||
EquityLevel = user.Vip,
|
||||
CreatedAt = user.CreatedAt,
|
||||
LastLoginIp = loginIps.GetValueOrDefault(userId),
|
||||
Status = user.Status,
|
||||
|
|
@ -508,52 +508,6 @@ public class UserBusinessService : IUserBusinessService
|
|||
#endregion
|
||||
|
||||
|
||||
#region VIP管理
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<List<VipLevelDto>> GetVipLevelsAsync()
|
||||
{
|
||||
var vipLevels = await _dbContext.VipLevels
|
||||
.AsNoTracking()
|
||||
.Where(v => v.DeletedAt == null)
|
||||
.OrderBy(v => v.Level)
|
||||
.Select(v => new VipLevelDto
|
||||
{
|
||||
Id = v.Id,
|
||||
Level = v.Level,
|
||||
Title = v.Title,
|
||||
Number = v.Number,
|
||||
CreatedAt = v.CreatedAt,
|
||||
UpdatedAt = v.UpdatedAt
|
||||
})
|
||||
.ToListAsync();
|
||||
|
||||
return vipLevels;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<bool> UpdateVipLevelAsync(int id, VipLevelUpdateRequest request)
|
||||
{
|
||||
var vipLevel = await _dbContext.VipLevels.FirstOrDefaultAsync(v => v.Id == id && v.DeletedAt == null);
|
||||
if (vipLevel == null)
|
||||
{
|
||||
throw new BusinessException(BusinessErrorCodes.NotFound, "VIP等级不存在");
|
||||
}
|
||||
|
||||
vipLevel.Title = request.Title;
|
||||
vipLevel.Number = request.Number;
|
||||
vipLevel.UpdatedAt = DateTime.Now;
|
||||
|
||||
var result = await _dbContext.SaveChangesAsync() > 0;
|
||||
|
||||
_logger.LogInformation("更新VIP等级: Id={Id}, Title={Title}, Number={Number}", id, request.Title, request.Number);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region 统计功能
|
||||
|
||||
/// <inheritdoc />
|
||||
|
|
@ -1269,7 +1223,7 @@ public class UserBusinessService : IUserBusinessService
|
|||
Balance = user.Money,
|
||||
Integral = user.Integral,
|
||||
Diamond = user.Score,
|
||||
VipLevel = user.Vip,
|
||||
EquityLevel = user.Vip,
|
||||
CreatedAt = user.CreatedAt,
|
||||
LastLoginIp = loginIps.GetValueOrDefault(user.Id),
|
||||
Status = user.Status,
|
||||
|
|
|
|||
|
|
@ -3,17 +3,17 @@ using HoneyBox.Core.Interfaces;
|
|||
using HoneyBox.Model.Base;
|
||||
using HoneyBox.Model.Models.Asset;
|
||||
using HoneyBox.Model.Models.Auth;
|
||||
using HoneyBox.Model.Models.Vip;
|
||||
using HoneyBox.Model.Models.Equity;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace HoneyBox.Api.Controllers;
|
||||
|
||||
/// <summary>
|
||||
/// 用户控制器 - 处理用户信息、资产和VIP相关功能
|
||||
/// 用户控制器 - 处理用户信息、资产和权益相关功能
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 提供用户信息查询和更新、资产明细查询、VIP信息查询等功能
|
||||
/// 提供用户信息查询和更新、资产明细查询、权益信息查询等功能
|
||||
/// </remarks>
|
||||
[ApiController]
|
||||
[Route("api")]
|
||||
|
|
@ -22,7 +22,7 @@ public class UserController : ControllerBase
|
|||
private readonly IUserService _userService;
|
||||
private readonly IAuthService _authService;
|
||||
private readonly IAssetService _assetService;
|
||||
private readonly IVipService _vipService;
|
||||
private readonly IEquityService _equityService;
|
||||
private readonly IQuanYiService _quanYiService;
|
||||
private readonly IImageUploadService _imageUploadService;
|
||||
private readonly ILogger<UserController> _logger;
|
||||
|
|
@ -31,7 +31,7 @@ public class UserController : ControllerBase
|
|||
IUserService userService,
|
||||
IAuthService authService,
|
||||
IAssetService assetService,
|
||||
IVipService vipService,
|
||||
IEquityService equityService,
|
||||
IQuanYiService quanYiService,
|
||||
IImageUploadService imageUploadService,
|
||||
ILogger<UserController> logger)
|
||||
|
|
@ -39,7 +39,7 @@ public class UserController : ControllerBase
|
|||
_userService = userService;
|
||||
_authService = authService;
|
||||
_assetService = assetService;
|
||||
_vipService = vipService;
|
||||
_equityService = equityService;
|
||||
_quanYiService = quanYiService;
|
||||
_imageUploadService = imageUploadService;
|
||||
_logger = logger;
|
||||
|
|
@ -384,50 +384,50 @@ public class UserController : ControllerBase
|
|||
|
||||
#endregion
|
||||
|
||||
#region VIP Endpoints
|
||||
#region Equity Endpoints
|
||||
|
||||
/// <summary>
|
||||
/// 获取VIP信息
|
||||
/// 获取权益等级信息
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// POST /api/vip_list
|
||||
/// GET /api/equity_list
|
||||
///
|
||||
/// 获取当前用户的VIP等级信息和权益列表
|
||||
/// 获取当前用户的权益等级信息和权益列表
|
||||
/// Requirements: 2.1-2.5
|
||||
/// </remarks>
|
||||
/// <returns>VIP信息数据</returns>
|
||||
[HttpGet("vip_list")]
|
||||
/// <returns>权益等级信息数据</returns>
|
||||
[HttpGet("equity_list")]
|
||||
[Authorize]
|
||||
[ProducesResponseType(typeof(ApiResponse<VipInfoResponse>), StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(typeof(ApiResponse<VipInfoResponse>), StatusCodes.Status401Unauthorized)]
|
||||
public async Task<ApiResponse<VipInfoResponse>> GetVipInfo()
|
||||
[ProducesResponseType(typeof(ApiResponse<EquityInfoResponse>), StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(typeof(ApiResponse<EquityInfoResponse>), StatusCodes.Status401Unauthorized)]
|
||||
public async Task<ApiResponse<EquityInfoResponse>> GetEquityInfo()
|
||||
{
|
||||
var userId = GetCurrentUserId();
|
||||
if (userId == null)
|
||||
{
|
||||
return ApiResponse<VipInfoResponse>.Unauthorized();
|
||||
return ApiResponse<EquityInfoResponse>.Unauthorized();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var result = await _vipService.GetVipInfoAsync(userId.Value);
|
||||
return ApiResponse<VipInfoResponse>.Success(result);
|
||||
var result = await _equityService.GetEquityInfoAsync(userId.Value);
|
||||
return ApiResponse<EquityInfoResponse>.Success(result);
|
||||
}
|
||||
catch (InvalidOperationException ex)
|
||||
{
|
||||
_logger.LogWarning("Get VIP info failed: UserId={UserId}, Error={Error}", userId, ex.Message);
|
||||
return ApiResponse<VipInfoResponse>.Fail(ex.Message);
|
||||
_logger.LogWarning("Get equity info failed: UserId={UserId}, Error={Error}", userId, ex.Message);
|
||||
return ApiResponse<EquityInfoResponse>.Fail(ex.Message);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Failed to get VIP info: UserId={UserId}", userId);
|
||||
return ApiResponse<VipInfoResponse>.Fail("获取VIP信息失败");
|
||||
_logger.LogError(ex, "Failed to get equity info: UserId={UserId}", userId);
|
||||
return ApiResponse<EquityInfoResponse>.Fail("获取权益信息失败");
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region QuanYi (VIP Rights) Endpoints
|
||||
#region QuanYi (Equity Rights) Endpoints
|
||||
|
||||
/// <summary>
|
||||
/// 获取权益中心信息
|
||||
|
|
|
|||
|
|
@ -0,0 +1,30 @@
|
|||
using HoneyBox.Model.Models.Equity;
|
||||
|
||||
namespace HoneyBox.Core.Interfaces;
|
||||
|
||||
/// <summary>
|
||||
/// 权益服务接口
|
||||
/// </summary>
|
||||
public interface IEquityService
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取权益信息
|
||||
/// </summary>
|
||||
/// <param name="userId">用户ID</param>
|
||||
/// <returns>权益信息响应</returns>
|
||||
Task<EquityInfoResponse> GetEquityInfoAsync(int userId);
|
||||
|
||||
/// <summary>
|
||||
/// 计算权益等级
|
||||
/// </summary>
|
||||
/// <param name="userId">用户ID</param>
|
||||
/// <param name="currentLevel">当前权益等级</param>
|
||||
/// <returns>计算后的权益等级</returns>
|
||||
Task<int> CalculateEquityLevelAsync(int userId, int currentLevel);
|
||||
|
||||
/// <summary>
|
||||
/// 获取权益等级列表
|
||||
/// </summary>
|
||||
/// <returns>权益等级列表</returns>
|
||||
Task<List<EquityLevelDto>> GetEquityLevelsAsync();
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
using HoneyBox.Model.Models.Vip;
|
||||
using HoneyBox.Model.Models.Equity;
|
||||
|
||||
namespace HoneyBox.Core.Interfaces;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,30 +0,0 @@
|
|||
using HoneyBox.Model.Models.Vip;
|
||||
|
||||
namespace HoneyBox.Core.Interfaces;
|
||||
|
||||
/// <summary>
|
||||
/// VIP服务接口
|
||||
/// </summary>
|
||||
public interface IVipService
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取VIP信息
|
||||
/// </summary>
|
||||
/// <param name="userId">用户ID</param>
|
||||
/// <returns>VIP信息响应</returns>
|
||||
Task<VipInfoResponse> GetVipInfoAsync(int userId);
|
||||
|
||||
/// <summary>
|
||||
/// 计算VIP等级
|
||||
/// </summary>
|
||||
/// <param name="userId">用户ID</param>
|
||||
/// <param name="currentVip">当前VIP等级</param>
|
||||
/// <returns>计算后的VIP等级</returns>
|
||||
Task<int> CalculateVipLevelAsync(int userId, int currentVip);
|
||||
|
||||
/// <summary>
|
||||
/// 获取VIP等级列表
|
||||
/// </summary>
|
||||
/// <returns>VIP等级列表</returns>
|
||||
Task<List<VipLevelDto>> GetVipLevelsAsync();
|
||||
}
|
||||
|
|
@ -1,28 +1,28 @@
|
|||
using HoneyBox.Core.Interfaces;
|
||||
using HoneyBox.Model.Data;
|
||||
using HoneyBox.Model.Entities;
|
||||
using HoneyBox.Model.Models.Vip;
|
||||
using HoneyBox.Model.Models.Equity;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace HoneyBox.Core.Services;
|
||||
|
||||
/// <summary>
|
||||
/// VIP服务实现
|
||||
/// 权益服务实现
|
||||
/// </summary>
|
||||
public class VipService : IVipService
|
||||
public class EquityService : IEquityService
|
||||
{
|
||||
private readonly HoneyBoxDbContext _dbContext;
|
||||
private readonly ILogger<VipService> _logger;
|
||||
private readonly ILogger<EquityService> _logger;
|
||||
|
||||
public VipService(HoneyBoxDbContext dbContext, ILogger<VipService> logger)
|
||||
public EquityService(HoneyBoxDbContext dbContext, ILogger<EquityService> logger)
|
||||
{
|
||||
_dbContext = dbContext;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<VipInfoResponse> GetVipInfoAsync(int userId)
|
||||
public async Task<EquityInfoResponse> GetEquityInfoAsync(int userId)
|
||||
{
|
||||
// 获取用户信息
|
||||
var user = await _dbContext.Users
|
||||
|
|
@ -35,24 +35,24 @@ public class VipService : IVipService
|
|||
throw new InvalidOperationException("用户不存在");
|
||||
}
|
||||
|
||||
// 计算并更新VIP等级
|
||||
var currentVip = await CalculateVipLevelAsync(userId, user.Vip);
|
||||
// 计算并更新权益等级
|
||||
var currentLevel = await CalculateEquityLevelAsync(userId, user.Vip);
|
||||
|
||||
// 获取所有VIP等级列表
|
||||
var vipLevels = await _dbContext.VipLevels
|
||||
// 获取所有权益等级列表
|
||||
var equityLevels = await _dbContext.EquityLevels
|
||||
.Where(v => v.DeletedAt == null)
|
||||
.OrderBy(v => v.Level)
|
||||
.ToListAsync();
|
||||
|
||||
// 获取最大VIP等级
|
||||
var maxVipLevel = vipLevels.Any() ? vipLevels.Max(v => v.Level) : 0;
|
||||
// 获取最大权益等级
|
||||
var maxLevel = equityLevels.Any() ? equityLevels.Max(v => v.Level) : 0;
|
||||
|
||||
// 构建用户VIP信息
|
||||
var userInfo = new VipUserInfoDto
|
||||
// 构建用户权益信息
|
||||
var userInfo = new EquityUserInfoDto
|
||||
{
|
||||
Nickname = user.Nickname,
|
||||
Headimg = user.HeadImg,
|
||||
Vip = currentVip,
|
||||
Vip = currentLevel,
|
||||
UpgradeMoney = "0",
|
||||
LastVip = 0,
|
||||
JinDu = 0,
|
||||
|
|
@ -60,14 +60,14 @@ public class VipService : IVipService
|
|||
};
|
||||
|
||||
// 如果未达到最高等级,计算升级进度
|
||||
if (currentVip < maxVipLevel)
|
||||
if (currentLevel < maxLevel)
|
||||
{
|
||||
// 计算累计消费
|
||||
var totalOrder = await GetTotalOrderConsumptionAsync(userId);
|
||||
|
||||
// 获取下一个VIP等级的条件
|
||||
var nextLevel = vipLevels
|
||||
.Where(v => v.Level > currentVip)
|
||||
// 获取下一个权益等级的条件
|
||||
var nextLevel = equityLevels
|
||||
.Where(v => v.Level > currentLevel)
|
||||
.OrderBy(v => v.Level)
|
||||
.FirstOrDefault();
|
||||
|
||||
|
|
@ -96,72 +96,72 @@ public class VipService : IVipService
|
|||
}
|
||||
|
||||
// 获取当前等级的提示信息
|
||||
var currentLevelInfo = vipLevels.FirstOrDefault(v => v.Level == currentVip);
|
||||
var currentLevelInfo = equityLevels.FirstOrDefault(v => v.Level == currentLevel);
|
||||
if (currentLevelInfo != null)
|
||||
{
|
||||
userInfo.Notice = currentLevelInfo.Title; // 使用标题作为提示信息
|
||||
userInfo.Notice = currentLevelInfo.Title;
|
||||
}
|
||||
|
||||
// 构建VIP等级列表DTO
|
||||
var vipLevelDtos = vipLevels.Select(v => new VipLevelDto
|
||||
// 构建权益等级列表DTO
|
||||
var levelDtos = equityLevels.Select(v => new EquityLevelDto
|
||||
{
|
||||
Id = v.Id,
|
||||
Level = v.Level,
|
||||
Title = v.Title,
|
||||
Imgurl = string.Empty, // SQL Server表中没有imgurl字段
|
||||
Imgurl = string.Empty,
|
||||
Condition = v.Number,
|
||||
Discount = 0, // SQL Server表中没有discount字段
|
||||
Discount = 0,
|
||||
Notice = v.Title
|
||||
}).ToList();
|
||||
|
||||
return new VipInfoResponse
|
||||
return new EquityInfoResponse
|
||||
{
|
||||
Userinfo = userInfo,
|
||||
Data = vipLevelDtos
|
||||
Data = levelDtos
|
||||
};
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<int> CalculateVipLevelAsync(int userId, int currentVip)
|
||||
public async Task<int> CalculateEquityLevelAsync(int userId, int currentLevel)
|
||||
{
|
||||
// 计算累计消费
|
||||
var totalOrder = await GetTotalOrderConsumptionAsync(userId);
|
||||
|
||||
// 查找符合升级条件的最高等级
|
||||
// 条件:等级 > 当前等级 且 升级条件 <= 累计消费
|
||||
var newVipLevel = await _dbContext.VipLevels
|
||||
var newLevel = await _dbContext.EquityLevels
|
||||
.Where(v => v.DeletedAt == null)
|
||||
.Where(v => v.Level > currentVip)
|
||||
.Where(v => v.Level > currentLevel)
|
||||
.Where(v => v.Number <= totalOrder)
|
||||
.OrderByDescending(v => v.Level)
|
||||
.FirstOrDefaultAsync();
|
||||
|
||||
if (newVipLevel != null)
|
||||
if (newLevel != null)
|
||||
{
|
||||
// 更新用户VIP等级
|
||||
// 更新用户权益等级
|
||||
var user = await _dbContext.Users.FindAsync(userId);
|
||||
if (user != null)
|
||||
{
|
||||
user.Vip = (byte)newVipLevel.Level;
|
||||
user.Vip = (byte)newLevel.Level;
|
||||
await _dbContext.SaveChangesAsync();
|
||||
_logger.LogInformation("用户 {UserId} VIP等级从 {OldVip} 升级到 {NewVip}",
|
||||
userId, currentVip, newVipLevel.Level);
|
||||
_logger.LogInformation("用户 {UserId} 权益等级从 {OldLevel} 升级到 {NewLevel}",
|
||||
userId, currentLevel, newLevel.Level);
|
||||
}
|
||||
return newVipLevel.Level;
|
||||
return newLevel.Level;
|
||||
}
|
||||
|
||||
return currentVip;
|
||||
return currentLevel;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<List<VipLevelDto>> GetVipLevelsAsync()
|
||||
public async Task<List<EquityLevelDto>> GetEquityLevelsAsync()
|
||||
{
|
||||
var vipLevels = await _dbContext.VipLevels
|
||||
var equityLevels = await _dbContext.EquityLevels
|
||||
.Where(v => v.DeletedAt == null)
|
||||
.OrderBy(v => v.Level)
|
||||
.ToListAsync();
|
||||
|
||||
return vipLevels.Select(v => new VipLevelDto
|
||||
return equityLevels.Select(v => new EquityLevelDto
|
||||
{
|
||||
Id = v.Id,
|
||||
Level = v.Level,
|
||||
|
|
@ -176,8 +176,6 @@ public class VipService : IVipService
|
|||
/// <summary>
|
||||
/// 获取用户累计订单消费金额
|
||||
/// </summary>
|
||||
/// <param name="userId">用户ID</param>
|
||||
/// <returns>累计消费金额</returns>
|
||||
private async Task<decimal> GetTotalOrderConsumptionAsync(int userId)
|
||||
{
|
||||
// 计算累计消费:status=1(已支付)且 order_type<5
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
using HoneyBox.Core.Interfaces;
|
||||
using HoneyBox.Model.Data;
|
||||
using HoneyBox.Model.Entities;
|
||||
using HoneyBox.Model.Models.Vip;
|
||||
using HoneyBox.Model.Models.Equity;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
|
|
@ -33,7 +33,7 @@ public class QuanYiService : IQuanYiService
|
|||
}
|
||||
|
||||
// 从数据库获取等级配置
|
||||
var vipLevelConfigs = await _dbContext.VipLevels
|
||||
var equityLevelConfigs = await _dbContext.EquityLevels
|
||||
.Where(v => v.DeletedAt == null)
|
||||
.OrderBy(v => v.Level)
|
||||
.ToListAsync();
|
||||
|
|
@ -41,28 +41,28 @@ public class QuanYiService : IQuanYiService
|
|||
var response = new QuanYiResponse
|
||||
{
|
||||
UserImg = GetImageUrl(user.HeadImg),
|
||||
QuanYiLevel = GetQuanYiLevelInfo(user.OuQiLevel ?? 0, user.OuQi ?? 0, vipLevelConfigs)
|
||||
QuanYiLevel = GetQuanYiLevelInfo(user.OuQiLevel ?? 0, user.OuQi ?? 0, equityLevelConfigs)
|
||||
};
|
||||
|
||||
// Get all VIP levels with level > 0
|
||||
var vipLevels = await _dbContext.VipLevels
|
||||
// Get all equity levels with level > 0
|
||||
var equityLevels = await _dbContext.EquityLevels
|
||||
.Where(v => v.Level > 0 && v.DeletedAt == null)
|
||||
.OrderBy(v => v.Level)
|
||||
.ToListAsync();
|
||||
|
||||
var levelList = new List<QuanYiLevelDto>();
|
||||
|
||||
foreach (var vipLevel in vipLevels)
|
||||
foreach (var equityLevel in equityLevels)
|
||||
{
|
||||
var levelDto = new QuanYiLevelDto
|
||||
{
|
||||
Id = vipLevel.Id,
|
||||
Level = vipLevel.Level
|
||||
Id = equityLevel.Id,
|
||||
Level = equityLevel.Level
|
||||
};
|
||||
|
||||
// Get coupon rewards (type = 1)
|
||||
var puJiang = await _dbContext.VipLevelRewards
|
||||
.Where(r => r.VipLevelId == vipLevel.Id && r.Type == 1 && r.DeletedAt == null)
|
||||
var puJiang = await _dbContext.EquityLevelRewards
|
||||
.Where(r => r.EquityLevelId == equityLevel.Id && r.Type == 1 && r.DeletedAt == null)
|
||||
.OrderBy(r => r.Id)
|
||||
.Select(r => new QuanYiRewardDto
|
||||
{
|
||||
|
|
@ -75,8 +75,8 @@ public class QuanYiService : IQuanYiService
|
|||
levelDto.PuJiang = puJiang;
|
||||
|
||||
// Get prize rewards (type = 2)
|
||||
var gaoJiangRaw = await _dbContext.VipLevelRewards
|
||||
.Where(r => r.VipLevelId == vipLevel.Id && r.Type == 2 && r.DeletedAt == null)
|
||||
var gaoJiangRaw = await _dbContext.EquityLevelRewards
|
||||
.Where(r => r.EquityLevelId == equityLevel.Id && r.Type == 2 && r.DeletedAt == null)
|
||||
.OrderBy(r => r.Id)
|
||||
.Select(r => new QuanYiRewardDto
|
||||
{
|
||||
|
|
@ -94,7 +94,7 @@ public class QuanYiService : IQuanYiService
|
|||
levelDto.GaoJiang = gaoJiangRaw;
|
||||
|
||||
// Check if user can claim this level's rewards
|
||||
if ((user.OuQiLevel ?? 0) >= vipLevel.Level)
|
||||
if ((user.OuQiLevel ?? 0) >= equityLevel.Level)
|
||||
{
|
||||
levelDto.IsLing = 1; // Can claim
|
||||
}
|
||||
|
|
@ -104,9 +104,9 @@ public class QuanYiService : IQuanYiService
|
|||
}
|
||||
|
||||
// Check if user has already claimed this level's rewards
|
||||
var hasClaimed = await _dbContext.UserVipRewards
|
||||
.AnyAsync(r => r.VipLevelId == vipLevel.Id
|
||||
&& r.VipLevel == vipLevel.Level
|
||||
var hasClaimed = await _dbContext.UserEquityRewards
|
||||
.AnyAsync(r => r.EquityLevelId == equityLevel.Id
|
||||
&& r.EquityLevel == equityLevel.Level
|
||||
&& r.UserId == userId
|
||||
&& r.DeletedAt == null);
|
||||
|
||||
|
|
@ -144,21 +144,21 @@ public class QuanYiService : IQuanYiService
|
|||
throw new InvalidOperationException("用户不存在");
|
||||
}
|
||||
|
||||
var vipLevel = await _dbContext.VipLevels
|
||||
var equityLevel = await _dbContext.EquityLevels
|
||||
.FirstOrDefaultAsync(v => v.Id == levelId && v.DeletedAt == null);
|
||||
if (vipLevel == null)
|
||||
if (equityLevel == null)
|
||||
{
|
||||
throw new InvalidOperationException("数据错误");
|
||||
}
|
||||
|
||||
if (vipLevel.Level > (user.OuQiLevel ?? 0))
|
||||
if (equityLevel.Level > (user.OuQiLevel ?? 0))
|
||||
{
|
||||
throw new InvalidOperationException("暂未达到该等级");
|
||||
}
|
||||
|
||||
// Check if rewards exist for this level
|
||||
var hasRewards = await _dbContext.VipLevelRewards
|
||||
.AnyAsync(r => r.VipLevelId == vipLevel.Id && r.DeletedAt == null);
|
||||
var hasRewards = await _dbContext.EquityLevelRewards
|
||||
.AnyAsync(r => r.EquityLevelId == equityLevel.Id && r.DeletedAt == null);
|
||||
if (!hasRewards)
|
||||
{
|
||||
throw new InvalidOperationException("奖品不存在");
|
||||
|
|
@ -172,8 +172,8 @@ public class QuanYiService : IQuanYiService
|
|||
try
|
||||
{
|
||||
// Process coupon rewards (type = 1)
|
||||
var couponRewards = await _dbContext.VipLevelRewards
|
||||
.Where(r => r.VipLevelId == vipLevel.Id && r.Type == 1 && r.DeletedAt == null)
|
||||
var couponRewards = await _dbContext.EquityLevelRewards
|
||||
.Where(r => r.EquityLevelId == equityLevel.Id && r.Type == 1 && r.DeletedAt == null)
|
||||
.ToListAsync();
|
||||
|
||||
foreach (var reward in couponRewards)
|
||||
|
|
@ -223,12 +223,12 @@ public class QuanYiService : IQuanYiService
|
|||
_dbContext.CouponReceives.Add(couponReceive);
|
||||
}
|
||||
|
||||
// Record user vip reward
|
||||
var userVipReward = new UserVipReward
|
||||
// Record user equity reward
|
||||
var userEquityReward = new UserEquityReward
|
||||
{
|
||||
UserId = userId,
|
||||
VipLevelId = vipLevel.Id,
|
||||
VipLevel = vipLevel.Level,
|
||||
EquityLevelId = equityLevel.Id,
|
||||
EquityLevel = equityLevel.Level,
|
||||
CouponId = reward.CouponId,
|
||||
Type = 1,
|
||||
Title = reward.Title,
|
||||
|
|
@ -240,18 +240,18 @@ public class QuanYiService : IQuanYiService
|
|||
CreatedAt = DateTime.UtcNow,
|
||||
UpdatedAt = DateTime.UtcNow
|
||||
};
|
||||
_dbContext.UserVipRewards.Add(userVipReward);
|
||||
_dbContext.UserEquityRewards.Add(userEquityReward);
|
||||
}
|
||||
|
||||
// Process prize rewards (type = 2) with probability
|
||||
var prizeRewards = await _dbContext.VipLevelRewards
|
||||
.Where(r => r.VipLevelId == vipLevel.Id && r.Type == 2 && r.Probability > 0 && r.DeletedAt == null)
|
||||
var prizeRewards = await _dbContext.EquityLevelRewards
|
||||
.Where(r => r.EquityLevelId == equityLevel.Id && r.Type == 2 && r.Probability > 0 && r.DeletedAt == null)
|
||||
.ToListAsync();
|
||||
|
||||
if (prizeRewards.Any())
|
||||
{
|
||||
// Build probability pool
|
||||
var probabilityPool = new List<VipLevelReward>();
|
||||
var probabilityPool = new List<EquityLevelReward>();
|
||||
foreach (var prize in prizeRewards)
|
||||
{
|
||||
var count = (int)((prize.Probability ?? 0) * 100);
|
||||
|
|
@ -327,12 +327,12 @@ public class QuanYiService : IQuanYiService
|
|||
};
|
||||
_dbContext.OrderItems.Add(orderItem);
|
||||
|
||||
// Record user vip reward for prize
|
||||
var userVipReward = new UserVipReward
|
||||
// Record user equity reward for prize
|
||||
var userEquityReward = new UserEquityReward
|
||||
{
|
||||
UserId = userId,
|
||||
VipLevelId = vipLevel.Id,
|
||||
VipLevel = vipLevel.Level,
|
||||
EquityLevelId = equityLevel.Id,
|
||||
EquityLevel = equityLevel.Level,
|
||||
Type = 2,
|
||||
Title = selectedPrize.Title,
|
||||
ImgUrl = selectedPrize.ImgUrl,
|
||||
|
|
@ -345,20 +345,20 @@ public class QuanYiService : IQuanYiService
|
|||
CreatedAt = DateTime.UtcNow,
|
||||
UpdatedAt = DateTime.UtcNow
|
||||
};
|
||||
_dbContext.UserVipRewards.Add(userVipReward);
|
||||
_dbContext.UserEquityRewards.Add(userEquityReward);
|
||||
}
|
||||
}
|
||||
|
||||
await _dbContext.SaveChangesAsync();
|
||||
await transaction.CommitAsync();
|
||||
|
||||
_logger.LogInformation("User {UserId} claimed VIP level {LevelId} rewards", userId, levelId);
|
||||
_logger.LogInformation("User {UserId} claimed equity level {LevelId} rewards", userId, levelId);
|
||||
return new QuanYiLingResponse(rewards);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await transaction.RollbackAsync();
|
||||
_logger.LogError(ex, "Failed to claim VIP rewards for user {UserId}, level {LevelId}", userId, levelId);
|
||||
_logger.LogError(ex, "Failed to claim equity rewards for user {UserId}, level {LevelId}", userId, levelId);
|
||||
throw new InvalidOperationException("网络故障,请稍后再试");
|
||||
}
|
||||
}
|
||||
|
|
@ -380,14 +380,14 @@ public class QuanYiService : IQuanYiService
|
|||
/// <summary>
|
||||
/// Get QuanYi level info based on ou_qi_level and ou_qi
|
||||
/// </summary>
|
||||
private QuanYiLevelInfo GetQuanYiLevelInfo(int ouQiLevel, int ouQi, List<VipLevel> vipLevelConfigs)
|
||||
private QuanYiLevelInfo GetQuanYiLevelInfo(int ouQiLevel, int ouQi, List<EquityLevel> equityLevelConfigs)
|
||||
{
|
||||
// 从数据库配置构建等级阈值
|
||||
var levelThresholds = vipLevelConfigs
|
||||
var levelThresholds = equityLevelConfigs
|
||||
.ToDictionary(v => v.Level, v => v.Number);
|
||||
|
||||
// 构建等级标题
|
||||
var levelTitles = vipLevelConfigs
|
||||
var levelTitles = equityLevelConfigs
|
||||
.ToDictionary(v => v.Level, v => v.Title ?? $"等级{v.Level}");
|
||||
|
||||
// 如果没有配置,使用默认值
|
||||
|
|
|
|||
|
|
@ -156,7 +156,7 @@ public class UserService : BaseService<User, int>, IUserService
|
|||
Integral = user.Integral,
|
||||
Score = user.Score,
|
||||
Vip = user.Vip,
|
||||
VipImgurl = GetVipImageUrl(user.Vip),
|
||||
VipImgurl = GetEquityImageUrl(user.Vip),
|
||||
Coupon = couponCount,
|
||||
Day = registrationDays,
|
||||
QuanYiLevel = quanYiLevel
|
||||
|
|
@ -221,24 +221,24 @@ public class UserService : BaseService<User, int>, IUserService
|
|||
if (user == null)
|
||||
return currentVip;
|
||||
|
||||
// Get all VIP levels ordered by level
|
||||
var vipLevels = await _dbContext.VipLevels
|
||||
// Get all equity levels ordered by level
|
||||
var equityLevels = await _dbContext.EquityLevels
|
||||
.Where(v => v.DeletedAt == null)
|
||||
.OrderBy(v => v.Level)
|
||||
.ToListAsync();
|
||||
|
||||
if (!vipLevels.Any())
|
||||
if (!equityLevels.Any())
|
||||
return currentVip;
|
||||
|
||||
// Calculate VIP level based on total spending (Money)
|
||||
var totalSpending = user.Money;
|
||||
|
||||
int newVipLevel = 0;
|
||||
foreach (var vipLevel in vipLevels)
|
||||
foreach (var equityLevel in equityLevels)
|
||||
{
|
||||
if (totalSpending >= vipLevel.Number)
|
||||
if (totalSpending >= equityLevel.Number)
|
||||
{
|
||||
newVipLevel = vipLevel.Level;
|
||||
newVipLevel = equityLevel.Level;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -381,14 +381,14 @@ public class UserService : BaseService<User, int>, IUserService
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get VIP image URL based on VIP level
|
||||
/// Get equity image URL based on equity level
|
||||
/// </summary>
|
||||
private string? GetVipImageUrl(int vipLevel)
|
||||
private string? GetEquityImageUrl(int equityLevel)
|
||||
{
|
||||
if (vipLevel <= 0)
|
||||
if (equityLevel <= 0)
|
||||
return null;
|
||||
|
||||
// Return a placeholder URL - actual URLs should be configured
|
||||
return $"https://example.com/vip/level_{vipLevel}.png";
|
||||
return $"https://example.com/equity/level_{equityLevel}.png";
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -73,13 +73,13 @@ public class ServiceModule : Module
|
|||
return new AssetService(dbContext, logger);
|
||||
}).As<IAssetService>().InstancePerLifetimeScope();
|
||||
|
||||
// 注册VIP服务
|
||||
// 注册权益服务
|
||||
builder.Register(c =>
|
||||
{
|
||||
var dbContext = c.Resolve<HoneyBoxDbContext>();
|
||||
var logger = c.Resolve<ILogger<VipService>>();
|
||||
return new VipService(dbContext, logger);
|
||||
}).As<IVipService>().InstancePerLifetimeScope();
|
||||
var logger = c.Resolve<ILogger<EquityService>>();
|
||||
return new EquityService(dbContext, logger);
|
||||
}).As<IEquityService>().InstancePerLifetimeScope();
|
||||
|
||||
// 注册优惠券服务
|
||||
builder.Register(c =>
|
||||
|
|
|
|||
|
|
@ -88,11 +88,11 @@ public partial class HoneyBoxDbContext : DbContext
|
|||
|
||||
public virtual DbSet<UserTask> UserTasks { get; set; }
|
||||
|
||||
public virtual DbSet<UserVipReward> UserVipRewards { get; set; }
|
||||
public virtual DbSet<UserEquityReward> UserEquityRewards { get; set; }
|
||||
|
||||
public virtual DbSet<VipLevel> VipLevels { get; set; }
|
||||
public virtual DbSet<EquityLevel> EquityLevels { get; set; }
|
||||
|
||||
public virtual DbSet<VipLevelReward> VipLevelRewards { get; set; }
|
||||
public virtual DbSet<EquityLevelReward> EquityLevelRewards { get; set; }
|
||||
|
||||
public virtual DbSet<RedeemCode> RedeemCodes { get; set; }
|
||||
|
||||
|
|
@ -118,10 +118,6 @@ public partial class HoneyBoxDbContext : DbContext
|
|||
|
||||
public virtual DbSet<RankMonth> RankMonths { get; set; }
|
||||
|
||||
public virtual DbSet<EquityLevel> EquityLevels { get; set; }
|
||||
|
||||
public virtual DbSet<EquityLevelPrize> EquityLevelPrizes { get; set; }
|
||||
|
||||
public virtual DbSet<GoodsKingRank> GoodsKingRanks { get; set; }
|
||||
|
||||
public virtual DbSet<UserRefreshToken> UserRefreshTokens { get; set; }
|
||||
|
|
@ -2459,21 +2455,21 @@ public partial class HoneyBoxDbContext : DbContext
|
|||
.HasColumnName("z_number");
|
||||
});
|
||||
|
||||
modelBuilder.Entity<UserVipReward>(entity =>
|
||||
modelBuilder.Entity<UserEquityReward>(entity =>
|
||||
{
|
||||
entity.HasKey(e => e.Id).HasName("pk_user_vip_rewards");
|
||||
entity.HasKey(e => e.Id).HasName("pk_user_equity_rewards");
|
||||
|
||||
entity.ToTable("user_vip_rewards", tb => tb.HasComment("用户领取的VIP奖品表"));
|
||||
entity.ToTable("user_equity_rewards", tb => tb.HasComment("用户领取的权益奖品表"));
|
||||
|
||||
entity.HasIndex(e => e.Type, "ix_user_vip_rewards_type");
|
||||
entity.HasIndex(e => e.Type, "ix_user_equity_rewards_type");
|
||||
|
||||
entity.HasIndex(e => e.UserId, "ix_user_vip_rewards_user_id");
|
||||
entity.HasIndex(e => e.UserId, "ix_user_equity_rewards_user_id");
|
||||
|
||||
entity.HasIndex(e => new { e.UserId, e.VipLevel }, "ix_user_vip_rewards_user_level");
|
||||
entity.HasIndex(e => new { e.UserId, e.EquityLevel }, "ix_user_equity_rewards_user_level");
|
||||
|
||||
entity.HasIndex(e => e.VipLevel, "ix_user_vip_rewards_vip_level");
|
||||
entity.HasIndex(e => e.EquityLevel, "ix_user_equity_rewards_equity_level");
|
||||
|
||||
entity.HasIndex(e => e.VipLevelId, "ix_user_vip_rewards_vip_level_id");
|
||||
entity.HasIndex(e => e.EquityLevelId, "ix_user_equity_rewards_equity_level_id");
|
||||
|
||||
entity.Property(e => e.Id)
|
||||
.HasComment("主键ID")
|
||||
|
|
@ -2549,26 +2545,26 @@ public partial class HoneyBoxDbContext : DbContext
|
|||
entity.Property(e => e.UserId)
|
||||
.HasComment("用户ID")
|
||||
.HasColumnName("user_id");
|
||||
entity.Property(e => e.VipLevel)
|
||||
entity.Property(e => e.EquityLevel)
|
||||
.HasDefaultValue(0)
|
||||
.HasComment("VIP等级")
|
||||
.HasColumnName("vip_level");
|
||||
entity.Property(e => e.VipLevelId)
|
||||
.HasComment("VIP等级ID")
|
||||
.HasColumnName("vip_level_id");
|
||||
.HasComment("权益等级")
|
||||
.HasColumnName("equity_level");
|
||||
entity.Property(e => e.EquityLevelId)
|
||||
.HasComment("权益等级ID")
|
||||
.HasColumnName("equity_level_id");
|
||||
entity.Property(e => e.ZNum)
|
||||
.HasDefaultValue(0)
|
||||
.HasComment("数量")
|
||||
.HasColumnName("z_num");
|
||||
});
|
||||
|
||||
modelBuilder.Entity<VipLevel>(entity =>
|
||||
modelBuilder.Entity<EquityLevel>(entity =>
|
||||
{
|
||||
entity.HasKey(e => e.Id).HasName("pk_vip_levels");
|
||||
entity.HasKey(e => e.Id).HasName("pk_equity_levels");
|
||||
|
||||
entity.ToTable("vip_levels", tb => tb.HasComment("VIP等级配置表"));
|
||||
entity.ToTable("equity_levels", tb => tb.HasComment("权益等级配置表"));
|
||||
|
||||
entity.HasIndex(e => e.Level, "ix_vip_levels_level");
|
||||
entity.HasIndex(e => e.Level, "ix_equity_levels_level");
|
||||
|
||||
entity.Property(e => e.Id)
|
||||
.HasComment("主键ID")
|
||||
|
|
@ -2581,10 +2577,10 @@ public partial class HoneyBoxDbContext : DbContext
|
|||
.HasComment("删除时间")
|
||||
.HasColumnName("deleted_at");
|
||||
entity.Property(e => e.Level)
|
||||
.HasComment("VIP等级")
|
||||
.HasComment("权益等级")
|
||||
.HasColumnName("level");
|
||||
entity.Property(e => e.Number)
|
||||
.HasComment("升级所需数量")
|
||||
.HasComment("升级所需欧气值")
|
||||
.HasColumnName("number");
|
||||
entity.Property(e => e.Title)
|
||||
.HasMaxLength(255)
|
||||
|
|
@ -2596,19 +2592,19 @@ public partial class HoneyBoxDbContext : DbContext
|
|||
.HasColumnName("updated_at");
|
||||
});
|
||||
|
||||
modelBuilder.Entity<VipLevelReward>(entity =>
|
||||
modelBuilder.Entity<EquityLevelReward>(entity =>
|
||||
{
|
||||
entity.HasKey(e => e.Id).HasName("pk_vip_level_rewards");
|
||||
entity.HasKey(e => e.Id).HasName("pk_equity_level_rewards");
|
||||
|
||||
entity.ToTable("vip_level_rewards", tb => tb.HasComment("VIP等级奖品配置表"));
|
||||
entity.ToTable("equity_level_rewards", tb => tb.HasComment("权益等级奖品配置表"));
|
||||
|
||||
entity.HasIndex(e => e.CouponId, "ix_vip_level_rewards_coupon_id");
|
||||
entity.HasIndex(e => e.CouponId, "ix_equity_level_rewards_coupon_id");
|
||||
|
||||
entity.HasIndex(e => e.Type, "ix_vip_level_rewards_type");
|
||||
entity.HasIndex(e => e.Type, "ix_equity_level_rewards_type");
|
||||
|
||||
entity.HasIndex(e => e.VipLevel, "ix_vip_level_rewards_vip_level");
|
||||
entity.HasIndex(e => e.EquityLevel, "ix_equity_level_rewards_equity_level");
|
||||
|
||||
entity.HasIndex(e => e.VipLevelId, "ix_vip_level_rewards_vip_level_id");
|
||||
entity.HasIndex(e => e.EquityLevelId, "ix_equity_level_rewards_equity_level_id");
|
||||
|
||||
entity.Property(e => e.Id)
|
||||
.HasComment("主键ID")
|
||||
|
|
@ -2679,13 +2675,13 @@ public partial class HoneyBoxDbContext : DbContext
|
|||
.HasDefaultValueSql("(getdate())")
|
||||
.HasComment("更新时间")
|
||||
.HasColumnName("updated_at");
|
||||
entity.Property(e => e.VipLevel)
|
||||
entity.Property(e => e.EquityLevel)
|
||||
.HasDefaultValue(0)
|
||||
.HasComment("VIP等级")
|
||||
.HasColumnName("vip_level");
|
||||
entity.Property(e => e.VipLevelId)
|
||||
.HasComment("VIP等级ID")
|
||||
.HasColumnName("vip_level_id");
|
||||
.HasComment("权益等级")
|
||||
.HasColumnName("equity_level");
|
||||
entity.Property(e => e.EquityLevelId)
|
||||
.HasComment("权益等级ID")
|
||||
.HasColumnName("equity_level_id");
|
||||
entity.Property(e => e.ZNum)
|
||||
.HasDefaultValue(0)
|
||||
.HasComment("数量")
|
||||
|
|
@ -3240,145 +3236,6 @@ public partial class HoneyBoxDbContext : DbContext
|
|||
.HasColumnName("prize_imgurl");
|
||||
});
|
||||
|
||||
modelBuilder.Entity<EquityLevel>(entity =>
|
||||
{
|
||||
entity.HasKey(e => e.Id).HasName("pk_equity_levels");
|
||||
|
||||
entity.ToTable("equity_levels", tb => tb.HasComment("权益等级表,存储用户权益等级配置"));
|
||||
|
||||
entity.HasIndex(e => e.Level, "ix_equity_levels_level");
|
||||
entity.HasIndex(e => e.DeletedAt, "ix_equity_levels_deleted_at");
|
||||
|
||||
entity.Property(e => e.Id)
|
||||
.HasComment("主键ID")
|
||||
.HasColumnName("id");
|
||||
entity.Property(e => e.Level)
|
||||
.HasComment("等级")
|
||||
.HasColumnName("level");
|
||||
entity.Property(e => e.Title)
|
||||
.HasMaxLength(100)
|
||||
.HasComment("等级名称")
|
||||
.HasColumnName("title");
|
||||
entity.Property(e => e.RequiredPoints)
|
||||
.HasDefaultValue(0)
|
||||
.HasComment("所需欧气值")
|
||||
.HasColumnName("required_points");
|
||||
entity.Property(e => e.CreatedAt)
|
||||
.HasDefaultValueSql("(getdate())")
|
||||
.HasComment("创建时间")
|
||||
.HasColumnName("created_at");
|
||||
entity.Property(e => e.UpdatedAt)
|
||||
.HasDefaultValueSql("(getdate())")
|
||||
.HasComment("更新时间")
|
||||
.HasColumnName("updated_at");
|
||||
entity.Property(e => e.DeletedAt)
|
||||
.HasComment("删除时间(软删除)")
|
||||
.HasColumnName("deleted_at");
|
||||
});
|
||||
|
||||
modelBuilder.Entity<EquityLevelPrize>(entity =>
|
||||
{
|
||||
entity.HasKey(e => e.Id).HasName("pk_equity_level_prizes");
|
||||
|
||||
entity.ToTable("equity_level_prizes", tb => tb.HasComment("权益等级奖品表,存储各等级对应的奖品配置"));
|
||||
|
||||
entity.HasIndex(e => e.QyLevelId, "ix_equity_level_prizes_qy_level_id");
|
||||
entity.HasIndex(e => e.Type, "ix_equity_level_prizes_type");
|
||||
entity.HasIndex(e => e.DeletedAt, "ix_equity_level_prizes_deleted_at");
|
||||
entity.HasIndex(e => e.Sort, "ix_equity_level_prizes_sort");
|
||||
|
||||
entity.Property(e => e.Id)
|
||||
.HasComment("主键ID")
|
||||
.HasColumnName("id");
|
||||
entity.Property(e => e.QyLevelId)
|
||||
.HasComment("权益等级ID")
|
||||
.HasColumnName("qy_level_id");
|
||||
entity.Property(e => e.QyLevel)
|
||||
.HasComment("权益等级")
|
||||
.HasColumnName("qy_level");
|
||||
entity.Property(e => e.Type)
|
||||
.HasDefaultValue((byte)2)
|
||||
.HasComment("奖品类型:1-优惠券 2-实物奖品")
|
||||
.HasColumnName("type");
|
||||
entity.Property(e => e.Title)
|
||||
.HasMaxLength(255)
|
||||
.HasComment("奖品标题")
|
||||
.HasColumnName("title");
|
||||
entity.Property(e => e.CouponId)
|
||||
.HasComment("优惠券ID")
|
||||
.HasColumnName("coupon_id");
|
||||
entity.Property(e => e.ZNum)
|
||||
.HasDefaultValue(0)
|
||||
.HasComment("优惠券数量")
|
||||
.HasColumnName("z_num");
|
||||
entity.Property(e => e.ManPrice)
|
||||
.HasDefaultValue(0m)
|
||||
.HasComment("满减门槛")
|
||||
.HasColumnType("decimal(10, 2)")
|
||||
.HasColumnName("man_price");
|
||||
entity.Property(e => e.JianPrice)
|
||||
.HasDefaultValue(0m)
|
||||
.HasComment("减免金额")
|
||||
.HasColumnType("decimal(10, 2)")
|
||||
.HasColumnName("jian_price");
|
||||
entity.Property(e => e.EffectiveDay)
|
||||
.HasDefaultValue(0)
|
||||
.HasComment("有效天数")
|
||||
.HasColumnName("effective_day");
|
||||
entity.Property(e => e.JiangPrice)
|
||||
.HasDefaultValue(0m)
|
||||
.HasComment("奖品价值")
|
||||
.HasColumnType("decimal(10, 2)")
|
||||
.HasColumnName("jiang_price");
|
||||
entity.Property(e => e.Money)
|
||||
.HasDefaultValue(0m)
|
||||
.HasComment("兑换价格")
|
||||
.HasColumnType("decimal(10, 2)")
|
||||
.HasColumnName("money");
|
||||
entity.Property(e => e.ScMoney)
|
||||
.HasDefaultValue(0m)
|
||||
.HasComment("市场参考价")
|
||||
.HasColumnType("decimal(10, 2)")
|
||||
.HasColumnName("sc_money");
|
||||
entity.Property(e => e.Probability)
|
||||
.HasDefaultValue(0m)
|
||||
.HasComment("中奖概率(0-100)")
|
||||
.HasColumnType("decimal(5, 2)")
|
||||
.HasColumnName("probability");
|
||||
entity.Property(e => e.ImgUrl)
|
||||
.HasMaxLength(500)
|
||||
.HasComment("奖品图片URL")
|
||||
.HasColumnName("imgurl");
|
||||
entity.Property(e => e.PrizeCode)
|
||||
.HasMaxLength(100)
|
||||
.HasComment("奖品编码")
|
||||
.HasColumnName("prize_code");
|
||||
entity.Property(e => e.ShangId)
|
||||
.HasComment("奖品等级ID")
|
||||
.HasColumnName("shang_id");
|
||||
entity.Property(e => e.Sort)
|
||||
.HasDefaultValue(0)
|
||||
.HasComment("排序")
|
||||
.HasColumnName("sort");
|
||||
entity.Property(e => e.CreatedAt)
|
||||
.HasDefaultValueSql("(getdate())")
|
||||
.HasComment("创建时间")
|
||||
.HasColumnName("created_at");
|
||||
entity.Property(e => e.UpdatedAt)
|
||||
.HasDefaultValueSql("(getdate())")
|
||||
.HasComment("更新时间")
|
||||
.HasColumnName("updated_at");
|
||||
entity.Property(e => e.DeletedAt)
|
||||
.HasComment("删除时间(软删除)")
|
||||
.HasColumnName("deleted_at");
|
||||
|
||||
entity.HasOne(d => d.EquityLevel)
|
||||
.WithMany(p => p.Prizes)
|
||||
.HasForeignKey(d => d.QyLevelId)
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.HasConstraintName("fk_equity_level_prizes_equity_levels");
|
||||
});
|
||||
|
||||
modelBuilder.Entity<GoodsKingRank>(entity =>
|
||||
{
|
||||
entity.HasKey(e => e.Id).HasName("pk_goods_king_ranks");
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ using System.Collections.Generic;
|
|||
namespace HoneyBox.Model.Entities;
|
||||
|
||||
/// <summary>
|
||||
/// 权益等级表
|
||||
/// 权益等级配置表
|
||||
/// </summary>
|
||||
public partial class EquityLevel
|
||||
{
|
||||
|
|
@ -14,7 +14,7 @@ public partial class EquityLevel
|
|||
public int Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 等级
|
||||
/// 权益等级
|
||||
/// </summary>
|
||||
public int Level { get; set; }
|
||||
|
||||
|
|
@ -24,27 +24,22 @@ public partial class EquityLevel
|
|||
public string Title { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// 所需欧气值
|
||||
/// 升级所需欧气值
|
||||
/// </summary>
|
||||
public int RequiredPoints { get; set; }
|
||||
public int Number { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 创建时间
|
||||
/// </summary>
|
||||
public DateTime? CreatedAt { get; set; }
|
||||
public DateTime CreatedAt { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 更新时间
|
||||
/// </summary>
|
||||
public DateTime? UpdatedAt { get; set; }
|
||||
public DateTime UpdatedAt { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 删除时间(软删除)
|
||||
/// 删除时间
|
||||
/// </summary>
|
||||
public DateTime? DeletedAt { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 关联的奖品列表
|
||||
/// </summary>
|
||||
public virtual ICollection<EquityLevelPrize> Prizes { get; set; } = new List<EquityLevelPrize>();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,119 +0,0 @@
|
|||
using System;
|
||||
|
||||
namespace HoneyBox.Model.Entities;
|
||||
|
||||
/// <summary>
|
||||
/// 权益等级奖品表
|
||||
/// </summary>
|
||||
public partial class EquityLevelPrize
|
||||
{
|
||||
/// <summary>
|
||||
/// 主键ID
|
||||
/// </summary>
|
||||
public int Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 权益等级ID
|
||||
/// </summary>
|
||||
public int QyLevelId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 权益等级
|
||||
/// </summary>
|
||||
public int QyLevel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 奖品类型:1-优惠券 2-实物奖品
|
||||
/// </summary>
|
||||
public byte Type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 奖品标题
|
||||
/// </summary>
|
||||
public string? Title { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 优惠券ID
|
||||
/// </summary>
|
||||
public int? CouponId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 优惠券数量
|
||||
/// </summary>
|
||||
public int? ZNum { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 满减门槛
|
||||
/// </summary>
|
||||
public decimal? ManPrice { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 减免金额
|
||||
/// </summary>
|
||||
public decimal? JianPrice { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 有效天数
|
||||
/// </summary>
|
||||
public int? EffectiveDay { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 奖品价值
|
||||
/// </summary>
|
||||
public decimal? JiangPrice { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 兑换价格
|
||||
/// </summary>
|
||||
public decimal? Money { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 市场参考价
|
||||
/// </summary>
|
||||
public decimal? ScMoney { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 中奖概率(0-100)
|
||||
/// </summary>
|
||||
public decimal? Probability { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 奖品图片URL
|
||||
/// </summary>
|
||||
public string? ImgUrl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 奖品编码
|
||||
/// </summary>
|
||||
public string? PrizeCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 奖品等级ID
|
||||
/// </summary>
|
||||
public int? ShangId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 排序
|
||||
/// </summary>
|
||||
public int? Sort { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 创建时间
|
||||
/// </summary>
|
||||
public DateTime? CreatedAt { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 更新时间
|
||||
/// </summary>
|
||||
public DateTime? UpdatedAt { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 删除时间(软删除)
|
||||
/// </summary>
|
||||
public DateTime? DeletedAt { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 关联的权益等级
|
||||
/// </summary>
|
||||
public virtual EquityLevel? EquityLevel { get; set; }
|
||||
}
|
||||
|
|
@ -1,12 +1,12 @@
|
|||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace HoneyBox.Model.Entities;
|
||||
|
||||
/// <summary>
|
||||
/// VIP等级奖品配置表
|
||||
/// 权益等级奖品配置表
|
||||
/// </summary>
|
||||
public partial class VipLevelReward
|
||||
public partial class EquityLevelReward
|
||||
{
|
||||
/// <summary>
|
||||
/// 主键ID
|
||||
|
|
@ -14,14 +14,14 @@ public partial class VipLevelReward
|
|||
public int Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// VIP等级ID
|
||||
/// 权益等级ID
|
||||
/// </summary>
|
||||
public int VipLevelId { get; set; }
|
||||
public int EquityLevelId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// VIP等级
|
||||
/// 权益等级
|
||||
/// </summary>
|
||||
public int? VipLevel { get; set; }
|
||||
public int? EquityLevel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 奖品类型
|
||||
|
|
@ -1,12 +1,12 @@
|
|||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace HoneyBox.Model.Entities;
|
||||
|
||||
/// <summary>
|
||||
/// 用户领取的VIP奖品表
|
||||
/// 用户领取的权益奖品表
|
||||
/// </summary>
|
||||
public partial class UserVipReward
|
||||
public partial class UserEquityReward
|
||||
{
|
||||
/// <summary>
|
||||
/// 主键ID
|
||||
|
|
@ -19,14 +19,14 @@ public partial class UserVipReward
|
|||
public int? UserId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// VIP等级ID
|
||||
/// 权益等级ID
|
||||
/// </summary>
|
||||
public int VipLevelId { get; set; }
|
||||
public int EquityLevelId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// VIP等级
|
||||
/// 权益等级
|
||||
/// </summary>
|
||||
public int? VipLevel { get; set; }
|
||||
public int? EquityLevel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 优惠券ID
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace HoneyBox.Model.Entities;
|
||||
|
||||
/// <summary>
|
||||
/// VIP等级配置表
|
||||
/// </summary>
|
||||
public partial class VipLevel
|
||||
{
|
||||
/// <summary>
|
||||
/// 主键ID
|
||||
/// </summary>
|
||||
public int Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// VIP等级
|
||||
/// </summary>
|
||||
public int Level { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 等级名称
|
||||
/// </summary>
|
||||
public string Title { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// 升级所需数量
|
||||
/// </summary>
|
||||
public int Number { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 创建时间
|
||||
/// </summary>
|
||||
public DateTime CreatedAt { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 更新时间
|
||||
/// </summary>
|
||||
public DateTime UpdatedAt { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 删除时间
|
||||
/// </summary>
|
||||
public DateTime? DeletedAt { get; set; }
|
||||
}
|
||||
|
|
@ -1,29 +1,29 @@
|
|||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace HoneyBox.Model.Models.Vip;
|
||||
namespace HoneyBox.Model.Models.Equity;
|
||||
|
||||
/// <summary>
|
||||
/// VIP信息响应
|
||||
/// 权益等级信息响应
|
||||
/// </summary>
|
||||
public class VipInfoResponse
|
||||
public class EquityInfoResponse
|
||||
{
|
||||
/// <summary>
|
||||
/// 用户VIP信息
|
||||
/// 用户权益信息
|
||||
/// </summary>
|
||||
[JsonPropertyName("userinfo")]
|
||||
public VipUserInfoDto Userinfo { get; set; } = new();
|
||||
public EquityUserInfoDto Userinfo { get; set; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// VIP等级列表
|
||||
/// 权益等级列表
|
||||
/// </summary>
|
||||
[JsonPropertyName("data")]
|
||||
public List<VipLevelDto> Data { get; set; } = new();
|
||||
public List<EquityLevelDto> Data { get; set; } = new();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// VIP用户信息DTO
|
||||
/// 权益用户信息DTO
|
||||
/// </summary>
|
||||
public class VipUserInfoDto
|
||||
public class EquityUserInfoDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 昵称
|
||||
|
|
@ -38,7 +38,7 @@ public class VipUserInfoDto
|
|||
public string Headimg { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 当前VIP等级
|
||||
/// 当前权益等级
|
||||
/// </summary>
|
||||
[JsonPropertyName("vip")]
|
||||
public int Vip { get; set; }
|
||||
|
|
@ -50,7 +50,7 @@ public class VipUserInfoDto
|
|||
public string UpgradeMoney { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 下一个VIP等级
|
||||
/// 下一个权益等级
|
||||
/// </summary>
|
||||
[JsonPropertyName("last_vip")]
|
||||
public int LastVip { get; set; }
|
||||
|
|
@ -69,9 +69,9 @@ public class VipUserInfoDto
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// VIP等级DTO
|
||||
/// 权益等级DTO
|
||||
/// </summary>
|
||||
public class VipLevelDto
|
||||
public class EquityLevelDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 等级ID
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace HoneyBox.Model.Models.Vip;
|
||||
namespace HoneyBox.Model.Models.Equity;
|
||||
|
||||
/// <summary>
|
||||
/// 权益中心响应
|
||||
|
|
@ -182,7 +182,7 @@ public class QyLevelServiceTests : IDisposable
|
|||
var level = await _dbContext.EquityLevels.FindAsync(1);
|
||||
Assert.NotNull(level);
|
||||
Assert.Equal("更新后的青铜会员", level.Title);
|
||||
Assert.Equal(200, level.RequiredPoints);
|
||||
Assert.Equal(200, level.Number);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -239,7 +239,7 @@ public class QyLevelServiceTests : IDisposable
|
|||
}
|
||||
|
||||
[Fact]
|
||||
public async Task UpdateQyLevelAsync_WithInvalidRequiredPoints_ThrowsException()
|
||||
public async Task UpdateQyLevelAsync_WithNegativeRequiredPoints_ThrowsException()
|
||||
{
|
||||
// Arrange
|
||||
await SeedTestQyLevels();
|
||||
|
|
@ -247,7 +247,7 @@ public class QyLevelServiceTests : IDisposable
|
|||
{
|
||||
Level = 1,
|
||||
Title = "测试",
|
||||
RequiredPoints = 0
|
||||
RequiredPoints = -1
|
||||
};
|
||||
|
||||
// Act & Assert
|
||||
|
|
@ -311,7 +311,7 @@ public class QyLevelServiceTests : IDisposable
|
|||
// Arrange
|
||||
await SeedTestQyLevelsWithPrizes();
|
||||
// Mark one prize as deleted
|
||||
var prize = await _dbContext.EquityLevelPrizes.FindAsync(1);
|
||||
var prize = await _dbContext.EquityLevelRewards.FindAsync(1);
|
||||
prize!.DeletedAt = DateTime.Now;
|
||||
await _dbContext.SaveChangesAsync();
|
||||
|
||||
|
|
@ -351,7 +351,7 @@ public class QyLevelServiceTests : IDisposable
|
|||
|
||||
// Assert
|
||||
Assert.True(id > 0);
|
||||
var prize = await _dbContext.EquityLevelPrizes.FindAsync(id);
|
||||
var prize = await _dbContext.EquityLevelRewards.FindAsync(id);
|
||||
Assert.NotNull(prize);
|
||||
Assert.Equal(2, prize.Type);
|
||||
Assert.Equal("测试实物奖品", prize.Title);
|
||||
|
|
@ -374,7 +374,7 @@ public class QyLevelServiceTests : IDisposable
|
|||
|
||||
// Assert
|
||||
Assert.True(id > 0);
|
||||
var prize = await _dbContext.EquityLevelPrizes.FindAsync(id);
|
||||
var prize = await _dbContext.EquityLevelRewards.FindAsync(id);
|
||||
Assert.NotNull(prize);
|
||||
Assert.Equal(1, prize.Type);
|
||||
Assert.Equal(1, prize.CouponId);
|
||||
|
|
@ -523,7 +523,7 @@ public class QyLevelServiceTests : IDisposable
|
|||
|
||||
// Assert
|
||||
Assert.True(result);
|
||||
var prize = await _dbContext.EquityLevelPrizes.FindAsync(2);
|
||||
var prize = await _dbContext.EquityLevelRewards.FindAsync(2);
|
||||
Assert.NotNull(prize);
|
||||
Assert.Equal("更新后的奖品", prize.Title);
|
||||
Assert.Equal(200, prize.JiangPrice);
|
||||
|
|
@ -564,7 +564,7 @@ public class QyLevelServiceTests : IDisposable
|
|||
|
||||
// Assert
|
||||
Assert.True(result);
|
||||
var prize = await _dbContext.EquityLevelPrizes.FindAsync(1);
|
||||
var prize = await _dbContext.EquityLevelRewards.FindAsync(1);
|
||||
Assert.NotNull(prize);
|
||||
Assert.NotNull(prize.DeletedAt);
|
||||
}
|
||||
|
|
@ -591,7 +591,7 @@ public class QyLevelServiceTests : IDisposable
|
|||
Id = 1,
|
||||
Level = 1,
|
||||
Title = "青铜会员",
|
||||
RequiredPoints = 100,
|
||||
Number = 100,
|
||||
CreatedAt = DateTime.Now,
|
||||
UpdatedAt = DateTime.Now
|
||||
},
|
||||
|
|
@ -600,7 +600,7 @@ public class QyLevelServiceTests : IDisposable
|
|||
Id = 2,
|
||||
Level = 2,
|
||||
Title = "白银会员",
|
||||
RequiredPoints = 500,
|
||||
Number = 500,
|
||||
CreatedAt = DateTime.Now.AddMinutes(-1),
|
||||
UpdatedAt = DateTime.Now.AddMinutes(-1)
|
||||
},
|
||||
|
|
@ -609,7 +609,7 @@ public class QyLevelServiceTests : IDisposable
|
|||
Id = 3,
|
||||
Level = 3,
|
||||
Title = "黄金会员",
|
||||
RequiredPoints = 1000,
|
||||
Number = 1000,
|
||||
CreatedAt = DateTime.Now.AddMinutes(-2),
|
||||
UpdatedAt = DateTime.Now.AddMinutes(-2)
|
||||
}
|
||||
|
|
@ -623,26 +623,23 @@ public class QyLevelServiceTests : IDisposable
|
|||
{
|
||||
await SeedTestQyLevels();
|
||||
|
||||
var prizes = new List<EquityLevelPrize>
|
||||
var prizes = new List<EquityLevelReward>
|
||||
{
|
||||
new()
|
||||
{
|
||||
Id = 1,
|
||||
QyLevelId = 1,
|
||||
QyLevel = 1,
|
||||
EquityLevelId = 1,
|
||||
Type = 1,
|
||||
Title = "优惠券奖品",
|
||||
CouponId = 1,
|
||||
ZNum = 5,
|
||||
Sort = 1,
|
||||
CreatedAt = DateTime.Now,
|
||||
UpdatedAt = DateTime.Now
|
||||
},
|
||||
new()
|
||||
{
|
||||
Id = 2,
|
||||
QyLevelId = 1,
|
||||
QyLevel = 1,
|
||||
EquityLevelId = 1,
|
||||
Type = 2,
|
||||
Title = "实物奖品",
|
||||
JiangPrice = 100,
|
||||
|
|
@ -650,13 +647,12 @@ public class QyLevelServiceTests : IDisposable
|
|||
ScMoney = 120,
|
||||
Probability = 10.5m,
|
||||
ImgUrl = "http://example.com/image.jpg",
|
||||
Sort = 2,
|
||||
CreatedAt = DateTime.Now.AddMinutes(-1),
|
||||
UpdatedAt = DateTime.Now.AddMinutes(-1)
|
||||
}
|
||||
};
|
||||
|
||||
_dbContext.EquityLevelPrizes.AddRange(prizes);
|
||||
_dbContext.EquityLevelRewards.AddRange(prizes);
|
||||
await _dbContext.SaveChangesAsync();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -124,21 +124,6 @@ public class UserBusinessServiceTests : IDisposable
|
|||
return (goods, item);
|
||||
}
|
||||
|
||||
private async Task<VipLevel> CreateTestVipLevelAsync()
|
||||
{
|
||||
var vipLevel = new VipLevel
|
||||
{
|
||||
Level = 1,
|
||||
Title = "VIP1",
|
||||
Number = 100,
|
||||
CreatedAt = DateTime.Now,
|
||||
UpdatedAt = DateTime.Now
|
||||
};
|
||||
_dbContext.VipLevels.Add(vipLevel);
|
||||
await _dbContext.SaveChangesAsync();
|
||||
return vipLevel;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region GetUserListAsync Tests
|
||||
|
|
@ -627,68 +612,6 @@ public class UserBusinessServiceTests : IDisposable
|
|||
|
||||
#endregion
|
||||
|
||||
#region VIP Management Tests
|
||||
|
||||
[Fact]
|
||||
public async Task GetVipLevelsAsync_ReturnsAllLevels()
|
||||
{
|
||||
// Arrange
|
||||
await CreateTestVipLevelAsync();
|
||||
var vip2 = new VipLevel
|
||||
{
|
||||
Level = 2,
|
||||
Title = "VIP2",
|
||||
Number = 500,
|
||||
CreatedAt = DateTime.Now,
|
||||
UpdatedAt = DateTime.Now
|
||||
};
|
||||
_dbContext.VipLevels.Add(vip2);
|
||||
await _dbContext.SaveChangesAsync();
|
||||
|
||||
// Act
|
||||
var result = await _userService.GetVipLevelsAsync();
|
||||
|
||||
// Assert
|
||||
Assert.Equal(2, result.Count);
|
||||
Assert.Equal("VIP1", result[0].Title);
|
||||
Assert.Equal("VIP2", result[1].Title);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task UpdateVipLevelAsync_UpdatesLevel()
|
||||
{
|
||||
// Arrange
|
||||
var vipLevel = await CreateTestVipLevelAsync();
|
||||
var request = new VipLevelUpdateRequest
|
||||
{
|
||||
Title = "Updated VIP",
|
||||
Number = 200
|
||||
};
|
||||
|
||||
// Act
|
||||
var result = await _userService.UpdateVipLevelAsync(vipLevel.Id, request);
|
||||
|
||||
// Assert
|
||||
Assert.True(result);
|
||||
var updated = await _dbContext.VipLevels.FindAsync(vipLevel.Id);
|
||||
Assert.Equal("Updated VIP", updated!.Title);
|
||||
Assert.Equal(200, updated.Number);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task UpdateVipLevelAsync_NonExistingLevel_ThrowsException()
|
||||
{
|
||||
// Arrange
|
||||
var request = new VipLevelUpdateRequest { Title = "Test", Number = 100 };
|
||||
|
||||
// Act & Assert
|
||||
var ex = await Assert.ThrowsAsync<BusinessException>(
|
||||
() => _userService.UpdateVipLevelAsync(99999, request));
|
||||
Assert.Equal(BusinessErrorCodes.NotFound, ex.Code);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region GetSubordinateUsersAsync Tests
|
||||
|
||||
[Fact]
|
||||
|
|
|
|||
|
|
@ -141,7 +141,7 @@ public class UserServicePropertyTests
|
|||
/// <summary>
|
||||
/// Property 11: VIP等级计算
|
||||
/// For any user with a given spending amount, CalculateVipLevelAsync should return
|
||||
/// a VIP level that matches the spending threshold configured in VipLevel table.
|
||||
/// a VIP level that matches the spending threshold configured in EquityLevel table.
|
||||
/// Validates: Requirements 4.5
|
||||
/// </summary>
|
||||
[Property(MaxTest = 100)]
|
||||
|
|
@ -150,15 +150,15 @@ public class UserServicePropertyTests
|
|||
var dbContext = CreateInMemoryDbContext();
|
||||
var userService = CreateUserService(dbContext);
|
||||
|
||||
// Setup VIP levels
|
||||
var vipLevels = new[]
|
||||
// Setup equity levels
|
||||
var equityLevels = new[]
|
||||
{
|
||||
new VipLevel { Level = 1, Title = "Bronze", Number = 100, CreatedAt = DateTime.UtcNow, UpdatedAt = DateTime.UtcNow },
|
||||
new VipLevel { Level = 2, Title = "Silver", Number = 500, CreatedAt = DateTime.UtcNow, UpdatedAt = DateTime.UtcNow },
|
||||
new VipLevel { Level = 3, Title = "Gold", Number = 1000, CreatedAt = DateTime.UtcNow, UpdatedAt = DateTime.UtcNow }
|
||||
new EquityLevel { Level = 1, Title = "Bronze", Number = 100, CreatedAt = DateTime.UtcNow, UpdatedAt = DateTime.UtcNow },
|
||||
new EquityLevel { Level = 2, Title = "Silver", Number = 500, CreatedAt = DateTime.UtcNow, UpdatedAt = DateTime.UtcNow },
|
||||
new EquityLevel { Level = 3, Title = "Gold", Number = 1000, CreatedAt = DateTime.UtcNow, UpdatedAt = DateTime.UtcNow }
|
||||
};
|
||||
|
||||
await dbContext.VipLevels.AddRangeAsync(vipLevels);
|
||||
await dbContext.EquityLevels.AddRangeAsync(equityLevels);
|
||||
await dbContext.SaveChangesAsync();
|
||||
|
||||
// Create user with spending
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user