feat: 完成激活码功能
This commit is contained in:
@@ -16,19 +16,15 @@ public class ActivationCodeCreateInput
|
|||||||
/// 数量
|
/// 数量
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int Count { get; set; } = 1;
|
public int Count { get; set; } = 1;
|
||||||
|
}
|
||||||
/// <summary>
|
|
||||||
/// 是否允许多人各使用一次
|
/// <summary>
|
||||||
/// </summary>
|
/// 批量生成激活码列表输入
|
||||||
public bool IsReusable { get; set; }
|
/// </summary>
|
||||||
|
public class ActivationCodeCreateListInput
|
||||||
/// <summary>
|
{
|
||||||
/// 是否限制同类型只能兑换一次
|
/// <summary>
|
||||||
/// </summary>
|
/// 生成项列表
|
||||||
public bool IsSameTypeOnce { get; set; }
|
/// </summary>
|
||||||
|
public List<ActivationCodeCreateInput> Items { get; set; } = new();
|
||||||
/// <summary>
|
|
||||||
/// 备注
|
|
||||||
/// </summary>
|
|
||||||
public string? Remark { get; set; }
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,3 +22,14 @@ public class ActivationCodeCreateOutput
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public List<string> Codes { get; set; } = new();
|
public List<string> Codes { get; set; } = new();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 批量生成激活码列表输出
|
||||||
|
/// </summary>
|
||||||
|
public class ActivationCodeCreateListOutput
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 分组输出
|
||||||
|
/// </summary>
|
||||||
|
public List<ActivationCodeCreateOutput> Items { get; set; } = new();
|
||||||
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ public interface IActivationCodeService : IApplicationService
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 批量生成激活码
|
/// 批量生成激活码
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Task<ActivationCodeCreateOutput> CreateBatchAsync(ActivationCodeCreateInput input);
|
Task<ActivationCodeCreateListOutput> CreateBatchAsync(ActivationCodeCreateListInput input);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 兑换激活码
|
/// 兑换激活码
|
||||||
|
|||||||
@@ -35,20 +35,29 @@ public class ActivationCodeService : ApplicationService, IActivationCodeService
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
[Authorize]
|
[Authorize]
|
||||||
[HttpPost("activationCode/Batch")]
|
[HttpPost("activationCode/Batch")]
|
||||||
public async Task<ActivationCodeCreateOutput> CreateBatchAsync(ActivationCodeCreateInput input)
|
public async Task<ActivationCodeCreateListOutput> CreateBatchAsync(ActivationCodeCreateListInput input)
|
||||||
{
|
{
|
||||||
var entities = await _activationCodeManager.CreateBatchAsync(
|
if (input.Items == null || input.Items.Count == 0)
|
||||||
input.GoodsType,
|
|
||||||
input.Count,
|
|
||||||
input.IsReusable,
|
|
||||||
input.IsSameTypeOnce,
|
|
||||||
input.Remark);
|
|
||||||
|
|
||||||
return new ActivationCodeCreateOutput
|
|
||||||
{
|
{
|
||||||
GoodsType = input.GoodsType,
|
throw new UserFriendlyException("生成列表不能为空");
|
||||||
Count = input.Count,
|
}
|
||||||
Codes = entities.Select(x => x.Code).ToList()
|
|
||||||
|
var entities = await _activationCodeManager.CreateBatchAsync(
|
||||||
|
input.Items.Select(x => (x.GoodsType, x.Count)).ToList());
|
||||||
|
|
||||||
|
var outputs = entities
|
||||||
|
.GroupBy(x => x.GoodsType)
|
||||||
|
.Select(group => new ActivationCodeCreateOutput
|
||||||
|
{
|
||||||
|
GoodsType = group.Key,
|
||||||
|
Count = group.Count(),
|
||||||
|
Codes = group.Select(x => x.Code).ToList()
|
||||||
|
})
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
return new ActivationCodeCreateListOutput
|
||||||
|
{
|
||||||
|
Items = outputs
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ public class ActivationCodeGoodsAttribute : Attribute
|
|||||||
public long TokenAmount { get; }
|
public long TokenAmount { get; }
|
||||||
public int VipMonths { get; }
|
public int VipMonths { get; }
|
||||||
public bool IsCombo { get; }
|
public bool IsCombo { get; }
|
||||||
|
public bool IsReusable { get; }
|
||||||
|
public bool IsSameTypeOnce { get; }
|
||||||
public string DisplayName { get; }
|
public string DisplayName { get; }
|
||||||
public string Content { get; }
|
public string Content { get; }
|
||||||
|
|
||||||
@@ -21,6 +23,8 @@ public class ActivationCodeGoodsAttribute : Attribute
|
|||||||
long tokenAmount,
|
long tokenAmount,
|
||||||
int vipMonths,
|
int vipMonths,
|
||||||
bool isCombo,
|
bool isCombo,
|
||||||
|
bool isReusable,
|
||||||
|
bool isSameTypeOnce,
|
||||||
string displayName,
|
string displayName,
|
||||||
string content)
|
string content)
|
||||||
{
|
{
|
||||||
@@ -28,6 +32,8 @@ public class ActivationCodeGoodsAttribute : Attribute
|
|||||||
TokenAmount = tokenAmount;
|
TokenAmount = tokenAmount;
|
||||||
VipMonths = vipMonths;
|
VipMonths = vipMonths;
|
||||||
IsCombo = isCombo;
|
IsCombo = isCombo;
|
||||||
|
IsReusable = isReusable;
|
||||||
|
IsSameTypeOnce = isSameTypeOnce;
|
||||||
DisplayName = displayName;
|
DisplayName = displayName;
|
||||||
Content = content;
|
Content = content;
|
||||||
}
|
}
|
||||||
@@ -41,37 +47,43 @@ public enum ActivationCodeGoodsTypeEnum
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 48.90【意心Ai会员1月+2000w 尊享Token】新人首单组合包(推荐)
|
/// 48.90【意心Ai会员1月+2000w 尊享Token】新人首单组合包(推荐)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[ActivationCodeGoods(48.90, 20000000, 1, true, "意心Ai会员1月+2000w 尊享Token", "新人首单组合包(推荐)")]
|
[ActivationCodeGoods(price: 48.90, tokenAmount: 20000000, vipMonths: 1, isCombo: true, isReusable: false,
|
||||||
|
isSameTypeOnce: true, displayName: "意心Ai会员1月+2000w 尊享Token", content: "新人首单组合包(推荐)")]
|
||||||
Vip1MonthPlus2000W = 1,
|
Vip1MonthPlus2000W = 1,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 1.00【10w 尊享Token】测试体验包
|
/// 1.00【10w 尊享Token】测试体验包
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[ActivationCodeGoods(1.00, 100000, 0, false, "10w 尊享Token", "测试体验包")]
|
[ActivationCodeGoods(price: 1.00, tokenAmount: 100000, vipMonths: 0, isCombo: false, isReusable: false,
|
||||||
|
isSameTypeOnce: false, displayName: "10w 尊享Token", content: "测试体验包")]
|
||||||
Premium10W = 2,
|
Premium10W = 2,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 9.90【1000w 尊享Token】意心会员首单回馈包
|
/// 9.90【1000w 尊享Token】意心会员首单回馈包
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[ActivationCodeGoods(9.90, 10000000, 0, false, "1000w 尊享Token", "意心会员首单回馈包")]
|
[ActivationCodeGoods(price: 9.90, tokenAmount: 10000000, vipMonths: 0, isCombo: false, isReusable: false,
|
||||||
|
isSameTypeOnce: true, displayName: "1000w 尊享Token", content: "意心会员首单回馈包")]
|
||||||
Premium1000W = 3,
|
Premium1000W = 3,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 22.90【意心Ai会员1月】特价包
|
/// 22.90【意心Ai会员1月】特价包
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[ActivationCodeGoods(22.90, 0, 1, false, "意心Ai会员1月", "特价包")]
|
[ActivationCodeGoods(price: 22.90, tokenAmount: 0, vipMonths: 1, isCombo: false, isReusable: false,
|
||||||
|
isSameTypeOnce: false, displayName: "意心Ai会员1月", content: "特价包")]
|
||||||
Vip1Month = 4,
|
Vip1Month = 4,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 138.90【5000w 尊享Token】特价包
|
/// 138.90【5000w 尊享Token】特价包
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[ActivationCodeGoods(138.90, 50000000, 0, false, "5000w 尊享Token", "特价包")]
|
[ActivationCodeGoods(price: 138.90, tokenAmount: 50000000, vipMonths: 0, isCombo: false, isReusable: false,
|
||||||
|
isSameTypeOnce: false, displayName: "5000w 尊享Token", content: "特价包")]
|
||||||
Premium5000W = 5,
|
Premium5000W = 5,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 198.90【1亿 尊享Token】特价包
|
/// 198.90【1亿 尊享Token】特价包
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[ActivationCodeGoods(198.90, 100000000, 0, false, "1亿 尊享Token", "特价包")]
|
[ActivationCodeGoods(price: 198.90, tokenAmount: 100000000, vipMonths: 0, isCombo: false, isReusable: false,
|
||||||
|
isSameTypeOnce: false, displayName: "1亿 尊享Token", content: "特价包")]
|
||||||
Premium1Yi = 6
|
Premium1Yi = 6
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -34,27 +34,36 @@ public class ActivationCodeManager : DomainService
|
|||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<List<ActivationCodeAggregateRoot>> CreateBatchAsync(ActivationCodeGoodsTypeEnum goodsType,
|
public async Task<List<ActivationCodeAggregateRoot>> CreateBatchAsync(
|
||||||
int count, bool isReusable, bool isSameTypeOnce, string? remark)
|
List<(ActivationCodeGoodsTypeEnum GoodsType, int Count)> items)
|
||||||
{
|
{
|
||||||
if (count <= 0)
|
|
||||||
{
|
|
||||||
throw new UserFriendlyException("生成数量必须大于0");
|
|
||||||
}
|
|
||||||
|
|
||||||
var entities = new List<ActivationCodeAggregateRoot>();
|
var entities = new List<ActivationCodeAggregateRoot>();
|
||||||
for (var i = 0; i < count; i++)
|
foreach (var item in items)
|
||||||
{
|
{
|
||||||
var code = await GenerateUniqueActivationCodeAsync();
|
if (item.Count <= 0)
|
||||||
entities.Add(new ActivationCodeAggregateRoot
|
|
||||||
{
|
{
|
||||||
Code = code,
|
throw new UserFriendlyException("生成数量必须大于0");
|
||||||
GoodsType = goodsType,
|
}
|
||||||
IsReusable = isReusable,
|
|
||||||
IsSameTypeOnce = isSameTypeOnce,
|
var goods = item.GoodsType.GetGoods();
|
||||||
UsedCount = 0,
|
if (goods == null)
|
||||||
Remark = remark
|
{
|
||||||
});
|
throw new UserFriendlyException("激活码商品类型无效");
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < item.Count; i++)
|
||||||
|
{
|
||||||
|
var code = await GenerateUniqueActivationCodeAsync();
|
||||||
|
entities.Add(new ActivationCodeAggregateRoot
|
||||||
|
{
|
||||||
|
Code = code,
|
||||||
|
GoodsType = item.GoodsType,
|
||||||
|
IsReusable = goods.IsReusable,
|
||||||
|
IsSameTypeOnce = goods.IsSameTypeOnce,
|
||||||
|
UsedCount = 0,
|
||||||
|
Remark = null
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
await _activationCodeRepository.InsertRangeAsync(entities);
|
await _activationCodeRepository.InsertRangeAsync(entities);
|
||||||
@@ -161,4 +170,5 @@ public class ActivationCodeManager : DomainService
|
|||||||
|
|
||||||
return builder.ToString();
|
return builder.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -358,8 +358,8 @@ namespace Yi.Abp.Web
|
|||||||
var app = context.GetApplicationBuilder();
|
var app = context.GetApplicationBuilder();
|
||||||
app.UseRouting();
|
app.UseRouting();
|
||||||
|
|
||||||
// app.ApplicationServices.GetRequiredService<ISqlSugarDbContext>().SqlSugarClient.CodeFirst.InitTables<AiModelEntity>();
|
// app.ApplicationServices.GetRequiredService<ISqlSugarDbContext>().SqlSugarClient.CodeFirst.InitTables<ActivationCodeAggregateRoot>();
|
||||||
// app.ApplicationServices.GetRequiredService<ISqlSugarDbContext>().SqlSugarClient.CodeFirst.InitTables<TokenAggregateRoot>();
|
// app.ApplicationServices.GetRequiredService<ISqlSugarDbContext>().SqlSugarClient.CodeFirst.InitTables<ActivationCodeRecordAggregateRoot>();
|
||||||
// app.ApplicationServices.GetRequiredService<ISqlSugarDbContext>().SqlSugarClient.CodeFirst.InitTables<UsageStatisticsAggregateRoot>();
|
// app.ApplicationServices.GetRequiredService<ISqlSugarDbContext>().SqlSugarClient.CodeFirst.InitTables<UsageStatisticsAggregateRoot>();
|
||||||
|
|
||||||
//跨域
|
//跨域
|
||||||
|
|||||||
Reference in New Issue
Block a user