初始提交

This commit is contained in:
wanyongkang
2020-10-07 20:25:03 +08:00
commit d318014316
3809 changed files with 263103 additions and 0 deletions

View File

@@ -0,0 +1,537 @@
using AngleSharp.Html.Parser;
using Hncore.Infrastructure.Common;
using Hncore.Infrastructure.Extension;
using Hncore.Infrastructure.Serializer;
using Hncore.Infrastructure.WebApi;
using Hncore.Pass.Vpn.Model;
using Hncore.Pass.Vpn.Request.Product;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
namespace Hncore.Pass.Vpn.Service
{
public class AgentClient1Service:AgentClientBaseService
{
string LoginUrl { get; set; } = "main/agentLogin.html";
string LoginCodeUrl { get; set; } = "main/imgcode.html";
string RefrushTokenUrl { get; set; } = "agent/index.html";
string SingleAddUrl { get; set; } = "agent/memberSingleAdd.html";
string SingleReAddUrl { get; set; } = "agent/memberRenew.html";
string MuiltAddUrl { get; set; } = "agent/memberMuiltAdd.html";
string RefundUrl { get; set; } = "agent/memberRefundAct.html ";
string UpdateUrl = "agent/memberUpdate/id/";//agent/memberUpdate/id/1155709.html
string OnlineUrl { get; set; } = "agent/radiusOnline.html?search=1&username=";
string KIllUrl { get; set; } = "agent/disConnect2/radacctid/{0}.html";
string searchAccountUrl = "agent/memberList/type/1.html?search=1&username=";
string searchTestAccountUrl = "agent/memberList/type/0.html?search=1&username=";
string DeleteUrl { get; set; } = "agent/memberDel/id/";//1160862.html";
IHttpClientFactory m_HttpClientFactory;
public AgentClient1Service(IHttpClientFactory httpClientFactory):base(httpClientFactory)
{
m_HttpClientFactory = httpClientFactory;
}
public override async Task<int> RefrushStatus()
{
int status = 0;
if (this.Token.Has())
{
var client = CreateHttpClient();
if (this.RefrushTokenUrl.Has())
{
// client.DefaultRequestHeaders.Add("Cookie", this.Token);
var getResp = await client.GetAsync(this.RefrushTokenUrl);
var content = await getResp.Content.ReadAsStringAsync();
if (getResp.StatusCode == HttpStatusCode.OK && content.IndexOf("agentLogin.html") == -1)
{
status = 1;
}
else
{
Debug.WriteLine("离线");
Debug.WriteLine(content);
}
}
}
return status;
}
public override async Task<(byte[], string)> GetCode()
{
var client = CreateHttpClient(false);
if (this.LoginUrl.NotHas()) return (null, "");
var getResp = await client.GetAsync(this.LoginUrl);
var cookie = this.GetCookie(getResp, "PHPSESSID");
if (cookie.Has())
{
client.DefaultRequestHeaders.Add("Cookie", cookie);
var ret = await client.GetByteArrayAsync(this.LoginCodeUrl + "?t=" + DateTime.Now.Millisecond);
return (ret, cookie);
}
return (null, "");
}
public override async Task<ApiResult> Login(AgentLoginRequest request)
{
var client = CreateHttpClient(false);
var map = new Dictionary<string, string>(){
{"agentName",request.Account },
{"password",request.Pwd },
{"authnum",request.Code },
};
LogHelper.Info("Login", map.ToJson());
AddCookie(client, request.Key);
//client.DefaultRequestHeaders.Add("Cookie", request.Key);
var resp = await client.PostAsForm(this.LoginUrl, map);
var content = await resp.Content.ReadAsStringAsync();
if (content.IndexOf("alert alert-danger") != -1)
{
return new ApiResult(ResultCode.C_VISITOR_CHECKING, "登录失败");
}
return new ApiResult(request.Key);
}
public override bool CheckAccount(int productId,List<string> accounts)
{
return false;
}
/// <summary>
/// 新开
/// </summary>
/// <param name="packageId"></param>
/// <param name="account"></param>
/// <param name="pwd"></param>
/// <returns></returns>
public override async Task<ApiResult> NewAccount(string packageKey, string account, string pwd, int connCount = 1, int accountType = 1, int payCount = 1)
{
var client = CreateHttpClient();
var map = new Dictionary<string, string>(){
{"taocanName",packageKey },
{"username",account },
{"password",pwd },
{"maxonline",connCount.ToString()},
{"type",accountType.ToString()}
};
var title = GetOpTitle("NewAccount", account);
LogHelper.Info(title, map.ToJson());
try
{
var resp = await client.PostAsForm(this.SingleAddUrl, map);
var content = await resp.Content.ReadAsStringAsync();
if (content.Has() && content.IndexOf("{alert(\"成功\")") != -1)
{
return new ApiResult(ResultCode.C_SUCCESS);
}
else
{
LogHelper.Error(title, content);
return new ApiResult(ResultCode.C_INVALID_ERROR, "开户失败");
}
}
catch (Exception ex)
{
LogHelper.Error(title, ex.Message);
return new ApiResult(ResultCode.C_INVALID_ERROR, "开户失败");
}
}
/// <summary>
/// 新开
/// </summary>
/// <param name="packageId"></param>
/// <param name="account"></param>
/// <param name="pwd"></param>
/// <returns></returns>
public override async Task<ApiResult> NewMuiltAccount(string packageKey, string account, string pwd, int connCount = 1, int accountType = 1,int startNum=0, int endNum=1 )
{
var client = CreateHttpClient();
var map = new Dictionary<string, string>(){
{"taocanName",packageKey },
{"usernameTpl",account },
{"password",pwd },
{"maxonline",connCount.ToString()},
{"startNum",startNum.ToString()},
{"endNum",endNum.ToString()},
{"mode",accountType.ToString()},
};
var title = GetOpTitle("NewMuiltAccount", account);
LogHelper.Info(title, map.ToJson());
try
{
var resp = await client.PostAsForm(this.MuiltAddUrl, map);
var content = await resp.Content.ReadAsStringAsync();
if (content.Has() && content.IndexOf("<td>成功</td>") != -1)
{
return new ApiResult(1);
}
else
{
LogHelper.Error(title, content);
return new ApiResult(ResultCode.C_INVALID_ERROR, "开户失败");
}
}
catch (Exception ex)
{
LogHelper.Error(title, ex.Message);
return new ApiResult(ResultCode.C_INVALID_ERROR, "开户失败");
}
}
/// <summary>
/// 续费
/// </summary>
/// <param name="productId"></param>
/// <param name="account"></param>
/// <param name="pwd"></param>
/// <returns></returns>
public override async Task<ApiResult> NewReAccount(string packageKey, string account, int connCount)
{
var client = CreateHttpClient();
var map = new Dictionary<string, string>(){
{"taocanName",packageKey },
{"username",account },
{"iscz","3" },
};
var title = GetOpTitle("NewReAccount", account);
LogHelper.Info(title, map.ToJson());
try
{
var resp = await client.PostAsForm(this.SingleReAddUrl, map);
var content = await resp.Content.ReadAsStringAsync();
if (content.Has() && content.IndexOf("alert(\"成功\")") != -1)
{
return new ApiResult(1);
}
else
{
LogHelper.Error(title, content);
return new ApiResult(ResultCode.C_INVALID_ERROR, "续费失败");
}
}
catch (Exception ex)
{
LogHelper.Error(title, ex.Message);
return new ApiResult(ResultCode.C_INVALID_ERROR, "续费失败");
}
}
/// <summary>
/// 删除账号
/// </summary>
/// <param name="productId"></param>
/// <param name="account"></param>
/// <returns></returns>
public override async Task<bool> DeleteAccount(string account)
{
var client = CreateHttpClient();
var infoRet = await this.GetAccountInfo(account, true);
if (infoRet.Code != ResultCode.C_SUCCESS)
return false;
var title = GetOpTitle("DeleteAccount", account);
LogHelper.Info(title, account);
try
{
var delete = this.DeleteUrl + infoRet.Data.Id + ".html";
var resp = await client.GetAsync(delete);
var content = await resp.Content.ReadAsStringAsync();
if (content.Has() && content.IndexOf("alert(\"删除成功\")") != -1)
{
return true;
}
else
{
LogHelper.Error(title, content);
return false;
}
}
catch (Exception ex)
{
LogHelper.Error(title, ex.Message);
return false;
}
}
/// <summary>
/// 得到账号信息
/// </summary>
/// <param name="productId"></param>
/// <param name="account"></param>
/// <returns></returns>
public override async Task<ApiResult<OriginAccountModel>> GetAccountInfo(string account,bool isTest=false)
{
var client = CreateHttpClient();
var title = GetOpTitle("GetAccountInfo", account);
var info = "";
try
{
var url = this.searchAccountUrl + account;
if (isTest)
{
url = this.searchTestAccountUrl + account;
}
var resp = await client.GetAsync(url);
var content = await resp.Content.ReadAsStringAsync();
var parser = new HtmlParser();
var document = await parser.ParseDocumentAsync(content);
////table class="table table-bordered"
var trs = document.QuerySelectorAll("table.table tr").ToList();
// var trs= table.QuerySelectorAll("tr").ToList();
var retData = new List<OriginAccountModel>();
if (trs.Count() > 1)
{
foreach(var tr in trs.Skip(1))
{
var tds = tr.QuerySelectorAll("td").ToList();
var tdAccount = tds[1].FirstChild.TextContent;
if (tdAccount != account)
continue;
info = string.Join("", tds.Select(m => m.OuterHtml));
//<td >会员账号</td><td >类型</td><td >套餐</td><td >注册日期</td><td >过期日期</td><td >连接数</td><td >余额</td><td >激活</td><td >备注</td>
var trData = new OriginAccountModel
{
Account = account,
Pwd = tds[1].QuerySelector("font").TextContent,
AccountType = tds[2].TextContent,
Package = tds[3].TextContent,
RegistTime = tds[4].TextContent,
EndTime = tds[5].ChildNodes[0].TextContent.Replace("\n", "").Replace("\t", "").Trim(),
RestTime = tds[5].ChildNodes[2].TextContent.Replace("\n", "").Replace("\t", ""),
ConnectCount = tds[6].TextContent,
Amount = tds[7].TextContent,
IsActive = tds[8].TextContent,
Remark = tds[9].TextContent,
};
trData.RealEndTime = DateTime.Parse(trData.EndTime);
if (tds[5].TextContent.Contains("已过期"))
{
trData.RestTime = "已过期";
}else
{
// "6.14:32"
var timeStr = trData.RestTime.Replace("天", ".").Replace("时", ":").Replace("分", "").Trim();
var restTime = TimeSpan.Parse(timeStr);
trData.RealEndTime = DateTime.Now.Add(restTime);
}
var href = tr.LastElementChild.QuerySelector("a")?.Attributes["href"]?.Value;
if (href.Has())
{
var start = href.LastIndexOf('/');
var end = href.IndexOf(".html");
if (start != -1 && end != -1)
{
trData.Id = href.Substring(start + 1, end - start).TrimEnd('.');
}
}
return new ApiResult<OriginAccountModel>(trData);
}
}
}
catch (Exception ex)
{
LogHelper.Error(title, ex.Message+"-->info:"+ info);
return new ApiResult<OriginAccountModel>(ResultCode.C_INVALID_ERROR, "查询失败");
}
return new ApiResult<OriginAccountModel>(ResultCode.C_INVALID_ERROR, "没有查询到信息");
}
/// <summary>
/// 修改账号密码
/// </summary>
/// <param name="productId"></param>
/// <param name="account"></param>
/// <param name="pwd"></param>
/// <returns></returns>
public override async Task<bool> UpdateAccountPwd(string account, string pwd)
{
var ret = await this.GetAccountInfo(account);
if (ret.Code != ResultCode.C_SUCCESS)
{
return false;
}
var accountModel = ret.Data;
if (accountModel == null)
{
return false;
}
var client = CreateHttpClient();
var map = new Dictionary<string, string>(){
{"username",account },
{"password",pwd },
{"submit","提交" },
};
LogHelper.Info(GetOpTitle("UpdateAccountPwd", account), map.ToJson());
try
{
var resp = await client.PostAsForm(this.UpdateUrl + accountModel.Id + ".html", map);
var content = await resp.Content.ReadAsStringAsync();
if (content.Has() && content.IndexOf("更新成功") != -1)
{
return true;
}
else
{
LogHelper.Error(GetOpTitle("UpdateAccountPwd", account), content);
}
}
catch (Exception ex)
{
LogHelper.Error(GetOpTitle("UpdateAccountPwd", account), ex);
}
return false;
}
/// <summary>
/// 退款
/// </summary>
/// <param name="packageId"></param>
/// <param name="account"></param>
/// <returns></returns>
public override async Task<ApiResult> Refund(string account, string packageKey, int days)
{
var client = CreateHttpClient();
var map = new Dictionary<string, string>(){
{"refundUser",account },
{"refundReason","hl" },
};
var title = GetOpTitle("Refund", account);
LogHelper.Info(title, map.ToJson());
try
{
var resp = await client.PostAsForm(this.RefundUrl, map);
var content = await resp.Content.ReadAsStringAsync();
content = System.Text.RegularExpressions.Regex.Unescape(content);
if (content.Has() && content.IndexOf("退款成功") != -1)
{
return new ApiResult(1);
}
else
{
LogHelper.Error(title, content);
return new ApiResult(ResultCode.C_INVALID_ERROR, "退款失败");
}
}
catch (Exception ex)
{
LogHelper.Error(title, ex.Message);
return new ApiResult(ResultCode.C_INVALID_ERROR, "退款失败");
}
}
/// <summary>
/// 是否在线
/// </summary>
/// <param name="productId"></param>
/// <param name="account"></param>
/// <returns></returns>
public override async Task<ApiResult<List<OriginAccountOnlineModel>>> OnLine(string account)
{
var client = CreateHttpClient();
var title = GetOpTitle("OnLine", account);
var info = "";
try
{
var url = this.OnlineUrl + account;
var resp = await client.GetAsync(url);
var content = await resp.Content.ReadAsStringAsync();
var parser = new HtmlParser();
var document = await parser.ParseDocumentAsync(content);
var trs = document.QuerySelectorAll("table.table tr").ToList();
var retData = new List<OriginAccountOnlineModel>();
if (trs.Count() > 1)
{
foreach (var tr in trs.Skip(1))
{
var tds = tr.QuerySelectorAll("td").ToList();
var tdAccount = tds[1].FirstChild.TextContent;
if (tdAccount != account)
continue;
info = string.Join("", tds.Select(m => m.OuterHtml));
//序号 会员账号 服务器IP 登录时间 在线时长 会员IP 上行流量 下行流量 操作
var trData = new OriginAccountOnlineModel
{
Account = account,
ServerIP = tds[2].TextContent,
LoginTime = tds[3].TextContent,
OnlineTime = tds[4].TextContent,
LoginIP = tds[5].TextContent,
UpStream = tds[6].TextContent,
DownStream = tds[7].TextContent,
Id= account,
};
var href = tr.LastElementChild.QuerySelector("a")?.Attributes["href"]?.Value;
if (href.Has())
{
var start = href.LastIndexOf('/');
var end = href.IndexOf(".html");
if (start != -1 && end != -1)
{
trData.Id = href.Substring(start + 1, end - start).TrimEnd('.');
}
}
retData.Add(trData);
}
}
return new ApiResult<List<OriginAccountOnlineModel>>(retData);
}
catch (Exception ex)
{
LogHelper.Error(title, ex.Message + "-->info:" + info);
return new ApiResult<List<OriginAccountOnlineModel>>(ResultCode.C_INVALID_ERROR, "查询失败");
}
}
/// <summary>
/// 踢号
/// </summary>
/// <param name="productId"></param>
/// <param name="account"></param>
/// <returns></returns>
public override async Task<bool> KillOut( string id)
{
var client = CreateHttpClient();
var title = GetOpTitle("KillOut", id);
var info = "";
try
{
var url = string.Format(this.KIllUrl, id);
var resp = await client.GetAsync(url);
var content = await resp.Content.ReadAsStringAsync();
if(content.Has()&&content.IndexOf("断开成功")!=-1)
{
return true;
}
}
catch (Exception ex)
{
LogHelper.Error(title, ex.Message + "-->info:" + info);
}
return false;
}
/// <summary>
/// 是否存在
/// </summary>
/// <param name="account"></param>
/// <returns></returns>
public override async Task<bool> Exist(string account)
{
var client = CreateHttpClient();
var title = GetOpTitle("Exist", account);
LogHelper.Info(title, account);
var testRet = await this.NewAccount("free", account, "1234", 1, 0);
if (testRet.Code == ResultCode.C_SUCCESS)
{
await DeleteAccount(account);
return false;
}
return true;
}
}
}

View File

@@ -0,0 +1,526 @@
using AngleSharp.Html.Parser;
using Hncore.Infrastructure.Common;
using Hncore.Infrastructure.Extension;
using Hncore.Infrastructure.Serializer;
using Hncore.Infrastructure.WebApi;
using Hncore.Pass.Vpn.Model;
using Hncore.Pass.Vpn.Request.Product;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
namespace Hncore.Pass.Vpn.Service
{
//老鹰A组
public class AgentClient2Service : AgentClientBaseService
{
string LoginUrl { get; set; } = "index.php/admin/index/login.html";
string LoginCodeUrl { get; set; } = "main/imgcode.html";
string RefrushTokenUrl { get; set; } = "index.php/admin/index/public_welcome.html";// "";
string SingleAddUrl { get; set; } = "index.php/admin/users/useradd.html";
string SingleReAddUrl { get; set; } = "index.php/admin/users/userrenew.html";
string MuiltAddUrl { get; set; } = "index.php/admin/users/usersadd.html";
string RefundUrl { get; set; } = "index.php/admin/users/userrefund.html";
string OnlineUrl { get; set; } = "";
string GetAccount { get; set; } = "index.php/admin/users/users/grid/datagrid.html";
string KIllUrl { get; set; } = "index.php/admin/users/useroffline.html";
string UpdateUrl { get; set; } = "index.php/admin/users/useredit.html";
string DeleteAccountUrl { get; set; } = "index.php/admin/users/userdelete.html";
string searchAccountUrl = "index.php/admin/users/users/grid/datagrid.html";
string existCheckUrl = "index.php/admin/users/public_checkusername.html";
string refrushCookie = "admin/Common/getCookie";
string sessionlife = "index.php/admin/index/public_sessionlife.html";
IHttpClientFactory m_HttpClientFactory;
public AgentClient2Service(IHttpClientFactory httpClientFactory):base(httpClientFactory)
{
m_HttpClientFactory = httpClientFactory;
}
public async Task<int> RefrushStatus1()
{
int status = 0;
if (this.Token.Has())
{
var client = CreateHttpClient();
if (this.RefrushTokenUrl.Has())
{
var getResp = await client.GetAsync(this.RefrushTokenUrl);
var content = await getResp.Content.ReadAsStringAsync();
if (getResp.StatusCode == HttpStatusCode.OK && content.IndexOf("正常登录") == -1)
{
status = 1;
}
else
{
Debug.WriteLine("离线");
Debug.WriteLine(content);
}
}
}
return status;
}
public override async Task<int> RefrushStatus()
{
var map = new Dictionary<string, string>(){
{"key","1" }
};
int status = 0;
var client = CreateHttpClient();
client.DefaultRequestHeaders.Add("X-Requested-With", "XMLHttpRequest");
var getResp = await client.PostAsForm(this.sessionlife, map);
var content = await getResp.Content.ReadAsStringAsync();
content= System.Text.RegularExpressions.Regex.Unescape(content);
if (getResp.StatusCode == HttpStatusCode.OK && content.IndexOf("登录后台") == -1)
{
status = 1;
}
//else
//{
// var request = new AgentLoginRequest()
// {
// Account = this.Product.Account,
// Pwd = this.Product.Pwd
// };
// var ret = await this.Login(request);
// if (ret.Code == ResultCode.C_SUCCESS)
// {
// this.Product.Token = ret.Data.ToString();
// status = 1;
// }
// else
// {
// Debug.WriteLine("离线");
// }
//}
client.DefaultRequestHeaders.Remove("X-Requested-With");
return status;
}
private async Task<string> GetHomeCookie()
{
var client = CreateHttpClient(false);
if (this.LoginUrl.NotHas()) return "";
var getResp = await client.GetAsync(this.LoginUrl);
var cookies = this.GetCookies(getResp);
cookies=cookies.Replace("path=/;", "").Replace("httponly", "").Trim();
return cookies;
}
public override async Task<ApiResult> Login(AgentLoginRequest request)
{
var client = CreateHttpClient(false);
var map = new Dictionary<string, string>(){
{"managername",request.Account },
{"password",request.Pwd },
// {"authnum",request.Code },
};
LogHelper.Info("Login", map.ToJson());
request.Key = await GetHomeCookie();
AddCookie(client, request.Key);
var resp = await client.PostAsForm(this.LoginUrl, map);
var content = await resp.Content.ReadAsStringAsync();
if (content.IndexOf("index.html") == -1)
{
return new ApiResult(ResultCode.C_VISITOR_CHECKING, "登录失败");
}
return new ApiResult(request.Key);
}
public override bool CheckAccount(int productId,List<string> accounts)
{
return false;
}
/// <summary>
/// 新开
/// </summary>
/// <param name="packageId"></param>
/// <param name="account"></param>
/// <param name="pwd"></param>
/// <returns></returns>
public override async Task<ApiResult> NewAccount(string packageKey, string account, string pwd, int connCount = 1, int accountType = 1, int payCount = 1)
{
var client = CreateHttpClient();
var map = new Dictionary<string, string>(){
{"info[groupid]","2001" },
{"info[srvid]","6" },
{"info[username]",account },
{"info[password]",pwd },
{"info[cycle]",packageKey },
{"info[simuse]",connCount.ToString() },
{"info[usetime]","1" },
{"info[tryuse]",accountType==1?"0":"1"},
};
var title = GetOpTitle("NewAccount", account);
LogHelper.Info(title, map.ToJson());
try
{
var resp = await client.PostAsForm(this.SingleAddUrl, map);
var content = await resp.Content.ReadAsStringAsync();
if (content.Has() && content.IndexOf("开通成功") != -1)
{
return new ApiResult(1);
}
else
{
LogHelper.Error(title, content);
return new ApiResult(ResultCode.C_INVALID_ERROR, "开户失败");
}
}
catch (Exception ex)
{
LogHelper.Error(title, ex.Message);
return new ApiResult(ResultCode.C_INVALID_ERROR, "开户失败");
}
}
/// <summary>
/// 批量新开
/// </summary>
/// <param name="packageId"></param>
/// <param name="account"></param>
/// <param name="pwd"></param>
/// <returns></returns>
public override async Task<ApiResult> NewMuiltAccount(string packageKey, string account, string pwd, int connCount = 1, int accountType = 1,int startNum=0, int endNum=1 )
{
var client = CreateHttpClient();
var map = new Dictionary<string, string>(){
{"info[groupid]","2001" },
{"info[srvid]","6" },
{"info[username_header]",account },
{"info[username_start]",startNum.ToString() },
{"info[username_end]",endNum.ToString() },
{"info[pwdtype]","0" },
{"info[password]",pwd },
{"info[repassword]",pwd },
{"info[cycle]",packageKey },
{"info[simuse]",connCount.ToString() },
{"info[usetime]","1" },
{"info[tryuse]","0" },
};
var title = GetOpTitle("NewMuiltAccount", account);
LogHelper.Info(title, map.ToJson());
try
{
var resp = await client.PostAsForm(this.MuiltAddUrl, map);
var content = await resp.Content.ReadAsStringAsync();
if (content.Has() && content.IndexOf("开通成功") != -1)
{
return new ApiResult(1);
}
else
{
LogHelper.Error(title, content);
return new ApiResult(ResultCode.C_INVALID_ERROR, "开户失败");
}
}
catch (Exception ex)
{
LogHelper.Error(title, ex.Message);
return new ApiResult(ResultCode.C_INVALID_ERROR, "开户失败");
}
}
/// <summary>
/// 续费
/// </summary>
/// <param name="productId"></param>
/// <param name="account"></param>
/// <param name="pwd"></param>
/// <returns></returns>
public override async Task<ApiResult> NewReAccount(string packageKey,string account, int connCount)
{
var client = CreateHttpClient();
Dictionary<string, int> priceMap = new Dictionary<string, int>()
{
{"daycardprice",3},
{"weekcardprice",15},
{"monthcardprice",60},
};
var price = priceMap[packageKey];
var totalAmount = price * connCount;
var map = new Dictionary<string, string>(){
{"info[username]",account },
{"info[cycle]",packageKey },
{"info[simuse]",connCount.ToString()},
{"info[usetime]","1" },
{"info[usemoney]",totalAmount.ToString() },
};
var title = GetOpTitle("NewReAccount", account);
LogHelper.Info(title, map.ToJson());
try
{
var resp = await client.PostAsForm(this.SingleReAddUrl, map);
var content = await resp.Content.ReadAsStringAsync();
if (content.Has() && content.IndexOf("续费成功") != -1)
{
return new ApiResult(1);
}
else
{
LogHelper.Error(title, content);
return new ApiResult(ResultCode.C_INVALID_ERROR, "续费失败");
}
}
catch (Exception ex)
{
LogHelper.Error(title, ex.Message);
return new ApiResult(ResultCode.C_INVALID_ERROR, "续费失败");
}
}
/// <summary>
/// 删除账号
/// </summary>
/// <param name="productId"></param>
/// <param name="account"></param>
/// <returns></returns>
public override async Task<bool> DeleteAccount(string account)
{
var client = CreateHttpClient();
var map = new Dictionary<string, string>(){
{"usernames",account }
};
LogHelper.Info(GetOpTitle("DeleteAccount", account), map.ToJson());
try
{
var resp = await client.PostAsForm(this.SingleAddUrl, map);
var content = await resp.Content.ReadAsStringAsync();
if (content.Has() && content.IndexOf("删除成功") != -1)
{
return true;
}
else
{
LogHelper.Error(GetOpTitle("DeleteAccount", account), content);
}
}
catch (Exception ex)
{
LogHelper.Error(GetOpTitle("DeleteAccount", account), ex);
}
return false;
}
/// <summary>
/// 得到账号信息
/// </summary>
/// <param name="productId"></param>
/// <param name="account"></param>
/// <returns></returns>
public override async Task<ApiResult<OriginAccountModel>> GetAccountInfo(string account,bool isTest)
{
var client = CreateHttpClient();
var map = new Dictionary<string, string>(){
{"search[username]",account },
{"page","1" },
{"rows","25" },
};
var title = GetOpTitle("GetAccountInfo", account);
try
{
var content = await client.PostAsFormGetString(this.searchAccountUrl, map);
JObject jo = (JObject)JsonConvert.DeserializeObject(content);
var rows = jo["rows"].ToArray();
var row = rows.FirstOrDefault();
var trData = new OriginAccountModel
{
User = row["groupname"].ToString(),
Account = row["username"].ToString(),
AccountType = row["username"].ToString(),
Package = row["cycle"].ToString(),
RegistTime = row["createdon"].ToString(),
EndTime = row["expiration"].ToString(),
ConnectCount = row["simuse"].ToString(),
Pwd=row["open_password"].ToString(),
// Amount = row["cycle"].ToString(),
RestTime = row["havetime"].ToString(),
IsActive = row["status"].ToString(),
Remark = row["comment"].ToString(),
OnLine = row["status"].ToString().IndexOf("在线") == -1 ? 0 : 1,
LoginTime= row["acctstarttime"].ToString(),
LoginServer= row["nasipaddress"].ToString(),
};
trData.RealEndTime = DateTime.Parse(trData.EndTime);
return new ApiResult<OriginAccountModel>(trData);
}
catch (Exception ex)
{
LogHelper.Error(title, ex.Message);
return new ApiResult<OriginAccountModel>(ResultCode.C_INVALID_ERROR, "查询失败");
}
}
/// <summary>
/// 修改账号密码
/// </summary>
/// <param name="productId"></param>
/// <param name="account"></param>
/// <param name="pwd"></param>
/// <returns></returns>
public override async Task<bool> UpdateAccountPwd(string account,string pwd)
{
var client = CreateHttpClient();
var map = new Dictionary<string, string>(){
{"info[groupid]","2001" },
{"info[srvid]","6" },
{"info[username]",account },
{"info[password]",pwd },
};
LogHelper.Info(GetOpTitle("UpdateAccountPwd", account), map.ToJson());
try
{
var resp = await client.PostAsForm(this.UpdateUrl, map);
var content = await resp.Content.ReadAsStringAsync();
if (content.Has() && content.IndexOf("修改成功") != -1)
{
return true;
}
else
{
LogHelper.Error(GetOpTitle("UpdateAccountPwd", account), content);
}
}
catch (Exception ex)
{
LogHelper.Error(GetOpTitle("UpdateAccountPwd", account), ex);
}
return false;
}
/// <summary>
/// 退款
/// </summary>
/// <param name="packageId"></param>
/// <param name="account"></param>
/// <returns></returns>
public override async Task<ApiResult> Refund(string account, string packageKey, int days)
{
var client = CreateHttpClient();
var map = new Dictionary<string, string>(){
{"info[username]",account },
{"info[cycle]",packageKey },
{"info[expiretime]",days.ToString() },
};
var title = GetOpTitle("Refund", account);
LogHelper.Info(title, map.ToJson());
try
{
var resp = await client.PostAsForm(this.RefundUrl, map);
var content = await resp.Content.ReadAsStringAsync();
if (content.Has() && content.IndexOf("退款成功") != -1)
{
return new ApiResult(1);
}
else
{
LogHelper.Error(title, content);
return new ApiResult(ResultCode.C_INVALID_ERROR, "退款失败");
}
}
catch (Exception ex)
{
LogHelper.Error(title, ex.Message);
return new ApiResult(ResultCode.C_INVALID_ERROR, "退款失败");
}
}
/// <summary>
/// 是否在线
/// </summary>
/// <param name="productId"></param>
/// <param name="account"></param>
/// <returns></returns>
public override async Task<ApiResult<List<OriginAccountOnlineModel>>> OnLine(string account)
{
var accountInfo =await this.GetAccountInfo(account, false);
if (accountInfo.Code != ResultCode.C_SUCCESS) return await base.OnLine(account);
var list = new List<OriginAccountOnlineModel>();
if (accountInfo.Data.OnLine == 1)
{
list.Add(new OriginAccountOnlineModel()
{
Account = account,
OnLine = accountInfo.Data.OnLine,
Id = account,
LoginTime= accountInfo.Data.LoginTime,
LoginIP= accountInfo.Data.LoginServer
});
}
return new ApiResult<List<OriginAccountOnlineModel>>(list);
}
/// <summary>
/// 踢号
/// </summary>
/// <param name="productId"></param>
/// <param name="account">账号</param>
/// <returns></returns>
public override async Task<bool> KillOut( string account)
{
var client = CreateHttpClient();
client.DefaultRequestHeaders.Add("X-Requested-With", "XMLHttpRequest");
var map = new Dictionary<string, string>(){
{"usernames",account },
};
var title = GetOpTitle("KillOut", account);
LogHelper.Info(title, map.ToJson());
try
{
var resp = await client.PostAsForm(this.KIllUrl, map);
var content = await resp.Content.ReadAsStringAsync();
if (content.Has() && content.IndexOf("次踢人操作") != -1)
{
return true;
}
else
{
LogHelper.Error(title, content);
}
}
catch (Exception ex)
{
LogHelper.Error(title, ex.Message);
}
return false;
}
/// <summary>
/// 是否存在
/// </summary>
/// <param name="account"></param>
/// <returns></returns>
public override async Task<bool> Exist(string account)
{
var client = CreateHttpClient();
var map = new Dictionary<string, string>(){
{"username",account }
};
var title = GetOpTitle("Exist", account);
LogHelper.Info(title, map.ToJson());
try
{
var resp = await client.PostAsForm(this.existCheckUrl, map);
var content = await resp.Content.ReadAsStringAsync();
if (content.Has() && content.IndexOf("false") != -1)
{
return true;
}
else
{
return false;
}
}
catch (Exception ex)
{
LogHelper.Error(title, ex.Message);
return false;
}
}
}
}

View File

@@ -0,0 +1,539 @@
using AngleSharp.Html.Parser;
using Hncore.Infrastructure.Common;
using Hncore.Infrastructure.Extension;
using Hncore.Infrastructure.Serializer;
using Hncore.Infrastructure.WebApi;
using Hncore.Pass.Vpn.Model;
using Hncore.Pass.Vpn.Request.Product;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
namespace Hncore.Pass.Vpn.Service
{
//老鹰B组
public class AgentClient3Service : AgentClientBaseService
{
string LoginUrl { get; set; } = "api/login";
string LoginCodeUrl { get; set; } = "";
string RefrushTokenUrl { get; set; } = "api/info?_=";
string SingleAddUrl { get; set; } = "api/ppp/one";
string ReAddUrl { get; set; } = "api/ppp/renewal";
string MuiltAddUrl { get; set; } = "api/ppp/batch";
string RefundUrl { get; set; } = "api/ppp/delete";
string OnlineUrl { get; set; } = "api/ppp/oln?user={0}&_={1}";
string GetAccount { get; set; } = "index.php/admin/users/users/grid/datagrid.html";
string KIllUrl { get; set; } = "api/ppp/oln/stop";
string UpdateUrl { get; set; } = "api/ppp/update";
string DeleteAccountUrl { get; set; } = "api/ppp/delete?user=hl&_=1583126809671";
string InfoUrl = "api/ppp?page=1&user=";
string TestAddUrl { get; set; } = "api/ppp/test";
IHttpClientFactory m_HttpClientFactory;
public AgentClient3Service(IHttpClientFactory httpClientFactory):base(httpClientFactory)
{
m_HttpClientFactory = httpClientFactory;
}
public override async Task<int> RefrushStatus()
{
int status = 0;
if (this.Token.Has())
{
var client = CreateHttpClient();
if (this.RefrushTokenUrl.Has())
{
var getResp = await client.GetAsync(this.RefrushTokenUrl+DateTime.Now.GetUnixTimeStamp());
var content = await getResp.Content.ReadAsStringAsync();
if (getResp.StatusCode == HttpStatusCode.OK && content.IndexOf("\"ret\":200") != -1)
{
status = 1;
}
else
{
Debug.WriteLine("离线");
Debug.WriteLine(content);
}
}
}
return status;
}
public override async Task<ApiResult> Login(AgentLoginRequest request)
{
var client = CreateHttpClient(false);
var map = new Dictionary<string, string>(){
{"username",request.Account },
{"password",request.Pwd },
{"autologon","false"},
};
LogHelper.Info("Login", map.ToJson());
var resp = await client.PostAsForm(this.LoginUrl, map);
var content = await resp.Content.ReadAsStringAsync();
if (content.IndexOf("登陆成功")!= -1)
{
request.Key = this.GetCookie(resp, "_dailissid");
return new ApiResult(request.Key);
}
return new ApiResult(ResultCode.C_VISITOR_CHECKING, "登录失败");
}
public override bool CheckAccount(int productId,List<string> accounts)
{
return false;
}
/// <summary>
/// 新开
/// </summary>
/// <param name="packageId"></param>
/// <param name="account"></param>
/// <param name="pwd"></param>
/// <returns></returns>
public override async Task<ApiResult> NewAccount(string packageKey, string account, string pwd, int connCount = 1, int accountType = 1, int payCount = 1)
{
if (accountType == 0)//新开测试号
{
return await NewTestAccount(account, pwd);
}
var client = CreateHttpClient();
var map = new Dictionary<string, string>(){
{"user",account },
{"passwd",pwd },
{"type",packageKey },
{"conn_max",connCount.ToString() },
{"paynum",payCount.ToString()},
{"details","hl" },
};
var title = GetOpTitle("NewAccount", account);
LogHelper.Info(title, map.ToJson());
try
{
var resp = await client.PostAsForm(this.SingleAddUrl, map);
var content = await resp.Content.ReadAsStringAsync();
if (content.Has() && content.IndexOf("开户成功") != -1)
{
return new ApiResult(ResultCode.C_SUCCESS);
}
else
{
LogHelper.Error(title, content);
return new ApiResult(ResultCode.C_INVALID_ERROR, "开户失败");
}
}
catch (Exception ex)
{
LogHelper.Error(title, ex.Message);
return new ApiResult(ResultCode.C_INVALID_ERROR, "开户失败");
}
}
public async Task<ApiResult> NewTestAccount(string account, string pwd)
{
var client = CreateHttpClient();
var map = new Dictionary<string, string>(){
{"user",account },
{"passwd",pwd },
};
var title = GetOpTitle("NewTestAccount", account);
LogHelper.Info(title, map.ToJson());
try
{
var resp = await client.PostAsForm(this.TestAddUrl, map);
var content = await resp.Content.ReadAsStringAsync();
if (content.Has() && content.IndexOf("开户成功") != -1)
{
return new ApiResult(ResultCode.C_SUCCESS);
}
else
{
LogHelper.Error(title, content);
return new ApiResult(ResultCode.C_INVALID_ERROR, "开户失败");
}
}
catch (Exception ex)
{
LogHelper.Error(title, ex.Message);
return new ApiResult(ResultCode.C_INVALID_ERROR, "开户失败");
}
}
/// <summary>
/// 批量新开
/// </summary>
/// <param name="packageId"></param>
/// <param name="account"></param>
/// <param name="pwd"></param>
/// <returns></returns>
public override async Task<ApiResult> NewMuiltAccount(string packageKey, string account, string pwd, int connCount = 1, int accountType = 1, int startNum = 0, int endNum = 1)
{
var client = CreateHttpClient();
var map = new Dictionary<string, string>(){
{"user",account },
{"passwd",pwd },
{"form",startNum.ToString() },
{"to",endNum.ToString() },
{"type",packageKey },
{"conn_max",connCount.ToString() },
{"paynum","1" },
{"details","hl" },
};
var title = GetOpTitle("NewMuiltAccount", account);
LogHelper.Info(title, map.ToJson());
try
{
var resp = await client.PostAsForm(this.MuiltAddUrl, map);
var content = await resp.Content.ReadAsStringAsync();
if (content.Has() && content.IndexOf("开户成功") != -1)
{
return new ApiResult(1);
}
else
{
LogHelper.Error(title, content);
return new ApiResult(ResultCode.C_INVALID_ERROR, "开户失败");
}
}
catch (Exception ex)
{
LogHelper.Error(title, ex.Message);
return new ApiResult(ResultCode.C_INVALID_ERROR, "开户失败");
}
}
/// <summary>
/// 续费
/// </summary>
/// <param name="productId"></param>
/// <param name="account"></param>
/// <param name="pwd"></param>
/// <returns></returns>
public override async Task<ApiResult> NewReAccount(string packageKey, string account, int connCount)
{
var client = CreateHttpClient();
var map = new Dictionary<string, string>(){
{"user",account },
{"type",packageKey },
{"paynum","1"},
};
var title = GetOpTitle("NewReAccount", account);
LogHelper.Info(title, map.ToJson());
try
{
var resp = await client.PostAsForm(this.ReAddUrl, map);
var content = await resp.Content.ReadAsStringAsync();
if (content.Has() && content.IndexOf("续费成功") != -1)
{
return new ApiResult(1);
}
else
{
LogHelper.Error(title, content);
return new ApiResult(ResultCode.C_INVALID_ERROR, "续费失败");
}
}
catch (Exception ex)
{
LogHelper.Error(title, ex.Message);
return new ApiResult(ResultCode.C_INVALID_ERROR, "续费失败");
}
}
/// <summary>
/// 删除账号
/// </summary>
/// <param name="productId"></param>
/// <param name="account"></param>
/// <returns></returns>
public override async Task<bool> DeleteAccount(string account)
{
var client = CreateHttpClient();
var map = new Dictionary<string, string>(){
{"usernames",account }
};
LogHelper.Info(GetOpTitle("DeleteAccount", account), map.ToJson());
try
{
var resp = await client.PostAsForm(this.SingleAddUrl, map);
var content = await resp.Content.ReadAsStringAsync();
if (content.Has() && content.IndexOf("删除成功") != -1)
{
return true;
}
else
{
LogHelper.Error(GetOpTitle("DeleteAccount", account), content);
}
}
catch (Exception ex)
{
LogHelper.Error(GetOpTitle("DeleteAccount", account), ex);
}
return false;
}
/// <summary>
/// 得到账号信息
/// </summary>
/// <param name="productId"></param>
/// <param name="account"></param>
/// <returns></returns>
public override async Task<ApiResult<OriginAccountModel>> GetAccountInfo(string account,bool isTest)
{
var client = CreateHttpClient();
var title = GetOpTitle("GetAccountInfo", account);
var info = "";
try
{
var resp = await client.GetAsync(this.InfoUrl+account);
var content = await resp.Content.ReadAsStringAsync();
info = content;
JObject jo = (JObject)JsonConvert.DeserializeObject(content);
var datas = jo["data"]["data"];
var row = datas?.FirstOrDefault();
var trData = new OriginAccountModel
{
User = row["user"].ToString(),
Account = row["user"].ToString(),
AccountType = row["type"].ToString(),
Package ="",
RegistTime = Convert.ToInt64(row["add_time"]).LoadFromUnixTimeStamp().AddHours(8).ToString(),
EndTime =Convert.ToInt64(row["end_time"]).LoadFromUnixTimeStamp().AddHours(8).ToString(),
ConnectCount = row["conn_max"].ToString(),
Pwd = row["passwd"].ToString(),
};
trData.RealEndTime = DateTime.Parse(trData.EndTime);
var restDay = (trData.RealEndTime - DateTime.Now).Days;
restDay = restDay < 0 ? 0 : restDay;
if (restDay <= 1) trData.Package = "天";
else if(restDay <= 7) trData.Package = "周";
else trData.Package = "月";
return new ApiResult<OriginAccountModel>(trData);
//var parser = new HtmlParser();
//var document = await parser.ParseDocumentAsync(content);
//////table class="table table-bordered"
//var trs = document.QuerySelectorAll("table[class='table table-bordered']>tr").ToList();
//// var trs= table.QuerySelectorAll("tr").ToList();
//if (trs.Count() > 1)
//{
// var tr = trs.Skip(1).FirstOrDefault();
// var tdTexts = tr.QuerySelectorAll("td").Select(m => m.TextContent).ToList();
// //<td >会员账号</td><td >类型</td><td >套餐</td><td >注册日期</td><td >过期日期</td><td >连接数</td><td >余额</td><td >激活</td><td >备注</td>
// var trData = new OriginAccountModel
// {
// Account = tdTexts[0],
// AccountType = tdTexts[1],
// Package = tdTexts[2],
// RegistTime = tdTexts[3],
// EndTime = tdTexts[4],
// ConnectCount = tdTexts[5],
// Amount = tdTexts[6],
// IsActive = tdTexts[7],
// Remark = tdTexts[8],
// };
// var href = tr.LastElementChild.QuerySelector("a")?.Attributes["href"]?.Value;
// if (href.Has())
// {
// var start = href.LastIndexOf('/');
// var end = href.IndexOf(".html");
// if (start != -1 && end != -1)
// {
// trData.Id = href.Substring(start, end - start);
// }
// }
// return new ApiResult<OriginAccountModel>(trData);
//}
}
catch (Exception ex)
{
LogHelper.Error(title, ex.Message+"-->info:"+ info);
return new ApiResult<OriginAccountModel>(ResultCode.C_INVALID_ERROR, "查询失败");
}
return new ApiResult<OriginAccountModel>(ResultCode.C_INVALID_ERROR, "没有查询到信息");
}
/// <summary>
/// 修改账号密码
/// </summary>
/// <param name="productId"></param>
/// <param name="account"></param>
/// <param name="pwd"></param>
/// <returns></returns>
public override async Task<bool> UpdateAccountPwd(string account,string pwd)
{
var client = CreateHttpClient();
var map = new Dictionary<string, string>(){
{"user",account },
{"new_user",account},
{"passwd",pwd },
{"details","hl" },
};
LogHelper.Info(GetOpTitle("UpdateAccountPwd", account), map.ToJson());
try
{
var resp = await client.PostAsForm(this.UpdateUrl, map);
var content = await resp.Content.ReadAsStringAsync();
if (content.Has() && content.IndexOf("修改成功") != -1)
{
return true;
}
else
{
LogHelper.Error(GetOpTitle("UpdateAccountPwd", account), content);
}
}
catch (Exception ex)
{
LogHelper.Error(GetOpTitle("UpdateAccountPwd", account), ex);
}
return false;
}
/// <summary>
/// 退款
/// </summary>
/// <param name="packageId"></param>
/// <param name="account"></param>
/// <returns></returns>
public override async Task<ApiResult> Refund(string account, string packageKey, int days)
{
var client = CreateHttpClient();
var title = GetOpTitle("Refund", account);
try
{
var resp = await client.GetAsync(this.RefundUrl+$"?user={account}&_={DateTime.Now.GetUnixTimeStamp()} ");
var content = await resp.Content.ReadAsStringAsync();
content = System.Text.RegularExpressions.Regex.Unescape(content);
if (content.Has() && content.IndexOf("删除成功") != -1)
{
return new ApiResult(1);
}
else
{
LogHelper.Error(title, content);
return new ApiResult(ResultCode.C_INVALID_ERROR, "退款失败");
}
}
catch (Exception ex)
{
LogHelper.Error(title, ex.Message);
return new ApiResult(ResultCode.C_INVALID_ERROR, "退款失败");
}
}
/// <summary>
/// 是否在线
/// </summary>
/// <param name="productId"></param>
/// <param name="account"></param>
/// <returns></returns>
public override async Task<ApiResult<List<OriginAccountOnlineModel>>> OnLine(string account)
{
var client = CreateHttpClient();
var title = GetOpTitle("OnLine", account);
var info = "";
try
{
string url = string.Format(this.OnlineUrl, account, DateTime.Now.GetUnixTimeStamp());
var resp = await client.GetAsync(url);
var content = await resp.Content.ReadAsStringAsync();
info = content;
JObject jo = (JObject)JsonConvert.DeserializeObject(content);
var datas = jo["data"]["data"];
var rows = datas.Children();
var retData = new List<OriginAccountOnlineModel>();
if (datas!=null&& rows.Count() > 0)
{
foreach (var row in rows)
{
var trData = new OriginAccountOnlineModel()
{
Account = account,
OnLine = 1,
LoginIP = row["client_ip"].ToString(),
ServerIP=row["nas_name"].ToString(),
LoginTime=row["add_time"].ToString(),
Id = row["id"].ToString()
};
trData.LoginTime = (DateTime.Now - trData.LoginTime.LoadFromUnixTimeStamp().Value).ToString("d\\.hh\\:mm\\:ss");
retData.Add(trData);
}
}
return new ApiResult<List<OriginAccountOnlineModel>>(retData);
}
catch (Exception ex)
{
LogHelper.Error(title, ex.Message + "-->info:" + info);
return await base.OnLine(account);
}
}
/// <summary>
/// 踢号
/// </summary>
/// <param name="productId"></param>
/// <param name="account"></param>
/// <returns></returns>
public override async Task<bool> KillOut( string id)
{
// formData id: d9bd8ac88e31d43b0507f5f66927c2ee
var client = CreateHttpClient();
var map = new Dictionary<string, string>(){
{"id",id },
};
LogHelper.Info(GetOpTitle("KillOut", id), map.ToJson());
try
{
var resp = await client.PostAsForm(this.KIllUrl, map);
var content = await resp.Content.ReadAsStringAsync();
if (content.Has() && content.IndexOf("踢线成功") != -1)
{
return true;
}
else
{
LogHelper.Error(GetOpTitle("KillOut", id), content);
}
}
catch (Exception ex)
{
LogHelper.Error(GetOpTitle("KillOut", id), ex);
}
return false;
}
/// <summary>
/// 是否存在
/// </summary>
/// <param name="account"></param>
/// <returns></returns>
public override async Task<bool> Exist(string account)
{
// return false;
var client = CreateHttpClient();
var map = new Dictionary<string, string>(){
{"groupname",account }
};
var title = GetOpTitle("Exist", account);
LogHelper.Info(title, map.ToJson());
var ret = await this.NewAccount("w", account, "123");
if (ret.Code == ResultCode.C_SUCCESS)
{
await this.Refund(account, "w", 1);
return false;
}
return true;
}
}
}

View File

@@ -0,0 +1,591 @@
using AngleSharp.Dom;
using AngleSharp.Html.Parser;
using Hncore.Infrastructure.Common;
using Hncore.Infrastructure.Extension;
using Hncore.Infrastructure.Serializer;
using Hncore.Infrastructure.WebApi;
using Hncore.Pass.Vpn.Model;
using Hncore.Pass.Vpn.Request.Product;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
namespace Hncore.Pass.Vpn.Service
{
//金桥
public class AgentClient4Service: AgentClient1Service
{
string LoginUrl { get; set; } = "main/agentLogin.html";
string LoginCodeUrl { get; set; } = "main/imgcode.html";
string RefrushTokenUrl { get; set; } = "agent.html";
string SingleAddUrl { get; set; } = "agent/memberSingleAdd.html";
string SingleReAddUrl { get; set; } = "agent/memberRenew.html";
string MuiltAddUrl { get; set; } = "agent/memberMuiltAdd.html";
string RefundUrl { get; set; } = "agent/memberRefundAct.html ";
string UpdateUrl = "agent/memberUpdate/id/";//agent/memberUpdate/id/1155709.html
string OnlineUrl { get; set; } = "";
string KIllUrl { get; set; } = "";
string searchAccountUrl = "agent/memberList/type/1.html?search=1&username=";
string searchTestAccountUrl = "agent/memberList/type/0.html?search=1&username=";
string DeleteUrl { get; set; } = "agent/memberDel/id/";//1160862.html";
string KillUrlClient = "/agent/disConnect/sessionid/{0}.html";
string ClientOnlineUrl { get; set; } = "agent/clientOnline/page/{0}.html";
IHttpClientFactory m_HttpClientFactory;
public AgentClient4Service(IHttpClientFactory httpClientFactory):base(httpClientFactory)
{
m_HttpClientFactory = httpClientFactory;
}
public override async Task<int> RefrushStatus()
{
int status = 0;
if (this.Token.Has())
{
var client = CreateHttpClient();
if (this.RefrushTokenUrl.Has())
{
// client.DefaultRequestHeaders.Add("Cookie", this.Token);
var getResp = await client.GetAsync(this.RefrushTokenUrl);
var content = await getResp.Content.ReadAsStringAsync();
if (getResp.StatusCode == HttpStatusCode.OK && content.IndexOf("agentLogin.html") == -1)
{
status = 1;
}
else
{
Debug.WriteLine("离线");
Debug.WriteLine(content);
}
}
}
return status;
}
public override async Task<(byte[], string)> GetCode()
{
var client = CreateHttpClient(false);
if (this.LoginUrl.NotHas()) return (null, "");
var getResp = await client.GetAsync(this.LoginUrl);
var cookie = this.GetCookie(getResp, "PHPSESSID");
if (cookie.Has())
{
client.DefaultRequestHeaders.Add("Cookie", cookie);
var ret = await client.GetByteArrayAsync(this.LoginCodeUrl + "?t=" + DateTime.Now.Millisecond);
return (ret, cookie);
}
return (null, "");
}
public override async Task<ApiResult> Login(AgentLoginRequest request)
{
var client = CreateHttpClient(false);
var map = new Dictionary<string, string>(){
{"agentName",request.Account },
{"password",request.Pwd },
{"authnum",request.Code },
};
LogHelper.Info("Login", map.ToJson());
AddCookie(client, request.Key);
//client.DefaultRequestHeaders.Add("Cookie", request.Key);
var resp = await client.PostAsForm(this.LoginUrl, map);
var content = await resp.Content.ReadAsStringAsync();
if (content.IndexOf("alert alert-danger") != -1)
{
return new ApiResult(ResultCode.C_VISITOR_CHECKING, "登录失败");
}
return new ApiResult(request.Key);
}
public override bool CheckAccount(int productId,List<string> accounts)
{
return false;
}
/// <summary>
/// 新开
/// </summary>
/// <param name="packageId"></param>
/// <param name="account"></param>
/// <param name="pwd"></param>
/// <returns></returns>
public override async Task<ApiResult> NewAccount(string packageKey, string account, string pwd, int connCount = 1, int accountType = 1, int payCount = 1)
{
var client = CreateHttpClient();
var map = new Dictionary<string, string>(){
{"taocanName",packageKey },
{"username",account },
{"password",pwd },
{"maxonline",connCount.ToString()},
{"type",accountType.ToString()}
};
var title = GetOpTitle("NewAccount", account);
LogHelper.Info(title, map.ToJson());
try
{
var resp = await client.PostAsForm(this.SingleAddUrl, map);
var content = await resp.Content.ReadAsStringAsync();
if (content.Has() && content.IndexOf("{alert(\"成功\")") != -1)
{
return new ApiResult(ResultCode.C_SUCCESS);
}
else
{
LogHelper.Error(title, content);
return new ApiResult(ResultCode.C_INVALID_ERROR, "开户失败");
}
}
catch (Exception ex)
{
LogHelper.Error(title, ex.Message);
return new ApiResult(ResultCode.C_INVALID_ERROR, "开户失败");
}
}
/// <summary>
/// 新开
/// </summary>
/// <param name="packageId"></param>
/// <param name="account"></param>
/// <param name="pwd"></param>
/// <returns></returns>
public override async Task<ApiResult> NewMuiltAccount(string packageKey, string account, string pwd, int connCount = 1, int accountType = 1,int startNum=0, int endNum=1 )
{
var client = CreateHttpClient();
var map = new Dictionary<string, string>(){
{"taocanName",packageKey },
{"usernameTpl",account },
{"password",pwd },
{"maxonline",connCount.ToString()},
{"startNum",startNum.ToString()},
{"endNum",endNum.ToString()},
{"mode",accountType.ToString()},
};
var title = GetOpTitle("NewMuiltAccount", account);
LogHelper.Info(title, map.ToJson());
try
{
var resp = await client.PostAsForm(this.MuiltAddUrl, map);
var content = await resp.Content.ReadAsStringAsync();
if (content.Has() && content.IndexOf("<td>成功</td>") != -1)
{
return new ApiResult(1);
}
else
{
LogHelper.Error(title, content);
return new ApiResult(ResultCode.C_INVALID_ERROR, "开户失败");
}
}
catch (Exception ex)
{
LogHelper.Error(title, ex.Message);
return new ApiResult(ResultCode.C_INVALID_ERROR, "开户失败");
}
}
/// <summary>
/// 续费
/// </summary>
/// <param name="productId"></param>
/// <param name="account"></param>
/// <param name="pwd"></param>
/// <returns></returns>
public override async Task<ApiResult> NewReAccount(string packageKey, string account, int connCount)
{
var client = CreateHttpClient();
var map = new Dictionary<string, string>(){
{"taocanName",packageKey },
{"username",account },
{"iscz","3" },
};
var title = GetOpTitle("NewReAccount", account);
LogHelper.Info(title, map.ToJson());
try
{
var resp = await client.PostAsForm(this.SingleReAddUrl, map);
var content = await resp.Content.ReadAsStringAsync();
if (content.Has() && content.IndexOf("alert(\"成功\")") != -1)
{
return new ApiResult(1);
}
else
{
LogHelper.Error(title, content);
return new ApiResult(ResultCode.C_INVALID_ERROR, "续费失败");
}
}
catch (Exception ex)
{
LogHelper.Error(title, ex.Message);
return new ApiResult(ResultCode.C_INVALID_ERROR, "续费失败");
}
}
/// <summary>
/// 删除账号
/// </summary>
/// <param name="productId"></param>
/// <param name="account"></param>
/// <returns></returns>
public override async Task<bool> DeleteAccount(string account)
{
var client = CreateHttpClient();
var infoRet = await this.GetAccountInfo(account, true);
if (infoRet.Code != ResultCode.C_SUCCESS)
return false;
var title = GetOpTitle("DeleteAccount", account);
LogHelper.Info(title, account);
try
{
var delete = this.DeleteUrl + infoRet.Data.Id + ".html";
var resp = await client.GetAsync(delete);
var content = await resp.Content.ReadAsStringAsync();
if (content.Has() && content.IndexOf("alert(\"删除成功\")") != -1)
{
return true;
}
else
{
LogHelper.Error(title, content);
return false;
}
}
catch (Exception ex)
{
LogHelper.Error(title, ex.Message);
return false;
}
}
/// <summary>
/// 得到账号信息
/// </summary>
/// <param name="productId"></param>
/// <param name="account"></param>
/// <returns></returns>
public override async Task<ApiResult<OriginAccountModel>> GetAccountInfo(string account,bool isTest=false)
{
var client = CreateHttpClient();
var title = GetOpTitle("GetAccountInfo", account);
var info = "";
try
{
var url = this.searchAccountUrl + account;
if (isTest)
{
url = this.searchTestAccountUrl + account;
}
var resp = await client.GetAsync(url);
var content = await resp.Content.ReadAsStringAsync();
var parser = new HtmlParser();
var document = await parser.ParseDocumentAsync(content);
////table class="table table-bordered"
var trs = document.QuerySelectorAll("table.table tr").ToList();
// var trs= table.QuerySelectorAll("tr").ToList();
var retData = new List<OriginAccountModel>();
if (trs.Count() > 1)
{
//var tr = trs.Skip(1).FirstOrDefault();
foreach(var tr in trs.Skip(1))
{
var tds = tr.QuerySelectorAll("td").ToList();
var tdAccount = tds[1].FirstChild.TextContent;
if (tdAccount != account)
continue;
info = string.Join("", tds.Select(m => m.OuterHtml));
//<td >会员账号</td><td >类型</td><td >套餐</td><td >注册日期 过期日期</td><td>专线IP </td><td >连接数</td><td >余额</td><td >激活</td><td >备注</td>
var dateText = tds[4].InnerHtml;
var endtext = dateText.Split("<br>")[1].Split('\n');
var trData = new OriginAccountModel
{
Account = account,
Pwd = tds[1].QuerySelector("font").TextContent,
AccountType = tds[2].TextContent,
Package = tds[3].TextContent,
RegistTime = dateText.Split("<br>")[0],
EndTime = endtext[0].Replace("\n", "").Replace("\t", ""),
RestTime = endtext[1].Replace("\n", "").Replace("\t", ""),
ConnectCount = tds[6].TextContent,
Amount = tds[7].TextContent,
IsActive = tds[8].TextContent,
Remark = tds[9].TextContent,
};
trData.RealEndTime = DateTime.Parse(trData.EndTime);
if (trData.RestTime.Contains("已过期"))
{
trData.RestTime = "已过期";
}else
{
// "6.14:32"
var timeStr = trData.RestTime.Replace("天", ".").Replace("时", ":").Replace("分", "");
var restTime = TimeSpan.Parse(timeStr);
trData.RealEndTime = DateTime.Now.Add(restTime);
}
var href = tr.LastElementChild.QuerySelector("a")?.Attributes["href"]?.Value;
if (href.Has())
{
var start = href.LastIndexOf('/');
var end = href.IndexOf(".html");
if (start != -1 && end != -1)
{
trData.Id = href.Substring(start + 1, end - start).TrimEnd('.');
}
}
return new ApiResult<OriginAccountModel>(trData);
}
}
}
catch (Exception ex)
{
LogHelper.Error(title, ex.Message+"-->info:"+ info);
return new ApiResult<OriginAccountModel>(ResultCode.C_INVALID_ERROR, "查询失败");
}
return new ApiResult<OriginAccountModel>(ResultCode.C_INVALID_ERROR, "没有查询到信息");
}
/// <summary>
/// 修改账号密码
/// </summary>
/// <param name="productId"></param>
/// <param name="account"></param>
/// <param name="pwd"></param>
/// <returns></returns>
public override async Task<bool> UpdateAccountPwd(string account, string pwd)
{
var ret = await this.GetAccountInfo(account);
if (ret.Code != ResultCode.C_SUCCESS)
{
return false;
}
var accountModel = ret.Data;
if (accountModel == null)
{
return false;
}
var client = CreateHttpClient();
var map = new Dictionary<string, string>(){
{"username",account },
{"password",pwd },
{"submit","提交" },
};
LogHelper.Info(GetOpTitle("UpdateAccountPwd", account), map.ToJson());
try
{
var resp = await client.PostAsForm(this.UpdateUrl + accountModel.Id + ".html", map);
var content = await resp.Content.ReadAsStringAsync();
if (content.Has() && content.IndexOf("更新成功") != -1)
{
return true;
}
else
{
LogHelper.Error(GetOpTitle("UpdateAccountPwd", account), content);
}
}
catch (Exception ex)
{
LogHelper.Error(GetOpTitle("UpdateAccountPwd", account), ex);
}
return false;
}
/// <summary>
/// 退款
/// </summary>
/// <param name="packageId"></param>
/// <param name="account"></param>
/// <returns></returns>
public override async Task<ApiResult> Refund(string account, string packageKey, int days)
{
var client = CreateHttpClient();
var map = new Dictionary<string, string>(){
{"refundUser",account },
{"refundReason","hl" },
};
var title = GetOpTitle("Refund", account);
LogHelper.Info(title, map.ToJson());
try
{
var resp = await client.PostAsForm(this.RefundUrl, map);
var content = await resp.Content.ReadAsStringAsync();
if (content.Has() && content.IndexOf("alert(\"退款成功\")") != -1)
{
return new ApiResult(1);
}
else
{
LogHelper.Error(title, content);
return new ApiResult(ResultCode.C_INVALID_ERROR, "退款失败");
}
}
catch (Exception ex)
{
LogHelper.Error(title, ex.Message);
return new ApiResult(ResultCode.C_INVALID_ERROR, "退款失败");
}
}
/// <summary>
/// 是否在线
/// </summary>
/// <param name="productId"></param>
/// <param name="account"></param>
/// <returns></returns>
public override async Task<ApiResult<List<OriginAccountOnlineModel>>> OnLine(string account)
{
//虚拟在线
var onlines = await base.OnLine(account);
if (onlines.Code == ResultCode.C_SUCCESS && onlines.Data.Count > 0)
return onlines;
var retData = new List<OriginAccountOnlineModel>();
var client = CreateHttpClient();
int page = 1;
var url = string.Format(this.ClientOnlineUrl, page);
var resp = await client.GetAsync(url);
var content = await resp.Content.ReadAsStringAsync();
var parser = new HtmlParser();
var document = await parser.ParseDocumentAsync(content);
var table = document.QuerySelectorAll("table");
var pageP = table?.Next("p")?.FirstOrDefault();
if (pageP != null)
{
var total = 0;
if (pageP.TextContent.Has())
{
var start = pageP.TextContent.IndexOf('(');
var end = pageP.TextContent.IndexOf("页)");
var pageStr = pageP.TextContent.Substring(start + 2, end - start - 1);
int.TryParse(pageStr, out total);
}
if (total > 1)
{
await Enumerable.Range(1, total).ForEachAsync(async (int i) =>
{
var ret = await ClientOnLine(account, i);
retData.AddRange(ret);
});
}
else
{
retData = await ClientOnLine(account, 1);
}
}
else
{
retData = await ClientOnLine(account, 1);
}
return new ApiResult<List<OriginAccountOnlineModel>>(retData);
}
public async Task<List<OriginAccountOnlineModel>> ClientOnLine(string account,int page=1)
{
var client = CreateHttpClient();
var title = GetOpTitle("ClientOnLine", account);
var info = "";
var retData = new List<OriginAccountOnlineModel>();
try
{
var url =string.Format(this.ClientOnlineUrl,page);
var resp = await client.GetAsync(url);
var content = await resp.Content.ReadAsStringAsync();
var parser = new HtmlParser();
var document = await parser.ParseDocumentAsync(content);
var trs = document.QuerySelectorAll("table.table tr").ToList();
if (trs.Count() > 1)
{
foreach (var tr in trs.Skip(1))
{
var tds = tr.QuerySelectorAll("td").ToList();
var tdAccount = tds[1].FirstChild.TextContent;
if (tdAccount != account)
continue;
info = string.Join("", tds.Select(m => m.OuterHtml));
//序号 会员账号 登录时间 在线时长 客户端IP地址 操作
var trData = new OriginAccountOnlineModel
{
Account = account,
LoginTime = tds[2].TextContent,
OnlineTime = tds[3].TextContent,
LoginIP = tds[4].TextContent,
};
var href = tr.LastElementChild.QuerySelector("a")?.Attributes["href"]?.Value;
if (href.Has())
{
var start = href.LastIndexOf('/');
var end = href.IndexOf(".html");
if (start != -1 && end != -1)
{
trData.Id = href.Substring(start + 1, end - start).TrimEnd('.');
}
}
retData.Add(trData);
}
}
return retData;
}
catch (Exception ex)
{
LogHelper.Error(title, ex.Message + "-->info:" + info);
}
return retData;
}
/// <summary>
/// 踢号
/// </summary>
/// <param name="productId"></param>
/// <param name="account"></param>
/// <returns></returns>
public override async Task<bool> KillOut( string id)
{
var flag = await base.KillOut(id);
if (flag) return true;
var client = CreateHttpClient();
var title = GetOpTitle("KillOut", id);
var info = "";
try
{
var url = string.Format(this.KillUrlClient, id);
var resp = await client.GetAsync(url);
var content = await resp.Content.ReadAsStringAsync();
if (content.Has() && content.IndexOf("已经向客户端发送断开消息") != -1)
{
return true;
}
}
catch (Exception ex)
{
LogHelper.Error(title, ex.Message + "-->info:" + info);
}
return false;
}
/// <summary>
/// 是否存在
/// </summary>
/// <param name="account"></param>
/// <returns></returns>
public override async Task<bool> Exist(string account)
{
var client = CreateHttpClient();
var title = GetOpTitle("Exist", account);
LogHelper.Info(title, account);
var testRet = await this.NewAccount("free", account, "1234", 1, 0);
if (testRet.Code == ResultCode.C_SUCCESS)
{
await DeleteAccount(account);
return false;
}
return true;
}
}
}

View File

@@ -0,0 +1,319 @@
using AngleSharp.Html.Parser;
using Hncore.Infrastructure.Common;
using Hncore.Infrastructure.Extension;
using Hncore.Infrastructure.Serializer;
using Hncore.Infrastructure.WebApi;
using Hncore.Pass.Vpn.Model;
using Hncore.Pass.Vpn.Request.Product;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
namespace Hncore.Pass.Vpn.Service
{
//先锋
public class AgentClient5Service : AgentClient1Service
{
string LoginUrl { get; set; } = "main/agentLogin.html";
string LoginCodeUrl { get; set; } = "main/imgcode.html";
string RefrushTokenUrl { get; set; } = "agent.html";
string SingleAddUrl { get; set; } = "agent/memberSingleAdd.html";
string SingleReAddUrl { get; set; } = "agent/memberRenew.html";
string MuiltAddUrl { get; set; } = "agent/memberMuiltAdd.html";
string RefundUrl { get; set; } = "agent/memberRefund/id/{0}.html";
string UpdateUrl = "agent/memberUpdate/id/{0}.html";//agent/memberUpdate/id/1155709.html
string OnlineUrl { get; set; } = "agent/radiusOnline.html?search=1&username=";
string ClientOnlineUrl { get; set; } = "agent/clientOnline.html?search=1&username=";
string KIllUrl { get; set; } = "";
string KillUrlClient = "/agent/disConnect/sessionid/{0}.html";
string KillUrl = "/agent/disConnect/radacctid/{0}.html";
string searchAccountUrl = "agent/memberList/type/1.html?search=1&username=";
string searchTestAccountUrl = "agent/memberList/type/0.html?search=1&username=";
string DeleteUrl { get; set; } = "agent/multiDelMember.html ";
IHttpClientFactory m_HttpClientFactory;
public AgentClient5Service(IHttpClientFactory httpClientFactory):base(httpClientFactory)
{
m_HttpClientFactory = httpClientFactory;
}
/// <summary>
/// 新开
/// </summary>
/// <param name="packageId"></param>
/// <param name="account"></param>
/// <param name="pwd"></param>
/// <returns></returns>
public override async Task<ApiResult> NewAccount(string packageKey, string account, string pwd, int connCount = 1, int accountType = 1, int payCount = 1)
{
var client = CreateHttpClient();
var map = new Dictionary<string, string>(){
{"taocanName",packageKey },
{"username",account },
{"password",pwd },
{"bingfa",connCount.ToString()},
{"type",accountType.ToString()}
};
var title = GetOpTitle("NewAccount", account);
LogHelper.Info(title, map.ToJson());
try
{
var resp = await client.PostAsForm(this.SingleAddUrl, map);
var content = await resp.Content.ReadAsStringAsync();
if (content.Has() && content.IndexOf("{alert(\"成功\")") != -1)
{
return new ApiResult(ResultCode.C_SUCCESS);
}
else
{
LogHelper.Error(title, content);
return new ApiResult(ResultCode.C_INVALID_ERROR, "开户失败");
}
}
catch (Exception ex)
{
LogHelper.Error(title, ex.Message);
return new ApiResult(ResultCode.C_INVALID_ERROR, "开户失败");
}
}
/// <summary>
/// 删除账号
/// </summary>
/// <param name="productId"></param>
/// <param name="account"></param>
/// <returns></returns>
public override async Task<bool> DeleteAccount(string account)
{
var client = CreateHttpClient();
var infoRet = await this.GetAccountInfo(account, true);
if (infoRet.Code != ResultCode.C_SUCCESS)
return false;
var map = new Dictionary<string, string>(){
{infoRet.Data.Id,infoRet.Data.Id },
};
var title = GetOpTitle("DeleteAccount", account);
LogHelper.Info(title, account);
try
{
var resp = await client.PostAsForm(this.DeleteUrl, map);
var content = await resp.Content.ReadAsStringAsync();
if (content.Has() && content.IndexOf("删除成功") != -1)
{
return true;
}
else
{
LogHelper.Error(title, content);
return false;
}
}
catch (Exception ex)
{
LogHelper.Error(title, ex.Message);
return false;
}
}
/// <summary>
/// 修改账号密码
/// </summary>
/// <param name="productId"></param>
/// <param name="account"></param>
/// <param name="pwd"></param>
/// <returns></returns>
public override async Task<bool> UpdateAccountPwd(string account, string pwd)
{
var ret = await this.GetAccountInfo(account);
if (ret.Code != ResultCode.C_SUCCESS)
{
return false;
}
var accountModel = ret.Data;
if (accountModel == null)
{
return false;
}
var client = CreateHttpClient();
var map = new Dictionary<string, string>(){
{"username",account },
{"password",pwd },
{"maxOnline",ret.Data.ConnectCount },
};
LogHelper.Info(GetOpTitle("UpdateAccountPwd", account), map.ToJson());
try
{
var url = string.Format(this.UpdateUrl, accountModel.Id);
var resp = await client.PostAsForm(url, map);
var content = await resp.Content.ReadAsStringAsync();
if (content.Has() && content.IndexOf("更新成功") != -1)
{
return true;
}
else
{
LogHelper.Error(GetOpTitle("UpdateAccountPwd", account), content);
}
}
catch (Exception ex)
{
LogHelper.Error(GetOpTitle("UpdateAccountPwd", account), ex);
}
return false;
}
/// <summary>
/// 退款
/// </summary>
/// <param name="packageId"></param>
/// <param name="account"></param>
/// <returns></returns>
public override async Task<ApiResult> Refund(string account, string packageKey, int days)
{
var client = CreateHttpClient();
var title = GetOpTitle("Refund", account);
try
{
var accountInfo = await this.GetAccountInfo(account);
if (accountInfo.Code != ResultCode.C_SUCCESS)
{
return new ApiResult(ResultCode.C_INVALID_ERROR, "退款失败");
}
var url = string.Format(this.RefundUrl, accountInfo.Data.Id);
var resp = await client.GetAsync(url);
var content = await resp.Content.ReadAsStringAsync();
if (content.Has() && content.IndexOf("退款成功!") != -1)
{
return new ApiResult(1);
}
else
{
LogHelper.Error(title, content);
return new ApiResult(ResultCode.C_INVALID_ERROR, "退款失败");
}
}
catch (Exception ex)
{
LogHelper.Error(title, ex.Message);
return new ApiResult(ResultCode.C_INVALID_ERROR, "退款失败");
}
}
/// <summary>
/// 是否在线
/// </summary>
/// <param name="productId"></param>
/// <param name="account"></param>
/// <returns></returns>
public override async Task<ApiResult<List<OriginAccountOnlineModel>>> OnLine(string account)
{
//虚拟在线
var onlines= await base.OnLine(account);
if (onlines.Code == ResultCode.C_SUCCESS && onlines.Data.Count > 0)
return onlines;
var client = CreateHttpClient();
var title = GetOpTitle("OnLine", account);
var info = "";
try
{
var url = this.ClientOnlineUrl + account;
var resp = await client.GetAsync(url);
var content = await resp.Content.ReadAsStringAsync();
var parser = new HtmlParser();
var document = await parser.ParseDocumentAsync(content);
var trs = document.QuerySelectorAll("table.table tr").ToList();
var retData = new List<OriginAccountOnlineModel>();
if (trs.Count() > 1)
{
foreach (var tr in trs.Skip(1))
{
var tds = tr.QuerySelectorAll("td").ToList();
var tdAccount = tds[1].FirstChild.TextContent;
if (tdAccount != account)
continue;
info = string.Join("", tds.Select(m => m.OuterHtml));
//序号 会员账号 登录时间 在线时长 客户端IP地址 操作
var trData = new OriginAccountOnlineModel
{
Account = account,
LoginTime = tds[2].TextContent,
OnlineTime = tds[3].TextContent,
LoginIP = tds[4].TextContent,
};
var href = tr.LastElementChild.QuerySelector("a")?.Attributes["href"]?.Value;
if (href.Has())
{
var start = href.LastIndexOf('/');
var end = href.IndexOf(".html");
if (start != -1 && end != -1)
{
trData.Id = href.Substring(start + 1, end - start).TrimEnd('.');
}
}
retData.Add(trData);
}
}
return new ApiResult<List<OriginAccountOnlineModel>>(retData);
}
catch (Exception ex)
{
LogHelper.Error(title, ex.Message + "-->info:" + info);
return new ApiResult<List<OriginAccountOnlineModel>>(ResultCode.C_INVALID_ERROR, "查询失败");
}
}
/// <summary>
/// 踢号
/// </summary>
/// <param name="productId"></param>
/// <param name="account"></param>
/// <returns></returns>
public override async Task<bool> KillOut(string id)
{
var flag = await this.KillOutClient(id);
var client = CreateHttpClient();
var title = GetOpTitle("KillOut", id);
var info = "";
try
{
var url = string.Format(this.KillUrl, id);
var resp = await client.GetAsync(url);
var content = await resp.Content.ReadAsStringAsync();
if (content.Has() && content.IndexOf("断开消息已发送") != -1)
{
return true;
}
}
catch (Exception ex)
{
LogHelper.Error(title, ex.Message + "-->info:" + info);
}
return false;
}
public async Task<bool> KillOutClient(string id)
{
var client = CreateHttpClient();
var title = GetOpTitle("KillOutClient", id);
var info = "";
try
{
var url = string.Format(this.KillUrlClient, id);
var resp = await client.GetAsync(url);
var content = await resp.Content.ReadAsStringAsync();
if (content.Has() && content.IndexOf("已经向客户端发送断开消息") != -1)
{
return true;
}
}
catch (Exception ex)
{
LogHelper.Error(title, ex.Message + "-->info:" + info);
}
return false;
}
}
}

View File

@@ -0,0 +1,597 @@
using AngleSharp.Dom;
using AngleSharp.Html.Parser;
using Bogus.DataSets;
using Hncore.Infrastructure.Common;
using Hncore.Infrastructure.Extension;
using Hncore.Infrastructure.Serializer;
using Hncore.Infrastructure.WebApi;
using Hncore.Pass.Vpn.Model;
using Hncore.Pass.Vpn.Request.Product;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
namespace Hncore.Pass.Vpn.Service
{
public class AgentClient6Service : AgentClientBaseService
{
string secretId = "20200716182518182489";
string secretKey = "OFcEJAfzYjWT3e2s";
string UserApiUrl = "userapi/";
string LoginIndexUrl { get; set; } = "login/";
string LoginUrl { get; set; } = "loginauth/";
string LoginCodeUrl { get; set; } = "";
string RefrushTokenUrl { get; set; } = "userInfo/";
string SingleAddUrl { get; set; } = "userapi/";
string SingleReAddUrl { get; set; } = "user_buy_server";
string MuiltAddUrl { get; set; } = "agent/memberMuiltAdd.html";
string RefundUrl { get; set; } = "agent/memberRefundAct.html ";
string UpdateUrl = "setuser";
string OnlineUrl { get; set; } = "active_log/?user=";
string KIllUrl { get; set; } = "agent/disConnect2/radacctid/{0}.html";
string searchAccountUrl = "userList/?sum=100&page=1&search_data=";
string searchTestAccountUrl = "agent/memberList/type/0.html?search=1&username=";
string DeleteUrl { get; set; } = "agent/memberDel/id/";//1160862.html";
IHttpClientFactory m_HttpClientFactory;
public AgentClient6Service(IHttpClientFactory httpClientFactory):base(httpClientFactory)
{
m_HttpClientFactory = httpClientFactory;
}
protected override HttpClient CreateHttpClient(bool autoCooke = true)
{
var client = m_HttpClientFactory.CreateClient("agentClient1.0");
client.BaseAddress = new System.Uri(this.BaseUrl);
if (this.Token.Has() && autoCooke)
{
AddCookie(client, this.Token);
}
return client;
}
private string FormatRequest(Dictionary<string, string> map)
{
map["secretId"] = this.secretId;
map["secretKey"] = this.secretKey;
var data = string.Join("&", map.Select(m => $"{m.Key}={m.Value}"));
return data;
}
public override async Task<int> RefrushStatus()
{
int status = 0;
if (this.Token.Has())
{
var client = CreateHttpClient();
if (this.RefrushTokenUrl.Has())
{
// client.DefaultRequestHeaders.Add("Cookie", this.Token);
var getResp = await client.GetAsync(this.RefrushTokenUrl);
if (getResp.StatusCode == HttpStatusCode.OK)
{
status = 1;
}
else
{
var request = new AgentLoginRequest()
{
Account = this.Product.Account,
Pwd = this.Product.Pwd
};
var ret = await this.Login(request);
if (ret.Code == ResultCode.C_SUCCESS)
{
this.Product.Token = ret.Data.ToString();
status = 1;
}
else
{
Debug.WriteLine("离线");
}
}
}
}
return status;
}
public override async Task<(byte[], string)> GetCode()
{
return (null, "");
}
private async Task<(string, string)> GetHomeCookie()
{
var client = CreateHttpClient(false);
var getResp = await client.GetAsync(this.LoginIndexUrl);
var cookies = this.GetCookies(getResp);
cookies = cookies.Replace("path=/;", "").Replace("httponly", "").Trim();
var content = await getResp.Content.ReadAsStringAsync();
var parser = new HtmlParser();
var document = await parser.ParseDocumentAsync(content);
var csrf_tokenNode = document.QuerySelector("input[name=csrfmiddlewaretoken]");//<input type='hidden' name='csrfmiddlewaretoken' value='b8XKenjQ9GJUJF0xSZySXLsG5FGNHepk' />
var csrf_token = csrf_tokenNode.GetAttribute("value");
return (cookies, csrf_token);
}
public override async Task<ApiResult> Login(AgentLoginRequest request)
{
var tokens = await this.GetHomeCookie();
var client = CreateHttpClient(false);
client.DefaultRequestHeaders.Add("Connection", "keep-alive");
client.DefaultRequestHeaders.Add("Upgrade-Insecure-Requests", "1");
var csrftoken = this.GetCookieValue(tokens.Item1, "csrftoken");
var key = this.GetCookieValue(tokens.Item1, "key");
var map = new Dictionary<string, string>(){
{"csrfmiddlewaretoken",tokens.Item2},
{"username",request.Account },
{"password",request.Pwd },
{"remember",key },
};
LogHelper.Info("Login", map.ToJson());
var loginToken = $"csrftoken={csrftoken};key={key}";
AddCookie(client, loginToken);
var resp = await client.PostAsForm(this.LoginUrl, map);
var content = await resp.Content.ReadAsStringAsync();
if (resp.StatusCode != HttpStatusCode.Found || resp.Headers.Location.ToString().IndexOf("http://user.webok.me/userInfo/")==-1)
{
return new ApiResult(ResultCode.C_VISITOR_CHECKING, "登录失败");
}
var sessionid = this.GetCookie(resp, "sessionid");
var username_user = this.GetCookie(resp, "username_user");
request.Key = $"{loginToken};{sessionid};{username_user}";
return new ApiResult(request.Key);
}
public override bool CheckAccount(int productId,List<string> accounts)
{
return false;
}
/// <summary>
/// 新开
/// </summary>
/// <param name="packageId"></param>
/// <param name="account"></param>
/// <param name="pwd"></param>
/// <returns></returns>
public override async Task<ApiResult> NewAccount(string packageKey, string account, string pwd, int connCount = 1, int accountType = 1, int payCount = 1)
{
if (packageKey == "test_pay")
return await NewTestAccount(account, pwd);
var client = CreateHttpClient();
var map = new Dictionary<string, string>(){
{"type","adduser" },
{"user",account },
{"pass",pwd },
{"logincount",connCount.ToString()},
{"serverid",packageKey },
};
var title = GetOpTitle("NewAccount", account);
LogHelper.Info(title, map.ToJson());
try
{
var resp = await client.GetAsync(this.UserApiUrl + "?" + this.FormatRequest(map));
var content = await resp.Content.ReadAsStringAsync();
JObject jo = (JObject)JsonConvert.DeserializeObject(content);
var status = jo["code"].ToString();
if (status == "1")
{
return new ApiResult(ResultCode.C_SUCCESS);
}
else
{
LogHelper.Error(title, content);
return new ApiResult(ResultCode.C_INVALID_ERROR, "开户失败");
}
}
catch (Exception ex)
{
LogHelper.Error(title, ex.GetInfo());
return new ApiResult(ResultCode.C_INVALID_ERROR, "开户失败");
}
}
/// <summary>
/// 新开测试账号
/// </summary>
/// <param name="account"></param>
/// <param name="pwd"></param>
/// <returns></returns>
public async Task<ApiResult> NewTestAccount(string account, string pwd)
{
var client = CreateHttpClient();
var map = new Dictionary<string, string>(){
{"user",account},
{"pass",pwd },
{"type","newuser" },
{"logincount","1"},
{"serverid","test_pay" },
{"username",this.Product.Account },
{"otherserver","no" },
};
var title = GetOpTitle("NewTestAccount", account);
LogHelper.Info(title, map.ToJson());
try
{
var resp = await client.PostAsForm("userRegisterAdd/" , map);
var content = await resp.Content.ReadAsStringAsync();
JObject jo = (JObject)JsonConvert.DeserializeObject(content);
var status = jo["code"].ToString();
if (status == "1")
{
return new ApiResult(ResultCode.C_SUCCESS);
}
else
{
LogHelper.Error(title, content);
return new ApiResult(ResultCode.C_INVALID_ERROR, "开户失败");
}
}
catch (Exception ex)
{
LogHelper.Error(title, ex.Message);
return new ApiResult(ResultCode.C_INVALID_ERROR, "开户失败");
}
}
/// <summary>
/// 新开
/// </summary>
/// <param name="packageId"></param>
/// <param name="account"></param>
/// <param name="pwd"></param>
/// <returns></returns>
public override async Task<ApiResult> NewMuiltAccount(string packageKey, string account, string pwd, int connCount = 1, int accountType = 1,int startNum=0, int endNum=1 )
{
var client = CreateHttpClient();
var map = new Dictionary<string, string>(){
{"taocanName",packageKey },
{"usernameTpl",account },
{"password",pwd },
{"maxonline",connCount.ToString()},
{"startNum",startNum.ToString()},
{"endNum",endNum.ToString()},
{"mode",accountType.ToString()},
};
var title = GetOpTitle("NewMuiltAccount", account);
LogHelper.Info(title, map.ToJson());
try
{
var resp = await client.PostAsForm(this.MuiltAddUrl, map);
var content = await resp.Content.ReadAsStringAsync();
if (content.Has() && content.IndexOf("<td>成功</td>") != -1)
{
return new ApiResult(1);
}
else
{
LogHelper.Error(title, content);
return new ApiResult(ResultCode.C_INVALID_ERROR, "开户失败");
}
}
catch (Exception ex)
{
LogHelper.Error(title, ex.Message);
return new ApiResult(ResultCode.C_INVALID_ERROR, "开户失败");
}
}
/// <summary>
/// 续费
/// </summary>
/// <param name="productId"></param>
/// <param name="account"></param>
/// <param name="pwd"></param>
/// <returns></returns>
public override async Task<ApiResult> NewReAccount(string packageKey, string account, int connCount)
{
var ret = await this.GetAccountInfo(account);
if (ret.Code != ResultCode.C_SUCCESS|| ret.Data==null)
{
return new ApiResult(ResultCode.C_INVALID_ERROR, "账户不存在,续费失败");
}
var client = CreateHttpClient();
var map = new Dictionary<string, string>(){
{"user",account },
{"serverid",packageKey },
{"type","buy" },
};
var title = GetOpTitle("NewReAccount", account);
LogHelper.Info(title, map.ToJson());
try
{
var resp = await client.GetAsync(this.UserApiUrl + "?" + this.FormatRequest(map));
var content = await resp.Content.ReadAsStringAsync();
JObject jo = (JObject)JsonConvert.DeserializeObject(content);
var status = jo["code"].ToString();
if (status == "1")
{
return new ApiResult(ResultCode.C_SUCCESS);
}
else
{
LogHelper.Error(title, content);
return new ApiResult(ResultCode.C_INVALID_ERROR, "续费失败");
}
}
catch (Exception ex)
{
LogHelper.Error(title, ex.Message);
return new ApiResult(ResultCode.C_INVALID_ERROR, "续费失败");
}
}
/// <summary>
/// 删除账号
/// </summary>
/// <param name="productId"></param>
/// <param name="account"></param>
/// <returns></returns>
public override async Task<bool> DeleteAccount(string account)
{
return false;
}
/// <summary>
/// 得到账号信息
/// </summary>
/// <param name="productId"></param>
/// <param name="account"></param>
/// <returns></returns>
public override async Task<ApiResult<OriginAccountModel>> GetAccountInfo(string account, bool isTest = false)
{
var client = CreateHttpClient();
var map = new Dictionary<string, string>(){
{"user",account },
{"type","getuserinfo" },
};
var title = GetOpTitle("GetAccountInfo", account);
try
{
var searchUser = $"userList/?sum=100&page=1&search_data={account}";
var resp = await client.GetAsync(searchUser);
var content = await resp.Content.ReadAsStringAsync();
var parser = new HtmlParser();
var document = await parser.ParseDocumentAsync(content);
////table class="table table-bordered"
var trs = document.QuerySelectorAll("#datatable tr").ToList();
// var trs= table.QuerySelectorAll("tr").ToList();
var retData = new List<OriginAccountModel>();
var info = "";
if (trs.Count() > 1)
{
//var tr = trs.Skip(1).FirstOrDefault();
foreach (var tr in trs.Skip(1))
{
var tds = tr.QuerySelectorAll("td").ToList();
var tdAccount = tds[1].TextContent;
if (tdAccount != account)
continue;
info = string.Join("", tds.Select(m => m.OuterHtml));
var trData = new OriginAccountModel
{
Account = account,
Pwd = tds[2].TextContent,
AccountType = tds[3].TextContent,
Package = tds[3].TextContent,
RegistTime = tds[5].TextContent,
EndTime = tds[6].TextContent,
ConnectCount = tds[4].TextContent,
IsActive = tds[7].TextContent,
Remark = tds[8].TextContent,
};
trData.RealEndTime = DateTime.Parse(trData.EndTime);
if (trData.RealEndTime < DateTime.Now)
{
trData.RestTime = "已过期";
}
else
{
trData.RestTime = (trData.RealEndTime - DateTime.Now).ToString(@"dd\.hh\:mm\:ss");
}
var button = tr.LastElementChild.QuerySelector("button")?.Attributes["onclick"]?.Value;
if (button.Has())
{
var start = button.IndexOf('(');
var end = button.IndexOf(")");
if (start != -1 && end != -1)
{
trData.Id = button.Substring(start + 1, end - start);
}
}
return new ApiResult<OriginAccountModel>(trData);
}
}
}
catch (Exception ex)
{
LogHelper.Error(title, ex.Message);
}
return new ApiResult<OriginAccountModel>(ResultCode.C_INVALID_ERROR, "没有查询到信息");
}
/// <summary>
/// 修改账号密码
/// </summary>
/// <param name="productId"></param>
/// <param name="account"></param>
/// <param name="pwd"></param>
/// <returns></returns>
public override async Task<bool> UpdateAccountPwd(string account, string pwd)
{
var client = CreateHttpClient();
var map = new Dictionary<string, string>(){
{"user",account },
{"new_pwd",pwd },
{"type","setuser" },
};
var title = GetOpTitle("UpdateAccountPwd", account);
LogHelper.Info(title, map.ToJson());
try
{
var resp = await client.GetAsync(this.UserApiUrl + "?" + this.FormatRequest(map));
var content = await resp.Content.ReadAsStringAsync();
JObject jo = (JObject)JsonConvert.DeserializeObject(content);
var status = jo["code"].ToString();
if (status == "1")
{
return true;
}
else
{
LogHelper.Error(title, content);
return false;
}
}
catch (Exception ex)
{
LogHelper.Error(GetOpTitle("UpdateAccountPwd", account), ex);
}
return false;
}
/// <summary>
/// 退款
/// </summary>
/// <param name="packageId"></param>
/// <param name="account"></param>
/// <returns></returns>
public override async Task<ApiResult> Refund(string account, string packageKey, int days)
{
var title = GetOpTitle("Refund", account);
LogHelper.Info(title, account);
return new ApiResult(ResultCode.C_INVALID_ERROR, "退款失败-不支持退款");
}
/// <summary>
/// 是否在线
/// </summary>
/// <param name="productId"></param>
/// <param name="account"></param>
/// <returns></returns>
public override async Task<ApiResult<List<OriginAccountOnlineModel>>> OnLine(string account)
{
var client = CreateHttpClient();
var title = GetOpTitle("OnLine", account);
var info = "";
try
{
var url = this.OnlineUrl + account;
var resp = await client.GetAsync(url);
var content = await resp.Content.ReadAsStringAsync();
var parser = new HtmlParser();
var document = await parser.ParseDocumentAsync(content);
var trs = document.QuerySelectorAll("table.table tr").ToList();
var retData = new List<OriginAccountOnlineModel>();
if (trs.Count() > 1)
{
foreach (var tr in trs.Skip(1))
{
var tds = tr.QuerySelectorAll("td").ToList();
var tdAccount = tds[1].FirstChild.TextContent;
if (tdAccount != account)
continue;
info = string.Join("", tds.Select(m => m.OuterHtml));
//序号 会员账号 服务器IP 登录时间 在线时长 会员IP 上行流量 下行流量 操作
var trData = new OriginAccountOnlineModel
{
Account = account,
ServerIP = tds[6].TextContent,
LoginTime = tds[1].TextContent,
OnlineTime = tds[3].TextContent,
LoginIP = tds[5].TextContent,
UpStream = tds[4].TextContent,
DownStream = tds[4].TextContent,
Id= account,
};
var href = tr.LastElementChild.QuerySelector("a")?.Attributes["href"]?.Value;
if (href.Has())
{
var start = href.LastIndexOf('/');
var end = href.IndexOf(".html");
if (start != -1 && end != -1)
{
trData.Id = href.Substring(start + 1, end - start).TrimEnd('.');
}
}
retData.Add(trData);
}
}
return new ApiResult<List<OriginAccountOnlineModel>>(retData);
}
catch (Exception ex)
{
LogHelper.Error(title, ex.Message + "-->info:" + info);
return new ApiResult<List<OriginAccountOnlineModel>>(ResultCode.C_INVALID_ERROR, "查询失败");
}
}
/// <summary>
/// 踢号
/// </summary>
/// <param name="productId"></param>
/// <param name="account"></param>
/// <returns></returns>
public override async Task<bool> KillOut( string id)
{
var client = CreateHttpClient();
var title = GetOpTitle("KillOut", id);
var info = "";
try
{
var url = string.Format(this.KIllUrl, id);
var resp = await client.GetAsync(url);
var content = await resp.Content.ReadAsStringAsync();
if(content.Has()&&content.IndexOf("断开成功")!=-1)
{
return true;
}
}
catch (Exception ex)
{
LogHelper.Error(title, ex.Message + "-->info:" + info);
}
return false;
}
/// <summary>
/// 是否存在
/// </summary>
/// <param name="account"></param>
/// <returns></returns>
public override async Task<bool> Exist(string account)
{
var client = CreateHttpClient();
var title = GetOpTitle("Exist", account);
LogHelper.Info(title, account);
string url = $"userapi3/?secretId={secretId}&secretKey={secretKey}&type=getuserlenNum&user={account}";
var resp = await client.GetAsync(url);
var content = await resp.Content.ReadAsStringAsync();
JObject jo = (JObject)JsonConvert.DeserializeObject(content);
var status = jo["code"].ToString();
if (status == "1")
{
var count = jo["count"].ToInt();
return count > 0;
}
else
{
return false;
}
}
}
}

View File

@@ -0,0 +1,532 @@
using AngleSharp;
using AngleSharp.Dom;
using AngleSharp.Html.Parser;
using Hncore.Infrastructure.Common;
using Hncore.Infrastructure.Extension;
using Hncore.Infrastructure.Serializer;
using Hncore.Infrastructure.WebApi;
using Hncore.Pass.Vpn.Model;
using Hncore.Pass.Vpn.Request.Product;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Security.Cryptography;
using System.Threading.Tasks;
namespace Hncore.Pass.Vpn.Service
{
public class AgentClient7Service : AgentClientBaseService
{
string apiId = "131";
string apiKey = "icJZ5ty7csDcmN4aZk25YCd5K5SCiRbf";
string LoginIndexUrl { get; set; } = "login";
string LoginUrl { get; set; } = "login";
string LoginCodeUrl { get; set; } = "";
string RefrushTokenUrl { get; set; } = "my";
string SingleAddUrl { get; set; } = "api/add";
string SingleReAddUrl { get; set; } = "api/renewal";
string MuiltAddUrl { get; set; } = "agent/memberMuiltAdd.html";
string RefundUrl { get; set; } = "agent/memberRefundAct.html ";
string UpdateUrl = "api/edit";
string OnlineLoginUrl { get; set; } = "online";
string OnlineUrl { get; set; } = "ppp/oln?";
string KIllUrl { get; set; } = "agent/disConnect2/radacctid/{0}.html";
string searchAccountUrl = "api/get";
string DeleteUrl { get; set; } = "api/del";//1160862.html";
string ExistUrl = "api/verify";
IHttpClientFactory m_HttpClientFactory;
public AgentClient7Service(IHttpClientFactory httpClientFactory) : base(httpClientFactory)
{
m_HttpClientFactory = httpClientFactory;
}
protected override HttpClient CreateHttpClient(bool autoCooke = true)
{
var client = m_HttpClientFactory.CreateClient("agentClient1.0");
client.BaseAddress = new System.Uri(this.BaseUrl);
if (this.Token.Has() && autoCooke)
{
AddCookie(client, this.Token);
}
return client;
}
public override async Task<int> RefrushStatus()
{
int status = 0;
if (this.Token.Has())
{
var client = CreateHttpClient();
if (this.RefrushTokenUrl.Has())
{
// client.DefaultRequestHeaders.Add("Cookie", this.Token);
var getResp = await client.GetAsync(this.RefrushTokenUrl);
if (getResp.StatusCode == HttpStatusCode.OK)
{
status = 1;
}
else
{
var request = new AgentLoginRequest()
{
Account = this.Product.Account,
Pwd = this.Product.Pwd
};
var ret = await this.Login(request);
if (ret.Code == ResultCode.C_SUCCESS)
{
this.Product.Token = ret.Data.ToString();
status = 1;
}
else
{
Debug.WriteLine("离线");
}
}
}
}
return status;
}
private async Task<(string, string)> GetHomeCookie()
{
var client = CreateHttpClient(false);
client.BaseAddress = new Url("http://dl.91ip.vip/");
var getResp = await client.GetAsync(this.LoginIndexUrl);
var cookies = this.GetCookies(getResp);
cookies = cookies.Replace("path=/;", "").Replace("httponly", "").Trim();
var content = await getResp.Content.ReadAsStringAsync();
var parser = new HtmlParser();
var document = await parser.ParseDocumentAsync(content);
var csrf_tokenNode = document.QuerySelector("meta[name=csrf-token]");//<meta name="csrf-token" content="WfjPwY-RY_A_3d09abknzQm-eRDaVnDeMNRxN-juDDEYzomD3cshgk-zk3M94FC9P8Yte6AjCvMCmz4BmYZvSw==">
var csrf_token = csrf_tokenNode.GetAttribute("content");
return (cookies, csrf_token);
}
public override async Task<ApiResult> Login(AgentLoginRequest request)
{
var tokens = await this.GetHomeCookie();
var client = CreateHttpClient(false);
client.BaseAddress = new Url("http://dl.91ip.vip/");
client.DefaultRequestHeaders.Add("Connection", "keep-alive");
client.DefaultRequestHeaders.Add("Upgrade-Insecure-Requests", "1");
var map = new Dictionary<string, string>(){
{"_csrf-daili",tokens.Item2},
{"LoginForm[username]",request.Account },
{"LoginForm[password]",request.Pwd },
};
LogHelper.Info("Login", map.ToJson());
var csrf = GetCookieValue(tokens.Item1, "_csrf-daili");
AddCookie(client, $"_csrf-daili={csrf}");
var resp = await client.PostAsForm(this.LoginUrl, map);
var content = await resp.Content.ReadAsStringAsync();
if (resp.StatusCode != HttpStatusCode.OK || content.IndexOf("成功") == -1)
{
return new ApiResult(ResultCode.C_VISITOR_CHECKING, "登录失败");
}
var frontend = this.GetCookie(resp, "advanced-frontend");
csrf = this.GetCookie(resp, "_csrf-daili");
request.Key = $"{frontend};{csrf}";
return new ApiResult(request.Key);
}
public override bool CheckAccount(int productId,List<string> accounts)
{
return false;
}
private string Sign(SortedDictionary<string, string> map)
{
map["apiid"] = this.apiId;
map["sendtime"] = DateTime.Now.GetUnixTimeStamp().ToString();
var data = string.Join("&", map.Select(m => $"{m.Key}={m.Value}"));
var signStr = Md5(data + apiKey);
data = $"{data}&sign={signStr}";
return data;
}
//Md5摘要
private static string Md5(string text)
{
MD5 md5 = new MD5CryptoServiceProvider();
byte[] fromData = System.Text.Encoding.UTF8.GetBytes(text);
byte[] targetData = md5.ComputeHash(fromData);
string byte2String = null;
for (int i = 0; i < targetData.Length; i++)
{
byte2String += targetData[i].ToString("x2");
}
return byte2String;
}
/// <summary>
/// 新开
/// </summary>
/// <param name="packageId"></param>
/// <param name="account"></param>
/// <param name="pwd"></param>
/// <returns></returns>
public override async Task<ApiResult> NewAccount(string packageKey, string account, string pwd, int connCount = 1, int accountType = 1, int payCount = 1)
{
var client = CreateHttpClient();
var map = new SortedDictionary<string, string>(){
{"user",account },
{"passwd",pwd },
{"num","1"},
{"conn_max",connCount.ToString() },
{"test",packageKey=="test"?"1":"0" },
{"type",packageKey=="test"?"d":packageKey },
{"paynum","1" },
};
var title = GetOpTitle("NewAccount", account);
LogHelper.Info(title, map.ToJson());
try
{
var resp = await client.GetAsync(this.SingleAddUrl+"?"+ Sign(map));
var content = await resp.Content.ReadAsStringAsync();
JObject jo = (JObject)JsonConvert.DeserializeObject(content);
var status = jo["status"].ToString();
if (status =="200")
{
var retAccount=jo["data"].ToArray().FirstOrDefault();
var id = retAccount["id"].ToString();
return new ApiResult(ResultCode.C_SUCCESS) { Data=id};
}
else
{
var info = jo["info"].ToString();
LogHelper.Error(title, content);
return new ApiResult(ResultCode.C_INVALID_ERROR, info);
}
}
catch (Exception ex)
{
LogHelper.Error(title, ex.Message);
return new ApiResult(ResultCode.C_INVALID_ERROR, "开户失败");
}
}
/// <summary>
/// 续费
/// </summary>
/// <param name="productId"></param>
/// <param name="account">原始的账号的id</param>
/// <param name="pwd"></param>
/// <returns></returns>
public override async Task<ApiResult> NewReAccount(string packageKey, string id, int connCount)
{
var ret = await this.GetAccountInfo(id);
if (ret.Code != ResultCode.C_SUCCESS|| ret.Data==null)
{
return new ApiResult(ResultCode.C_INVALID_ERROR, "账户不存在,续费失败");
}
var client = CreateHttpClient();
var map = new SortedDictionary<string, string>(){
{"id",id }, //原始的账号的id
{"type",packageKey },
{"paynum","1" },
};
var title = GetOpTitle("NewReAccount", id);
LogHelper.Info(title, map.ToJson());
try
{
var resp = await client.GetAsync(this.SingleReAddUrl + "?" + Sign(map));
var content = await resp.Content.ReadAsStringAsync();
JObject jo = (JObject)JsonConvert.DeserializeObject(content);
var status = jo["status"].ToString();
if (status =="200")
{
return new ApiResult(ResultCode.C_SUCCESS);
}
else
{
var info = jo["info"].ToString();
LogHelper.Error(title, content);
return new ApiResult(ResultCode.C_INVALID_ERROR, info);
}
}
catch (Exception ex)
{
LogHelper.Error(title, ex.Message);
return new ApiResult(ResultCode.C_INVALID_ERROR, "续费失败");
}
}
/// <summary>
/// 删除账号
/// </summary>
/// <param name="productId"></param>
/// <param name="account"></param>
/// <returns></returns>
public override async Task<bool> DeleteAccount(string id)
{
var client = CreateHttpClient();
var map = new SortedDictionary<string, string>(){
{"id",id },
};
var title = GetOpTitle("DeleteAccount", id);
LogHelper.Info(title, id);
try
{
var resp = await client.GetAsync(this.DeleteUrl + "?" + Sign(map));
var content = await resp.Content.ReadAsStringAsync();
JObject jo = (JObject)JsonConvert.DeserializeObject(content);
var status = jo["status"].ToString();
if (status=="200")
{
return true;
}
else
{
LogHelper.Error(title, content);
return false;
}
}
catch (Exception ex)
{
LogHelper.Error(title, ex.Message);
return false;
}
}
/// <summary>
/// 得到账号信息
/// </summary>
/// <param name="productId"></param>
/// <param name="account"></param>
/// <returns></returns>
public override async Task<ApiResult<OriginAccountModel>> GetAccountInfo(string id, bool isTest=false)
{
var client = CreateHttpClient();
var map = new SortedDictionary<string, string>(){
{"id",id },
};
var title = GetOpTitle("GetAccountInfo", id);
try
{
var resp = await client.GetAsync(this.searchAccountUrl + "?" + Sign(map));
var content = await resp.Content.ReadAsStringAsync();
JObject jo = (JObject)JsonConvert.DeserializeObject(content);
var status = jo["status"].ToString();
if (status == "200")
{
var data = jo["data"];
var trData = new OriginAccountModel
{
Id = data["id"].ToString(),
Account = data["user"].ToString(),
Pwd = data["passwd"].ToString(),
AccountType = data["type"].ToString(),
Package = "",
ConnectCount = data["conn_max"].ToString(),
RegistTime = data["add_time"].ToString(),
EndTime = data["end_time"].ToString(),
RestTime = "",
Amount = data["money"].ToString(),
Remark = data["details"].ToString(),
};
return new ApiResult<OriginAccountModel>(trData);
}
else
{
var info = jo["info"].ToString();
LogHelper.Error(title, content);
return new ApiResult<OriginAccountModel>(ResultCode.C_INVALID_ERROR, "没有查询到信息");
}
}
catch (Exception ex)
{
LogHelper.Error(title, ex.Message);
return new ApiResult<OriginAccountModel>(ResultCode.C_INVALID_ERROR, "查询失败");
}
}
/// <summary>
/// 修改账号密码
/// </summary>
/// <param name="productId"></param>
/// <param name="account"></param>
/// <param name="pwd"></param>
/// <returns></returns>
public override async Task<bool> UpdateAccountPwd(string account, string pwd)
{
var client = CreateHttpClient();
var map = new SortedDictionary<string, string>(){
{"id",Raw },
{"user",account },
{"passwd",pwd },
};
LogHelper.Info(GetOpTitle("UpdateAccountPwd", account), map.ToJson());
try
{
var resp = await client.GetAsync(this.UpdateUrl + "?" + Sign(map));
var content = await resp.Content.ReadAsStringAsync();
JObject jo = (JObject)JsonConvert.DeserializeObject(content);
var status = jo["status"].ToString();
if (status == "200")
{
return true;
}
else
{
LogHelper.Error(GetOpTitle("UpdateAccountPwd", account), content);
}
}
catch (Exception ex)
{
LogHelper.Error(GetOpTitle("UpdateAccountPwd", account), ex);
}
return false;
}
/// <summary>
/// 退款
/// </summary>
/// <param name="packageId"></param>
/// <param name="account"></param>
/// <returns></returns>
public override async Task<ApiResult> Refund(string id, string packageKey, int days)
{
var ret = await this.DeleteAccount(id);
if (ret)
{
return new ApiResult(ResultCode.C_SUCCESS);
}
else
{
return new ApiResult(ResultCode.C_INVALID_ERROR, "退款失败");
}
}
/// <summary>
/// 是否在线
/// </summary>
/// <param name="productId"></param>
/// <param name="account"></param>
/// <returns></returns>
public override async Task<ApiResult<List<OriginAccountOnlineModel>>> OnLine(string account)
{
var client = CreateHttpClient(false);
client.BaseAddress = new Url("http://dl.91ip.vip/");
var title = GetOpTitle("OnLine", account);
var info = "";
try
{
var resp = await client.GetAsync(this.OnlineUrl+ "user="+account);
var content = await resp.Content.ReadAsStringAsync();
var parser = new HtmlParser();
var document = await parser.ParseDocumentAsync(content);
var trs = document.QuerySelectorAll("table.table tr").ToList();
var retData = new List<OriginAccountOnlineModel>();
if (trs.Count() > 1)
{
foreach (var tr in trs.Skip(1))
{
var tds = tr.QuerySelectorAll("td").ToList();
var tdAccount = tds[1].FirstChild.TextContent;
if (tdAccount != account)
continue;
info = string.Join("", tds.Select(m => m.OuterHtml));
var trData = new OriginAccountOnlineModel
{
Account = account,
ServerIP = tds[1].TextContent,
OnlineTime = tds[2].TextContent,
Id= account,
};
var href = tr.LastElementChild.QuerySelector("a")?.Attributes["href"]?.Value;
if (href.Has())
{
var start = href.LastIndexOf('/');
var end = href.IndexOf(".html");
if (start != -1 && end != -1)
{
trData.Id = href.Substring(start + 1, end - start).TrimEnd('.');
}
}
retData.Add(trData);
}
}
return new ApiResult<List<OriginAccountOnlineModel>>(retData);
}
catch (Exception ex)
{
LogHelper.Error(title, ex.Message + "-->info:" + info);
return new ApiResult<List<OriginAccountOnlineModel>>(ResultCode.C_INVALID_ERROR, "查询失败");
}
}
/// <summary>
/// 踢号
/// </summary>
/// <param name="productId"></param>
/// <param name="account"></param>
/// <returns></returns>
public override async Task<bool> KillOut( string id)
{
var client = CreateHttpClient();
var title = GetOpTitle("KillOut", id);
var info = "";
try
{
var url = string.Format(this.KIllUrl, id);
var resp = await client.GetAsync(url);
var content = await resp.Content.ReadAsStringAsync();
if(content.Has()&&content.IndexOf("断开成功")!=-1)
{
return true;
}
}
catch (Exception ex)
{
LogHelper.Error(title, ex.Message + "-->info:" + info);
}
return false;
}
/// <summary>
/// 是否存在
/// </summary>
/// <param name="account"></param>
/// <returns></returns>
public override async Task<bool> Exist(string account)
{
var client = CreateHttpClient();
var map = new SortedDictionary<string, string>(){
{"user",account }
};
var title = GetOpTitle("Exist", account);
LogHelper.Info(title, account);
try
{
var resp = await client.GetAsync(this.ExistUrl + "?" + Sign(map));
var content = await resp.Content.ReadAsStringAsync();
JObject jo = (JObject)JsonConvert.DeserializeObject(content);
var status = jo["status"].ToString();
if (status != "200")
{
return true;
}
else
{
return false;
}
}
catch (Exception ex)
{
LogHelper.Error(title, ex);
}
return false;
}
}
}

View File

@@ -0,0 +1,223 @@
using Hncore.Infrastructure.Service;
using Hncore.Pass.Vpn.Domain;
using Hncore.Pass.Vpn.Request.Product;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
using Hncore.Infrastructure.Extension;
using Hncore.Infrastructure.WebApi;
using System.Diagnostics;
using System.IO;
using System.Net;
using Microsoft.EntityFrameworkCore;
using Hncore.Pass.Vpn.Model;
namespace Hncore.Pass.Vpn.Service
{
public abstract class AgentClientBaseService
{
protected string BaseUrl { get; set; }
protected string Token { get; set; }
string LoginUrl { get; set; }
string LoginCodeUrl { get; set; }
string RefrushTokenUrl { get; set; }
string SingleAddUrl { get; set; }
string SingleReAddUrl { get; set; }
string MuiltAddUrl { get; set; }
string RefundUrl { get; set; }
string OnlineUrl { get; set; }
string KIllUrl { get; set; }
string UpdateUrl { get; set; }
public string ClientName { get; set; }
public string Raw { get; set; }
IHttpClientFactory m_HttpClientFactory;
public AgentClientBaseService(IHttpClientFactory httpClientFactory)
{
m_HttpClientFactory = httpClientFactory;
}
public ProductEntity Product { get; set; }
public void Init(string BaseUrl,string Token)
{
this.BaseUrl = BaseUrl;
this.Token = Token;
}
public virtual string GetOpTitle(string op,string account)
{
return $"{this.ClientName}_{op}_{account}";
}
protected virtual HttpClient CreateHttpClient(bool autoCooke = true)
{
var client = m_HttpClientFactory.CreateClient("agentClient");
client.BaseAddress = new System.Uri(this.BaseUrl);
if (this.Token.Has()&& autoCooke)
{
AddCookie(client, this.Token);
}
return client;
}
protected virtual void AddCookie(HttpClient client, string cookie)
{
client.DefaultRequestHeaders.Remove("Cookie");
client.DefaultRequestHeaders.Add("Cookie", cookie);
}
public string GetCookie(HttpResponseMessage resp, string name)
{
if (resp.Headers.TryGetValues("Set-Cookie", out IEnumerable<string> cookies))
{
foreach (var cookie in cookies)
{
var ret = cookie.Split(";").FirstOrDefault(m => m.IndexOf(name) != -1);
if (ret.Has())
return ret;
}
}
return "";
}
public string GetCookies(HttpResponseMessage resp)
{
if (resp.Headers.TryGetValues("Set-Cookie", out IEnumerable<string> cookies))
{
return string.Join(";", cookies);
}
return "";
}
protected string GetCookieValue(string cookies, string name)
{
foreach (var item in cookies.Split(";"))
{
var token = item.Split("=");
if (token.Length == 2 && token[0] == name)
{
return token[1];
}
}
return "";
}
public virtual async Task<int> RefrushStatus()
{
return 0;
}
public virtual async Task<(byte[], string)> GetCode()
{
return (null, "");
}
public virtual async Task<ApiResult> Login(AgentLoginRequest request)
{
return new ApiResult();
}
public virtual bool CheckAccount(int productId,List<string> accounts)
{
return false;
}
/// <summary>
/// 新开
/// </summary>
/// <param name="packageId"></param>
/// <param name="account"></param>
/// <param name="pwd"></param>
/// <returns></returns>
public virtual async Task<ApiResult> NewAccount(string packageKey, string account,string pwd,int connCount=1,int accountType=1, int payCount = 1)
{
return new ApiResult();
}
public virtual async Task<ApiResult> NewMuiltAccount(string packageKey, string account, string pwd, int connCount = 1, int accountType = 1, int startNum = 0, int endNum = 1)
{
return new ApiResult();
}
/// <summary>
/// 续费
/// </summary>
/// <param name="productId"></param>
/// <param name="account"></param>
/// <param name="pwd"></param>
/// <returns></returns>
public virtual async Task<ApiResult> NewReAccount(string packageKey,string account,int connCount)
{
return new ApiResult();
}
/// <summary>
/// 删除账号
/// </summary>
/// <param name="productId"></param>
/// <param name="account"></param>
/// <returns></returns>
public virtual async Task<bool> DeleteAccount(string account)
{
return true;
}
/// <summary>
/// 得到账号信息
/// </summary>
/// <param name="productId"></param>
/// <param name="account"></param>
/// <returns></returns>
public virtual async Task<ApiResult<OriginAccountModel>> GetAccountInfo(string account, bool isTest = false)
{
return new ApiResult<OriginAccountModel>();
}
/// <summary>
/// 修改账号密码
/// </summary>
/// <param name="productId"></param>
/// <param name="account"></param>
/// <param name="pwd"></param>
/// <returns></returns>
public virtual async Task<bool> UpdateAccountPwd(string account,string pwd)
{
return true;
}
/// <summary>
/// 退款
/// </summary>
/// <param name="packageId"></param>
/// <param name="account"></param>
/// <returns></returns>
public virtual async Task<ApiResult> Refund(string account, string packageKey, int days)
{
return new ApiResult();
}
/// <summary>
/// 是否在线
/// </summary>
/// <param name="productId"></param>
/// <param name="account"></param>
/// <returns></returns>
public virtual async Task<ApiResult<List<OriginAccountOnlineModel>>> OnLine(string account)
{
return new ApiResult<List<OriginAccountOnlineModel>>();
}
/// <summary>
/// 踢号
/// </summary>
/// <param name="productId"></param>
/// <param name="account"></param>
/// <returns></returns>
public virtual async Task<bool> KillOut(string account)
{
return true;
}
/// <summary>
/// 是否存在
/// </summary>
/// <param name="account"></param>
/// <returns></returns>
public virtual async Task<bool> Exist(string account)
{
return true;
}
}
}

View File

@@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
namespace Hncore.Pass.Vpn.Service
{
public class AgentClientLogHandler : DelegatingHandler
{
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
if (request.Headers.Contains("hl"))
{
Console.WriteLine(request.RequestUri.ToString());
}
return base.SendAsync(request, cancellationToken);
}
}
}

View File

@@ -0,0 +1,419 @@
using Hncore.Infrastructure.Common;
using Hncore.Infrastructure.Extension;
using Hncore.Infrastructure.Service;
using Hncore.Infrastructure.WebApi;
using Hncore.Pass.Vpn.Domain;
using Hncore.Pass.Vpn.Model;
using Hncore.Pass.Vpn.Request.Product;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
namespace Hncore.Pass.Vpn.Service
{
public class AgentService:IFindService
{
CourseContext m_DbContext;
IHttpClientFactory m_HttpClientFactory;
protected ProductService m_ProductService;
protected ProductPackageService m_ProductPackageService;
protected ProductPackageUnitService m_ProductPackageUnitService;
protected ProductEntity m_Product;
protected ProductAccountChargeService m_AccountChargeService;
protected Dictionary<string,AgentClientBaseService> m_MapAgentClient=new Dictionary<string, AgentClientBaseService>();
public AgentService(ProductService _ProductService
, ProductPackageService _ProductPackageService
, ProductPackageUnitService _ProductPackageUnitService
, ProductAccountChargeService _AccountChargeService
, IHttpClientFactory httpClientFactory
, CourseContext _DbContext)
{
m_HttpClientFactory = httpClientFactory;
m_ProductService = _ProductService;
m_ProductPackageService = _ProductPackageService;
m_ProductPackageUnitService = _ProductPackageUnitService;
m_AccountChargeService = _AccountChargeService;
m_DbContext = _DbContext;
}
protected AgentClientBaseService _AgentClient;
private AgentClientBaseService GetAgent(ProductEntity product)
{
AgentClientBaseService agent=null;
if (product.GroupNO == "g1")
agent = new AgentClient1Service(m_HttpClientFactory) { ClientName=product.GroupNO};
if (product.GroupNO == "g2")
agent = new AgentClient2Service(m_HttpClientFactory) { ClientName = product.GroupNO };
if (product.GroupNO == "g3")
agent = new AgentClient3Service(m_HttpClientFactory) { ClientName = product.GroupNO };
if (product.GroupNO == "g4")
agent = new AgentClient4Service(m_HttpClientFactory) { ClientName = product.GroupNO };
if (product.GroupNO == "g5")
agent = new AgentClient5Service(m_HttpClientFactory) { ClientName = product.GroupNO };
if (product.GroupNO == "g6")
agent = new AgentClient6Service(m_HttpClientFactory) { ClientName = product.GroupNO };
if (product.GroupNO == "g7")
agent = new AgentClient7Service(m_HttpClientFactory) { ClientName = product.GroupNO };
agent.Product = product;
return agent;
}
public async Task RefrushAllStatus()
{
var products = await m_ProductService.Query(false).ToListAsync();
await products.ForEachAsync(async m =>
{
// if (m.GroupNO == "g6")
await RefrushStatus(m);
});
}
public virtual async Task RefrushStatus(ProductEntity product)
{
var agent = GetAgent(product);
agent.Init(product.BaseUrl, product.Token);
int status = await agent.RefrushStatus();
if (product.Status != status)
{
product.UpdateTime = DateTime.Now;
product.Status = status;
await m_ProductService.Update(product);
}
if (product.Status == 0)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine($"{product.Name}:离线");
Console.ResetColor();
}
}
public virtual async Task<(byte[], string)> GetCode(int productId)
{
var product = await m_ProductService.GetById(productId);
var agent = GetAgent(product);
agent.Init(product.BaseUrl, product.Token);
return await agent.GetCode();
}
public virtual async Task<ApiResult> Login(AgentLoginRequest request)
{
var product = await m_ProductService.GetById(request.ProductId);
product.Token = request.Key;
var agent = GetAgent(product);
agent.Init(product.BaseUrl, product.Token);
request.Account = product.Account;
request.Pwd = product.Pwd;
var ret = await agent.Login(request);
if (ret.Code == ResultCode.C_SUCCESS)
{
product.Status = 1;
product.Token = ret.Data.ToString();
await m_ProductService.Update(product);
}
return ret;
}
public virtual async Task<ApiResult<List<OriginAccountModel>>> GetOriginAccounts(List<ProductAccountEntity> accountList)
{
var retList = new List<OriginAccountModel>();
foreach (var item in accountList)
{
var product = await m_ProductService.GetById(item.ProductId);
var agent = GetAgent(product);
agent.Init(product.BaseUrl, product.Token);
var account = item.Account;
if (product.GroupNO == "g7") account = item.Raw;
var ret = await agent.GetAccountInfo(account);
if (ret.Code == ResultCode.C_SUCCESS)
retList.Add(ret.Data as OriginAccountModel);
}
return new ApiResult<List<OriginAccountModel>>(retList);
}
public virtual async Task<ApiResult<OriginAccountModel>> GetOriginAccountInfo(int productId, string account, string pwd = "")
{
var product = await m_ProductService.GetById(productId);
var agent = GetAgent(product);
agent.Init(product.BaseUrl, product.Token);
if (product.GroupNO == "g7")
{
var accountInfo = await GetProductAccount(productId, account);
if (accountInfo != null && accountInfo.Raw.Has())
account = accountInfo.Raw;
}
var ret = await agent.GetAccountInfo(account);
if (ret.Code != ResultCode.C_SUCCESS) return new ApiResult<OriginAccountModel>(ResultCode.C_NOT_EXISTS_ERROR, "账号不存在");
if (pwd.Has()&&ret.Data.Pwd != pwd)
return new ApiResult<OriginAccountModel>(ResultCode.C_NOT_EXISTS_ERROR, "密码不正确");
return ret;
}
public virtual async Task<List<OriginAccountModel>> GetOriginAccountInfo(int productId, List<string> accounts)
{
var list = new List<OriginAccountModel>();
var product = await m_ProductService.GetById(productId);
var agent = GetAgent(product);
agent.Init(product.BaseUrl, product.Token);
foreach (var item in accounts)
{
var account = item;
if (product.GroupNO == "g7")
{
var accountInfo = await GetProductAccount(productId, item);
if (accountInfo != null && accountInfo.Raw.Has())
account = accountInfo.Raw;
}
var ret = await agent.GetAccountInfo(account);
if (ret.Code == ResultCode.C_SUCCESS)
{
list.Add(ret.Data);
}
}
return list;
}
/// <summary>
/// 新开
/// </summary>
/// <param name="packageId"></param>
/// <param name="account"></param>
/// <param name="pwd"></param>
/// <returns></returns>
public virtual async Task<ApiResult> NewAccount(int orderId, int packageId, string account, string pwd, int connCount = 1, int accountType = 1)
{
ApiResult flagResult = new ApiResult(ResultCode.C_SUCCESS);
var package = await m_ProductPackageService.GetById(packageId);
var product = await m_ProductService.GetById(package.ProductId);
var agent = GetAgent(product);
agent.Init(product.BaseUrl, product.Token);
if (package.PackageType == PackageType.Base)
{
var ret = await agent.NewAccount(package.OriginKey, account, pwd, connCount, accountType);
//var ret = new ApiResult(ResultCode.C_INVALID_ERROR);
var status = ret.Code == ResultCode.C_SUCCESS ? ChargeStatus.Ok : ChargeStatus.Faild;
await m_AccountChargeService.RecordNew(package, orderId, product.GroupNO, account, pwd, accountType, connCount, status);
return ret;
}
else
{
var basePackages = await m_ProductPackageService.GetBasePackages(packageId);
var firstPackage = basePackages.FirstOrDefault();
basePackages.Remove(firstPackage);
if (firstPackage.Count > 1)
{
firstPackage.Count--;
basePackages.Insert(0, firstPackage);
}
var ret = await agent.NewAccount(firstPackage.Package.OriginKey, account, pwd, connCount, accountType);
//var ret = new ApiResult(ResultCode.C_INVALID_ERROR);
var status = ret.Code == ResultCode.C_SUCCESS ? ChargeStatus.Ok : ChargeStatus.Faild;
await m_AccountChargeService.RecordNew(firstPackage.Package, orderId, product.GroupNO, account, pwd, accountType, connCount, status);
if (ret.Code != ResultCode.C_SUCCESS)
flagResult = ret;
foreach (var item in basePackages)
{
for (var j = 0; j < item.Count; j++)
{
ret = await agent.NewReAccount(item.Package.OriginKey, account, connCount);
// ret = new ApiResult(ResultCode.C_INVALID_ERROR);
status = ret.Code == ResultCode.C_SUCCESS ? ChargeStatus.Ok : ChargeStatus.Faild;
await m_AccountChargeService.RecordReNew(item.Package, orderId, product.GroupNO, account, connCount, status);
if (ret.Code != ResultCode.C_SUCCESS)
flagResult = ret;
}
}
return flagResult;
}
}
/// <summary>
/// 续费
/// </summary>
/// <param name="productId"></param>
/// <param name="account"></param>
/// <param name="pwd"></param>
/// <returns></returns>
public virtual async Task<ApiResult> ReNewAccount(int orderId, int packageId, string account, int connCount)
{
var package = await m_ProductPackageService.GetById(packageId);
var product = await m_ProductService.GetById(package.ProductId);
if (product.GroupNO == "g7")
{
var accountInfo = await GetProductAccount(package.ProductId, account);
if (accountInfo != null && accountInfo.Raw.Has())
account = accountInfo.Raw;
}
var agent = GetAgent(product);
agent.Init(product.BaseUrl, product.Token);
ApiResult flagResult = new ApiResult(ResultCode.C_SUCCESS);
if (package.PackageType == PackageType.Base)
{
var ret = await agent.NewReAccount(package.OriginKey, account, connCount);
// var ret = new ApiResult(ResultCode.C_INVALID_ERROR);
var status = ret.Code == ResultCode.C_SUCCESS ? ChargeStatus.Ok : ChargeStatus.Faild;
await m_AccountChargeService.RecordReNew(package, orderId, product.GroupNO, account, connCount, status);
return ret;
}
else
{
var basePackages = await m_ProductPackageService.GetBasePackages(packageId);
foreach (var basePackage in basePackages)
{
for (var j = 0; j < basePackage.Count; j++)
{
var ret = await agent.NewReAccount(basePackage.Package.OriginKey, account, connCount);
//var ret = new ApiResult(ResultCode.C_INVALID_ERROR);
var status = ret.Code == ResultCode.C_SUCCESS ? ChargeStatus.Ok : ChargeStatus.Faild;
await m_AccountChargeService.RecordReNew(basePackage.Package, orderId, product.GroupNO, account, connCount, status);
if (status == ChargeStatus.Faild) flagResult = ret;
}
}
return flagResult;
}
}
/// <summary>
/// 删除账号
/// </summary>
/// <param name="productId"></param>
/// <param name="account"></param>
/// <returns></returns>
public virtual bool DeleteAccount(int productId, string account)
{
return true;
}
/// <summary>
/// 修改账号密码
/// </summary>
/// <param name="productId"></param>
/// <param name="account"></param>
/// <param name="pwd"></param>
/// <returns></returns>
public virtual async Task<bool> UpdateAccountPwd(int productId, string account, string pwd)
{
var product = await m_ProductService.GetById(productId);
var agent = GetAgent(product);
agent.Init(product.BaseUrl, product.Token);
if (product.GroupNO == "g7")
{
var accountInfo = await GetProductAccount(productId, account);
if (accountInfo != null && accountInfo.Raw.Has())
agent.Raw = accountInfo.Raw;
}
return await agent.UpdateAccountPwd(account, pwd);
}
/// <summary>
/// 退款
/// </summary>
/// <param name="packageId"></param>
/// <param name="account"></param>
/// <returns></returns>
public virtual async Task<ApiResult> Refund(ProductPackageEntity package, ProductAccountEntity accountInfo)
{
var product = await m_ProductService.GetById(package.ProductId);
var agent = GetAgent(product);
agent.Init(product.BaseUrl, product.Token);
var account = accountInfo.Account;
if (product.GroupNO == "g7")
{
if (accountInfo != null && accountInfo.Raw.Has())
account = accountInfo.Raw;
}
var flag = await agent.Refund(account, package.OriginKey, accountInfo.RestDay);
return flag;
}
/// <summary>
/// 是否在线
/// </summary>
/// <param name="productId"></param>
/// <param name="account"></param>
/// <returns></returns>
public virtual async Task<ApiResult<List<OriginAccountOnlineModel>>> OnLine(int productId, string account)
{
var product = await m_ProductService.GetById(productId);
var agent = GetAgent(product);
agent.Init(product.BaseUrl, product.Token);
return await agent.OnLine(account);
}
/// <summary>
/// 踢号
/// </summary>
/// <param name="productId"></param>
/// <param name="account"></param>
/// <returns></returns>
public virtual async Task<bool> KillOut(int productId, string id)
{
var product = await m_ProductService.GetById(productId);
var agent = GetAgent(product);
agent.Init(product.BaseUrl, product.Token);
return await agent.KillOut(id);
}
/// <summary>
/// 是否存在
/// </summary>
/// <param name="account"></param>
/// <returns></returns>
public async Task<bool> Exist(int productId, string account)
{
if (productId == 5) productId = 12;
var product = await m_ProductService.GetById(productId);
var agent = GetAgent(product);
agent.Init(product.BaseUrl, product.Token);
return await agent.Exist(account);
}
public async Task FaildTry()
{
var records = await m_AccountChargeService.GetFaildRecord();
foreach (var chargeEntity in records)
{
if (chargeEntity.Status != ChargeStatus.Faild)
{
continue;
}
if (chargeEntity.TryTimes > 3)
{
chargeEntity.Status = ChargeStatus.Outtime;
chargeEntity.UpdateTime = DateTime.Now;
await m_AccountChargeService.Update(chargeEntity);
continue;
}
var product = await m_ProductService.GetById(chargeEntity.ProductId);
var agent = GetAgent(product);
agent.Init(product.BaseUrl, product.Token);
if (chargeEntity.OperationType == ChargeOperationType.New)
{
var ret = await agent.NewAccount(chargeEntity.PackageOriginKey, chargeEntity.Account, chargeEntity.Pwd, chargeEntity.ConnectCount, chargeEntity.AccountType);
var status = ret.Code == ResultCode.C_SUCCESS ? ChargeStatus.Ok : ChargeStatus.Faild;
chargeEntity.Status = status;
chargeEntity.TryTimes++;
chargeEntity.UpdateTime = DateTime.Now;
await m_AccountChargeService.Update(chargeEntity);
}else if(chargeEntity.OperationType == ChargeOperationType.ReNew)
{
var ret = await agent.NewReAccount(chargeEntity.PackageOriginKey, chargeEntity.Account, chargeEntity.ConnectCount);
// var ret = new ApiResult(ResultCode.C_INVALID_ERROR);
var status = ret.Code == ResultCode.C_SUCCESS ? ChargeStatus.Ok : ChargeStatus.Faild;
chargeEntity.Status = status;
chargeEntity.TryTimes++;
chargeEntity.UpdateTime = DateTime.Now;
await m_AccountChargeService.Update(chargeEntity);
}
}
}
protected async Task<ProductAccountEntity> GetProductAccount(int productId, string account)
{
return await m_DbContext.Set<ProductAccountEntity>().FirstOrDefaultAsync(m => m.ProductId == productId && m.Account == account);
}
}
}

View File

@@ -0,0 +1,25 @@
using Hncore.Infrastructure.Service;
using Hncore.Pass.Vpn.Domain;
using Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Hncore.Pass.Vpn.Service
{
public partial class ArticleService : ServiceBase<ArticleEntity>, IFindService
{
CourseContext m_DbContext;
public ArticleService(CourseContext dbContext, IHttpContextAccessor httpContextAccessor) : base(dbContext, httpContextAccessor)
{
m_DbContext = dbContext;
}
public async Task<List<ArticleEntity>> GetTop(int top, ArticleCatalog catalog)
{
return await this.Query(m => m.CatalogId == catalog).Take(top).ToListAsync();
}
}
}

View File

@@ -0,0 +1,96 @@
using Hncore.Infrastructure.Service;
using Hncore.Pass.Vpn.Domain;
using Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Hncore.Pass.Vpn.Service
{
public partial class ProductAccountChargeService : ServiceBase<ProductAccountChargeEntity>, IFindService
{
CourseContext m_DbContext;
public ProductAccountChargeService(CourseContext dbContext
, IHttpContextAccessor httpContextAccessor) : base(dbContext, httpContextAccessor)
{
m_DbContext = dbContext;
}
/// <summary>
/// 记录新开操作
/// </summary>
/// <param name="package"></param>
/// <param name="orderId"></param>
/// <param name="gid"></param>
/// <param name="account"></param>
/// <param name="pwd"></param>
/// <param name="accountType"></param>
/// <param name="connCount"></param>
/// <param name="chargeStatus"></param>
/// <returns></returns>
public async Task RecordNew(ProductPackageEntity package, int orderId, string gid, string account, string pwd, int accountType, int connCount, ChargeStatus chargeStatus = ChargeStatus.Ok)
{
var chargeEntity = new ProductAccountChargeEntity()
{
Account = account,
AccountType = accountType,
ConnectCount = connCount,
OperationType = ChargeOperationType.New,
OrderId = orderId,
PackageId = package.Id,
PackageOriginKey = package.OriginKey,
ProductGroup = gid,
ProductId = package.ProductId,
Pwd = pwd,
Status = chargeStatus,
TryTimes = 1,
};
await this.Add(chargeEntity);
}
/// <summary>
/// 记录续费操作
/// </summary>
/// <param name="package"></param>
/// <param name="orderId"></param>
/// <param name="gid"></param>
/// <param name="account"></param>
/// <param name="pwd"></param>
/// <param name="accountType"></param>
/// <param name="connCount"></param>
/// <param name="chargeStatus"></param>
/// <returns></returns>
public async Task RecordReNew(ProductPackageEntity package, int orderId, string gid, string account, int connCount, ChargeStatus chargeStatus = ChargeStatus.Ok)
{
var chargeEntity = new ProductAccountChargeEntity()
{
Account = account,
AccountType =0,
ConnectCount = connCount,
OperationType = ChargeOperationType.ReNew,
OrderId = orderId,
PackageId = package.Id,
PackageOriginKey = package.OriginKey,
ProductGroup = gid,
ProductId = package.ProductId,
Pwd = "",
Status = chargeStatus,
TryTimes = 1,
};
await this.Add(chargeEntity);
}
public async Task<List<ProductAccountChargeEntity>> GetFaildRecord(int maxTryTimes = 3, int maxTop = 100)
{
var query = this.Query(m => m.Status == ChargeStatus.Faild
&& m.TryTimes <= maxTryTimes
&& (DateTime.Now - m.CreateTime).Minutes <= 10);
return await query.OrderBy(m => m.Id)
.Take(maxTop)
.ToListAsync();
}
}
}

View File

@@ -0,0 +1,150 @@
using HHncore.Pass.Vpn.Request.Product;
using Hncore.Infrastructure.Common;
using Hncore.Infrastructure.Extension;
using Hncore.Infrastructure.Service;
using Hncore.Infrastructure.WebApi;
using Hncore.Pass.Vpn.Domain;
using Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;
using Hncore.Infrastructure.EntitiesExtension;
using Hncore.Infrastructure.EF;
namespace Hncore.Pass.Vpn.Service
{
public partial class ProductAccountService : ServiceBase<ProductAccountEntity>, IFindService
{
CourseContext m_DbContext;
private IConfiguration m_Configuration;
public AgentService m_AgentService;
private UserService m_UserService;
public ProductAccountService(CourseContext dbContext
, AgentService _AgentService
, UserService _UserService
, IConfiguration _Configuration
, IHttpContextAccessor httpContextAccessor) : base(dbContext, httpContextAccessor)
{
m_DbContext = dbContext;
m_AgentService = _AgentService;
m_Configuration = _Configuration;
m_UserService = _UserService;
}
public async Task<bool> CheckAccountExist(int productId, List<string> accouts)
{
var flag = this.Exist(m => accouts.Contains(m.Account));
if (flag)
{
return true;
}
foreach (var item in accouts)
{
var ret = await m_AgentService.Exist(productId, item);
await Task.Delay(50);
if (ret == true)
return true;
}
return false;
}
public bool CheckUserAccountExist(int product, List<string> accouts, int userId)
{
return this.Exist(m => accouts.Contains(m.Account) && m.UserId == userId);
}
public async Task<ProductAccountEntity> GetAccountInfo(string accout, int userId)
{
return await this.Query(true).FirstOrDefaultAsync(m => m.Account == accout && m.UserId == userId);
}
public async Task<List<ProductAccountEntity>> GetAccounts(string accouts,int userId=0)
{
var alist = accouts.Split(",");
return await this.Query(m =>(userId==0||m.UserId== userId)&& alist.Contains(m.Account)).ToListAsync();
}
public async Task<ProductAccountEntity> GetAccountInfo(string accout)
{
return await this.Query(true).FirstOrDefaultAsync(m => m.Account == accout);
}
public async Task<ProductAccountEntity> GetAccountInfo(int packageId,string accout)
{
return await this.Query(true).FirstOrDefaultAsync(m =>m.PackageId== packageId&& m.Account == accout);
}
public async Task<ProductAccountEntity> GetProductAccountInfo(int productId, string accout)
{
return await this.Query(true).FirstOrDefaultAsync(m => m.ProductId == productId && m.Account == accout);
}
/// <summary>
/// day 0已过期1天
/// </summary>
/// <param name="day"></param>
/// <returns></returns>
public async Task<List<ProductAccountEntity>> GetExpireingAccounts_bak(int day)
{
Expression<Func<ProductAccountEntity, bool>> expr = m => 1 == 1;
if (day == 0)
{
expr = expr.And(m => m.EndTime.Value < DateTime.Now);
}
else
{
var startTime = DateTime.Now.Begin().AddDays(day);
var EndTime = DateTime.Now.End().AddDays(day);
expr = expr.And(m => m.EndTime >= startTime && m.EndTime <= EndTime);
}
return await this.Query(expr,true).ToListAsync();
}
public async Task<List<ProductAccountEntity>> GetExpireingAccounts(int day)
{
var sql = $"select * from product_account where DATEDIFF(EndTime,now())={day}";
return this.m_DbContext.SqlQuery<ProductAccountEntity>(sql);
}
public async Task<ApiResult> UpdateAccountPwd(UpdateAccountPwdRequest request)
{
var entity = await this.GetById(request.Id);
if (entity == null)
{
return new ApiResult(ResultCode.C_INVALID_ERROR, "账号不存在");
}
if (request.Pwd.NotHas())
{
return new ApiResult(ResultCode.C_INVALID_ERROR, "密码不能为空");
}
var agentRet = await m_AgentService.UpdateAccountPwd(entity.ProductId.Value, entity.Account, request.Pwd);
if (!agentRet)
{
return new ApiResult(ResultCode.C_INVALID_ERROR, "远程更新失败");
}
entity.Pwd = request.Pwd;
await this.Update(entity);
return new ApiResult(1);
}
public async Task<List<ProductAccountEntity>> GetUserTestAccount(int userId)
{
return await this.Query(m => m.UserId == userId && m.AccountType == (int)AccountType.Test).ToListAsync();
}
public async Task<int> GetRestTestCount(int userId)
{
var userInfo = await m_UserService.GetById(userId);
var restTimes = Convert.ToInt32(m_Configuration["TestCountLimit"]);
if (userInfo.TestCountLimit > 0) restTimes = userInfo.TestCountLimit.Value;
restTimes = restTimes - userInfo.UseTestCount.Value;
restTimes = restTimes < 0 ? 0 : restTimes;
return restTimes;
}
}
}

View File

@@ -0,0 +1,63 @@
using Hncore.Infrastructure.Service;
using Hncore.Infrastructure.WebApi;
using Hncore.Pass.Vpn.Domain;
using Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Hncore.Pass.Vpn.Service
{
public partial class ProductOrderItemService : ServiceBase<ProductOrderItemEntity>, IFindService
{
CourseContext m_DbContext;
public ProductOrderItemService(CourseContext dbContext
, IHttpContextAccessor httpContextAccessor) : base(dbContext, httpContextAccessor)
{
m_DbContext = dbContext;
}
public async Task<List<ProductOrderItemEntity>> CreateOrderItems(ProductOrderEntity orderEntity,string pwd)
{
List<ProductOrderItemEntity> items = new List<ProductOrderItemEntity>();
var accounts = orderEntity.Accounts.Split(',').ToList();
accounts.ForEach(m =>
{
var item = new ProductOrderItemEntity()
{
ConnectCount = orderEntity.ConnectCount,
DayPrice = orderEntity.DayPrice.Value,
DayCount=orderEntity.DayCount,
OrderId = orderEntity.Id,
OrderNo = orderEntity.OrderNo,
OrderState = orderEntity.OrderState,
OrderType = orderEntity.OrderType,
PackageId = orderEntity.PackageId,
PackageName = orderEntity.PackageName,
PayState = orderEntity.PayState,
PayType = orderEntity.PayType,
Account = m,
ProductId = orderEntity.ProductId,
ProductName = orderEntity.ProductName,
TenantId = orderEntity.TenantId,
UserId = orderEntity.UserId,
UserName = orderEntity.UserName,
AccountPwd = pwd
};
items.Add(item);
});
await this.Adds(items);
return items;
}
public async Task<ProductOrderItemEntity> GetLastByAccount(string account)
{
var orderItem = await this.Query(m => m.Account == account && m.OrderState == OrderStatus.Complete)
.OrderByDescending(m => m.Id)
.FirstOrDefaultAsync();
return orderItem;
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,34 @@
using Hncore.Infrastructure.Service;
using Hncore.Pass.Vpn.Domain;
using Hncore.Pass.Vpn.Model;
using Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Hncore.Pass.Vpn.Service
{
public partial class ProductPackageService : ServiceBase<ProductPackageEntity>, IFindService
{
CourseContext m_DbContext;
ProductPackageUnitService m_ProductPackageUnitService;
public ProductPackageService(CourseContext dbContext
, ProductPackageUnitService _ProductPackageUnitService
, IHttpContextAccessor httpContextAccessor) : base(dbContext, httpContextAccessor)
{
m_DbContext = dbContext;
this.m_ProductPackageUnitService = _ProductPackageUnitService;
}
public async Task<List<PackageUnitItemModel>> GetBasePackages(int packageId)
{
var packageUnits = m_ProductPackageUnitService.Query(m => m.PackageId == packageId);
var query = from packageUnit in packageUnits
join package in this.Query(true) on packageUnit.BasePackageId equals package.Id
select new PackageUnitItemModel { Count = packageUnit.Count, Package = package };
return await query.ToListAsync();
}
}
}

View File

@@ -0,0 +1,15 @@
using Hncore.Infrastructure.Service;
using Hncore.Pass.Vpn.Domain;
using Microsoft.AspNetCore.Http;
namespace Hncore.Pass.Vpn.Service
{
public partial class ProductPackageUnitService : ServiceBase<ProductPackageUnitEntity>, IFindService
{
CourseContext m_DbContext;
public ProductPackageUnitService(CourseContext dbContext, IHttpContextAccessor httpContextAccessor) : base(dbContext, httpContextAccessor)
{
m_DbContext = dbContext;
}
}
}

View File

@@ -0,0 +1,54 @@
using Hncore.Infrastructure.Service;
using Hncore.Pass.Vpn.Domain;
using Hncore.Pass.Vpn.Response.Product;
using Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;
using System.Threading.Tasks;
using Hncore.Infrastructure.Extension;
using System.Linq;
namespace Hncore.Pass.Vpn.Service
{
public partial class ProductPriceDiscountService : ServiceBase<ProductPriceDiscountEntity>, IFindService
{
CourseContext m_DbContext;
ProductService m_ProductService;
ProductPackageService m_ProductPackageService;
public ProductPriceDiscountService(CourseContext dbContext
, ProductService _ProductService
, ProductPackageService _ProductPackageService
, IHttpContextAccessor httpContextAccessor) : base(dbContext, httpContextAccessor)
{
m_DbContext = dbContext;
m_ProductService = _ProductService;
m_ProductPackageService = _ProductPackageService;
}
public async Task<List<ProductWithPriceDiscountResponse>> GetPriceDiscount(int schemeId)
{
var products = await m_ProductService.Query(true).ToListAsync();
var packages = m_ProductPackageService.Query(true);
var priceDiscount = this.Query(m => m.SchemeId == schemeId);
var ret = from pakcage in packages
join uDiscount in priceDiscount on pakcage.Id equals uDiscount.PackageId into temp
from uDiscount in temp.DefaultIfEmpty()
select new PackagePriceDiscount()
{
Package = pakcage,
PriceDiscount = uDiscount ?? new ProductPriceDiscountEntity()
};
var packgesPrice = await ret.ToListAsync();
List<ProductWithPriceDiscountResponse> respList = new List<ProductWithPriceDiscountResponse>();
products.ForEach(p =>
{
var resp = new ProductWithPriceDiscountResponse();
resp.Product = p.MapTo<ProductResponse>();
resp.PackageDiscounts = packgesPrice.Where(m => m.Package.ProductId == p.Id).ToList();
respList.Add(resp);
});
return respList;
}
}
}

View File

@@ -0,0 +1,15 @@
using Hncore.Infrastructure.Service;
using Hncore.Pass.Vpn.Domain;
using Microsoft.AspNetCore.Http;
namespace Hncore.Pass.Vpn.Service
{
public partial class ProductPriceSchemeService : ServiceBase<ProductPriceSchemeEntity>, IFindService
{
CourseContext m_DbContext;
public ProductPriceSchemeService(CourseContext dbContext, IHttpContextAccessor httpContextAccessor) : base(dbContext, httpContextAccessor)
{
m_DbContext = dbContext;
}
}
}

View File

@@ -0,0 +1,15 @@
using Hncore.Infrastructure.Service;
using Hncore.Pass.Vpn.Domain;
using Microsoft.AspNetCore.Http;
namespace Hncore.Pass.Vpn.Service
{
public partial class ProductRouteService : ServiceBase<ProductRouteEntity>, IFindService
{
CourseContext m_DbContext;
public ProductRouteService(CourseContext dbContext, IHttpContextAccessor httpContextAccessor) : base(dbContext, httpContextAccessor)
{
m_DbContext = dbContext;
}
}
}

View File

@@ -0,0 +1,78 @@
using Hncore.Infrastructure.Extension;
using Hncore.Infrastructure.Service;
using Hncore.Pass.Vpn.Domain;
using Hncore.Pass.Vpn.Response.Product;
using Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Hncore.Pass.Vpn.Service
{
public partial class ProductService : ServiceBase<ProductEntity>, IFindService
{
private static readonly string m_ProductCacheKey = "Product:{0}";
CourseContext m_DbContext;
ProductPackageService m_ProductPackageService;
public ProductService(CourseContext dbContext, ProductPackageService _ProductPackageService, IHttpContextAccessor httpContextAccessor) : base(dbContext, httpContextAccessor)
{
m_DbContext = dbContext;
m_ProductPackageService = _ProductPackageService;
}
public async override Task<ProductEntity> GetById(object id)
{
return await base.GetById(id);
string key = string.Format(m_ProductCacheKey, id);
var cacheData = await RedisHelper.GetAsync<ProductEntity>(key);
if (cacheData == null)
{
cacheData = await base.GetById(id);
if (cacheData != null)
await RedisHelper.SetAsync(key, cacheData, 60 * 30);
}
return cacheData;
}
public async override Task<bool> Update(ProductEntity entity, bool autoSave = true)
{
string key = string.Format(m_ProductCacheKey, entity.Id);
await RedisHelper.SetAsync(key, entity, 60 * 30);
return await base.Update(entity, autoSave);
}
public async Task<List<ProductWithPackageResponse>> ProductWithPackage(int online=1)
{
var products = await this.Query(m => m.Sort != 1000).Where(m=>m.OnLine==online).ToListAsync();
var packages = await m_ProductPackageService.Query(true).ToListAsync();
List<ProductWithPackageResponse> respList = new List<ProductWithPackageResponse>();
products.ForEach(p =>
{
var resp = new ProductWithPackageResponse();
resp.Product = p.MapTo<ProductResponse>();
resp.Packages = packages.Where(m => m.ProductId == p.Id).ToList();
respList.Add(resp);
});
return respList;
}
public async Task<ProductWithPackageResponse> GetOneProductWithPackage(int productId)
{
var product = await this.GetById(productId);
var packages = await m_ProductPackageService.Query(m => m.ProductId == productId).ToListAsync();
List<ProductWithPackageResponse> respList = new List<ProductWithPackageResponse>();
var resp = new ProductWithPackageResponse();
resp.Product = product.MapTo<ProductResponse>();
resp.Packages = packages;
return resp;
}
}
}

View File

@@ -0,0 +1,68 @@
using Hncore.Infrastructure.Extension;
using Hncore.Infrastructure.Service;
using Hncore.Pass.Vpn.Domain;
using Hncore.Pass.Vpn.Response.Product;
using Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Hncore.Pass.Vpn.Service
{
public partial class ProductUserPriceService : ServiceBase<ProductUserPriceEntity>, IFindService
{
CourseContext m_DbContext;
ProductService m_ProductService;
ProductPackageService m_ProductPackageService;
public ProductUserPriceService(ProductPackageService m_ProductPackageService
, ProductService m_ProductService
,CourseContext dbContext, IHttpContextAccessor httpContextAccessor) : base(dbContext, httpContextAccessor)
{
m_DbContext = dbContext;
this.m_ProductPackageService = m_ProductPackageService;
this.m_ProductService = m_ProductService;
}
public async Task<List<ProductWithPackageUserPriceResponse>> GetPackageUserPrice(int userId)
{
var products = await m_ProductService.Query(true).ToListAsync();
var packages = m_ProductPackageService.Query(true);
var userPrice = this.Query(m => m.UserId == userId);
var ret = from pakcage in packages
join uPrice in userPrice on pakcage.Id equals uPrice.PackageId into temp
from uPrice in temp.DefaultIfEmpty()
select new PackageUserPriceResponse()
{
Package = pakcage,
UserPrice = uPrice ?? new ProductUserPriceEntity() { RefundDayPrice= products.FirstOrDefault(m=>m.Id==pakcage.ProductId).RefundDayPrice, UserPrice=pakcage.Price }
};
var packgesPrice = await ret.ToListAsync();
List<ProductWithPackageUserPriceResponse> respList = new List<ProductWithPackageUserPriceResponse>();
products.ForEach(p =>
{
var resp = new ProductWithPackageUserPriceResponse();
resp.Product = p.MapTo<ProductResponse>();
resp.PackageUserPrices = packgesPrice.Where(m => m.Package.ProductId == p.Id).ToList();
respList.Add(resp);
});
return respList;
}
public async Task<List<ProductUserPriceEntity>> GetProductUserPrice(int product,int userId)
{
return this.Query(m => m.ProductId == product && m.UserId == userId && m.Status == 1).ToList();
}
public async Task<List<ProductUserPriceEntity>> GetProductUserPrice(int userId)
{
return this.Query(m => m.UserId == userId && m.Status == 1).ToList();
}
public async Task<ProductUserPriceEntity> GetPackageUserPrice(int packageId, int userId)
{
return this.Query(m => m.PackageId == packageId && m.UserId == userId&& m.Status==1).FirstOrDefault();
}
}
}

View File

@@ -0,0 +1,30 @@
using Hncore.Infrastructure.Service;
using Hncore.Infrastructure.WebApi;
using Hncore.Pass.Vpn.Domain;
using Hncore.Pass.Vpn.Request.Product;
using Microsoft.AspNetCore.Http;
using System.Threading.Tasks;
using Hncore.Infrastructure.Extension;
using System;
using Hncore.Infrastructure.Common;
using System.Collections.Generic;
using Hncore.Pass.BaseInfo.Models;
using Microsoft.EntityFrameworkCore;
namespace Hncore.Pass.Vpn.Service
{
public class UserService : ServiceBase<UserEntity>, IFindService
{
CourseContext m_DbContext;
public UserService(CourseContext dbContext
,IHttpContextAccessor httpContextAccessor) : base(dbContext, httpContextAccessor)
{
m_DbContext = dbContext;
}
public async Task<List<UserEntity>> GetByIds(List<int> userids)
{
return await this.Query(m => userids.Contains(m.Id)).ToListAsync();
}
}
}

View File

@@ -0,0 +1,49 @@
using Hncore.Infrastructure.Service;
using Hncore.Pass.Vpn.Domain;
using Hncore.Wx.Open;
using Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore;
using System.Threading.Tasks;
namespace Hncore.Pass.Vpn.Service
{
public partial class WxAppService : ServiceBase<WxAppEntity>
{
public WxAppService(CourseContext dbContext, IHttpContextAccessor httpContextAccessor) : base(dbContext, httpContextAccessor)
{
}
public async Task SaveAppInfo(GetAuthorizerInfoResponse info, int tenantId, int storeId)
{
var wxAppInfo = await this.Query(true).FirstOrDefaultAsync(m => m.TenantId == tenantId
&& m.Appid == info.authorization_info.authorizer_appid
&& m.DeleteTag == 0);
var wxAuthInfoNew = new WxAppEntity()
{
TenantId = tenantId,
StoreId = storeId,
Appid = info.authorization_info.authorizer_appid,
HeadImg = info.authorizer_info.head_img,
NickName = info.authorizer_info.nick_name,
PrincipalName = info.authorizer_info.principal_name,
UserName = info.authorizer_info.user_name,
Bussinessinfo = info.authorizer_info.signature,
AuthorizerState = 0,
RefreshToken = info.authorization_info.authorizer_refresh_token,
ExpiresIn = info.authorization_info.expires_in,
};
if (wxAppInfo == null)
{
await this.Add(wxAuthInfoNew);
}
else
{
wxAuthInfoNew.Id = wxAppInfo.Id;
await this.Update(wxAuthInfoNew);
}
}
}
}

View File

@@ -0,0 +1,34 @@
using Hncore.Infrastructure.Service;
using Hncore.Pass.Vpn.Domain;
using Hncore.Wx.Open;
using Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace Hncore.Pass.Vpn.Service
{
public partial class WxAppUserService : ServiceBase<WxAppUserEntity>
{
WxAppService m_WxAppService;
public WxAppUserService(WxAppService _WxAppService, CourseContext dbContext, IHttpContextAccessor httpContextAccessor) : base(dbContext, httpContextAccessor)
{
m_WxAppService = _WxAppService;
}
public async Task<List<WxAppUserEntity>> GetWxUsers(List<int> UserId)
{
return await this.Query(m => UserId.Contains(m.UserId)).ToListAsync();
}
public async Task<WxAppUserEntity> GetWxUser(string appId, int userId)
{
return await this.Query(m => m.Appid == appId && m.UserId == userId).FirstOrDefaultAsync();
}
public async Task<WxAppUserEntity> GetWxUser(string appId, string openId)
{
return await this.Query(m => m.Appid == appId && m.Openid == openId).FirstOrDefaultAsync();
}
}
}