MeiRiYiCheng_1_old/YBDevice.NApi/Application/BusinessClient/AccountInfo/AccountService.cs

451 lines
19 KiB
C#

using Furion.DataEncryption;
using Furion.DependencyInjection;
using Nirvana.Common;
using Nirvana.Common.ApiBase;
using Senparc.Weixin;
using Senparc.Weixin.WxOpen.AdvancedAPIs.Sns;
using Senparc.Weixin.WxOpen.Containers;
using Senparc.Weixin.WxOpen.Helpers;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using YBDevice.Core;
using YBDevice.Entity;
namespace YBDevice.NApi.Application.BusinessClient.AccountInfo
{
public class AccountService : IAccountService, ITransient
{
public string WxOpenAppId = Senparc.Weixin.Config.SenparcWeixinSetting.WxOpenAppId;
public string WxOpenAppSecret = Senparc.Weixin.Config.SenparcWeixinSetting.WxOpenAppSecret;
public string WxOpenToken = Senparc.Weixin.Config.SenparcWeixinSetting.WxOpenToken;
public string WxOpenEncodingAESKey = Senparc.Weixin.Config.SenparcWeixinSetting.WxOpenEncodingAESKey;
private readonly ISqlSugarRepository<YB_OfficlaAccount> repository;
private readonly SqlSugarClient dbClient;
private readonly ILoggerService _loggerService;
private readonly IHttpClientFactory _clientFactory;
public AccountService(ISqlSugarRepository<YB_OfficlaAccount> sqlSugarRepository, ILoggerService loggerService, IHttpClientFactory clientFactory)
{
repository = sqlSugarRepository;
dbClient = repository.Context;
_loggerService = loggerService;
_clientFactory = clientFactory;
}
/// <summary>
/// 手机号授权,如果未注册会自动进行注册
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public async Task<ResultInfo> DecryptPhoneAsync(BusinessDecryptSubmitModel model)
{
var sessionBag = await SessionContainer.GetSessionAsync(model.sessionId);
if (sessionBag == null)
{
return new ResultInfo(ResultState.FAIL, "sessionId未找到");
}
var phone = EncryptHelper.DecryptPhoneNumber(model.sessionId, model.encryptedData, model.iv);
_loggerService.AddLogger($"手机号解密信息:{phone.ToJson()}");
return await InsertOrUpdateAccountInfoAsync(new BusinessRegDto
{
isvrcode = false,
sessionId = model.sessionId,
NickName = phone.purePhoneNumber,
Password = phone.purePhoneNumber,
RePassword = phone.purePhoneNumber,
Phone = phone.purePhoneNumber,
code = ""
});
}
/// <summary>
/// 小程序登录
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public async Task<ResultInfo> OnLoginAsync(WXOpenLoginSubmitModel model)
{
#region appid
if (!string.IsNullOrEmpty(model.appid))
{
var itemlist = Config.SenparcWeixinSetting.Items;
foreach (var item in itemlist)
{
if (item.Value.WxOpenAppId == model.appid)
{
WxOpenAppId = item.Value.WxOpenAppId;
WxOpenAppSecret = item.Value.WxOpenAppSecret;
break;
}
}
}
#endregion
var jsonResult = await SnsApi.JsCode2JsonAsync(WxOpenAppId, WxOpenAppSecret, model.code);
if (jsonResult.errcode == ReturnCode.)
{
//检查此openid是否已注册
var wxdata = await dbClient.Queryable<YB_BusinessWX>().FirstAsync(x => x.OpenId == jsonResult.openid);
TimeSpan val = new TimeSpan(1, 0, 0);//一个小时
if (wxdata == null)
{
//记录信息
var sessionBag = await SessionContainer.UpdateSessionAsync(jsonResult.openid, jsonResult.openid, jsonResult.session_key, jsonResult.unionid, val);
return new ResultInfo(ResultState.WXUNAUTHORITY, "此账户还未注册", new WxOpenLoginData
{
sessionid = sessionBag.Key
});
}
//刷新key
var sessionbag = await SessionContainer.UpdateSessionAsync(jsonResult.openid, jsonResult.openid, jsonResult.session_key, jsonResult.unionid, val);
//生成token
return await GenTokenAsync(wxdata.UserId, wxdata.BusinessId, wxdata.OpenId, sessionbag.Key);
}
return new ResultInfo(ResultState.FAIL, jsonResult.errmsg);
}
/// <summary>
/// 根据手机号进行注册
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public async Task<ResultInfo> RegisterAsync(BusinessRegDto model)
{
//检查此手机号是否已注册
if (await dbClient.Queryable<YB_Business>().AnyAsync(x => x.Phone == model.Phone))
{
return new ResultInfo(ResultState.FAIL, "此手机号已注册,可直接登录");
}
if (model.isvrcode)
{
if (string.IsNullOrEmpty(model.code))
{
return new ResultInfo(ResultState.FAIL, "验证码不可为空");
}
//检查验证码
var yzm = RedisHelpers.stringGet<string>($"ybdeviceclient_yam_{model.Phone}");
if (model.code != yzm)
{
return new ResultInfo() { code = ResultState.FAIL, message = "验证码错误" };
}
}
//检查两次密码是否一致
if (model.Password != model.RePassword)
{
return new ResultInfo(ResultState.FAIL, "两次密码不一致");
}
return await InsertOrUpdateAccountInfoAsync(model);
}
/// <summary>
/// 生成code
/// </summary>
/// <param name="cnt"></param>
/// <returns></returns>
private string GenCode(int cnt) =>
cnt switch
{
< 9 => $"000{cnt + 1}",
< 99 and >= 9 => $"00{cnt + 1}",
< 999 and >= 99 => $"0{cnt + 1}",
< 9999 and >= 999 => $"{cnt + 1}",
_ => ""
};
/// <summary>
/// 生成token
/// </summary>
/// <returns></returns>
private async Task<ResultInfo> GenTokenAsync(int userid, int businessid, string openid, string sessionid)
{
openid = openid.ToStr();
sessionid = sessionid.ToStr();
var business = await dbClient.Queryable<YB_Account>().FirstAsync(x => x.BusinessId == businessid);
//生成token
var token = JWTEncryption.Encrypt(new Dictionary<string, object>() {
{"UserId",userid},
{"BusinessId",businessid},
{"loginttime",DateTime.Now },
{"fansid",openid },
{"AccountType",business !=null?business.AccountType:1 }
});
var refreshToken = JWTEncryption.GenerateRefreshToken(token, 43200);
return new ResultInfo(ResultState.SUCCESS, "登录成功", new
{
token = token,
sessionid = sessionid,
refreshtoken = refreshToken
});
}
/// <summary>
/// 添加或者更新商户信息
/// </summary>
/// <param name="businessRegDto"></param>
/// <returns></returns>
public async Task<ResultInfo> InsertOrUpdateAccountInfoAsync(BusinessRegDto businessRegDto)
{
SessionBag sessionBag = null;
if (!businessRegDto.sessionId.IsEmpty())
{
sessionBag = await SessionContainer.GetSessionAsync(businessRegDto.sessionId);
if (sessionBag == null)
{
return new ResultInfo(ResultState.FAIL, "sessionId未找到");
}
}
var busienss = await dbClient.Queryable<YB_Business>().FirstAsync(x => x.Phone == businessRegDto.Phone);
//如果未注册自动进行注册
if (busienss == null)
{
//生成编码
int cnt = await dbClient.Queryable<YB_Business>().CountAsync(x => x.ParentId == 0);
string scode = GenCode(cnt);
if (string.IsNullOrEmpty(scode))
{
return new ResultInfo(ResultState.FAIL, "超过最大注册数量");
}
var buss = new YB_Business
{
CreateTime = DateTime.Now,
Status = (int)StatusType.Enabled,
Name = businessRegDto.NickName,
Phone = businessRegDto.Phone,
Remark = "",
ParentId = 0,
Type = 2, //1-系统默认,2-通过商户小程序自主注册的
Code = scode
};
var bid = await dbClient.Insertable(buss).ExecuteReturnIdentityAsync();
var secretkey = Md5.md5(Common.CreateNo(), 16).ToLower();
var password = Md5.md5(DESEncrypt.Encrypt(Md5.md5(businessRegDto.Password, 32).ToLower(), secretkey).ToLower(), 32).ToLower();
var user = new YB_Account
{
Secret = secretkey,
AccountType = (int)AccountType.agent,
Status = (int)StatusType.Enabled,
BusinessId = bid,
CreateTime = DateTime.Now,
LastVisitIP = "",
LastVisitTime = DateTime.Now,
Phone = businessRegDto.Phone,
RealName = businessRegDto.NickName,
RoleId = 2,
UserName = businessRegDto.Phone,
Password = password
};
int userid = await dbClient.Insertable(user).ExecuteReturnIdentityAsync();
//插入商户数据
await dbClient.Insertable(new YB_BusinessRealData
{
BusinessCount = 0,
CreateTime = DateTime.Now,
Balance = 0,
BusinessId = bid,
DevCount = 0,
TodayIncome = 0,
TodayResultCnt = 0,
TotalIncome = 0,
TotalResultCnt = 0,
TotalTxAmount = 0,
TodayRealCnt = 0,
TotalRealCnt = 0,
TodayDevCount = 0
}).ExecuteCommandAsync();
//更新汇总表
int devcnt = await dbClient.Queryable<YB_Device>().CountAsync();
int businesscnt = await dbClient.Queryable<YB_Business>().CountAsync();
int todaydevactinvecnt = await dbClient.Queryable<YB_Device>().Where(x => SqlFunc.DateIsSame(x.LastHeartTime, DateTime.Now)).CountAsync();
if (await dbClient.Queryable<YB_Combined>().AnyAsync(x => x.Id == 1))
{
await dbClient.Updateable<YB_Combined>().SetColumns(x => new YB_Combined
{
TotalDevCnt = devcnt,
BusinessCnt = businesscnt,
TodayDevCnt = todaydevactinvecnt
}).Where(x => x.Id == 1).ExecuteCommandAsync();
}
else
{
await dbClient.Insertable(new YB_Combined
{
TodayDevCnt = todaydevactinvecnt,
BusinessCnt = businesscnt,
TodayIncome = 0,
TodayRegCnt = 0,
TodayResultCnt = 0,
TotalDevCnt = devcnt,
TotalIncome = 0,
TotalRegCnt = 0,
TotalResultCnt = 0,
Id = 1
}).ExecuteCommandAsync();
}
//增加关联记录
if (sessionBag != null)
{
await dbClient.Insertable(new YB_BusinessWX
{
BusinessId = bid,
CreateTime = DateTime.Now,
OpenId = sessionBag.OpenId,
UnionId = sessionBag.UnionId.ToStr(),
UserId = userid
}).ExecuteCommandAsync();
}
//生成token
return await GenTokenAsync(userid, user.BusinessId, sessionBag?.OpenId, businessRegDto.sessionId);
}
else
{
var user = await dbClient.Queryable<YB_Account>().FirstAsync(x => x.BusinessId == busienss.Id);
//更新数据
if (sessionBag != null && !await dbClient.Queryable<YB_BusinessWX>().AnyAsync(x => x.BusinessId == busienss.Id && x.OpenId == sessionBag.OpenId))
{
await dbClient.Insertable(new YB_BusinessWX
{
BusinessId = busienss.Id,
CreateTime = DateTime.Now,
OpenId = sessionBag.OpenId,
UnionId = sessionBag.UnionId.ToStr(),
UserId = user.Id
}).ExecuteCommandAsync();
}
//更新登录时间
await dbClient.Updateable<YB_Account>().SetColumns(x => new YB_Account
{
LastVisitIP = Net.Ip,
LastVisitTime = DateTime.Now
}).Where(x => x.Id == user.Id).ExecuteCommandAsync();
//生成token
return await GenTokenAsync (user.Id, user.BusinessId, sessionBag?.OpenId, businessRegDto.sessionId);
}
}
/// <summary>
/// 根据手机号和密码进行登录
/// </summary>
/// <param name="businessLoginDto"></param>
/// <returns></returns>
public async Task<ResultInfo> LoginAsync(BusinessLoginDto businessLoginDto)
{
//检查此手机号是否已注册
if (!await dbClient.Queryable<YB_Business>().AnyAsync(x => x.Phone == businessLoginDto.Phone))
{
return new ResultInfo(ResultState.FAIL, "此手机号还未注册账户");
}
var user = await dbClient.Queryable<YB_Account>().FirstAsync(x => x.Phone == businessLoginDto.Phone);
if (user == null)
{
return new ResultInfo(ResultState.FAIL, "此手机号还未注册账户");
}
//检查密码是否正确
var checkpassword = Md5.md5(DESEncrypt.Encrypt(Md5.md5(businessLoginDto.Password, 32).ToLower(), user.Secret).ToLower(), 32).ToLower();
if (checkpassword != user.Password)
{
return new ResultInfo(ResultState.FAIL, "密码不正确");
}
return await InsertOrUpdateAccountInfoAsync(new BusinessRegDto
{
code = "",
sessionId = businessLoginDto.sessionId,
isvrcode = false,
NickName = businessLoginDto.Phone,
Phone = businessLoginDto.Phone,
Password = businessLoginDto.Password,
RePassword = businessLoginDto.Password
});
}
/// <summary>
/// 手机号快捷登录
/// </summary>
/// <param name="businessQLoginDto"></param>
/// <returns></returns>
public async Task<ResultInfo> SLoginAsync(BusinessQLoginDto businessQLoginDto)
{
if (businessQLoginDto.isvrcode)
{
if (string.IsNullOrEmpty(businessQLoginDto.code))
{
return new ResultInfo(ResultState.FAIL, "验证码不可为空");
}
//检查验证码
var yzm = RedisHelpers.stringGet<string>($"ybdeviceclient_yam_{businessQLoginDto.Phone}");
if (businessQLoginDto.code != yzm)
{
return new ResultInfo() { code = ResultState.FAIL, message = "验证码错误" };
}
}
return await InsertOrUpdateAccountInfoAsync(new BusinessRegDto
{
code = "",
sessionId = businessQLoginDto.sessionId,
isvrcode = false,
NickName = businessQLoginDto.Phone,
Password = businessQLoginDto.Phone,
Phone = businessQLoginDto.Phone,
RePassword = businessQLoginDto.Phone
});
}
/// <summary>
/// 发送短信验证码
/// </summary>
/// <param name="phone"></param>
/// <returns></returns>
public async Task<ResultInfo> SendCodeAsync(string phone)
{
if (string.IsNullOrEmpty(phone))
{
return new ResultInfo(ResultState.FAIL, "手机号不可为空");
}
if (!Validate.IsValidMobile(phone))
{
return new ResultInfo(ResultState.FAIL, "手机号码不合法");
}
Random rd = new Random();
var yzm = rd.Next(100000, 999999);
var platform = "每日一称";
var content = $"【{platform}】您好,欢迎使用{platform},您的手机验证码是:{yzm},验证码一分钟内有效,若非本人操作,请忽略!";
var data = new
{
phone = phone,
Content = HttpUtility.UrlEncode(content)
};
var par = $"ybdeviceclient_yam_{phone}";
if (!string.IsNullOrEmpty(RedisHelpers.stringGet<string>(par)))
{
return new ResultInfo(ResultState.FAIL, "请求频繁");
}
var url = "http://sms.ybhdmob.com/Message/Send?token=ybhdmob";
var request = new HttpRequestMessage(HttpMethod.Post,
url);
string body = data.ToJson();
request.Content = new StringContent(body, Encoding.UTF8, "application/json");
var client = _clientFactory.CreateClient();
var response = await client.SendAsync(request);
if (response.IsSuccessStatusCode)
{
var result = await response.Content.ReadAsStringAsync();
var results = result.ToObject<SMSMODEL>();
//记录日志
var msg = $"短信发送:参数:{data.ToJson()}\r\n返回值:{result}";
_loggerService.AddLogger(msg);
if (results != null && results.code == 0)
{
RedisHelpers.Insert(par, yzm.ToString(), 60);
}
return new ResultInfo(ResultState.SUCCESS, "验证码已发送");
}
else
{
return new ResultInfo(ResultState.FAIL, "短信发送失败");
}
}
}
}