Admin.NET/Admin.NET.Application/Configuration/Swagger.json
@@ -31,6 +31,13 @@ "Description": "非政府采购交易平台", "Version": "1.0.0", "Order": 10000 }, { "Group": "FZCAPISYS", "Title": "前端系统", "Description": "非政府采购交易平台", "Version": "1.0.0", "Order": 10000 } ], "DefaultGroupName": "Default", // 默认分组名 Admin.NET/Admin.NET.Core/Service/Auth/SysAuthService.cs
Admin.NET/FZCTB.NET.API.Application/Auth/AuthService.cs
New file @@ -0,0 +1,18 @@ using Furion.DynamicApiController; using Microsoft.AspNetCore.Mvc; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace FZCTB.NET.API.Application.Auth { /// <summary> /// 鉴权服务 /// </summary> [ApiDescriptionSettings("FZCAPISYS", Order = 149)] public class AuthService: IDynamicApiController { } } Admin.NET/FZCTB.NET.API.Application/FZCTB.NET.API.Application.csproj
@@ -10,6 +10,7 @@ <ProjectReference Include="..\Admin.NET.Application\Admin.NET.Application.csproj" /> <ProjectReference Include="..\Admin.NET.Core\Admin.NET.Core.csproj" /> <ProjectReference Include="..\FZCZTB.NET.MD\FZCZTB.NET.MD.csproj" /> <ProjectReference Include="..\FZCZTB.NET.SYSService\FZCZTB.NET.SYSService.csproj" /> </ItemGroup> </Project> Admin.NET/FZCTB.NET.API.Application/User/CustomerService.cs
New file @@ -0,0 +1,47 @@ // Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。 // // 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。 // // 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任! using Admin.NET.Core.Service; using Furion.DynamicApiController; using FZCZTB.NET.MD.CutomerMd; using FZCZTB.NET.SYSService.CustomerSYS; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace FZCTB.NET.API.Application.User; /// <summary> /// 客户处里 /// </summary> public class CustomerService: IDynamicApiController { private readonly CustomerManagerS _customerManager; private readonly SysCacheService _sysCacheService; /// <summary> /// /// </summary> public CustomerService(SysCacheService cacheService, CustomerManagerS managerS) { _sysCacheService= cacheService; _customerManager = managerS; } /// <summary> /// 用户注册 /// </summary> /// <returns></returns> public async Task<bool> CustomerRegistration(CustomerDto param ) { //_customerManager. await Task.CompletedTask; return true; } } Admin.NET/FZCZTB.NET.SYSService/CustomerSYS/CustomerManager.cs
File was deleted Admin.NET/FZCZTB.NET.SYSService/CustomerSYS/CustomerManagerS.cs
New file @@ -0,0 +1,339 @@ using Admin.NET.Core; using Admin.NET.Core.Service; using Furion.DependencyInjection; using FZCZTB.NET.MD.CutomerMd; using Mapster; using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; using System.Text; using System.Threading.Tasks; namespace FZCZTB.NET.SYSService.CustomerSYS { /// <summary> /// customermanger 服务 /// </summary> public class CustomerManagerS: IScoped { private readonly SqlSugarRepository<FBS_ExRole> _fBS_ExRoleRep; private readonly SqlSugarRepository<FBS_Customer> _fBS_CustomerRep; private readonly SysCacheService _sysCacheService; public CustomerManagerS(SysCacheService sysCacheService, SqlSugarRepository<FBS_ExRole> fBS_ExRoleRep, SqlSugarRepository<FBS_Customer> fBS_CustomerRep) { _sysCacheService = sysCacheService; _fBS_ExRoleRep = fBS_ExRoleRep; _fBS_CustomerRep = fBS_CustomerRep; } /// <summary> /// 返回当前可用的用户角色 再注册和登录时需要返回编码 /// </summary> /// <returns></returns> public async Task< List<ExRoleVM>> GetExRole() { return await _fBS_ExRoleRep.AsQueryable().Where(x=>x.Status== StatusEnum.Enable) .Select<ExRoleVM>().WithCache(20).ToListAsync(); } /// <summary> /// 返回当前可用的用户角色 再注册和登录时需要返回编码 /// </summary> /// <returns></returns> public async Task<CustomerDto> GetCustomer(int id) { return (await _fBS_CustomerRep.GetFirstAsync(x => x.Id == id && x.Status == StatusEnum.Enable)).Adapt<CustomerDto>(); } /// <summary> /// 返回当前可用的用户角色 再注册和登录时需要返回编码 /// </summary> /// <returns></returns> public async Task<CustomerDto> UpDataCustomer(int id) { return (await _fBS_CustomerRep.GetFirstAsync(x => x.Id == id && x.Status == StatusEnum.Enable)).Adapt<CustomerDto>(); } } /// <summary> /// 客户主分类角色基础输入参数 /// </summary> public class ExRoleVM { /// <summary> /// 主键Id /// </summary> public virtual long? Id { get; set; } /// <summary> /// 名称 /// </summary> [Required(ErrorMessage = "名称不能为空")] public virtual string Name { get; set; } /// <summary> /// 编码 /// </summary> public virtual string? Code { get; set; } /// <summary> /// 排序 /// </summary> [Required(ErrorMessage = "排序不能为空")] public virtual int? OrderNo { get; set; } /// <summary> /// 数据范围 /// </summary> [Dict(nameof(DataScopeEnum), AllowNullValue = true)] [Required(ErrorMessage = "数据范围不能为空")] public virtual DataScopeEnum? DataScope { get; set; } /// <summary> /// 备注 /// </summary> public virtual string? Remark { get; set; } /// <summary> /// 状态 /// </summary> [Dict(nameof(StatusEnum), AllowNullValue = true)] [Required(ErrorMessage = "状态不能为空")] public virtual StatusEnum? Status { get; set; } } /// <summary> /// 客户表输出参数 /// </summary> public class CustomerDto { /// <summary> /// 主键Id /// </summary> public long Id { get; set; } /// <summary> /// 账号 /// </summary> public string Account { get; set; } /// <summary> /// 密码 /// </summary> public string Password { get; set; } /// <summary> /// 真实姓名 /// </summary> public string RealName { get; set; } /// <summary> /// 昵称 /// </summary> public string? NickName { get; set; } /// <summary> /// 头像 /// </summary> public string? Avatar { get; set; } /// <summary> /// 性别 /// </summary> public GenderEnum Sex { get; set; } /// <summary> /// 年龄 /// </summary> public int Age { get; set; } /// <summary> /// 出生日期 /// </summary> public DateTime? Birthday { get; set; } /// <summary> /// 民族 /// </summary> public string? Nation { get; set; } /// <summary> /// 手机号码 /// </summary> public string? Phone { get; set; } /// <summary> /// 证件类型 /// </summary> public CardTypeEnum CardType { get; set; } /// <summary> /// 身份证号 /// </summary> public string? IdCardNum { get; set; } /// <summary> /// 身份证 /// </summary> public string? IdCardPath { get; set; } /// <summary> /// 邮箱 /// </summary> public string? Email { get; set; } /// <summary> /// 地址 /// </summary> public string? Address { get; set; } /// <summary> /// 文化程度 /// </summary> public CultureLevelEnum CultureLevel { get; set; } /// <summary> /// 政治面貌 /// </summary> public string? PoliticalOutlook { get; set; } /// <summary> /// 毕业院校 /// </summary> public string? College { get; set; } /// <summary> /// 办公电话 /// </summary> public string? OfficePhone { get; set; } /// <summary> /// 紧急联系人 /// </summary> public string? EmergencyContact { get; set; } /// <summary> /// 紧急联系人电话 /// </summary> public string? EmergencyPhone { get; set; } /// <summary> /// 紧急联系人地址 /// </summary> public string? EmergencyAddress { get; set; } /// <summary> /// 个人简介 /// </summary> public string? Introduction { get; set; } /// <summary> /// 排序 /// </summary> public int OrderNo { get; set; } /// <summary> /// 状态 /// </summary> public StatusEnum Status { get; set; } /// <summary> /// 备注 /// </summary> public string? Remark { get; set; } /// <summary> /// 职级 /// </summary> public string? PosLevel { get; set; } /// <summary> /// 职称 /// </summary> public string? PosTitle { get; set; } /// <summary> /// 擅长领域 /// </summary> public string? Expertise { get; set; } /// <summary> /// 办公区域 /// </summary> public string? OfficeZone { get; set; } /// <summary> /// 办公室 /// </summary> public string? Office { get; set; } /// <summary> /// 入职日期 /// </summary> public DateTime? JoinDate { get; set; } /// <summary> /// 最新登录Ip /// </summary> public string? LastLoginIp { get; set; } /// <summary> /// 最新登录地点 /// </summary> public string? LastLoginAddress { get; set; } /// <summary> /// 最新登录时间 /// </summary> public DateTime? LastLoginTime { get; set; } /// <summary> /// 最新登录设备 /// </summary> public string? LastLoginDevice { get; set; } /// <summary> /// 电子签名 /// </summary> public string? Signature { get; set; } /// <summary> /// 租户Id /// </summary> public long? TenantId { get; set; } /// <summary> /// 注册用户角色 /// </summary> public string? ExRoleCode { get; set; } } } Admin.NET/FZCZTB.NET.SYSService/FZCZTB.NET.SYSService.csproj
@@ -8,6 +8,7 @@ <ItemGroup> <ProjectReference Include="..\Admin.NET.Core\Admin.NET.Core.csproj" /> <ProjectReference Include="..\FZCZTB.NET.MD\FZCZTB.NET.MD.csproj" /> </ItemGroup> </Project> Admin.NET/FZCZTB.NET.SYSService/FZCZTSYSServiceConfig.json
New file @@ -0,0 +1,24 @@ { "SMSConfigMd": { "LingKaiXinxiSets": { //凌凯短信配置 "Url": "https://mb345.com/ws/BatchSend2.aspx", "Number": "XP010534", "AccountPassPassword": "123321", "VerifyTimeOut": 60, //秒 "Templates": [ { "Id": "0", "SignName": "【政采咨询网】", //需要加入的公司标签 "TemplateCode": "VCode", "Content": "您的验证码为:${code},请勿泄露于他人!" }, { "Id": "1", "SignName": "【政采咨询网】", "TemplateCode": "RegistrationOK ", "Content": "注册成功,感谢您的注册,请妥善保管您的账户信息" } ] } } } Admin.NET/FZCZTB.NET.SYSService/MSM/SMSConfigMd.cs
New file @@ -0,0 +1,48 @@ // Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。 // // 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。 // // 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任! using Admin.NET.Core; using Furion.ConfigurableOptions; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace FZCZTB.NET.SYSService.MSM; public class SMSConfigOptions : IConfigurableOptions { /// <summary> /// 凌凯信息配置 /// </summary> public LingKaiXinxiSets lingKai { get; set; } } public class LingKaiXinxiSets { /// <summary> /// d地址 /// </summary> public string Url { get; set; } /// <summary> /// 账号 /// </summary> public string Number { get; set; } /// <summary> /// 密码 /// </summary> public string AccountPassPassword { get; set; } /// <summary> /// 超时时间 /// </summary> public int VerifyTimeOut { get; set; } /// <summary> /// Templates /// </summary> public List<SmsTemplate> Templates { get; set; } } Admin.NET/FZCZTB.NET.SYSService/MSM/ZCSMSService.cs
New file @@ -0,0 +1,213 @@ // Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。 // // 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。 // // 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任! using Admin.NET.Core.Service; using Admin.NET.Core; using Furion.DependencyInjection; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Microsoft.Extensions.Options; using Dm.util; using Aop.Api.Domain; using Furion.FriendlyException; using Furion.DataValidation; using static QRCoder.PayloadGenerator; using System.Net; using Org.BouncyCastle.Asn1.Ocsp; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Authorization; using Furion.DynamicApiController; using System.ComponentModel; using System.ComponentModel.DataAnnotations; using Yitter.IdGenerator; using Lazy.Captcha.Core; using Furion; namespace FZCZTB.NET.SYSService.MSM; /// <summary> /// 政采短信服务 /// </summary> [AllowAnonymous] [ApiDescriptionSettings("FZCAPISYS",Order = 149)] public class ZCSMSService : IDynamicApiController,ITransient { private readonly SMSConfigOptions _smsOptions; private readonly SysCacheService _sysCacheService; private readonly ICaptcha _captcha; public ZCSMSService(IOptions<SMSConfigOptions> smsOptions, SysCacheService sysCacheService, ICaptcha captcha ) { _smsOptions = smsOptions.Value; _sysCacheService = _sysCacheService; _captcha = captcha; } /// <summary> /// 根据藏用模版格式化短信内容 会自动贴上标签 /// </summary> /// <param name="Code"> 需要替换的内容,用于替换末班内容的code部分</param> /// <param name="Key"></param> [NonAction] public string FormartMessage(string? Code, string Key = "VCode") { var Temp= _smsOptions.lingKai.Templates.Where(x => x.TemplateCode == Key).FirstOrDefault(); if ( Temp != null ) { if(Code != null) { return Temp.Content.replace("${code}", Code) + Temp.SignName; } else return Temp.Content+Temp.SignName; } if (Code == null) Oops.Oh("短信内容为空"); return Code; } /// <summary> /// 发送短信 /// </summary> /// <param name="Content">要替换的内容</param> [NonAction] public async Task SendSMSAsync(string Content,string Phone) { if (!Phone.TryValidate(ValidationTypes.PhoneNumber).IsValid) throw Oops.Oh("请正确填写手机号码"); if( string.IsNullOrEmpty(Content)) throw Oops.Oh("请填写正确的手机号码"); string postdata1 = "CorpID=" + _smsOptions.lingKai.Number + "&Pwd=" + _smsOptions.lingKai.AccountPassPassword + "&Mobile=" + Phone + "&Content="+ Content + "&SendTime="; string code = (string)await HttpPost(_smsOptions.lingKai.Url, postdata1); var data = Convert.ToInt64(code); if (data > 0) { return ; } Oops.Oh($"发送短信失败,错误码{data}"); } /// <summary> /// 获取验证码 🔖 /// </summary> /// <returns></returns> [AllowAnonymous] [SuppressMonitor] [DisplayName("获取验证码")] public dynamic GetCaptcha() { var codeId = YitIdHelper.NextId().ToString(); var captcha = _captcha.Generate(codeId); var expirySeconds = App.GetOptions<CaptchaOptions>()?.ExpirySeconds ?? 60; return new { Id = codeId, Img = captcha.Base64, ExpirySeconds = expirySeconds }; } /// <summary> /// 校验短信验证码 /// </summary> /// <param name="input"></param> /// <returns></returns> [AllowAnonymous] [DisplayName("校验短信验证码")] public bool VerifyCode(SmsVerifyCodeInput input) { var verifyCode = _sysCacheService.Get<string>($"{CacheConst.KeyPhoneVerCode}{input.Phone}"); if (string.IsNullOrWhiteSpace(verifyCode)) throw Oops.Oh("验证码不存在或已失效,请重新获取!"); if (verifyCode != input.Code) throw Oops.Oh("验证码错误!"); return true; } /// <summary> /// 发送验证短信,要要验证码 需要输入校验,避免电脑攻击 /// </summary> /// <param name="phoneNumber"> 电话号码</param> /// <param name="VerifyCode">图片校验数据</param> /// <param name="VerifyCodeId">检验的ID</param> /// <returns></returns> [AllowAnonymous] [DisplayName("发送验证码")] public async Task SendSMS([Required] string phoneNumber , [Required] string VerifyCode, [Required] string VerifyCodeId) { if (!phoneNumber.TryValidate(ValidationTypes.PhoneNumber).IsValid) throw Oops.Oh("请正确填写手机号码"); // 校验验证码 if (!_captcha.Validate(VerifyCodeId, VerifyCode)) throw Oops.Oh(ErrorCodeEnum.D0008); _captcha.Generate(VerifyCodeId); // 生成随机验证码 var random = new Random(); var verifyCode = random.Next(100000, 999999); var templateParam = new { code = verifyCode }; var code= FormartMessage(verifyCode.toString()); await SendSMSAsync(code, phoneNumber); _sysCacheService.Set($"{CacheConst.KeyPhoneVerCode}{phoneNumber}", verifyCode, TimeSpan.FromSeconds(_smsOptions.lingKai.VerifyTimeOut)); await Task.CompletedTask; } /// <summary> /// 发送验证码 /// </summary> /// <param name="Url"> 链接</param> /// <param name="postDataStr"> 验证码</param> /// <returns></returns> private async Task<string> HttpPost(string Url, string postDataStr) { //HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url); //request.Method = "POST"; //request.ContentType = "application/x-www-form-urlencoded;charset=gb2312"; //byte[] postData = Encoding.GetEncoding("gb2312").GetBytes(postDataStr); //request.ContentLength = postData.Length; //Stream myRequestStream = request.GetRequestStream(); //myRequestStream.Write(postData, 0, postData.Length); //myRequestStream.Close(); //HttpWebResponse response = (HttpWebResponse)await request.GetResponseAsync(); //Stream myResponseStream = response.GetResponseStream(); //StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.GetEncoding("gb2312")); //string retString = myStreamReader.ReadToEnd(); //myStreamReader.Close(); //myResponseStream.Close(); //return retString; // 创建 HttpClient 实例 using var httpClient = new HttpClient(); // 准备要发送的内容,设置编码和内容类型 var content = new StringContent(postDataStr, Encoding.GetEncoding("gb2312"), "application/x-www-form-urlencoded"); // 发送 POST 请求 var response = await httpClient.PostAsync(Url, content); // 确保请求成功,若失败则抛出异常 response.EnsureSuccessStatusCode(); // 读取响应内容 return await response.Content.ReadAsStringAsync(); } }