diff --git a/GDZZ.Application/Entity/InvitationCode.cs b/GDZZ.Application/Entity/InvitationCode.cs new file mode 100644 index 0000000..6934436 --- /dev/null +++ b/GDZZ.Application/Entity/InvitationCode.cs @@ -0,0 +1,23 @@ +using System; +using SqlSugar; +using System.ComponentModel; +using GDZZ.Core.Entity; +namespace GDZZ.Application.Entity +{ + /// + /// 邀请码表 + /// + [SugarTable("InvitationCode")] + [Description("邀请码表")] + public class InvitationCode : DEntityBase + { + /// + /// 企业ID + /// + public long EnterpriseID { get; set; } + /// + /// 邀请码 + /// + public long InviteCode { get; set; } + } +} \ No newline at end of file diff --git a/GDZZ.Application/Entity/InviteUserPos.cs b/GDZZ.Application/Entity/InviteUserPos.cs new file mode 100644 index 0000000..dbb8624 --- /dev/null +++ b/GDZZ.Application/Entity/InviteUserPos.cs @@ -0,0 +1,27 @@ +using System; +using SqlSugar; +using System.ComponentModel; +using GDZZ.Core.Entity; +namespace GDZZ.Application.Entity +{ + /// + /// 邀请用户表 + /// + [SugarTable("Invite_user_pos")] + [Description("邀请用户表")] + public class InviteUserPos : PrimaryKeyEntity + { + /// + /// 邀请码ID + /// + public long InviteID { get; set; } + /// + /// 被邀请用户ID + /// + public long UserID { get; set; } + /// + /// 邀请人ID + /// + public long InviteUserID { get; set; } + } +} \ No newline at end of file diff --git a/GDZZ.Application/GDZZ.Application.csproj b/GDZZ.Application/GDZZ.Application.csproj index 0512eed..d85ddef 100644 --- a/GDZZ.Application/GDZZ.Application.csproj +++ b/GDZZ.Application/GDZZ.Application.csproj @@ -16,6 +16,7 @@ + diff --git a/GDZZ.Application/GDZZ.Application.xml b/GDZZ.Application/GDZZ.Application.xml index d0acb29..cea7f17 100644 --- a/GDZZ.Application/GDZZ.Application.xml +++ b/GDZZ.Application/GDZZ.Application.xml @@ -199,6 +199,41 @@ 反馈意见 + + + 邀请码表 + + + + + 企业ID + + + + + 邀请码 + + + + + 邀请用户表 + + + + + 邀请码ID + + + + + 被邀请用户ID + + + + + 邀请人ID + + 聊天历史任务列表 @@ -706,6 +741,20 @@ + + + + + + + + + + 根据ID生成六位随机邀请码 + + 用户id + 返回6位邀请码 + 获取配置文件 @@ -1558,6 +1607,104 @@ + + + 邀请码表输出参数 + + + + + 主键Id + + + + + 企业ID + + + + + 邀请码 + + + + + 邀请码表输入参数 + + + + + 企业ID + + + + + 邀请码 + + + + + 主键Id + + + + + 主键Id + + + + + 邀请码表输出参数 + + + + + 主键Id + + + + + 企业ID + + + + + 邀请码 + + + + + 邀请码表服务 + + + + + 获取邀请码 + + + + + + + 获取邀请码详情 + + + + + + + 获取邀请人数 + + + + + + + 填写邀请码 + + + + 聊天历史任务列表输出参数 diff --git a/GDZZ.Application/Help/Utils.cs b/GDZZ.Application/Help/Utils.cs index 8ad946b..8f7b90a 100644 --- a/GDZZ.Application/Help/Utils.cs +++ b/GDZZ.Application/Help/Utils.cs @@ -1,13 +1,30 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Reflection; using System.Text; using System.Threading.Tasks; namespace GDZZ.Application.Help { - public class Utils + public static class Utils { + + //自定义进制(0、O没有加入,容易混淆;同时排除X,用X补位) + private static char[] r = new char[] { 'Q', 'W', 'E', '8', 'A', 'S', '2', 'D', 'Z', '9', 'C', '7', 'P', '5', 'I', 'K', '3', 'M', 'J', 'U', 'F', 'R', '4', 'V', 'Y', 'L', 'T', 'N', '6', 'B', 'G', 'H' }; + //不能与自定义进制有重复 + private static char b = 'X'; + //进制长度 + private static int binLen = r.Length; + //生成的邀请码长度 + private static int length = 6; + + static Random random = new Random(); + /// + /// + /// + /// + /// public static bool ShowHelp(DateTime date) { bool isTheDay = false; @@ -27,5 +44,48 @@ namespace GDZZ.Application.Help } return isTheDay; } + + + + /// + /// 根据ID生成六位随机邀请码 + /// + /// 用户id + /// 返回6位邀请码 + public static string Encode(long id) + { + char[] buf = new char[32]; + int charPos = 32; + + while ((id / binLen) > 0) + { + int ind = (int)(id % binLen); + buf[--charPos] = r[ind]; + id /= binLen; + } + buf[--charPos] = r[(int)(id % binLen)]; + String str = new String(buf, charPos, (32 - charPos)); + //不够长度的自动随机补全 + if (str.Length < length) + { + StringBuilder sb = new StringBuilder(); + sb.Append(b); + Random rnd = new Random(); + for (int i = 1; i < length - str.Length; i++) + { + sb.Append(r[rnd.Next(binLen)]); + } + str += sb.ToString(); + } + return str; + } + + public static long NextLong(long minValue, long maxValue) + { + byte[] buffer = new byte[8]; + random.NextBytes(buffer); + long result = BitConverter.ToInt64(buffer, 0); + return (Math.Abs(result % (maxValue - minValue)) + minValue); + } } } diff --git a/GDZZ.Application/Service/InvitationCode/Dto/InvitationCodeDto.cs b/GDZZ.Application/Service/InvitationCode/Dto/InvitationCodeDto.cs new file mode 100644 index 0000000..401637a --- /dev/null +++ b/GDZZ.Application/Service/InvitationCode/Dto/InvitationCodeDto.cs @@ -0,0 +1,27 @@ +using System; +using GDZZ.Core; + +namespace GDZZ.Application +{ + /// + /// 邀请码表输出参数 + /// + public class InvitationCodeDto + { + /// + /// 主键Id + /// + public long Id { get; set; } + + /// + /// 企业ID + /// + public long EnterpriseID { get; set; } + + /// + /// 邀请码 + /// + public long Code { get; set; } + + } +} diff --git a/GDZZ.Application/Service/InvitationCode/Dto/InvitationCodeInput.cs b/GDZZ.Application/Service/InvitationCode/Dto/InvitationCodeInput.cs new file mode 100644 index 0000000..57cda91 --- /dev/null +++ b/GDZZ.Application/Service/InvitationCode/Dto/InvitationCodeInput.cs @@ -0,0 +1,53 @@ +using GDZZ.Core; +using System; +using System.ComponentModel.DataAnnotations; + +namespace GDZZ.Application +{ + /// + /// 邀请码表输入参数 + /// + public class InvitationCodeInput : PageInputBase + { + /// + /// 企业ID + /// + public virtual long EnterpriseID { get; set; } + + /// + /// 邀请码 + /// + public long InviteCode { get; set; } + + + } + + public class AddInvitationCodeInput : InvitationCodeInput + { + } + + public class DeleteInvitationCodeInput + { + /// + /// 主键Id + /// + [Required(ErrorMessage = "主键Id不能为空")] + public long Id { get; set; } + + } + + public class UpdateInvitationCodeInput : InvitationCodeInput + { + /// + /// 主键Id + /// + [Required(ErrorMessage = "主键Id不能为空")] + public long Id { get; set; } + + } + + public class QueryeInvitationCodeInput : DeleteInvitationCodeInput + { + + } +} diff --git a/GDZZ.Application/Service/InvitationCode/Dto/InvitationCodeOutput.cs b/GDZZ.Application/Service/InvitationCode/Dto/InvitationCodeOutput.cs new file mode 100644 index 0000000..c0cb08c --- /dev/null +++ b/GDZZ.Application/Service/InvitationCode/Dto/InvitationCodeOutput.cs @@ -0,0 +1,26 @@ +using System; + +namespace GDZZ.Application +{ + /// + /// 邀请码表输出参数 + /// + public class InvitationCodeOutput + { + /// + /// 主键Id + /// + public long Id { get; set; } + + /// + /// 企业ID + /// + public long EnterpriseID { get; set; } + + /// + /// 邀请码 + /// + public long Code { get; set; } + + } +} diff --git a/GDZZ.Application/Service/InvitationCode/IInvitationCodeService.cs b/GDZZ.Application/Service/InvitationCode/IInvitationCodeService.cs new file mode 100644 index 0000000..e3eaad1 --- /dev/null +++ b/GDZZ.Application/Service/InvitationCode/IInvitationCodeService.cs @@ -0,0 +1,13 @@ +using GDZZ.Core; +using Microsoft.AspNetCore.Mvc; +using System.Threading.Tasks; +using GDZZ.Application.Entity; +namespace GDZZ.Application +{ + public interface IInvitationCodeService + { + Task AddOrUpdate(AddInvitationCodeInput input); + + Task Get([FromQuery] QueryeInvitationCodeInput input); + } +} \ No newline at end of file diff --git a/GDZZ.Application/Service/InvitationCode/InvitationCodeService.cs b/GDZZ.Application/Service/InvitationCode/InvitationCodeService.cs new file mode 100644 index 0000000..68a663a --- /dev/null +++ b/GDZZ.Application/Service/InvitationCode/InvitationCodeService.cs @@ -0,0 +1,130 @@ +using GDZZ.Core; +using Furion.DependencyInjection; +using Furion.DynamicApiController; +using Mapster; +using Microsoft.AspNetCore.Mvc; +using SqlSugar; +using System.Linq; +using System.Threading.Tasks; +using GDZZ.Application.Entity; +using GDZZ.Application.Help; +using Furion.DistributedIDGenerator; +using Furion.FriendlyException; +using System; + +namespace GDZZ.Application +{ + /// + /// 邀请码表服务 + /// + [ApiDescriptionSettings("Application", Name = "InvitationCode", Order = 1)] + public class InvitationCodeService : IInvitationCodeService, IDynamicApiController, ITransient + { + private readonly SqlSugarRepository _rep; + + private readonly SqlSugarRepository inviteUserPosrep; + + public InvitationCodeService(SqlSugarRepository rep, SqlSugarRepository inviteUserPosrep) + { + _rep = rep; + this.inviteUserPosrep = inviteUserPosrep; + } + + + /// + /// 获取邀请码 + /// + /// + /// + [HttpPost("/InvitationCode/AddOrUpdate")] + public async Task AddOrUpdate(AddInvitationCodeInput input) + { + + var entity = input.Adapt(); + var first = await this._rep.FirstOrDefaultAsync(x => x.InviteCode == entity.InviteCode); + if (first.IsNullOrZero()) + { + entity.InviteCode = Utils.NextLong(0, 100000000); + entity.EnterpriseID = UserManager.UserId; + var incode = await this._rep.FirstOrDefaultAsync(x => x.InviteCode == entity.InviteCode); + if (incode.IsNullOrZero()) + await _rep.InsertAsync(entity); + } + else + { + first.InviteCode = Utils.NextLong(0, 100000000); + await _rep.AsUpdateable(first).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync(); + } + } + + + + /// + /// 获取邀请码详情 + /// + /// + /// + [HttpGet("/InvitationCode/Detail")] + public async Task Get([FromQuery] QueryeInvitationCodeInput input) + { + var invitation = await _rep.FirstOrDefaultAsync(u => u.CreatedUserId == UserManager.UserId); + if (invitation == null) + throw Oops.Oh("暂无邀请码"); + return invitation; + + } + + + /// + /// 获取邀请人数 + /// + /// + /// + [HttpGet("/InvitationCode/GetPNumber")] + public async Task GetPNumber() + { + var invitation = await this.inviteUserPosrep.Where(u => u.InviteUserID == UserManager.UserId).ToArrayAsync(); + if (invitation.IsNullOrZero()) + throw Oops.Oh("暂无邀请人"); + return invitation.Count(); + } + + + /// + /// 填写邀请码 + /// + /// + /// + [HttpPost("/Mini/InvitationCode/Receive")] + public async Task Receive(AddInvitationCodeInput input) + { + var incode = await this._rep.FirstOrDefaultAsync(x => x.InviteCode == input.InviteCode); + if (incode.IsNullOrZero()) + throw Oops.Oh("无此邀请码!"); + this.inviteUserPosrep.Insert(new InviteUserPos() + { + InviteID = incode.Id, + InviteUserID = (long)incode.CreatedUserId, + UserID = UserManager.UserId, + }); + } + + + /// + /// 获取邀请码 + /// + /// + /// + [HttpGet("/Mini/InvitationCode/GetNumber")] + public async Task GetNumber() + { + var inviteUserPos = await this.inviteUserPosrep.FirstOrDefaultAsync(u => u.UserID == UserManager.UserId); + if (inviteUserPos.IsNullOrZero()) + return 0; + var res = await this._rep.FirstOrDefaultAsync(x => x.Id == inviteUserPos.InviteID); + return res.InviteCode; + } + + + } +} diff --git a/GDZZ.Core/GDZZ.Core.xml b/GDZZ.Core/GDZZ.Core.xml index 3ff130b..101f44d 100644 --- a/GDZZ.Core/GDZZ.Core.xml +++ b/GDZZ.Core/GDZZ.Core.xml @@ -9395,6 +9395,13 @@ + + + 根据ID生成六位随机邀请码 + + 用户id + 返回6位邀请码 + 枚举的Entity类 diff --git a/GDZZ.Core/Service/User/SysUserService.cs b/GDZZ.Core/Service/User/SysUserService.cs index 62b2865..9fd00a4 100644 --- a/GDZZ.Core/Service/User/SysUserService.cs +++ b/GDZZ.Core/Service/User/SysUserService.cs @@ -24,6 +24,7 @@ namespace GDZZ.Core.Service; [ApiDescriptionSettings(Name = "User", Order = 150)] public class SysUserService : ISysUserService, IDynamicApiController, ITransient { + private readonly SqlSugarRepository _sysUserRep; // 用户表仓储 private readonly ISysCacheService _sysCacheService; diff --git a/GDZZ.Core/Util/Encode/InvitaCode.cs b/GDZZ.Core/Util/Encode/InvitaCode.cs new file mode 100644 index 0000000..c5acc49 --- /dev/null +++ b/GDZZ.Core/Util/Encode/InvitaCode.cs @@ -0,0 +1,55 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; + +namespace GDZZ.Core +{ + public class InvitaCode + { + + //自定义进制(0、O没有加入,容易混淆;同时排除X,用X补位) + private static char[] r = new char[] { 'Q', 'W', 'E', '8', 'A', 'S', '2', 'D', 'Z', '9', 'C', '7', 'P', '5', 'I', 'K', '3', 'M', 'J', 'U', 'F', 'R', '4', 'V', 'Y', 'L', 'T', 'N', '6', 'B', 'G', 'H' }; + //不能与自定义进制有重复 + private static char b = 'X'; + //进制长度 + private static int binLen = r.Length; + //生成的邀请码长度 + private static int length = 6; + + /// + /// 根据ID生成六位随机邀请码 + /// + /// 用户id + /// 返回6位邀请码 + public static string Encode(long id) + { + char[] buf = new char[32]; + int charPos = 32; + + while ((id / binLen) > 0) + { + int ind = (int)(id % binLen); + buf[--charPos] = r[ind]; + id /= binLen; + } + buf[--charPos] = r[(int)(id % binLen)]; + String str = new String(buf, charPos, (32 - charPos)); + //不够长度的自动随机补全 + if (str.Length < length) + { + StringBuilder sb = new StringBuilder(); + sb.Append(b); + Random rnd = new Random(); + for (int i = 1; i < length - str.Length; i++) + { + sb.Append(r[rnd.Next(binLen)]); + } + str += sb.ToString(); + } + return str; + } + } +}