@@ -433,6 +433,31 @@ namespace Learun.Application.Organization | |||||
} | } | ||||
} | } | ||||
/// <summary> | |||||
/// 获取实体,通过手机号 | |||||
/// </summary> | |||||
/// <param name="mobile">手机号</param> | |||||
/// <returns></returns> | |||||
public UserEntity GetEntityByMobile(string mobile) | |||||
{ | |||||
try | |||||
{ | |||||
return userService.GetEntityByName(mobile); | |||||
} | |||||
catch (Exception ex) | |||||
{ | |||||
if (ex is ExceptionEx) | |||||
{ | |||||
throw; | |||||
} | |||||
else | |||||
{ | |||||
throw ExceptionEx.ThrowBusinessException(ex); | |||||
} | |||||
} | |||||
} | |||||
public void UpdateIp(string ip, string id) | public void UpdateIp(string ip, string id) | ||||
{ | { | ||||
try | try | ||||
@@ -668,7 +693,7 @@ namespace Learun.Application.Organization | |||||
companyId = item.F_CompanyId, | companyId = item.F_CompanyId, | ||||
departmentId = item.F_DepartmentId, | departmentId = item.F_DepartmentId, | ||||
name = item.F_RealName, | name = item.F_RealName, | ||||
mobile=item.F_Mobile ?? "" | |||||
mobile = item.F_Mobile ?? "" | |||||
}; | }; | ||||
string img = ""; | string img = ""; | ||||
if (!string.IsNullOrEmpty(item.F_HeadIcon)) | if (!string.IsNullOrEmpty(item.F_HeadIcon)) | ||||
@@ -88,6 +88,12 @@ namespace Learun.Application.Organization | |||||
/// <returns></returns> | /// <returns></returns> | ||||
UserEntity GetEntityByUserId(string userId); | UserEntity GetEntityByUserId(string userId); | ||||
/// <summary> | /// <summary> | ||||
/// 获取用户数据根据手机号 | |||||
/// </summary> | |||||
/// <param name="mobile"></param> | |||||
/// <returns></returns> | |||||
UserEntity GetEntityByMobile(string mobile); | |||||
/// <summary> | |||||
/// 获取用户列表数据 | /// 获取用户列表数据 | ||||
/// </summary> | /// </summary> | ||||
/// <param name="userIds">用户主键串</param> | /// <param name="userIds">用户主键串</param> | ||||
@@ -78,6 +78,32 @@ namespace Learun.Application.Organization | |||||
} | } | ||||
} | } | ||||
} | } | ||||
/// <summary> | |||||
/// 获取实体,通过用户手机号 | |||||
/// </summary> | |||||
/// <param name="account">用户账号</param> | |||||
/// <returns></returns> | |||||
public UserEntity GetEntityByMobile(string mobile) | |||||
{ | |||||
try | |||||
{ | |||||
return this.BaseRepository() | |||||
.FindEntity<UserEntity>(a => a.F_Mobile.Equals(mobile) && a.F_DeleteMark == 0); | |||||
} | |||||
catch (Exception ex) | |||||
{ | |||||
if (ex is ExceptionEx) | |||||
{ | |||||
throw; | |||||
} | |||||
else | |||||
{ | |||||
throw ExceptionEx.ThrowServiceException(ex); | |||||
} | |||||
} | |||||
} | |||||
/// <summary> | /// <summary> | ||||
/// 用户列表(根据公司主键) | /// 用户列表(根据公司主键) | ||||
/// </summary> | /// </summary> | ||||
@@ -17,6 +17,11 @@ using System.Web; | |||||
using Quanjiang.DigitalScholl.WebLicense; | using Quanjiang.DigitalScholl.WebLicense; | ||||
using Learun.Application.TwoDevelopment.EducationalAdministration; | using Learun.Application.TwoDevelopment.EducationalAdministration; | ||||
using Newtonsoft.Json; | using Newtonsoft.Json; | ||||
using System.Threading.Tasks; | |||||
using System.Text.RegularExpressions; | |||||
using Quanjiang.DigitalScholl.SendSms; | |||||
using System.Collections.Generic; | |||||
using Learun.Cache.Redis; | |||||
namespace Learun.Application.Web.Controllers | namespace Learun.Application.Web.Controllers | ||||
{ | { | ||||
@@ -40,7 +45,8 @@ namespace Learun.Application.Web.Controllers | |||||
WeChatDevelopIBLL weChatDevelopIbll = new WeChatDevelopBLL(); | WeChatDevelopIBLL weChatDevelopIbll = new WeChatDevelopBLL(); | ||||
private Sys_DefaultPwdConfigIBLL sys_DefaultPwdConfigIBLL = new Sys_DefaultPwdConfigBLL(); | private Sys_DefaultPwdConfigIBLL sys_DefaultPwdConfigIBLL = new Sys_DefaultPwdConfigBLL(); | ||||
#endregion | #endregion | ||||
private readonly ISms _aliyunSms = new AliyunSms(); | |||||
CacheByRedis _redis = new CacheByRedis(); | |||||
#region 视图功能 | #region 视图功能 | ||||
LR_Base_LogoIBLL baseLogoIbll = new LR_Base_LogoBLL(); | LR_Base_LogoIBLL baseLogoIbll = new LR_Base_LogoBLL(); | ||||
@@ -1036,6 +1042,110 @@ namespace Learun.Application.Web.Controllers | |||||
#endregion | #endregion | ||||
#region 忘记密码 | |||||
/// <summary> | |||||
/// 获取短信验证码 | |||||
/// </summary> | |||||
/// <returns></returns> | |||||
[HttpPost] | |||||
public async Task<ActionResult> GetCheckCode(string mobile, string smsType) | |||||
{ | |||||
ActionResult actionResult; | |||||
var logEntity = new LogEntity(); | |||||
//var usermobile = Request["mobile"].Trim(); | |||||
//var smsType = Request["smsType"].Trim(); | |||||
if (mobile.IsEmpty() || !Regex.IsMatch(mobile, @"^1[3-9]\d{9}$")) | |||||
{ | |||||
return Fail("请输入正确的手机号!"); | |||||
} | |||||
var type = (SmsType)Enum.Parse(typeof(SmsType), smsType); | |||||
//判断验证码是否已发送 | |||||
var smscode = _redis.Read<string>($"checkcode_{type}_{mobile}"); | |||||
if (!string.IsNullOrEmpty(smscode)) | |||||
{ | |||||
return Fail("验证码已发送!"); | |||||
} | |||||
var (code, randomNum, message, errortype) = await _aliyunSms.SendSmsToSingle(mobile, type); | |||||
if (code == "OK") | |||||
{ | |||||
//写入redis | |||||
_redis.Write($"checkcode_{type}_{mobile}", randomNum, TimeSpan.FromMinutes(5)); | |||||
//WebHelper.WriteSession($"checkcode_{type}_{mobile}", randomNum); | |||||
actionResult = Success("发送成功,请注意查收"); | |||||
} | |||||
else | |||||
{ | |||||
logEntity.F_LogId = Guid.NewGuid().ToString(); | |||||
logEntity.F_Module = "FindPassword"; | |||||
logEntity.F_ExecuteResult = 0; | |||||
logEntity.F_ExecuteResultJson = $"发送短信失败,异常类型:{errortype},错误码:{code},描述:{message}"; | |||||
logEntity.WriteLog(); | |||||
actionResult = Fail("发送失败请重试!"); | |||||
} | |||||
return actionResult; | |||||
} | |||||
/// <summary> | |||||
/// 找回密码 | |||||
/// </summary> | |||||
/// <returns></returns> | |||||
[HttpPost] | |||||
[AjaxOnly] | |||||
public async Task<ActionResult> FindPassword(string mobile, string checkcode, string newPassword, string smsType) | |||||
{ | |||||
if (string.IsNullOrEmpty(mobile)) | |||||
{ | |||||
return Fail("手机号码不能为空!"); | |||||
} | |||||
if (!Regex.IsMatch(mobile, @"^1[3-9]\d{9}$")) | |||||
{ | |||||
return Fail("请输入正确的手机号!"); | |||||
} | |||||
if (string.IsNullOrEmpty(checkcode)) | |||||
{ | |||||
return Fail("验证码不能为空!"); | |||||
} | |||||
var type = (SmsType)Enum.Parse(typeof(SmsType), smsType); | |||||
var smscode = _redis.Read<string>($"checkcode_{type}_{mobile}"); | |||||
if (!string.IsNullOrEmpty(smscode)) | |||||
{ | |||||
if (smscode != checkcode) | |||||
{ | |||||
return Fail("验证码不正确,请核对!"); | |||||
} | |||||
else | |||||
{ | |||||
//获取用户密码 | |||||
UserEntity userEntity = userBll.GetEntityByMobile(mobile); | |||||
if (userEntity == null) | |||||
{ | |||||
return Fail("用户不存在!"); | |||||
} | |||||
else if (userEntity.F_EnabledMark == 0) | |||||
{ | |||||
return Fail("账户被系统锁定,请联系管理员!"); | |||||
} | |||||
userEntity.F_Password = Md5Helper.Encrypt(DESEncrypt.Encrypt(newPassword.ToLower(), userEntity.F_Secretkey).ToLower(), 32).ToLower(); | |||||
userBll.SaveEntity(userEntity.F_UserId, userEntity); | |||||
//删除验证码 | |||||
_redis.Remove($"checkcode_{type}_{mobile}"); | |||||
} | |||||
} | |||||
else | |||||
{ | |||||
return Fail("验证码已过期,请重新获取!"); | |||||
} | |||||
return Success("您的密码已发送,请重新登录!"); | |||||
} | |||||
#endregion | |||||
/// <summary> | /// <summary> | ||||
/// 获取IP | /// 获取IP | ||||
/// </summary> | /// </summary> | ||||
@@ -226,7 +226,7 @@ | |||||
</Reference> | </Reference> | ||||
<Reference Include="System.ServiceModel" /> | <Reference Include="System.ServiceModel" /> | ||||
<Reference Include="System.ServiceModel.Web" /> | <Reference Include="System.ServiceModel.Web" /> | ||||
<Reference Include="System.ValueTuple, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51"> | |||||
<Reference Include="System.ValueTuple, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL"> | |||||
<HintPath>..\packages\System.ValueTuple.4.5.0\lib\net461\System.ValueTuple.dll</HintPath> | <HintPath>..\packages\System.ValueTuple.4.5.0\lib\net461\System.ValueTuple.dll</HintPath> | ||||
</Reference> | </Reference> | ||||
<Reference Include="System.Web.DynamicData" /> | <Reference Include="System.Web.DynamicData" /> | ||||
@@ -6516,6 +6516,10 @@ | |||||
<Project>{1d192591-b85a-41db-ae3a-4bf9765786c1}</Project> | <Project>{1d192591-b85a-41db-ae3a-4bf9765786c1}</Project> | ||||
<Name>Learun.Workflow.Engine</Name> | <Name>Learun.Workflow.Engine</Name> | ||||
</ProjectReference> | </ProjectReference> | ||||
<ProjectReference Include="..\Quanjiang.DigitalScholl.SendSms\Quanjiang.DigitalScholl.SendSms.csproj"> | |||||
<Project>{65cc5cdc-9638-4dd0-b2d6-3182cc16d2da}</Project> | |||||
<Name>Quanjiang.DigitalScholl.SendSms</Name> | |||||
</ProjectReference> | |||||
<ProjectReference Include="..\Quanjiang.DigitalScholl.WebLicense\Quanjiang.DigitalScholl.WebLicense.csproj"> | <ProjectReference Include="..\Quanjiang.DigitalScholl.WebLicense\Quanjiang.DigitalScholl.WebLicense.csproj"> | ||||
<Project>{4D841EAD-3FD8-4FAC-BC67-C4CE6C0D1181}</Project> | <Project>{4D841EAD-3FD8-4FAC-BC67-C4CE6C0D1181}</Project> | ||||
<Name>Quanjiang.DigitalScholl.WebLicense</Name> | <Name>Quanjiang.DigitalScholl.WebLicense</Name> | ||||
@@ -49,7 +49,7 @@ | |||||
<system.webServer> | <system.webServer> | ||||
<security> | <security> | ||||
<requestFiltering allowDoubleEscaping="true"> | <requestFiltering allowDoubleEscaping="true"> | ||||
<requestLimits maxAllowedContentLength ="2048000000"></requestLimits> | |||||
<requestLimits maxAllowedContentLength="2048000000"></requestLimits> | |||||
</requestFiltering> | </requestFiltering> | ||||
</security> | </security> | ||||
<validation validateIntegratedModeConfiguration="false" /> | <validation validateIntegratedModeConfiguration="false" /> | ||||
@@ -24,7 +24,7 @@ | |||||
<package id="MySql.Data" version="6.9.9" targetFramework="net45" /> | <package id="MySql.Data" version="6.9.9" targetFramework="net45" /> | ||||
<package id="MySql.Data.Entity" version="6.9.9" targetFramework="net45" /> | <package id="MySql.Data.Entity" version="6.9.9" targetFramework="net45" /> | ||||
<package id="NETStandard.Library" version="1.6.1" targetFramework="net462" /> | <package id="NETStandard.Library" version="1.6.1" targetFramework="net462" /> | ||||
<package id="Newtonsoft.Json" version="12.0.2" targetFramework="net462" /> | |||||
<package id="Newtonsoft.Json" version="12.0.1" targetFramework="net462" /> | |||||
<package id="NPOI" version="2.3.0" targetFramework="net45" /> | <package id="NPOI" version="2.3.0" targetFramework="net45" /> | ||||
<package id="Oracle.ManagedDataAccess" version="12.1.24160719" targetFramework="net45" /> | <package id="Oracle.ManagedDataAccess" version="12.1.24160719" targetFramework="net45" /> | ||||
<package id="Oracle.ManagedDataAccess.EntityFramework" version="12.1.2400" targetFramework="net45" /> | <package id="Oracle.ManagedDataAccess.EntityFramework" version="12.1.2400" targetFramework="net45" /> | ||||
@@ -73,6 +73,7 @@ | |||||
<package id="System.Threading" version="4.3.0" targetFramework="net462" /> | <package id="System.Threading" version="4.3.0" targetFramework="net462" /> | ||||
<package id="System.Threading.Tasks" version="4.3.0" targetFramework="net462" /> | <package id="System.Threading.Tasks" version="4.3.0" targetFramework="net462" /> | ||||
<package id="System.Threading.Timer" version="4.3.0" targetFramework="net462" /> | <package id="System.Threading.Timer" version="4.3.0" targetFramework="net462" /> | ||||
<package id="System.ValueTuple" version="4.5.0" targetFramework="net462" /> | |||||
<package id="System.Xml.ReaderWriter" version="4.3.0" targetFramework="net462" /> | <package id="System.Xml.ReaderWriter" version="4.3.0" targetFramework="net462" /> | ||||
<package id="System.Xml.XDocument" version="4.3.0" targetFramework="net462" /> | <package id="System.Xml.XDocument" version="4.3.0" targetFramework="net462" /> | ||||
<package id="Unity" version="4.0.1" targetFramework="net45" /> | <package id="Unity" version="4.0.1" targetFramework="net45" /> |
@@ -0,0 +1,97 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Threading.Tasks; | |||||
using Aliyun.Acs.Core; | |||||
using Aliyun.Acs.Core.Exceptions; | |||||
using Aliyun.Acs.Core.Profile; | |||||
using Aliyun.Acs.Dysmsapi.Model.V20170525; | |||||
using Newtonsoft.Json; | |||||
using Learun.Util; | |||||
namespace Quanjiang.DigitalScholl.SendSms | |||||
{ | |||||
public class AliyunSms:ISms | |||||
{ | |||||
private static readonly string RegionIdForPop = ConfigManager.AppSettings["regionIdForPop"].Value; | |||||
private static readonly string AccessId = ConfigManager.AppSettings["accessId"].Value; | |||||
private static readonly string AccessSecret = ConfigManager.AppSettings["accessSecret"].Value; | |||||
private static readonly string Product = ConfigManager.AppSettings["product"].Value; | |||||
private static readonly string Domain = ConfigManager.AppSettings["domain"].Value; | |||||
private static readonly string SignName = ConfigManager.AppSettings["SignName"].Value; | |||||
/// <summary> | |||||
/// 发送短信 | |||||
/// </summary> | |||||
/// <param name="phoneNumber">手机号</param> | |||||
/// <param name="st">短信通知类型</param> | |||||
/// <returns>发送结果</returns> | |||||
public async Task<(string code,string randomNum, string message,string errorType)> SendSmsToSingle(string phoneNumber, SmsType st, List<string> sendParams = null) | |||||
{ | |||||
(string code, string randomNum, string message,string errorType) result; | |||||
IClientProfile profile = DefaultProfile.GetProfile(RegionIdForPop, AccessId, AccessSecret); | |||||
DefaultProfile.AddEndpoint(RegionIdForPop, RegionIdForPop, Product, Domain); | |||||
IAcsClient acsClient = new DefaultAcsClient(profile); | |||||
var request = new SendSmsRequest(); | |||||
try | |||||
{ | |||||
request.PhoneNumbers = phoneNumber; | |||||
request.SignName = SignName; | |||||
var (templatecode, templateparam, randomNum) = GetSmsTemplateBySmsType(st); | |||||
request.TemplateCode = templatecode; | |||||
request.TemplateParam = templateparam; | |||||
var sendSmsResponse = await Task.FromResult(acsClient.GetAcsResponse(request)); | |||||
result=(sendSmsResponse.Code, randomNum, sendSmsResponse.Message,""); | |||||
} | |||||
catch (ServerException e) | |||||
{ | |||||
result = (e.ErrorCode,"",e.ErrorMessage,Enum.GetName(typeof(ErrorType),e.ErrorType)); | |||||
} | |||||
catch (ClientException e) | |||||
{ | |||||
result = (e.ErrorCode,"", e.ErrorMessage, Enum.GetName(typeof(ErrorType), e.ErrorType)); | |||||
} | |||||
return result; | |||||
} | |||||
public Task<(string code, string randomNum, string message, string errorType)> SendSmsToMulti(List<string> phoneNumbers, SmsType st, List<string> sendParams = null) | |||||
{ | |||||
throw new NotImplementedException(); | |||||
} | |||||
/// <summary> | |||||
/// 根据短信通知类型获取短信模板 | |||||
/// </summary> | |||||
/// <param name="st"></param> | |||||
/// <returns></returns> | |||||
private (string templateCode, string templateParam, string randomNum) GetSmsTemplateBySmsType(SmsType st) | |||||
{ | |||||
(string templateCode, string templateParam,string randomNum) result; | |||||
var randomNum = CommonHelper.RndNum(6); | |||||
switch (st) | |||||
{ | |||||
case SmsType.Register: | |||||
result = ("SMS_137485060", JsonConvert.SerializeObject(new { code = randomNum }), randomNum); | |||||
break; | |||||
case SmsType.LoginBind: | |||||
result = ("SMS_137485060", JsonConvert.SerializeObject(new { code = randomNum }), randomNum); | |||||
break; | |||||
case SmsType.ForgetPassWord: | |||||
result = ("SMS_137485060", JsonConvert.SerializeObject(new { code = randomNum }), randomNum); | |||||
break; | |||||
case SmsType.FindPassWord: | |||||
result = ("SMS_137485060", JsonConvert.SerializeObject(new { code = randomNum }), randomNum); | |||||
break; | |||||
//case SmsType.LeaveNotification: | |||||
// result = ("SMS_137485060", JsonConvert.SerializeObject(new { code = randomNum }), randomNum); | |||||
// break; | |||||
//case SmsType.MakeUpMissedLessonsNotification: | |||||
// result = ("SMS_137485060", JsonConvert.SerializeObject(new { code = randomNum }), randomNum); | |||||
// break; | |||||
default: | |||||
throw new ArgumentOutOfRangeException(nameof(st), st, null); | |||||
} | |||||
return result; | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,26 @@ | |||||
<?xml version="1.0" encoding="utf-8"?> | |||||
<configuration> | |||||
<appSettings> | |||||
<!--阿里云短信平台参数--> | |||||
<add key="product" value="Dysmsapi" /> | |||||
<add key="domain" value="dysmsapi.aliyuncs.com" /> | |||||
<add key="accessId" value="LTAIv9edWmNRk2ai" /> | |||||
<add key="accessSecret" value="iFBh4DYE7kwKACV4hhoGxDrILd63uL" /> | |||||
<add key="regionIdForPop" value="cn-hangzhou" /> | |||||
<add key="SignName" value="阿里云短信测试专用" /> | |||||
<!--斑羚短信平台--> | |||||
<add key="sdkappid" value="140009369387" /> | |||||
<add key="appkey" value="4d2743a4233e5d8625eefa31f876721b" /> | |||||
</appSettings> | |||||
<startup> | |||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" /> | |||||
</startup> | |||||
<runtime> | |||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> | |||||
<dependentAssembly> | |||||
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" /> | |||||
<bindingRedirect oldVersion="0.0.0.0-12.0.0.0" newVersion="12.0.0.0" /> | |||||
</dependentAssembly> | |||||
</assemblyBinding> | |||||
</runtime> | |||||
</configuration> |
@@ -0,0 +1,100 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.IO; | |||||
using System.Linq; | |||||
using System.Net; | |||||
using System.Net.Http; | |||||
using System.Net.Http.Headers; | |||||
using System.Security.Cryptography; | |||||
using System.Text; | |||||
using System.Threading.Tasks; | |||||
using Newtonsoft.Json; | |||||
using Newtonsoft.Json.Linq; | |||||
using Quanjiang.DigitalScholl.SendSms.Banling.Sms; | |||||
using Learun.Util; | |||||
namespace Quanjiang.DigitalScholl.SendSms.Banling | |||||
{ | |||||
/// <summary> | |||||
/// 斑羚短信平台 | |||||
/// </summary> | |||||
public class BanLingSms : ISms | |||||
{ | |||||
private static readonly string SdkAppId = ConfigManager.AppSettings["sdkappid"].Value; | |||||
private static readonly string AppKey = ConfigManager.AppSettings["appkey"].Value; | |||||
public async Task<(string code, string randomNum, string message, string errorType)> SendSmsToSingle(string phoneNumber, SmsType st, List<string> sendParams = null) | |||||
{ | |||||
(string code, string randomNum, string message, string errorType) result; | |||||
var (templatecode, templateparam, randomNum) = GetSmsTemplate(st, sendParams); | |||||
try | |||||
{ | |||||
var singleSender = new SmsSingleSender(SdkAppId, AppKey); | |||||
var singleResult = await Task.FromResult(singleSender.SendWithParam("86", phoneNumber, templatecode, templateparam, "深圳国际公益学院", "", "")); | |||||
result = singleResult.result==0 ? ("OK", randomNum, "", "") : (singleResult.result.ToString(), "", singleResult.errmsg, "Client"); | |||||
} | |||||
catch (Exception e) | |||||
{ | |||||
result = ("", "", e.Message, e.GetType().ToString()); | |||||
} | |||||
return result; | |||||
} | |||||
public async Task<(string code, string randomNum, string message, string errorType)> SendSmsToMulti(List<string> phoneNumbers, SmsType st, List<string> sendParams = null) | |||||
{ | |||||
(string code, string randomNum, string message, string errorType) result; | |||||
var (templatecode, templateparam, randomNum) = GetSmsTemplate(st, sendParams); | |||||
try | |||||
{ | |||||
var multiSender = new SmsMultiSender(SdkAppId, AppKey); | |||||
var multiResult = await Task.FromResult(multiSender.SendWithParam("86", phoneNumbers, templatecode, templateparam, "深圳国际公益学院", "", "")); | |||||
result = multiResult.result == 0 ? ("OK", randomNum, "", "") : (multiResult.result.ToString(), "", multiResult.errmsg, "Client"); | |||||
} | |||||
catch (Exception e) | |||||
{ | |||||
result = ("", "", e.Message, e.GetType().ToString()); | |||||
} | |||||
return result; | |||||
} | |||||
/// <summary> | |||||
/// 根据短信通知类型获取短信模板 | |||||
/// </summary> | |||||
/// <param name="st"></param> | |||||
/// <param name="sendParams"></param> | |||||
/// <returns></returns> | |||||
private (string templateCode, List<string> templateParam, string randomNum) GetSmsTemplate(SmsType st, List<string> sendParams) | |||||
{ | |||||
(string templateCode, List<string> templateParam, string randomNum) result; | |||||
var randomNum = CommonHelper.RndNum(6); | |||||
switch (st) | |||||
{ | |||||
case SmsType.Register: | |||||
result = ("141577", new List<string>() { randomNum, "5" }, randomNum); | |||||
break; | |||||
case SmsType.LoginBind: | |||||
result = ("141578", new List<string>() { randomNum, "5" }, randomNum); | |||||
break; | |||||
case SmsType.ForgetPassWord: | |||||
result = ("141581", new List<string>() { randomNum, "5" }, randomNum); | |||||
break; | |||||
//case SmsType.LessionNotification: | |||||
// result = ("141583", sendParams, randomNum); | |||||
// break; | |||||
//case SmsType.LeaveNotification: | |||||
// result = ("141585", sendParams, randomNum); | |||||
// break; | |||||
//case SmsType.MakeUpMissedLessonsNotification: | |||||
// result = ("141588", sendParams, randomNum); | |||||
// break; | |||||
//case SmsType.ClassManagerLeaveNotification: | |||||
// result = ("156728", sendParams, randomNum); | |||||
// break; | |||||
//case SmsType.ClassManagerMakeUpMissedLessonsNotification: | |||||
// result = ("156729", sendParams, randomNum); | |||||
// break; | |||||
default: | |||||
throw new ArgumentOutOfRangeException(nameof(st), st, null); | |||||
} | |||||
return result; | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,717 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.IO; | |||||
using System.Linq; | |||||
using System.Net; | |||||
using System.Security.Cryptography; | |||||
using System.Text; | |||||
using Newtonsoft.Json; | |||||
using Newtonsoft.Json.Linq; | |||||
// newtonsoft json 模块请自行到 http://www.newtonsoft.com/json 下载 | |||||
// 注意 json 库中有 .net 的多个版本,请开发者集成自己项目相应 .net 版本的 json 库 | |||||
namespace Quanjiang.DigitalScholl.SendSms.Banling | |||||
{ | |||||
namespace Sms | |||||
{ | |||||
class SmsSingleSender | |||||
{ | |||||
string sdkappid; | |||||
string appkey; | |||||
string url = "https://msg.yundashi.com/api/sms/sendsms"; | |||||
SmsSenderUtil util = new SmsSenderUtil(); | |||||
public SmsSingleSender(string sdkappid, string appkey) | |||||
{ | |||||
this.sdkappid = sdkappid; | |||||
this.appkey = appkey; | |||||
} | |||||
/** | |||||
* 普通单发短信接口,明确指定内容,如果有多个签名,请在内容中以【】的方式添加到信息内容中,否则系统将使用默认签名 | |||||
* @param type 短信类型,0 为普通短信,1 营销短信 | |||||
* @param nationCode 国家码,如 86 为中国 | |||||
* @param phoneNumber 不带国家码的手机号 | |||||
* @param msg 信息内容,必须与申请的模板格式一致,否则将返回错误 | |||||
* @param extend 扩展码,可填空 | |||||
* @param ext 服务端原样返回的参数,可填空 | |||||
* @return SmsSingleSenderResult | |||||
*/ | |||||
public SmsSingleSenderResult Send( | |||||
int type, | |||||
string nationCode, | |||||
string phoneNumber, | |||||
string msg, | |||||
string extend, | |||||
string ext) | |||||
{ | |||||
/* | |||||
请求包体 | |||||
{ | |||||
"tel": { | |||||
"nationcode": "86", | |||||
"mobile": "13788888888" | |||||
}, | |||||
"type": 0, | |||||
"msg": "你的验证码是1234", | |||||
"sig": "fdba654e05bc0d15796713a1a1a2318c", | |||||
"time": 1479888540, | |||||
"extend": "", | |||||
"ext": "" | |||||
} | |||||
应答包体 | |||||
{ | |||||
"result": 0, | |||||
"errmsg": "OK", | |||||
"ext": "", | |||||
"sid": "xxxxxxx", | |||||
"fee": 1 | |||||
} | |||||
*/ | |||||
if (0 != type && 1 != type) | |||||
{ | |||||
throw new Exception("type " + type + " error"); | |||||
} | |||||
if (null == extend) | |||||
{ | |||||
extend = ""; | |||||
} | |||||
if (null == ext) | |||||
{ | |||||
ext = ""; | |||||
} | |||||
long random = util.GetRandom(); | |||||
long curTime = util.GetCurTime(); | |||||
// 按照协议组织 post 请求包体 | |||||
JObject data = new JObject(); | |||||
JObject tel = new JObject(); | |||||
tel.Add("nationcode", nationCode); | |||||
tel.Add("mobile", phoneNumber); | |||||
data.Add("tel", tel); | |||||
data.Add("msg", msg); | |||||
data.Add("type", type); | |||||
data.Add("sig", util.StrToHash(String.Format( | |||||
"appkey={0}&random={1}&time={2}&mobile={3}", | |||||
appkey, random, curTime, phoneNumber))); | |||||
data.Add("time", curTime); | |||||
data.Add("extend", extend); | |||||
data.Add("ext", ext); | |||||
string wholeUrl = url + "?sdkappid=" + sdkappid + "&random=" + random; | |||||
HttpWebRequest request = util.GetPostHttpConn(wholeUrl); | |||||
byte[] requestData = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(data)); | |||||
request.ContentLength = requestData.Length; | |||||
Stream requestStream = request.GetRequestStream(); | |||||
requestStream.Write(requestData, 0, requestData.Length); | |||||
requestStream.Close(); | |||||
// 接收返回包 | |||||
HttpWebResponse response = (HttpWebResponse)request.GetResponse(); | |||||
Stream responseStream = response.GetResponseStream(); | |||||
StreamReader streamReader = new StreamReader(responseStream, Encoding.GetEncoding("utf-8")); | |||||
string responseStr = streamReader.ReadToEnd(); | |||||
streamReader.Close(); | |||||
responseStream.Close(); | |||||
SmsSingleSenderResult result; | |||||
if (HttpStatusCode.OK == response.StatusCode) | |||||
{ | |||||
result = util.ResponseStrToSingleSenderResult(responseStr); | |||||
} | |||||
else | |||||
{ | |||||
result = new SmsSingleSenderResult(); | |||||
result.result = -1; | |||||
result.errmsg = "http error " + response.StatusCode + " " + responseStr; | |||||
} | |||||
return result; | |||||
} | |||||
/** | |||||
* 指定模板单发 | |||||
* @param nationCode 国家码,如 86 为中国 | |||||
* @param phoneNumber 不带国家码的手机号 | |||||
* @param templId 模板 id | |||||
* @param templParams 模板参数列表,如模板 {1}...{2}...{3},那么需要带三个参数 | |||||
* @param extend 扩展码,可填空 | |||||
* @param ext 服务端原样返回的参数,可填空 | |||||
* @return SmsSingleSenderResult | |||||
*/ | |||||
public SmsSingleSenderResult SendWithParam( | |||||
string nationCode, | |||||
string phoneNumber, | |||||
string templId, | |||||
List<string> templParams, | |||||
string sign, | |||||
string extend, | |||||
string ext) | |||||
{ | |||||
/* | |||||
请求包体 | |||||
{ | |||||
"tel": { | |||||
"nationcode": "86", | |||||
"mobile": "13788888888" | |||||
}, | |||||
"sign": "云大师", | |||||
"tpl_id": 19, | |||||
"params": [ | |||||
"验证码", | |||||
"1234", | |||||
"4" | |||||
], | |||||
"sig": "fdba654e05bc0d15796713a1a1a2318c", | |||||
"time": 1479888540, | |||||
"extend": "", | |||||
"ext": "" | |||||
} | |||||
应答包体 | |||||
{ | |||||
"result": 0, | |||||
"errmsg": "OK", | |||||
"ext": "", | |||||
"sid": "xxxxxxx", | |||||
"fee": 1 | |||||
} | |||||
*/ | |||||
if (null == sign) | |||||
{ | |||||
sign = ""; | |||||
} | |||||
if (null == extend) | |||||
{ | |||||
extend = ""; | |||||
} | |||||
if (null == ext) | |||||
{ | |||||
ext = ""; | |||||
} | |||||
long random = util.GetRandom(); | |||||
long curTime = util.GetCurTime(); | |||||
// 按照协议组织 post 请求包体 | |||||
JObject data = new JObject(); | |||||
JObject tel = new JObject(); | |||||
tel.Add("nationcode", nationCode); | |||||
tel.Add("mobile", phoneNumber); | |||||
data.Add("tel", tel); | |||||
data.Add("sig", util.CalculateSigForTempl(appkey, random, curTime, phoneNumber)); | |||||
data.Add("tpl_id", templId); | |||||
data.Add("params", util.SmsParamsToJSONArray(templParams)); | |||||
data.Add("sign", sign); | |||||
data.Add("time", curTime); | |||||
data.Add("extend", extend); | |||||
data.Add("ext", ext); | |||||
string wholeUrl = url + "?sdkappid=" + sdkappid + "&random=" + random; | |||||
HttpWebRequest request = util.GetPostHttpConn(wholeUrl); | |||||
byte[] requestData = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(data)); | |||||
request.ContentLength = requestData.Length; | |||||
Stream requestStream = request.GetRequestStream(); | |||||
requestStream.Write(requestData, 0, requestData.Length); | |||||
requestStream.Close(); | |||||
// 接收返回包 | |||||
HttpWebResponse response = (HttpWebResponse)request.GetResponse(); | |||||
Stream responseStream = response.GetResponseStream(); | |||||
StreamReader streamReader = new StreamReader(responseStream, Encoding.GetEncoding("utf-8")); | |||||
string responseStr = streamReader.ReadToEnd(); | |||||
streamReader.Close(); | |||||
responseStream.Close(); | |||||
SmsSingleSenderResult result; | |||||
if (HttpStatusCode.OK == response.StatusCode) | |||||
{ | |||||
result = util.ResponseStrToSingleSenderResult(responseStr); | |||||
} | |||||
else | |||||
{ | |||||
result = new SmsSingleSenderResult(); | |||||
result.result = -1; | |||||
result.errmsg = "http error " + response.StatusCode + " " + responseStr; | |||||
} | |||||
return result; | |||||
} | |||||
} | |||||
class SmsSingleSenderResult | |||||
{ | |||||
/* | |||||
{ | |||||
"result": 0, | |||||
"errmsg": "OK", | |||||
"ext": "", | |||||
"sid": "xxxxxxx", | |||||
"fee": 1 | |||||
} | |||||
*/ | |||||
public int result { set; get; } | |||||
public string errmsg { set; get; } | |||||
public string ext { set; get; } | |||||
public string sid { set; get; } | |||||
public int fee { set; get; } | |||||
public override string ToString() | |||||
{ | |||||
return string.Format( | |||||
"SmsSingleSenderResult\nresult {0}\nerrMsg {1}\next {2}\nsid {3}\nfee {4}", | |||||
result, errmsg, ext, sid, fee); | |||||
} | |||||
} | |||||
class SmsMultiSender | |||||
{ | |||||
string sdkappid; | |||||
string appkey; | |||||
string url = "https://sms.banling.com/intf/sendmultisms"; | |||||
SmsSenderUtil util = new SmsSenderUtil(); | |||||
public SmsMultiSender(string sdkappid, string appkey) | |||||
{ | |||||
this.sdkappid = sdkappid; | |||||
this.appkey = appkey; | |||||
} | |||||
/** | |||||
* 普通群发短信接口,明确指定内容,如果有多个签名,请在内容中以【】的方式添加到信息内容中,否则系统将使用默认签名 | |||||
* 【注意】海外短信无群发功能 | |||||
* @param type 短信类型,0 为普通短信,1 营销短信 | |||||
* @param nationCode 国家码,如 86 为中国 | |||||
* @param phoneNumbers 不带国家码的手机号列表 | |||||
* @param msg 信息内容,必须与申请的模板格式一致,否则将返回错误 | |||||
* @param extend 扩展码,可填空 | |||||
* @param ext 服务端原样返回的参数,可填空 | |||||
* @return SmsMultiSenderResult | |||||
*/ | |||||
public SmsMultiSenderResult Send( | |||||
int type, | |||||
string nationCode, | |||||
List<string> phoneNumbers, | |||||
string msg, | |||||
string extend, | |||||
string ext) | |||||
{ | |||||
/* | |||||
请求包体 | |||||
{ | |||||
"tel": [ | |||||
{ | |||||
"nationcode": "86", | |||||
"mobile": "13788888888" | |||||
}, | |||||
{ | |||||
"nationcode": "86", | |||||
"mobile": "13788888889" | |||||
} | |||||
], | |||||
"type": 0, | |||||
"msg": "你的验证码是1234", | |||||
"sig": "fdba654e05bc0d15796713a1a1a2318c", | |||||
"time": 1479888540, | |||||
"extend": "", | |||||
"ext": "" | |||||
} | |||||
应答包体 | |||||
{ | |||||
"result": 0, | |||||
"errmsg": "OK", | |||||
"ext": "", | |||||
"detail": [ | |||||
{ | |||||
"result": 0, | |||||
"errmsg": "OK", | |||||
"mobile": "13788888888", | |||||
"nationcode": "86", | |||||
"sid": "xxxxxxx", | |||||
"fee": 1 | |||||
}, | |||||
{ | |||||
"result": 0, | |||||
"errmsg": "OK", | |||||
"mobile": "13788888889", | |||||
"nationcode": "86", | |||||
"sid": "xxxxxxx", | |||||
"fee": 1 | |||||
} | |||||
] | |||||
} | |||||
*/ | |||||
if (0 != type && 1 != type) | |||||
{ | |||||
throw new Exception("type " + type + " error"); | |||||
} | |||||
if (null == extend) | |||||
{ | |||||
extend = ""; | |||||
} | |||||
if (null == ext) | |||||
{ | |||||
ext = ""; | |||||
} | |||||
long random = util.GetRandom(); | |||||
long curTime = util.GetCurTime(); | |||||
// 按照协议组织 post 请求包体 | |||||
JObject data = new JObject(); | |||||
data.Add("tel", util.PhoneNumbersToJSONArray(nationCode, phoneNumbers)); | |||||
data.Add("type", type); | |||||
data.Add("msg", msg); | |||||
data.Add("sig", util.CalculateSig(appkey, random, curTime, phoneNumbers)); | |||||
data.Add("time", curTime); | |||||
data.Add("extend", extend); | |||||
data.Add("ext", ext); | |||||
string wholeUrl = url + "?sdkappid=" + sdkappid + "&random=" + random; | |||||
HttpWebRequest request = util.GetPostHttpConn(wholeUrl); | |||||
byte[] requestData = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(data)); | |||||
request.ContentLength = requestData.Length; | |||||
Stream requestStream = request.GetRequestStream(); | |||||
requestStream.Write(requestData, 0, requestData.Length); | |||||
requestStream.Close(); | |||||
// 接收返回包 | |||||
HttpWebResponse response = (HttpWebResponse)request.GetResponse(); | |||||
Stream responseStream = response.GetResponseStream(); | |||||
StreamReader streamReader = new StreamReader(responseStream, Encoding.GetEncoding("utf-8")); | |||||
string responseStr = streamReader.ReadToEnd(); | |||||
streamReader.Close(); | |||||
responseStream.Close(); | |||||
SmsMultiSenderResult result; | |||||
if (HttpStatusCode.OK == response.StatusCode) | |||||
{ | |||||
result = util.ResponseStrToMultiSenderResult(responseStr); | |||||
} | |||||
else | |||||
{ | |||||
result = new SmsMultiSenderResult(); | |||||
result.result = -1; | |||||
result.errmsg = "http error " + response.StatusCode + " " + responseStr; | |||||
} | |||||
return result; | |||||
} | |||||
/** | |||||
* 指定模板群发 | |||||
* 【注意】海外短信无群发功能 | |||||
* @param nationCode 国家码,如 86 为中国 | |||||
* @param phoneNumbers 不带国家码的手机号列表 | |||||
* @param templId 模板 id | |||||
* @param params 模板参数列表 | |||||
* @param sign 签名,如果填空,系统会使用默认签名 | |||||
* @param extend 扩展码,可以填空 | |||||
* @param ext 服务端原样返回的参数,可以填空 | |||||
* @return SmsMultiSenderResult | |||||
*/ | |||||
public SmsMultiSenderResult SendWithParam( | |||||
String nationCode, | |||||
List<string> phoneNumbers, | |||||
string templId, | |||||
List<string> templParams, | |||||
string sign, | |||||
string extend, | |||||
string ext) | |||||
{ | |||||
/* | |||||
请求包体 | |||||
{ | |||||
"tel": [ | |||||
{ | |||||
"nationcode": "86", | |||||
"mobile": "13788888888" | |||||
}, | |||||
{ | |||||
"nationcode": "86", | |||||
"mobile": "13788888889" | |||||
} | |||||
], | |||||
"type": 0, | |||||
"msg": "你的验证码是1234", | |||||
"sig": "fdba654e05bc0d15796713a1a1a2318c", | |||||
"time": 1479888540, | |||||
"extend": "", | |||||
"ext": "" | |||||
} | |||||
应答包体 | |||||
{ | |||||
"result": 0, | |||||
"errmsg": "OK", | |||||
"ext": "", | |||||
"detail": [ | |||||
{ | |||||
"result": 0, | |||||
"errmsg": "OK", | |||||
"mobile": "13788888888", | |||||
"nationcode": "86", | |||||
"sid": "xxxxxxx", | |||||
"fee": 1 | |||||
}, | |||||
{ | |||||
"result": 0, | |||||
"errmsg": "OK", | |||||
"mobile": "13788888889", | |||||
"nationcode": "86", | |||||
"sid": "xxxxxxx", | |||||
"fee": 1 | |||||
} | |||||
] | |||||
} | |||||
*/ | |||||
if (null == sign) | |||||
{ | |||||
sign = ""; | |||||
} | |||||
if (null == extend) | |||||
{ | |||||
extend = ""; | |||||
} | |||||
if (null == ext) | |||||
{ | |||||
ext = ""; | |||||
} | |||||
long random = util.GetRandom(); | |||||
long curTime = util.GetCurTime(); | |||||
// 按照协议组织 post 请求包体 | |||||
JObject data = new JObject(); | |||||
data.Add("tel", util.PhoneNumbersToJSONArray(nationCode, phoneNumbers)); | |||||
data.Add("sig", util.CalculateSigForTempl(appkey, random, curTime, phoneNumbers)); | |||||
data.Add("tpl_id", templId); | |||||
data.Add("params", util.SmsParamsToJSONArray(templParams)); | |||||
data.Add("sign", sign); | |||||
data.Add("time", curTime); | |||||
data.Add("extend", extend); | |||||
data.Add("ext", ext); | |||||
string wholeUrl = url + "?sdkappid=" + sdkappid + "&random=" + random; | |||||
HttpWebRequest request = util.GetPostHttpConn(wholeUrl); | |||||
byte[] requestData = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(data)); | |||||
request.ContentLength = requestData.Length; | |||||
Stream requestStream = request.GetRequestStream(); | |||||
requestStream.Write(requestData, 0, requestData.Length); | |||||
requestStream.Close(); | |||||
// 接收返回包 | |||||
HttpWebResponse response = (HttpWebResponse)request.GetResponse(); | |||||
Stream responseStream = response.GetResponseStream(); | |||||
StreamReader streamReader = new StreamReader(responseStream, Encoding.GetEncoding("utf-8")); | |||||
string responseStr = streamReader.ReadToEnd(); | |||||
streamReader.Close(); | |||||
responseStream.Close(); | |||||
SmsMultiSenderResult result; | |||||
if (HttpStatusCode.OK == response.StatusCode) | |||||
{ | |||||
result = util.ResponseStrToMultiSenderResult(responseStr); | |||||
} | |||||
else | |||||
{ | |||||
result = new SmsMultiSenderResult(); | |||||
result.result = -1; | |||||
result.errmsg = "http error " + response.StatusCode + " " + responseStr; | |||||
} | |||||
return result; | |||||
} | |||||
} | |||||
class SmsMultiSenderResult | |||||
{ | |||||
/* | |||||
{ | |||||
"result": 0, | |||||
"errmsg": "OK", | |||||
"ext": "", | |||||
"detail": [ | |||||
{ | |||||
"result": 0, | |||||
"errmsg": "OK", | |||||
"mobile": "13788888888", | |||||
"nationcode": "86", | |||||
"sid": "xxxxxxx", | |||||
"fee": 1 | |||||
}, | |||||
{ | |||||
"result": 0, | |||||
"errmsg": "OK", | |||||
"mobile": "13788888889", | |||||
"nationcode": "86", | |||||
"sid": "xxxxxxx", | |||||
"fee": 1 | |||||
} | |||||
] | |||||
} | |||||
*/ | |||||
public class Detail | |||||
{ | |||||
public int result { get; set; } | |||||
public string errmsg { get; set; } | |||||
public string mobile { get; set; } | |||||
public string nationcode { get; set; } | |||||
public string sid { get; set; } | |||||
public int fee { get; set; } | |||||
public override string ToString() | |||||
{ | |||||
return string.Format( | |||||
"\tDetail result {0} errmsg {1} mobile {2} nationcode {3} sid {4} fee {5}", | |||||
result, errmsg, mobile, nationcode, sid, fee); | |||||
} | |||||
} | |||||
public int result; | |||||
public string errmsg = ""; | |||||
public string ext = ""; | |||||
public IList<Detail> detail; | |||||
public override string ToString() | |||||
{ | |||||
if (null != detail) | |||||
{ | |||||
return String.Format( | |||||
"SmsMultiSenderResult\nresult {0}\nerrmsg {1}\next {2}\ndetail:\n{3}", | |||||
result, errmsg, ext, String.Join("\n", detail)); | |||||
} | |||||
else | |||||
{ | |||||
return String.Format( | |||||
"SmsMultiSenderResult\nresult {0}\nerrmsg {1}\next {2}\n", | |||||
result, errmsg, ext); | |||||
} | |||||
} | |||||
} | |||||
class SmsSenderUtil | |||||
{ | |||||
Random random = new Random(); | |||||
public HttpWebRequest GetPostHttpConn(string url) | |||||
{ | |||||
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); | |||||
request.Method = "POST"; | |||||
request.ContentType = "application/x-www-form-urlencoded"; | |||||
return request; | |||||
} | |||||
public long GetRandom() | |||||
{ | |||||
return random.Next(999999)%900000 + 100000; | |||||
} | |||||
public long GetCurTime() | |||||
{ | |||||
Int32 unixTimestamp = (Int32)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds; | |||||
return unixTimestamp; | |||||
} | |||||
// 将二进制的数值转换为 16 进制字符串,如 "abc" => "616263" | |||||
private static string ByteArrayToHex(byte[] byteArray) | |||||
{ | |||||
string returnStr = ""; | |||||
if (byteArray != null) | |||||
{ | |||||
for (int i = 0; i < byteArray.Length; i++) | |||||
{ | |||||
returnStr += byteArray[i].ToString("x2"); | |||||
} | |||||
} | |||||
return returnStr; | |||||
} | |||||
public string StrToHash(string str) | |||||
{ | |||||
SHA256 sha256 = SHA256Managed.Create(); | |||||
byte[] resultByteArray = sha256.ComputeHash(System.Text.Encoding.UTF8.GetBytes(str)); | |||||
return ByteArrayToHex(resultByteArray); | |||||
} | |||||
// 将单发回包解析成结果对象 | |||||
public SmsSingleSenderResult ResponseStrToSingleSenderResult(string str) | |||||
{ | |||||
SmsSingleSenderResult result = JsonConvert.DeserializeObject<SmsSingleSenderResult>(str); | |||||
return result; | |||||
} | |||||
// 将群发回包解析成结果对象 | |||||
public SmsMultiSenderResult ResponseStrToMultiSenderResult(string str) | |||||
{ | |||||
SmsMultiSenderResult result = JsonConvert.DeserializeObject<SmsMultiSenderResult>(str); | |||||
return result; | |||||
} | |||||
public JArray SmsParamsToJSONArray(List<string> templParams) | |||||
{ | |||||
JArray smsParams = new JArray(); | |||||
foreach (string templParamsElement in templParams) | |||||
{ | |||||
smsParams.Add(templParamsElement); | |||||
} | |||||
return smsParams; | |||||
} | |||||
public JArray PhoneNumbersToJSONArray(string nationCode, List<string> phoneNumbers) | |||||
{ | |||||
JArray tel = new JArray(); | |||||
int i = 0; | |||||
do | |||||
{ | |||||
JObject telElement = new JObject(); | |||||
telElement.Add("nationcode", nationCode); | |||||
telElement.Add("mobile", phoneNumbers.ElementAt(i)); | |||||
tel.Add(telElement); | |||||
} while (++i < phoneNumbers.Count); | |||||
return tel; | |||||
} | |||||
public string CalculateSigForTempl( | |||||
string appkey, | |||||
long random, | |||||
long curTime, | |||||
List<string> phoneNumbers) | |||||
{ | |||||
string phoneNumbersString = phoneNumbers.ElementAt(0); | |||||
for (int i = 1; i < phoneNumbers.Count; i++) | |||||
{ | |||||
phoneNumbersString += "," + phoneNumbers.ElementAt(i); | |||||
} | |||||
return StrToHash(String.Format( | |||||
"appkey={0}&random={1}&time={2}&mobile={3}", | |||||
appkey, random, curTime, phoneNumbersString)); | |||||
} | |||||
public string CalculateSigForTempl( | |||||
string appkey, | |||||
long random, | |||||
long curTime, | |||||
string phoneNumber) | |||||
{ | |||||
List<string> phoneNumbers = new List<string>(); | |||||
phoneNumbers.Add(phoneNumber); | |||||
return CalculateSigForTempl(appkey, random, curTime, phoneNumbers); | |||||
} | |||||
public string CalculateSig( | |||||
string appkey, | |||||
long random, | |||||
long curTime, | |||||
List<string> phoneNumbers) | |||||
{ | |||||
string phoneNumbersString = phoneNumbers.ElementAt(0); | |||||
for (int i = 1; i < phoneNumbers.Count; i++) | |||||
{ | |||||
phoneNumbersString += "," + phoneNumbers.ElementAt(i); | |||||
} | |||||
return StrToHash(String.Format( | |||||
"appkey={0}&random={1}&time={2}&mobile={3}", | |||||
appkey, random, curTime, phoneNumbersString)); | |||||
} | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,49 @@ | |||||
using System; | |||||
using System.Configuration; | |||||
namespace Quanjiang.DigitalScholl.SendSms | |||||
{ | |||||
internal static class ConfigManager | |||||
{ | |||||
private static readonly bool Error; | |||||
private static readonly Configuration AppConfig; | |||||
static ConfigManager() | |||||
{ | |||||
var dllPath =$"{AppDomain.CurrentDomain.RelativeSearchPath ?? AppDomain.CurrentDomain.BaseDirectory}\\Quanjiang.DigitalScholl.SendSms.dll"; | |||||
try | |||||
{ | |||||
AppConfig = ConfigurationManager.OpenExeConfiguration(dllPath); | |||||
} | |||||
catch (ConfigurationErrorsException) | |||||
{ | |||||
Error = true; | |||||
} | |||||
} | |||||
public static KeyValueConfigurationCollection AppSettings | |||||
{ | |||||
get | |||||
{ | |||||
if (Error) return null; | |||||
return AppConfig.AppSettings.Settings; | |||||
} | |||||
} | |||||
public static ConnectionStringSettingsCollection ConnectionStrings | |||||
{ | |||||
get | |||||
{ | |||||
if (Error) return null; | |||||
return AppConfig.ConnectionStrings.ConnectionStrings; | |||||
} | |||||
} | |||||
public static T GetSection<T>(string name) where T : ConfigurationSection | |||||
{ | |||||
if (Error) return null; | |||||
return AppConfig.GetSection(name) as T; | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,56 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Text; | |||||
using System.Threading.Tasks; | |||||
namespace Quanjiang.DigitalScholl.SendSms | |||||
{ | |||||
public interface ISms | |||||
{ | |||||
Task<(string code, string randomNum, string message, string errorType)> SendSmsToSingle(string phoneNumber, | |||||
SmsType st, List<string> sendParams = null); | |||||
Task<(string code, string randomNum, string message, string errorType)> SendSmsToMulti(List<string> phoneNumbers, | |||||
SmsType st, List<string> sendParams = null); | |||||
} | |||||
/// <summary> | |||||
/// 短信通知类型 | |||||
/// </summary> | |||||
public enum SmsType | |||||
{ | |||||
/// <summary> | |||||
/// 注册 | |||||
/// </summary> | |||||
Register, | |||||
/// <summary> | |||||
/// 第三方(QQ,微信)快捷登录绑定 | |||||
/// </summary> | |||||
LoginBind, | |||||
/// <summary> | |||||
/// 忘记密码 | |||||
/// </summary> | |||||
ForgetPassWord, | |||||
/// <summary> | |||||
/// 找回密码 | |||||
/// </summary> | |||||
FindPassWord, | |||||
///// <summary> | |||||
///// 学员请假通知 | |||||
///// </summary> | |||||
//LeaveNotification, | |||||
///// <summary> | |||||
///// 学员补课通知 | |||||
///// </summary> | |||||
//MakeUpMissedLessonsNotification, | |||||
///// <summary> | |||||
///// 班主任请假提醒 | |||||
///// </summary> | |||||
//ClassManagerLeaveNotification, | |||||
///// <summary> | |||||
///// 班主任补课提醒 | |||||
///// </summary> | |||||
//ClassManagerMakeUpMissedLessonsNotification | |||||
} | |||||
} |
@@ -0,0 +1,36 @@ | |||||
using System.Reflection; | |||||
using System.Runtime.CompilerServices; | |||||
using System.Runtime.InteropServices; | |||||
// 有关程序集的一般信息由以下 | |||||
// 控制。更改这些特性值可修改 | |||||
// 与程序集关联的信息。 | |||||
[assembly: AssemblyTitle("Quanjiang.DigitalScholl.SendSms")] | |||||
[assembly: AssemblyDescription("")] | |||||
[assembly: AssemblyConfiguration("")] | |||||
[assembly: AssemblyCompany("HP Inc.")] | |||||
[assembly: AssemblyProduct("Quanjiang.DigitalScholl.SendSms")] | |||||
[assembly: AssemblyCopyright("Copyright © HP Inc. 2021")] | |||||
[assembly: AssemblyTrademark("")] | |||||
[assembly: AssemblyCulture("")] | |||||
// 将 ComVisible 设置为 false 会使此程序集中的类型 | |||||
//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型 | |||||
//请将此类型的 ComVisible 特性设置为 true。 | |||||
[assembly: ComVisible(false)] | |||||
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID | |||||
[assembly: Guid("65cc5cdc-9638-4dd0-b2d6-3182cc16d2da")] | |||||
// 程序集的版本信息由下列四个值组成: | |||||
// | |||||
// 主版本 | |||||
// 次版本 | |||||
// 生成号 | |||||
// 修订号 | |||||
// | |||||
// 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号 | |||||
//通过使用 "*",如下所示: | |||||
// [assembly: AssemblyVersion("1.0.*")] | |||||
[assembly: AssemblyVersion("1.0.0.0")] | |||||
[assembly: AssemblyFileVersion("1.0.0.0")] |
@@ -0,0 +1,84 @@ | |||||
<?xml version="1.0" encoding="utf-8"?> | |||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | |||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> | |||||
<PropertyGroup> | |||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> | |||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> | |||||
<ProjectGuid>{65CC5CDC-9638-4DD0-B2D6-3182CC16D2DA}</ProjectGuid> | |||||
<OutputType>Library</OutputType> | |||||
<AppDesignerFolder>Properties</AppDesignerFolder> | |||||
<RootNamespace>Quanjiang.DigitalScholl.SendSms</RootNamespace> | |||||
<AssemblyName>Quanjiang.DigitalScholl.SendSms</AssemblyName> | |||||
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion> | |||||
<FileAlignment>512</FileAlignment> | |||||
<Deterministic>true</Deterministic> | |||||
</PropertyGroup> | |||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> | |||||
<DebugSymbols>true</DebugSymbols> | |||||
<DebugType>full</DebugType> | |||||
<Optimize>false</Optimize> | |||||
<OutputPath>bin\Debug\</OutputPath> | |||||
<DefineConstants>DEBUG;TRACE</DefineConstants> | |||||
<ErrorReport>prompt</ErrorReport> | |||||
<WarningLevel>4</WarningLevel> | |||||
</PropertyGroup> | |||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> | |||||
<DebugType>pdbonly</DebugType> | |||||
<Optimize>true</Optimize> | |||||
<OutputPath>bin\Release\</OutputPath> | |||||
<DefineConstants>TRACE</DefineConstants> | |||||
<ErrorReport>prompt</ErrorReport> | |||||
<WarningLevel>4</WarningLevel> | |||||
</PropertyGroup> | |||||
<ItemGroup> | |||||
<Reference Include="aliyun-net-sdk-core, Version=2.0.0.0, Culture=neutral, processorArchitecture=MSIL"> | |||||
<HintPath>..\packages\lan_Aliyun.MNS.1.0.0\lib\aliyun-net-sdk-core.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="aliyun-net-sdk-dybaseapi, Version=1.0.2.0, Culture=neutral, processorArchitecture=MSIL"> | |||||
<HintPath>..\packages\1mao1gou-net-sdk-dybaseapi.1.0.3\lib\net45\aliyun-net-sdk-dybaseapi.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="aliyun-net-sdk-dysmsapi, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL"> | |||||
<HintPath>..\packages\aliyun-net-sdk-dysmsapi.1.0.0\lib\netstandard2.0\aliyun-net-sdk-dysmsapi.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="Aliyun.MNS, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL"> | |||||
<HintPath>..\packages\lan_Aliyun.MNS.1.0.0\lib\Aliyun.MNS.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL"> | |||||
<HintPath>..\packages\Newtonsoft.Json.12.0.2\lib\net45\Newtonsoft.Json.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="System" /> | |||||
<Reference Include="System.Configuration" /> | |||||
<Reference Include="System.Core" /> | |||||
<Reference Include="System.Drawing" /> | |||||
<Reference Include="System.Security" /> | |||||
<Reference Include="System.ValueTuple, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL"> | |||||
<HintPath>..\packages\System.ValueTuple.4.5.0\lib\net461\System.ValueTuple.dll</HintPath> | |||||
</Reference> | |||||
<Reference Include="System.Web" /> | |||||
<Reference Include="System.Xml.Linq" /> | |||||
<Reference Include="System.Data.DataSetExtensions" /> | |||||
<Reference Include="Microsoft.CSharp" /> | |||||
<Reference Include="System.Data" /> | |||||
<Reference Include="System.Net.Http" /> | |||||
<Reference Include="System.Xml" /> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<Compile Include="AliyunSms.cs" /> | |||||
<Compile Include="Banling\BanLingSms.cs" /> | |||||
<Compile Include="Banling\SmsSender.cs" /> | |||||
<Compile Include="ConfigManager.cs" /> | |||||
<Compile Include="ISms.cs" /> | |||||
<Compile Include="Properties\AssemblyInfo.cs" /> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<None Include="App.config" /> | |||||
<None Include="packages.config" /> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<ProjectReference Include="..\Learun.Framework.Module\Learun.Util\Learun.Util\Learun.Util.csproj"> | |||||
<Project>{cf8ae293-88ab-436c-9720-a8386ba5d7b7}</Project> | |||||
<Name>Learun.Util</Name> | |||||
</ProjectReference> | |||||
</ItemGroup> | |||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> | |||||
</Project> |
@@ -0,0 +1,9 @@ | |||||
<?xml version="1.0" encoding="utf-8"?> | |||||
<packages> | |||||
<package id="1mao1gou-net-sdk-dybaseapi" version="1.0.3" targetFramework="net461" /> | |||||
<package id="aliyun-net-sdk-core" version="1.5.10" targetFramework="net461" /> | |||||
<package id="aliyun-net-sdk-dysmsapi" version="1.0.0" targetFramework="net461" /> | |||||
<package id="lan_Aliyun.MNS" version="1.0.0" targetFramework="net461" /> | |||||
<package id="Newtonsoft.Json" version="12.0.2" targetFramework="net461" /> | |||||
<package id="System.ValueTuple" version="4.5.0" targetFramework="net461" /> | |||||
</packages> |
@@ -0,0 +1,20 @@ | |||||
The MIT License (MIT) | |||||
Copyright (c) 2007 James Newton-King | |||||
Permission is hereby granted, free of charge, to any person obtaining a copy of | |||||
this software and associated documentation files (the "Software"), to deal in | |||||
the Software without restriction, including without limitation the rights to | |||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of | |||||
the Software, and to permit persons to whom the Software is furnished to do so, | |||||
subject to the following conditions: | |||||
The above copyright notice and this permission notice shall be included in all | |||||
copies or substantial portions of the Software. | |||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS | |||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR | |||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER | |||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | |||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
@@ -1,7 +1,7 @@ | |||||
| | ||||
Microsoft Visual Studio Solution File, Format Version 12.00 | Microsoft Visual Studio Solution File, Format Version 12.00 | ||||
# Visual Studio Version 16 | |||||
VisualStudioVersion = 16.0.30907.101 | |||||
# Visual Studio 15 | |||||
VisualStudioVersion = 15.0.28307.1500 | |||||
MinimumVisualStudioVersion = 10.0.40219.1 | MinimumVisualStudioVersion = 10.0.40219.1 | ||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "01 Framework 基础模块", "01 Framework 基础模块", "{C6B09613-CC72-4D16-8056-1FD68ED86BF3}" | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "01 Framework 基础模块", "01 Framework 基础模块", "{C6B09613-CC72-4D16-8056-1FD68ED86BF3}" | ||||
EndProject | EndProject | ||||
@@ -124,6 +124,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Learun.Application.Website" | |||||
EndProject | EndProject | ||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Quanjiang.DigitalSchool.IMServerService", "IMServerService\Quanjiang.DigitalSchool.IMServerService.csproj", "{E05A2B9A-A939-450F-9A44-A8B3201D055A}" | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Quanjiang.DigitalSchool.IMServerService", "IMServerService\Quanjiang.DigitalSchool.IMServerService.csproj", "{E05A2B9A-A939-450F-9A44-A8B3201D055A}" | ||||
EndProject | EndProject | ||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Quanjiang.DigitalScholl.SendSms", "Quanjiang.DigitalScholl.SendSms\Quanjiang.DigitalScholl.SendSms.csproj", "{65CC5CDC-9638-4DD0-B2D6-3182CC16D2DA}" | |||||
EndProject | |||||
Global | Global | ||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||||
Debug|Android = Debug|Android | Debug|Android = Debug|Android | ||||
@@ -1586,6 +1588,42 @@ Global | |||||
{E05A2B9A-A939-450F-9A44-A8B3201D055A}.Release|Windows-x64.Build.0 = Release|Any CPU | {E05A2B9A-A939-450F-9A44-A8B3201D055A}.Release|Windows-x64.Build.0 = Release|Any CPU | ||||
{E05A2B9A-A939-450F-9A44-A8B3201D055A}.Release|Windows-x86.ActiveCfg = Release|Any CPU | {E05A2B9A-A939-450F-9A44-A8B3201D055A}.Release|Windows-x86.ActiveCfg = Release|Any CPU | ||||
{E05A2B9A-A939-450F-9A44-A8B3201D055A}.Release|Windows-x86.Build.0 = Release|Any CPU | {E05A2B9A-A939-450F-9A44-A8B3201D055A}.Release|Windows-x86.Build.0 = Release|Any CPU | ||||
{65CC5CDC-9638-4DD0-B2D6-3182CC16D2DA}.Debug|Android.ActiveCfg = Debug|Any CPU | |||||
{65CC5CDC-9638-4DD0-B2D6-3182CC16D2DA}.Debug|Android.Build.0 = Debug|Any CPU | |||||
{65CC5CDC-9638-4DD0-B2D6-3182CC16D2DA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | |||||
{65CC5CDC-9638-4DD0-B2D6-3182CC16D2DA}.Debug|Any CPU.Build.0 = Debug|Any CPU | |||||
{65CC5CDC-9638-4DD0-B2D6-3182CC16D2DA}.Debug|iOS.ActiveCfg = Debug|Any CPU | |||||
{65CC5CDC-9638-4DD0-B2D6-3182CC16D2DA}.Debug|iOS.Build.0 = Debug|Any CPU | |||||
{65CC5CDC-9638-4DD0-B2D6-3182CC16D2DA}.Debug|Windows-ARM.ActiveCfg = Debug|Any CPU | |||||
{65CC5CDC-9638-4DD0-B2D6-3182CC16D2DA}.Debug|Windows-ARM.Build.0 = Debug|Any CPU | |||||
{65CC5CDC-9638-4DD0-B2D6-3182CC16D2DA}.Debug|Windows-x64.ActiveCfg = Debug|Any CPU | |||||
{65CC5CDC-9638-4DD0-B2D6-3182CC16D2DA}.Debug|Windows-x64.Build.0 = Debug|Any CPU | |||||
{65CC5CDC-9638-4DD0-B2D6-3182CC16D2DA}.Debug|Windows-x86.ActiveCfg = Debug|Any CPU | |||||
{65CC5CDC-9638-4DD0-B2D6-3182CC16D2DA}.Debug|Windows-x86.Build.0 = Debug|Any CPU | |||||
{65CC5CDC-9638-4DD0-B2D6-3182CC16D2DA}.Development|Android.ActiveCfg = Debug|Any CPU | |||||
{65CC5CDC-9638-4DD0-B2D6-3182CC16D2DA}.Development|Android.Build.0 = Debug|Any CPU | |||||
{65CC5CDC-9638-4DD0-B2D6-3182CC16D2DA}.Development|Any CPU.ActiveCfg = Debug|Any CPU | |||||
{65CC5CDC-9638-4DD0-B2D6-3182CC16D2DA}.Development|Any CPU.Build.0 = Debug|Any CPU | |||||
{65CC5CDC-9638-4DD0-B2D6-3182CC16D2DA}.Development|iOS.ActiveCfg = Debug|Any CPU | |||||
{65CC5CDC-9638-4DD0-B2D6-3182CC16D2DA}.Development|iOS.Build.0 = Debug|Any CPU | |||||
{65CC5CDC-9638-4DD0-B2D6-3182CC16D2DA}.Development|Windows-ARM.ActiveCfg = Debug|Any CPU | |||||
{65CC5CDC-9638-4DD0-B2D6-3182CC16D2DA}.Development|Windows-ARM.Build.0 = Debug|Any CPU | |||||
{65CC5CDC-9638-4DD0-B2D6-3182CC16D2DA}.Development|Windows-x64.ActiveCfg = Debug|Any CPU | |||||
{65CC5CDC-9638-4DD0-B2D6-3182CC16D2DA}.Development|Windows-x64.Build.0 = Debug|Any CPU | |||||
{65CC5CDC-9638-4DD0-B2D6-3182CC16D2DA}.Development|Windows-x86.ActiveCfg = Debug|Any CPU | |||||
{65CC5CDC-9638-4DD0-B2D6-3182CC16D2DA}.Development|Windows-x86.Build.0 = Debug|Any CPU | |||||
{65CC5CDC-9638-4DD0-B2D6-3182CC16D2DA}.Release|Android.ActiveCfg = Release|Any CPU | |||||
{65CC5CDC-9638-4DD0-B2D6-3182CC16D2DA}.Release|Android.Build.0 = Release|Any CPU | |||||
{65CC5CDC-9638-4DD0-B2D6-3182CC16D2DA}.Release|Any CPU.ActiveCfg = Release|Any CPU | |||||
{65CC5CDC-9638-4DD0-B2D6-3182CC16D2DA}.Release|Any CPU.Build.0 = Release|Any CPU | |||||
{65CC5CDC-9638-4DD0-B2D6-3182CC16D2DA}.Release|iOS.ActiveCfg = Release|Any CPU | |||||
{65CC5CDC-9638-4DD0-B2D6-3182CC16D2DA}.Release|iOS.Build.0 = Release|Any CPU | |||||
{65CC5CDC-9638-4DD0-B2D6-3182CC16D2DA}.Release|Windows-ARM.ActiveCfg = Release|Any CPU | |||||
{65CC5CDC-9638-4DD0-B2D6-3182CC16D2DA}.Release|Windows-ARM.Build.0 = Release|Any CPU | |||||
{65CC5CDC-9638-4DD0-B2D6-3182CC16D2DA}.Release|Windows-x64.ActiveCfg = Release|Any CPU | |||||
{65CC5CDC-9638-4DD0-B2D6-3182CC16D2DA}.Release|Windows-x64.Build.0 = Release|Any CPU | |||||
{65CC5CDC-9638-4DD0-B2D6-3182CC16D2DA}.Release|Windows-x86.ActiveCfg = Release|Any CPU | |||||
{65CC5CDC-9638-4DD0-B2D6-3182CC16D2DA}.Release|Windows-x86.Build.0 = Release|Any CPU | |||||
EndGlobalSection | EndGlobalSection | ||||
GlobalSection(SolutionProperties) = preSolution | GlobalSection(SolutionProperties) = preSolution | ||||
HideSolutionNode = FALSE | HideSolutionNode = FALSE | ||||
@@ -1637,7 +1675,7 @@ Global | |||||
{E05A2B9A-A939-450F-9A44-A8B3201D055A} = {ED258CD0-0A0C-490B-9D8F-B4CEC4467251} | {E05A2B9A-A939-450F-9A44-A8B3201D055A} = {ED258CD0-0A0C-490B-9D8F-B4CEC4467251} | ||||
EndGlobalSection | EndGlobalSection | ||||
GlobalSection(ExtensibilityGlobals) = postSolution | GlobalSection(ExtensibilityGlobals) = postSolution | ||||
EnterpriseLibraryConfigurationToolBinariesPath = packages\Unity.2.1.505.0\lib\NET35 | |||||
SolutionGuid = {968C278F-4142-4DFF-96B0-B3D70A649451} | SolutionGuid = {968C278F-4142-4DFF-96B0-B3D70A649451} | ||||
EnterpriseLibraryConfigurationToolBinariesPath = packages\Unity.2.1.505.0\lib\NET35 | |||||
EndGlobalSection | EndGlobalSection | ||||
EndGlobal | EndGlobal |