初始提交
This commit is contained in:
54
Services/Hncore.Pass.Vpn/Controllers/AgentController.cs
Normal file
54
Services/Hncore.Pass.Vpn/Controllers/AgentController.cs
Normal file
@@ -0,0 +1,54 @@
|
||||
using Hncore.Infrastructure.WebApi;
|
||||
using Hncore.Pass.Vpn.Request.Product;
|
||||
using Hncore.Pass.Vpn.Response.Product;
|
||||
using Hncore.Pass.Vpn.Service;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Hncore.Pass.Vpn.Controllers
|
||||
{
|
||||
[ApiVersion("1.0")]
|
||||
[Route("api/course/v{version:apiVersion}/agent/[action]")]
|
||||
public class AgentController : HncoreControllerBase
|
||||
{
|
||||
private AgentService m_AgentService;
|
||||
IConfiguration m_Configuration;
|
||||
public AgentController(AgentService _AgentService,IConfiguration configuration)
|
||||
{
|
||||
m_AgentService = _AgentService;
|
||||
m_Configuration = configuration;
|
||||
}
|
||||
[HttpPost]
|
||||
public async Task<ApiResult> Login([FromBody] AgentLoginRequest request)
|
||||
{
|
||||
return await m_AgentService.Login(request);
|
||||
}
|
||||
[HttpGet]
|
||||
public async Task<ApiResult> GetCode([FromQuery] int productId)
|
||||
{
|
||||
var ret = await m_AgentService.GetCode(productId);
|
||||
if (ret.Item1 != null)
|
||||
{
|
||||
var file = $"codes/{Guid.NewGuid().ToString("N")}.jpg";
|
||||
var wwwrootFile = $"wwwroot/{file}";
|
||||
using (FileStream fs = new FileStream(wwwrootFile, FileMode.Create))
|
||||
{
|
||||
await fs.WriteAsync(ret.Item1, 0, ret.Item1.Length);
|
||||
}
|
||||
return Success(new CodeResponse()
|
||||
{
|
||||
Key = ret.Item2,
|
||||
CodeImage = $"{m_Configuration["Service_BaseUrl"]}{file}"
|
||||
});
|
||||
}
|
||||
return Success(new CodeResponse()
|
||||
{
|
||||
Key = "",
|
||||
CodeImage = ""
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
108
Services/Hncore.Pass.Vpn/Controllers/ArticleController.cs
Normal file
108
Services/Hncore.Pass.Vpn/Controllers/ArticleController.cs
Normal file
@@ -0,0 +1,108 @@
|
||||
using Hncore.Infrastructure.EntitiesExtension;
|
||||
using Hncore.Infrastructure.Extension;
|
||||
using Hncore.Infrastructure.WebApi;
|
||||
using Hncore.Pass.Vpn.Domain;
|
||||
using Hncore.Pass.Vpn.Service;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System;
|
||||
using System.Linq.Expressions;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Hncore.Pass.Vpn.Controllers
|
||||
{
|
||||
[ApiVersion("1.0")]
|
||||
[Route("api/course/v{version:apiVersion}/article/[action]")]
|
||||
public class ArticleController : HncoreControllerBase
|
||||
{
|
||||
private ArticleService m_ArticleService;
|
||||
|
||||
public ArticleController(ArticleService _ArticleService)
|
||||
{
|
||||
m_ArticleService = _ArticleService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<ApiResult> Post([FromBody]ArticleEntity request)
|
||||
{
|
||||
request.TenantId = this.Request.GetManageUserInfo().TenantId;
|
||||
await m_ArticleService.Add(request);
|
||||
return Success();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 修改
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<ApiResult> Put([FromBody]ArticleEntity request)
|
||||
{
|
||||
await m_ArticleService.Update(request);
|
||||
return Success();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<ApiResult> Delete([FromQuery]int id)
|
||||
{
|
||||
var flag = await m_ArticleService.DeleteById(id);
|
||||
if (flag)
|
||||
return Success();
|
||||
else
|
||||
return Error("删除失败");
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 详情
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet]
|
||||
public async Task<ApiResult> Get([FromQuery]int id)
|
||||
{
|
||||
var data = await m_ArticleService.GetById(id);
|
||||
return Success(data);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 分页查询
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet]
|
||||
public async Task<ApiResult> Page([FromQuery]PageRequestBase request)
|
||||
{
|
||||
Expression<Func<ArticleEntity, bool>> expr = m => 1 == 1;
|
||||
if (request.KeyWord.Has())
|
||||
{
|
||||
expr = expr.And(m => m.Title.Contains(request.KeyWord)
|
||||
|| m.SubTitle.Contains(request.KeyWord)
|
||||
|| m.Keyword.Contains(request.KeyWord));
|
||||
}
|
||||
var ret = await m_ArticleService.Page(request.PageIndex, request.PageSize, expr,true);
|
||||
var data = ret.ToApiResult();
|
||||
return data;
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public async Task<ApiResult> Audit([FromQuery] int id)
|
||||
{
|
||||
var entity = await m_ArticleService.GetById(id);
|
||||
|
||||
entity.Publish = entity.Publish == 1 ? 0 : 1;
|
||||
|
||||
await m_ArticleService.Update(entity);
|
||||
return Success(entity.Publish);
|
||||
}
|
||||
}
|
||||
}
|
||||
397
Services/Hncore.Pass.Vpn/Controllers/ProductAccountController.cs
Normal file
397
Services/Hncore.Pass.Vpn/Controllers/ProductAccountController.cs
Normal file
@@ -0,0 +1,397 @@
|
||||
using Hncore.Infrastructure.Common;
|
||||
using Hncore.Infrastructure.EntitiesExtension;
|
||||
using Hncore.Infrastructure.Extension;
|
||||
using Hncore.Infrastructure.WebApi;
|
||||
using Hncore.Pass.Vpn.Domain;
|
||||
using Hncore.Pass.Vpn.Model;
|
||||
using Hncore.Pass.Vpn.Request.Product;
|
||||
using Hncore.Pass.Vpn.Service;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Hncore.Pass.Vpn.Controllers
|
||||
{
|
||||
[ApiVersion("1.0")]
|
||||
[Route("api/course/v{version:apiVersion}/productaccount/[action]")]
|
||||
public class ProductAccountController : HncoreControllerBase
|
||||
{
|
||||
private ProductAccountService m_AccountService;
|
||||
private UserService m_UserService;
|
||||
private AgentService m_agentService;
|
||||
private ProductPackageService m_PackageService;
|
||||
private ProductService m_ProductService;
|
||||
public ProductAccountController(ProductAccountService _AccountServic
|
||||
, UserService _UserService
|
||||
, AgentService _agentService
|
||||
, ProductPackageService _PackageService
|
||||
, ProductService _ProductService)
|
||||
{
|
||||
m_AccountService = _AccountServic;
|
||||
m_UserService = _UserService;
|
||||
m_agentService = _agentService;
|
||||
m_PackageService = _PackageService;
|
||||
m_ProductService = _ProductService;
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<ApiResult> Post([FromBody]ProductAccountEntity request)
|
||||
{
|
||||
request.TenantId = this.Request.GetManageUserInfo().TenantId;
|
||||
await m_AccountService.Add(request);
|
||||
return Success();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 修改
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<ApiResult> Put([FromBody]ProductAccountEntity request)
|
||||
{
|
||||
await m_AccountService.Update(request);
|
||||
return Success();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<ApiResult> Delete([FromQuery]int id)
|
||||
{
|
||||
var flag = await m_AccountService.DeleteById(id);
|
||||
if (flag)
|
||||
return Success();
|
||||
else
|
||||
return Error("删除失败");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<ApiResult> Deletes([FromBody] List<int> ids)
|
||||
{
|
||||
var data= m_AccountService.Query(m => ids.Contains(m.Id));
|
||||
var flag = await m_AccountService.Deletes(data);
|
||||
if (flag)
|
||||
return Success();
|
||||
else
|
||||
return Error("删除失败");
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 详情
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet]
|
||||
public async Task<ApiResult> Get([FromQuery]int id)
|
||||
{
|
||||
var data = await m_AccountService.GetById(id);
|
||||
return Success(data);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 分页查询
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet]
|
||||
public async Task<ApiResult> Page([FromQuery]AccountPageRequest request)
|
||||
{
|
||||
Expression<Func<ProductAccountEntity, bool>> expr = m => 1 == 1;
|
||||
if (request.UserId > 0)
|
||||
{
|
||||
expr = expr.And(m => m.UserId == request.UserId);
|
||||
}
|
||||
if (request.KeyWord.Has())
|
||||
{
|
||||
expr = expr.And(m => m.UserCode.Contains(request.KeyWord)
|
||||
|| m.ProductName.Contains(request.KeyWord)
|
||||
|| m.PackageName.Contains(request.KeyWord)
|
||||
|| m.Account.Contains(request.KeyWord));
|
||||
}
|
||||
if (request.ProductId.HasValue)
|
||||
{
|
||||
expr = expr.And(m =>m.ProductId == request.ProductId);
|
||||
}
|
||||
if (request.PackageId.HasValue)
|
||||
{
|
||||
expr = expr.And(m => m.PackageId == request.PackageId);
|
||||
}
|
||||
if (request.AccountTypes!=null&&request.AccountTypes.Count>0)
|
||||
{
|
||||
expr = expr.And(m => request.AccountTypes.Contains(m.AccountType));
|
||||
}
|
||||
if (request.BTime.HasValue && request.ETime.HasValue)
|
||||
{
|
||||
expr = expr.And(m => m.EndTime>=request.BTime&&m.EndTime<=request.ETime);
|
||||
}
|
||||
if (request.ExpirdDay > -1)
|
||||
{
|
||||
if (request.ExpirdDay == 0)
|
||||
{
|
||||
expr = expr.And(m => m.EndTime.Value < DateTime.Now);
|
||||
}
|
||||
else
|
||||
{
|
||||
var startTime = DateTime.Now.Begin().AddDays(request.ExpirdDay);
|
||||
startTime = startTime < DateTime.Now ? DateTime.Now : startTime;
|
||||
var EndTime = DateTime.Now.End().AddDays(request.ExpirdDay);
|
||||
expr = expr.And(m => m.EndTime >= startTime && m.EndTime <= EndTime);
|
||||
}
|
||||
// expr = expr.And(m => Math.Ceiling((m.EndTime - DateTime.Now).Value.TotalDays) == request.ExpirdDay);
|
||||
}
|
||||
var ret = await m_AccountService.PageDesc(request.PageIndex, request.PageSize, expr,true,m=>m.Id);
|
||||
var data = ret.ToApiResult();
|
||||
return data;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 分页查询
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet]
|
||||
public async Task<ApiResult> Search([FromQuery]AccountPageRequest request)
|
||||
{
|
||||
if (request.KeyWord.Has())
|
||||
{
|
||||
Expression<Func<ProductAccountEntity, bool>> expr = m => m.Account== request.KeyWord||m.UserCode== request.KeyWord;
|
||||
var ret = await m_AccountService.PageDesc(request.PageIndex, request.PageSize, expr, true, m => m.Id);
|
||||
var data = ret.ToApiResult();
|
||||
return data;
|
||||
}
|
||||
return Error("请输入关键字");
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 迁移
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<ApiResult> BindUser([FromBody]BindUserRequest request)
|
||||
{
|
||||
var entityList = await m_AccountService.Query(m => request.AccountIds.Contains(m.Id)).ToListAsync();
|
||||
if (entityList == null|| entityList.Count==0)
|
||||
return Error("没有选择账号");
|
||||
var userEntity= await m_UserService.GetById(request.UserId);
|
||||
if (userEntity == null)
|
||||
return Error("会员不存在");
|
||||
|
||||
entityList.ForEach(entity =>
|
||||
{
|
||||
entity.UserId = request.UserId;
|
||||
entity.UserCode = userEntity.LoginCode;
|
||||
entity.UserPhone = userEntity.Phone;
|
||||
});
|
||||
|
||||
await m_AccountService.Update(entityList);
|
||||
return Success();
|
||||
}
|
||||
[HttpGet]
|
||||
public async Task<ApiResult> GetOrginAccount([FromQuery]string accounts)
|
||||
{
|
||||
var accountList = await m_AccountService.GetAccounts(string.Join(",", accounts));
|
||||
var originModel = await m_agentService.GetOriginAccounts(accountList);
|
||||
return Success(originModel);
|
||||
}
|
||||
|
||||
|
||||
[HttpGet]
|
||||
public async Task<ApiResult> UpdateOrginPwd([FromQuery]int productId, string account, string pwd)
|
||||
{
|
||||
var flag = await m_agentService.UpdateAccountPwd(productId, account, pwd);
|
||||
if (flag)
|
||||
return Success();
|
||||
else
|
||||
return Error("修改密码失败");
|
||||
}
|
||||
[HttpGet, UserAuth]
|
||||
public async Task<ApiResult> ExistAccount([FromQuery]int productId, [FromQuery]string accounts)
|
||||
{
|
||||
var flag =await m_AccountService.CheckAccountExist(productId, accounts.Split(',').ToList());
|
||||
if (flag)
|
||||
{
|
||||
return Error("账号已经存在");
|
||||
}
|
||||
return Success();
|
||||
}
|
||||
|
||||
[HttpPost, UserAuth]
|
||||
public async Task<ApiResult> CreateTestAccount([FromBody]CreateTestAccountRequest request)
|
||||
{
|
||||
if (request.Account.NotHas() || request.Pwd.NotHas())
|
||||
{
|
||||
return Error("账户和密码不能为空");
|
||||
}
|
||||
var userId = this.Request.GetUserInfo().UserId;
|
||||
var packageEntity = await m_PackageService.GetById(request.PackageId);
|
||||
if (packageEntity==null|| packageEntity.Status==0)
|
||||
{
|
||||
return Error("套餐不存在");
|
||||
}
|
||||
if (packageEntity.IsTest == 0)
|
||||
{
|
||||
return Error("非测试套餐");
|
||||
}
|
||||
|
||||
var flag = await m_AccountService.CheckAccountExist(packageEntity.ProductId, new List<string> { request.Account });
|
||||
if (flag)
|
||||
{
|
||||
return Error("账号已经存在");
|
||||
}
|
||||
var restTimes = await m_AccountService.GetRestTestCount(userId);
|
||||
|
||||
if (restTimes <= 0)
|
||||
{
|
||||
return Error("没有测试次数了");
|
||||
}
|
||||
|
||||
|
||||
var ret= await m_agentService.NewAccount(0, request.PackageId, request.Account, request.Pwd, accountType: 0);
|
||||
|
||||
if (ret.Code == ResultCode.C_SUCCESS)
|
||||
{
|
||||
var ProductEntity = await m_ProductService.GetById(packageEntity.ProductId);
|
||||
var accountEntity = new ProductAccountEntity()
|
||||
{
|
||||
Account = request.Account,
|
||||
AccountType = (int)AccountType.Test,
|
||||
ConnectCount = 1,
|
||||
StartTime = DateTime.Now,
|
||||
EndTime = DateTime.Now.AddHours(packageEntity.DayCount),
|
||||
PackageId = packageEntity.Id,
|
||||
PackageName = packageEntity.Name,
|
||||
ProductId = packageEntity.ProductId,
|
||||
ProductName = ProductEntity.Name,
|
||||
Pwd = request.Pwd,
|
||||
ChargeStatus = AccountChargeStatus.Normal,
|
||||
UserId = this.Request.GetUserInfo().UserId,
|
||||
UserCode = this.Request.GetUserInfo().LoginName,
|
||||
};
|
||||
await m_AccountService.Add(accountEntity);
|
||||
|
||||
var userEntity = await m_UserService.GetById(userId);
|
||||
userEntity.UseTestCount++;
|
||||
await m_UserService.Update(userEntity);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 是否在线
|
||||
/// </summary>
|
||||
/// <param name="productId"></param>
|
||||
/// <param name="account"></param>
|
||||
/// <returns></returns>
|
||||
// [UserAuth]
|
||||
[AllowAnonymous]
|
||||
public virtual async Task<ApiResult<List<OriginAccountOnlineModel>>> OnLine(int productId, string account)
|
||||
{
|
||||
return await m_agentService.OnLine(productId, account);
|
||||
}
|
||||
/// <summary>
|
||||
/// 踢号
|
||||
/// </summary>
|
||||
/// <param name="productId"></param>
|
||||
/// <param name="account"></param>
|
||||
/// <returns></returns>
|
||||
// [UserAuth]
|
||||
[AllowAnonymous]
|
||||
public virtual async Task<ApiResult> KillOut(int productId, string id)
|
||||
{
|
||||
return Success(await m_agentService.KillOut(productId, id));
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public async Task<IActionResult> Export([FromQuery]AccountPageRequest request)
|
||||
{
|
||||
|
||||
Expression<Func<ProductAccountEntity, bool>> expr = m => 1 == 1;
|
||||
if (request.UserId > 0)
|
||||
{
|
||||
expr = expr.And(m => m.UserId == request.UserId);
|
||||
}
|
||||
if (request.KeyWord.Has())
|
||||
{
|
||||
expr = expr.And(m => m.Account.Contains(request.KeyWord));
|
||||
}
|
||||
if (request.ProductId.HasValue)
|
||||
{
|
||||
expr = expr.And(m => m.ProductId == request.ProductId);
|
||||
}
|
||||
if (request.PackageId.HasValue)
|
||||
{
|
||||
expr = expr.And(m => m.PackageId == request.PackageId);
|
||||
}
|
||||
if (request.AccountTypes != null && request.AccountTypes.Count > 0)
|
||||
{
|
||||
expr = expr.And(m => request.AccountTypes.Contains(m.AccountType));
|
||||
}
|
||||
if (request.ExpirdDay > -1)
|
||||
{
|
||||
if (request.ExpirdDay == 0)
|
||||
{
|
||||
expr = expr.And(m => m.EndTime.Value < DateTime.Now);
|
||||
}
|
||||
else
|
||||
{
|
||||
var startTime = DateTime.Now.Begin().AddDays(request.ExpirdDay);
|
||||
startTime = startTime < DateTime.Now ? DateTime.Now : startTime;
|
||||
var EndTime = DateTime.Now.End().AddDays(request.ExpirdDay);
|
||||
expr = expr.And(m => m.EndTime >= startTime && m.EndTime <= EndTime);
|
||||
}
|
||||
// expr = expr.And(m => Math.Ceiling((m.EndTime - DateTime.Now).Value.TotalDays) == request.ExpirdDay);
|
||||
}
|
||||
var ret = await m_AccountService.PageDesc(request.PageIndex,10000, expr, true, m => m.Id);
|
||||
|
||||
var data = new ExcelData<ProductAccountEntity>
|
||||
{
|
||||
SheetName = DateTime.Now.ToString("yyyy-MM-dd"),
|
||||
Data = ret.List
|
||||
};
|
||||
|
||||
var title = new List<ExcelTitle>(){
|
||||
new ExcelTitle { Property = "UserCode", Title = "用户" },
|
||||
new ExcelTitle { Property = "ProductName", Title = "产品" },
|
||||
new ExcelTitle { Property = "PackageName", Title = "套餐" },
|
||||
new ExcelTitle { Property = "Account", Title = "账号" },
|
||||
new ExcelTitle { Property = "AccountType", Title = "类型" , Format=(val)=>((AccountType)val).GetEnumDisplayName() },
|
||||
new ExcelTitle { Property = "ConnectCount", Title = "连接数"},
|
||||
new ExcelTitle { Property = "StartTime", Title = "开通时间" , Format=(val)=>((DateTime) val).ToString("yyyy-MM-dd hh:mm:ss")},
|
||||
new ExcelTitle { Property = "EndTime", Title = "到期时间" ,Format=(val)=>((DateTime) val).ToString("yyyy-MM-dd hh:mm:ss")},
|
||||
new ExcelTitle { Property = "RestTime", Title = "剩余时间" },
|
||||
};
|
||||
var fileBytes = ExcelHelper.ExportListToExcel(data, title);
|
||||
|
||||
var fileName = $"{DateTime.Now.ToString("yyyyMMdd")}账号明细.xlsx";
|
||||
Response.Headers.Add("X-Suggested-Filename", fileName.UrlEncode());
|
||||
return File(fileBytes, "application/octet-stream", fileName);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
277
Services/Hncore.Pass.Vpn/Controllers/ProductController.cs
Normal file
277
Services/Hncore.Pass.Vpn/Controllers/ProductController.cs
Normal file
@@ -0,0 +1,277 @@
|
||||
using Hncore.Infrastructure.EntitiesExtension;
|
||||
using Hncore.Infrastructure.Extension;
|
||||
using Hncore.Infrastructure.WebApi;
|
||||
using Hncore.Pass.Vpn.Domain;
|
||||
using Hncore.Pass.Vpn.Request.Product;
|
||||
using Hncore.Pass.Vpn.Response.Product;
|
||||
using Hncore.Pass.Vpn.Service;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System;
|
||||
using System.Linq.Expressions;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Hncore.Pass.Vpn.Controllers
|
||||
{
|
||||
[ApiVersion("1.0")]
|
||||
[Route("api/course/v{version:apiVersion}/product/[action]")]
|
||||
public class ProductController : HncoreControllerBase
|
||||
{
|
||||
private ProductService m_ProductService;
|
||||
private ProductPackageService m_ProductPackageService;
|
||||
private ProductUserPriceService m_ProductUserPriceService;
|
||||
public ProductController(ProductService _ProductServic, ProductPackageService _ProductPackageService, ProductUserPriceService m_ProductUserPriceService)
|
||||
{
|
||||
m_ProductService = _ProductServic;
|
||||
m_ProductPackageService = _ProductPackageService;
|
||||
this.m_ProductUserPriceService = m_ProductUserPriceService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<ApiResult> Post([FromBody]ProductEntity request)
|
||||
{
|
||||
request.TenantId = this.Request.GetManageUserInfo().TenantId;
|
||||
await m_ProductService.Add(request);
|
||||
return Success();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 修改
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<ApiResult> Put([FromBody]ProductEntity request)
|
||||
{
|
||||
var entity = await m_ProductService.GetById(request.Id);
|
||||
entity.Name = request.Name;
|
||||
entity.Profile = request.Profile;
|
||||
entity.Image = request.Image;
|
||||
entity.RefundDayPrice = request.RefundDayPrice;
|
||||
entity.DayLimitPrice = request.DayLimitPrice;
|
||||
await m_ProductService.Update(entity);
|
||||
return Success();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 修改
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<ApiResult> PutConfig([FromBody]ProductEntity request)
|
||||
{
|
||||
var entity = await m_ProductService.GetById(request.Id);
|
||||
entity.Account = request.Account;
|
||||
entity.Pwd = request.Pwd;
|
||||
entity.BaseUrl = request.BaseUrl;
|
||||
entity.Token = "";
|
||||
await m_ProductService.Update(entity);
|
||||
return Success();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 修改
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<ApiResult> PutSoft([FromBody]ProductEntity request)
|
||||
{
|
||||
var entity = await m_ProductService.GetById(request.Id);
|
||||
entity.PcClientDownloadUrl = request.PcClientDownloadUrl;
|
||||
entity.SimulatorDownloadUrl = request.SimulatorDownloadUrl;
|
||||
entity.DroidDownloadUrl = request.DroidDownloadUrl;
|
||||
entity.IosDownloadUrl = request.IosDownloadUrl;
|
||||
await m_ProductService.Update(entity);
|
||||
return Success();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<ApiResult> Delete([FromQuery]int id)
|
||||
{
|
||||
var flag = await m_ProductService.DeleteById(id);
|
||||
if (flag)
|
||||
return Success();
|
||||
else
|
||||
return Error("删除失败");
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 详情
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet]
|
||||
public async Task<ApiResult> Get([FromQuery]int id)
|
||||
{
|
||||
var data = await m_ProductService.GetById(id);
|
||||
return Success(data);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 分页查询
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet]
|
||||
public async Task<ApiResult> Page([FromQuery]PageRequestBase request)
|
||||
{
|
||||
Expression<Func<ProductEntity, bool>> expr = m => 1 == 1;
|
||||
if (request.KeyWord.Has())
|
||||
{
|
||||
expr = expr.And(m => m.Name.Contains(request.KeyWord));
|
||||
}
|
||||
var ret = await m_ProductService.Page(request.PageIndex, request.PageSize, expr,true);
|
||||
var data = ret.ToApiResult();
|
||||
return data;
|
||||
}
|
||||
|
||||
[HttpGet,AllowAnonymous]
|
||||
public async Task<ApiResult> OpenPage([FromQuery]PageRequestBase request)
|
||||
{
|
||||
Expression<Func<ProductEntity, bool>> expr = m => 1 == 1;
|
||||
if (request.KeyWord.Has())
|
||||
{
|
||||
expr = expr.And(m => m.Name.Contains(request.KeyWord));
|
||||
}
|
||||
var ret = await m_ProductService.Page(request.PageIndex, request.PageSize, expr, true);
|
||||
var data = ret.ToApiResult();
|
||||
return data;
|
||||
}
|
||||
|
||||
[HttpGet, AllowAnonymous]
|
||||
public async Task<ApiResult> ProductWithPackage()
|
||||
{
|
||||
var respList = await m_ProductService.ProductWithPackage();
|
||||
return Success(respList);
|
||||
}
|
||||
|
||||
|
||||
[HttpGet]
|
||||
public async Task<ApiResult> ProductUserPrice(int userId)
|
||||
{
|
||||
var ret = await this.m_ProductUserPriceService.GetPackageUserPrice(userId);
|
||||
return Success(ret);
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public async Task<ApiResult> SetProductLine([FromQuery]int id)
|
||||
{
|
||||
var productEntity = await m_ProductService.GetById(id);
|
||||
if (productEntity == null)
|
||||
{
|
||||
return Error("产品不存在");
|
||||
}
|
||||
productEntity.Status = productEntity.OnLine == 0 ? 1 : 0;
|
||||
await m_ProductService.Update(productEntity);
|
||||
|
||||
return Success(productEntity.Status);
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public async Task<ApiResult> SetPackageLine([FromQuery]int id)
|
||||
{
|
||||
var packageEntity = await m_ProductPackageService.GetById(id);
|
||||
if (packageEntity == null)
|
||||
{
|
||||
return Error("套餐不存在");
|
||||
}
|
||||
packageEntity.Status = packageEntity.Status == 0 ? 1 : 0;
|
||||
await m_ProductPackageService.Update(packageEntity);
|
||||
|
||||
return Success(packageEntity.Status);
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public async Task<ApiResult> SetUserPriceStatus([FromQuery]int id)
|
||||
{
|
||||
var userPriceEntity = await m_ProductUserPriceService.GetById(id);
|
||||
if (userPriceEntity == null)
|
||||
{
|
||||
return Error("请设置会员价");
|
||||
}
|
||||
userPriceEntity.Status = userPriceEntity.Status == 0 ? 1 : 0;
|
||||
await m_ProductUserPriceService.Update(userPriceEntity);
|
||||
return Success(userPriceEntity.Status);
|
||||
}
|
||||
|
||||
|
||||
[HttpPost]
|
||||
public async Task<ApiResult> PutPackage([FromBody]ProductPackageEntity request)
|
||||
{
|
||||
var packageEntity = await m_ProductPackageService.GetById(request.Id);
|
||||
if (packageEntity == null)
|
||||
{
|
||||
return Error("套餐不存在");
|
||||
}
|
||||
packageEntity.LinePrice = request.LinePrice;
|
||||
packageEntity.MinPrice = request.MinPrice;
|
||||
packageEntity.Name = request.Name;
|
||||
packageEntity.Price = request.Price;
|
||||
packageEntity.Profile = request.Profile;
|
||||
packageEntity.Title = request.Title;
|
||||
await m_ProductPackageService.Update(packageEntity);
|
||||
return Success(packageEntity);
|
||||
}
|
||||
|
||||
|
||||
[HttpPost]
|
||||
public async Task<ApiResult> PutUserPrice([FromBody]PutUserPriceRequest request)
|
||||
{
|
||||
var userPriceEntity = await m_ProductUserPriceService.Query(m => m.PackageId == request.PackageId && m.UserId == request.UserId).FirstOrDefaultAsync();
|
||||
|
||||
var price = request.UserPrice;
|
||||
var packageEntity =await m_ProductPackageService.GetById(request.PackageId);
|
||||
// var product = await m_ProductService.GetById(packageEntity.ProductId);
|
||||
if (request.UserPrice < packageEntity.MinPrice && packageEntity.MinPrice > 0)
|
||||
{
|
||||
return Error($"不能低于最低限额[{ packageEntity.MinPrice}]");
|
||||
}
|
||||
|
||||
var productEntity = await m_ProductService.GetById(packageEntity.ProductId);
|
||||
|
||||
if (productEntity.DayLimitPrice>0&&request.RefundDayPrice < productEntity.DayLimitPrice)
|
||||
{
|
||||
return Error($"退款单价不能低于[{ productEntity.DayLimitPrice}]");
|
||||
}
|
||||
|
||||
//toto
|
||||
if (userPriceEntity == null)
|
||||
{
|
||||
userPriceEntity =new ProductUserPriceEntity()
|
||||
{
|
||||
PackageId = request.PackageId,
|
||||
ProductId = request.ProductId,
|
||||
UserId = request.UserId,
|
||||
UserPrice = request.UserPrice,
|
||||
Status = 1,
|
||||
DeleteTag = 0,
|
||||
Remark=request.Remark,
|
||||
RefundDayPrice= request.RefundDayPrice
|
||||
};
|
||||
await m_ProductUserPriceService.Add(userPriceEntity);
|
||||
}
|
||||
else
|
||||
{
|
||||
userPriceEntity.UserPrice = request.UserPrice;
|
||||
userPriceEntity.RefundDayPrice = request.RefundDayPrice;
|
||||
userPriceEntity.Remark = request.Remark;
|
||||
await m_ProductUserPriceService.Update(userPriceEntity);
|
||||
}
|
||||
return Success(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
752
Services/Hncore.Pass.Vpn/Controllers/ProductOrderController.cs
Normal file
752
Services/Hncore.Pass.Vpn/Controllers/ProductOrderController.cs
Normal file
@@ -0,0 +1,752 @@
|
||||
using Hncore.Infrastructure.Common;
|
||||
using Hncore.Infrastructure.EntitiesExtension;
|
||||
using Hncore.Infrastructure.Extension;
|
||||
using Hncore.Infrastructure.WebApi;
|
||||
using Hncore.Pass.BaseInfo.Service;
|
||||
using Hncore.Pass.Vpn.Domain;
|
||||
using Hncore.Pass.Vpn.Model;
|
||||
using Hncore.Pass.Vpn.Request.Product;
|
||||
using Hncore.Pass.Vpn.Service;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Threading.Tasks;
|
||||
using BaseUserService = Hncore.Pass.BaseInfo.Service.UserService;
|
||||
namespace Hncore.Pass.Vpn.Controllers
|
||||
{
|
||||
[ApiVersion("1.0")]
|
||||
[Route("api/course/v{version:apiVersion}/order/[action]")]
|
||||
public class ProductOrderController : HncoreControllerBase
|
||||
{
|
||||
private ProductService m_ProductService;
|
||||
private ProductOrderService m_ProductOrderService;
|
||||
private BaseUserService m_BaseUserService;
|
||||
|
||||
private ManageService m_ManageService;
|
||||
public ProductOrderController(ProductService _ProductServic
|
||||
, ProductOrderService _ProductOrderService
|
||||
, BaseUserService _BaseUserService
|
||||
, ManageService _ManageService)
|
||||
{
|
||||
m_ProductService = _ProductServic;
|
||||
m_ProductOrderService = _ProductOrderService;
|
||||
m_BaseUserService=_BaseUserService;
|
||||
m_ManageService = _ManageService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 详情
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet]
|
||||
public async Task<ApiResult> Get([FromQuery]int id)
|
||||
{
|
||||
var data = await m_ProductService.GetById(id);
|
||||
return Success(data);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 分页查询
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet]
|
||||
public async Task<ApiResult> Page([FromQuery]OrderQueryRequest request)
|
||||
{
|
||||
Expression<Func<ProductOrderEntity, bool>> expr = m =>( m.OrderState == OrderStatus.PayOk || m.OrderState == OrderStatus.Complete) && m.OrderType != OrderType.Refund;
|
||||
if (request.KeyWord.Has())
|
||||
{
|
||||
expr = expr.And(m =>
|
||||
m.ProductName.Contains(request.KeyWord)
|
||||
||m.Accounts.Contains(request.KeyWord)
|
||||
||m.OrderNo.Contains(request.KeyWord)
|
||||
||m.UserName.Contains(request.KeyWord)
|
||||
||m.PackageName.Contains(request.KeyWord));
|
||||
}
|
||||
if (request.ProductId.HasValue)
|
||||
{
|
||||
expr = expr.And(m =>m.ProductId==request.ProductId);
|
||||
}
|
||||
if (request.PackageId.HasValue)
|
||||
{
|
||||
expr = expr.And(m => m.PackageId == request.PackageId);
|
||||
}
|
||||
if (request.OrderTypes != null && request.OrderTypes.Count > 0)
|
||||
{
|
||||
expr = expr.And(m => request.OrderTypes.Contains((int)m.OrderType));
|
||||
}
|
||||
if (request.BTime.HasValue && request.ETime.HasValue)
|
||||
{
|
||||
expr = expr.And(m => m.CreateTime >= request.BTime && m.CreateTime <= request.ETime);
|
||||
}
|
||||
var ret = await m_ProductOrderService.PageDesc(request.PageIndex, request.PageSize, expr, true,m=>m.Id);
|
||||
var data = ret.ToApiResult();
|
||||
return data;
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public ApiResult Statistics([FromQuery]OrderQueryRequest request)
|
||||
{
|
||||
var ret = m_ProductOrderService.Statistics(request.BTime, request.ETime);
|
||||
return Success(ret);
|
||||
}
|
||||
|
||||
|
||||
[HttpGet]
|
||||
public ApiResult SellerStatistics([FromQuery]OrderQueryRequest request)
|
||||
{
|
||||
var ret = m_ProductOrderService.SellerStatistics(request.BTime, request.ETime);
|
||||
return Success(ret);
|
||||
}
|
||||
|
||||
|
||||
[HttpGet]
|
||||
public async Task<ApiResult> UserConsumeStatistics([FromQuery]UserConsumeRequest request)
|
||||
{
|
||||
|
||||
var loginInfo = this.Request.GetManageUserInfo();
|
||||
int id = loginInfo.OperaterId;
|
||||
var managerInfo =await m_ManageService.GetById(loginInfo.OperaterId);
|
||||
if (managerInfo.IsRoot == 1) id = 0;
|
||||
var ret = m_ProductOrderService.UserConsumeStatistics(request.PageIndex, request.PageSize, request.KeyWord, request.bTime1, request.eTime1, request.bTime2, request.eTime2, id, request.SortLable, request.SortOrder,request.Profile);
|
||||
return ret.ToApiResult();
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public async Task<ApiResult> RefundOrders([FromQuery]OrderQueryRequest request)
|
||||
{
|
||||
Expression<Func<ProductOrderEntity, bool>> expr = m => m.OrderType == OrderType.Refund;
|
||||
if (request.KeyWord.Has())
|
||||
{
|
||||
expr = expr.And(m => m.Accounts.Contains(request.KeyWord)
|
||||
|| m.OrderNo.Contains(request.KeyWord)
|
||||
|| m.UserName.Contains(request.KeyWord)
|
||||
|| m.PackageName.Contains(request.KeyWord));
|
||||
}
|
||||
if (request.ProductId.HasValue)
|
||||
{
|
||||
expr = expr.And(m => m.ProductId == request.ProductId);
|
||||
}
|
||||
if (request.OrderTypes != null && request.OrderTypes.Count > 0)
|
||||
{
|
||||
expr = expr.And(m => request.OrderTypes.Contains((int)m.OrderType));
|
||||
}
|
||||
if (request.BTime.HasValue && request.ETime.HasValue)
|
||||
{
|
||||
expr = expr.And(m => m.CreateTime >= request.BTime && m.CreateTime <= request.ETime);
|
||||
}
|
||||
var ret = await m_ProductOrderService.PageDesc(request.PageIndex, request.PageSize, expr, true,m=>m.Id);
|
||||
var data = ret.ToApiResult();
|
||||
return data;
|
||||
}
|
||||
|
||||
[HttpGet,AllowAnonymous]
|
||||
public async Task<ApiResult> OpenRefundOrders([FromQuery]RefundOrderQueryRequest request)
|
||||
{
|
||||
Expression<Func<ProductOrderEntity, bool>> expr = m => m.OrderType == OrderType.Refund;
|
||||
if (request.KeyWord.Has())
|
||||
{
|
||||
expr = expr.And(m => m.Accounts.Contains(request.KeyWord)
|
||||
|| m.OrderNo.Contains(request.KeyWord)
|
||||
|| m.UserName.Contains(request.KeyWord)
|
||||
|| m.PackageName.Contains(request.KeyWord));
|
||||
}
|
||||
if (request.ProductIds!=null&& request.ProductIds.Count>0)
|
||||
{
|
||||
expr = expr.And(m => request.ProductIds.Contains(m.ProductId));
|
||||
}
|
||||
|
||||
if (request.BTime.HasValue && request.ETime.HasValue)
|
||||
{
|
||||
expr = expr.And(m => m.CreateTime > request.BTime && m.CreateTime < request.ETime);
|
||||
}
|
||||
|
||||
var ret = await m_ProductOrderService.PageDesc(request.PageIndex, request.PageSize, expr, true, m => m.Id);
|
||||
var data = ret.ToApiResult();
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
[UserAuth]
|
||||
public async Task<ApiResult> CreateOrder(CreateOrderRequest request)
|
||||
{
|
||||
var userInfo = this.Request.GetUserInfo();
|
||||
var ret = await m_ProductOrderService.CreateOrder(request, userInfo.UserId);
|
||||
if (ret.Code != ResultCode.C_SUCCESS)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
return Success();
|
||||
}
|
||||
|
||||
[UserAuth]
|
||||
public async Task<ApiResult> Refund(string account)
|
||||
{
|
||||
var userInfo = this.Request.GetUserInfo();
|
||||
return await m_ProductOrderService.Refund(userInfo.UserId, account);
|
||||
}
|
||||
|
||||
[UserAuth]
|
||||
public async Task<ApiResult> CaclRefund(string account)
|
||||
{
|
||||
var userInfo = this.Request.GetUserInfo();
|
||||
return await m_ProductOrderService.CaclRefund(userInfo.UserId, account);
|
||||
}
|
||||
|
||||
|
||||
///// <summary>
|
||||
///// 支付(微信公众号、小程序支付,创建流水记录。)
|
||||
///// </summary>
|
||||
///// <param name="param"></param>
|
||||
///// <returns></returns>
|
||||
//[HttpPost, UserAuth]
|
||||
//public async Task<ApiResult> CreatePayOrder([FromBody] CreateOrderRequest request)
|
||||
//{
|
||||
|
||||
// var userInfo = this.Request.GetUserInfo();
|
||||
// var ret = await m_ProductOrderService.CreateOrder(request, userInfo.UserId);
|
||||
// if (ret.Code != ResultCode.C_SUCCESS)
|
||||
// {
|
||||
// return ret;
|
||||
// }
|
||||
// var req = new PayRequest()
|
||||
// {
|
||||
// OrderNO = ret.Data.OrderNo,
|
||||
// PayEnvironment = request.PayEnvironment,
|
||||
// PaymentType = request.PaymentType
|
||||
// };
|
||||
|
||||
// return await CreatePaymentOrder(req, ret.Data, userInfo);
|
||||
//}
|
||||
|
||||
//[UserAuth]
|
||||
//public async Task<ApiResult> Pay(PayRequest request)
|
||||
//{
|
||||
// var order = await m_CourseOrderService.GetByOrderNo(request.OrderNO);
|
||||
// var userInfo = this.Request.GetUserInfo();
|
||||
// return await CreatePaymentOrder(request, order, userInfo);
|
||||
//}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 支付部分
|
||||
/// </summary>
|
||||
/// <param name="param"></param>
|
||||
/// <param name="UserInfo"></param>
|
||||
/// <param name="OpenId"></param>
|
||||
/// <returns></returns>
|
||||
//private async Task<ApiResult> CreatePaymentOrder(PayRequest request, ProductOrderEntity orderData, AppUserInfo UserInfo)
|
||||
//{
|
||||
// string callBackUrl = $"{m_Configuration["Service_BaseUrl"]}/api/courseOrder/v1/WxOrderCallBack?orderId={orderData.OrderNo}&payType={(int)request.PaymentType}";
|
||||
// string attach = orderData.ToJson();
|
||||
// decimal payAmount = orderData.OrderAmount * 100.0M;
|
||||
// string orderDesc = "购买课程支付";
|
||||
// var resp = new CreatePaymentOrderResponse<CourseOrderEntity>()
|
||||
// {
|
||||
// OrderInfo = orderData
|
||||
// };
|
||||
// var weChatPayRequest = new WechatJsPayCreateOrderRequest()
|
||||
// {
|
||||
// Attach = attach,
|
||||
// Body = orderDesc,
|
||||
// CallbackUrl = callBackUrl + "&paymentType=" + (int)Payment.Enum.PaymentType.OnlinePayWechart,
|
||||
// OrderId = orderData.OrderNo,
|
||||
// OrderType = orderData.OrderType,
|
||||
// TenantId = orderData.TenantId,
|
||||
// PayEnvironment = request.PayEnvironment,
|
||||
// PaymentType = request.PaymentType,
|
||||
// TotalFee = Convert.ToInt32(payAmount),
|
||||
// UserOpenId = UserInfo.OpenId,
|
||||
// AppId = UserInfo.AppId,
|
||||
// StoreId = UserInfo.StoreId
|
||||
// };
|
||||
|
||||
// var wechatJsPayResp = await m_ServiceHttpClient.WechatJsPayCreateOrder(weChatPayRequest);
|
||||
// if (wechatJsPayResp.Code == ResultCode.C_SUCCESS)
|
||||
// {
|
||||
// try
|
||||
// {
|
||||
// //{"tradeNO":"2019102522001433001406080254","status":"0"}
|
||||
// var payOrderInfo = wechatJsPayResp.Data.ToString().FromJsonToOrDefault<WxPayOrderInfo>();
|
||||
|
||||
// if (payOrderInfo != null && payOrderInfo.package.Has())
|
||||
// {
|
||||
// string[] tmp2param = payOrderInfo.package.Split('=');
|
||||
// if (tmp2param != null && tmp2param.Length == 2)
|
||||
// {
|
||||
// orderData.TradeNo = tmp2param[1];
|
||||
// await m_CourseOrderService.Update(orderData);
|
||||
// }
|
||||
// }
|
||||
// resp.PayInfo = wechatJsPayResp.Data.ToString();
|
||||
// return Success(resp);
|
||||
// }
|
||||
// catch (Exception ex)
|
||||
// {
|
||||
// LogHelper.Error("课程支付获取微信支付订单信息转换出错:" + ex.Message, ex);
|
||||
// return new ApiResult(ResultCode.C_UNKNOWN_ERROR, "交易失败");
|
||||
// }
|
||||
// }
|
||||
// return new ApiResult(ResultCode.C_UNKNOWN_ERROR, wechatJsPayResp.Message);
|
||||
//}
|
||||
|
||||
//[InternalApiAuth]
|
||||
//public async Task<string> WxOrderCallBack([FromQuery]string orderId = "", [FromQuery] int paymentType = 0)
|
||||
//{
|
||||
// if (string.IsNullOrWhiteSpace(orderId) || paymentType <= 0)
|
||||
// {
|
||||
// return "faild";
|
||||
// }
|
||||
// var order = await m_CourseOrderService.GetByOrderNo(orderId);
|
||||
// if (order == null)
|
||||
// return "faild";
|
||||
|
||||
// order.OrderState = OrderStatus.PayOk;
|
||||
// order.PayType = paymentType;
|
||||
// await m_CourseOrderService.Update(order);
|
||||
// return "faild";
|
||||
//}
|
||||
|
||||
[HttpGet]
|
||||
public async Task<IActionResult> Export([FromQuery]OrderQueryRequest request)
|
||||
{
|
||||
Expression<Func<ProductOrderEntity, bool>> expr = m => (m.OrderState == OrderStatus.PayOk || m.OrderState == OrderStatus.Complete) && m.OrderType != OrderType.Refund;
|
||||
if (request.KeyWord.Has())
|
||||
{
|
||||
expr = expr.And(m =>
|
||||
m.OrderName.Contains(request.KeyWord)
|
||||
|| m.OrderNo.Contains(request.KeyWord)
|
||||
|| m.UserName.Contains(request.KeyWord)
|
||||
|| m.PackageName.Contains(request.KeyWord));
|
||||
}
|
||||
if (request.OrderTypes != null && request.OrderTypes.Count > 0)
|
||||
{
|
||||
expr = expr.And(m => request.OrderTypes.Contains((int)m.OrderType));
|
||||
}
|
||||
if (request.BTime.HasValue && request.ETime.HasValue)
|
||||
{
|
||||
expr = expr.And(m => m.CreateTime >= request.BTime && m.CreateTime <= request.ETime);
|
||||
}
|
||||
var ret = await m_ProductOrderService.PageDesc(request.PageIndex, 10000, expr, true,m=>m.Id);
|
||||
|
||||
|
||||
var data = new ExcelData<ProductOrderEntity>
|
||||
{
|
||||
SheetName = DateTime.Now.ToString("yyyy-MM-dd"),
|
||||
Data = ret.List
|
||||
};
|
||||
|
||||
var title = new List<ExcelTitle>(){
|
||||
new ExcelTitle { Property = "CreateTime", Title = "创建日期" , Format=(val)=>((DateTime) val).ToString("yyyy-MM-dd hh:mm:ss") },
|
||||
new ExcelTitle { Property = "OrderNo", Title = "订单号" },
|
||||
new ExcelTitle { Property = "OrderType", Title = "类型", Format=(val)=>((OrderType)val).GetEnumDisplayName() },
|
||||
new ExcelTitle { Property = "UserName", Title = "用户" },
|
||||
new ExcelTitle { Property = "ProductName", Title = "产品" },
|
||||
new ExcelTitle { Property = "PackageName", Title = "套餐" },
|
||||
new ExcelTitle { Property = "DayPrice", Title = "单价" },
|
||||
new ExcelTitle { Property = "ConnectCount", Title = "连接数",Expr=(p)=>((ProductOrderEntity)p).ConnectCount*((ProductOrderEntity)p).AccountCount},
|
||||
new ExcelTitle { Property = "Accounts", Title = "账号" },
|
||||
new ExcelTitle { Property = "OrderAmount", Title = "订单金额" },
|
||||
new ExcelTitle { Property = "CouponAmount", Title = "优惠金额" },
|
||||
new ExcelTitle { Property = "AccountPayAmount", Title = "余额支付" },
|
||||
new ExcelTitle { Property = "OtherPayAmount", Title = "在线支付" },
|
||||
new ExcelTitle { Property = "PaymentAmount", Title = "实付" },
|
||||
new ExcelTitle { Property = "PayType", Title = "付款方式" , Format=(val)=>((PayType)val).GetEnumDisplayName() },
|
||||
new ExcelTitle { Property = "TradeNo", Title = "支付流水号" },
|
||||
};
|
||||
var fileBytes = ExcelHelper.ExportListToExcel(data, title);
|
||||
|
||||
var fileName = $"{DateTime.Now.ToString("yyyyMMdd")}订单明细.xlsx";
|
||||
Response.Headers.Add("X-Suggested-Filename", fileName.UrlEncode());
|
||||
return File(fileBytes, "application/octet-stream", fileName);
|
||||
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public async Task<IActionResult> ExportRefundOrders([FromQuery]OrderQueryRequest request)
|
||||
{
|
||||
Expression<Func<ProductOrderEntity, bool>> expr = m => m.OrderType == OrderType.Refund;
|
||||
if (request.KeyWord.Has())
|
||||
{
|
||||
expr = expr.And(m =>
|
||||
m.OrderName.Contains(request.KeyWord)
|
||||
|| m.OrderNo.Contains(request.KeyWord)
|
||||
|| m.UserName.Contains(request.KeyWord)
|
||||
|| m.PackageName.Contains(request.KeyWord));
|
||||
}
|
||||
if (request.OrderTypes != null && request.OrderTypes.Count > 0)
|
||||
{
|
||||
expr = expr.And(m => request.OrderTypes.Contains((int)m.OrderType));
|
||||
}
|
||||
if (request.BTime.HasValue && request.ETime.HasValue)
|
||||
{
|
||||
expr = expr.And(m => m.CreateTime >= request.BTime && m.CreateTime <= request.ETime);
|
||||
}
|
||||
var ret = await m_ProductOrderService.Page(request.PageIndex, 10000, expr, true);
|
||||
|
||||
|
||||
var data = new ExcelData<ProductOrderEntity>
|
||||
{
|
||||
SheetName = DateTime.Now.ToString("yyyy-MM-dd"),
|
||||
Data = ret.List
|
||||
};
|
||||
|
||||
|
||||
Func<ProductOrderEntity, object> refundTypeFormat = (order) =>
|
||||
{
|
||||
switch (order.OrderState)
|
||||
{
|
||||
case OrderStatus.RequestRefund:
|
||||
return "未自动退款";
|
||||
case OrderStatus.UserRefundOver:
|
||||
return "已人工处理";
|
||||
case OrderStatus.AutoRefundOver:
|
||||
return "已自动退款";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
};
|
||||
|
||||
var title = new List<ExcelTitle>(){
|
||||
new ExcelTitle { Property = "CreateTime", Title = "创建日期" ,Format=(val)=>((DateTime) val).ToString("yyyy-MM-dd hh:mm:ss") },
|
||||
//new ExcelTitle { Property = "OrderNo", Title = "订单号" },
|
||||
// new ExcelTitle { Property = "OrderType", Title = "类型", Format=(val)=>((OrderType)val).GetEnumDisplayName() },
|
||||
// new ExcelTitle { Property = "UserName", Title = "用户" },
|
||||
new ExcelTitle { Property = "ProductName", Title = "产品" },
|
||||
new ExcelTitle { Property = "PackageName", Title = "套餐" },
|
||||
new ExcelTitle { Property = "ConnectCount", Title = "连接数",Expr=(p)=>((ProductOrderEntity)p).ConnectCount*((ProductOrderEntity)p).AccountCount},
|
||||
new ExcelTitle { Property = "Accounts", Title = "账号" },
|
||||
new ExcelTitle { Property = "PaymentAmount", Title = "实付金额" },
|
||||
new ExcelTitle { Property = "RefundAmount", Title = "退款金额" },
|
||||
new ExcelTitle { Property = "RefundRestTime", Title = "剩余时间" },
|
||||
new ExcelTitle { Property = "RefundRestTime", Title = "自动退款",Expr=(p)=>((ProductOrderEntity)p).IsAutoRefund.HasValue&&((ProductOrderEntity)p).IsAutoRefund==1?"是":"否" },
|
||||
new ExcelTitle { Property = "RefundRestTime", Title = "退款状态",Expr=(p)=>refundTypeFormat((ProductOrderEntity)p) },
|
||||
|
||||
};
|
||||
var fileBytes = ExcelHelper.ExportListToExcel(data, title);
|
||||
|
||||
var fileName = $"{DateTime.Now.ToString("yyyyMMdd")}退款明细.xlsx";
|
||||
Response.Headers.Add("X-Suggested-Filename", fileName.UrlEncode());
|
||||
return File(fileBytes, "application/octet-stream", fileName);
|
||||
|
||||
}
|
||||
|
||||
|
||||
[HttpGet,AllowAnonymous]
|
||||
public async Task<IActionResult> OpenExportRefundOrders([FromQuery]OrderQueryRequest request)
|
||||
{
|
||||
Expression<Func<ProductOrderEntity, bool>> expr = m => m.OrderType == OrderType.Refund;
|
||||
if (request.KeyWord.Has())
|
||||
{
|
||||
expr = expr.And(m =>
|
||||
m.OrderName.Contains(request.KeyWord)
|
||||
|| m.OrderNo.Contains(request.KeyWord)
|
||||
|| m.UserName.Contains(request.KeyWord)
|
||||
|| m.PackageName.Contains(request.KeyWord));
|
||||
}
|
||||
if (request.OrderTypes != null && request.OrderTypes.Count > 0)
|
||||
{
|
||||
expr = expr.And(m => request.OrderTypes.Contains((int)m.OrderType));
|
||||
}
|
||||
if (request.BTime.HasValue && request.ETime.HasValue)
|
||||
{
|
||||
expr = expr.And(m => m.CreateTime >= request.BTime && m.CreateTime <= request.ETime);
|
||||
}
|
||||
var ret = await m_ProductOrderService.Page(request.PageIndex, 10000, expr, true);
|
||||
|
||||
|
||||
var data = new ExcelData<ProductOrderEntity>
|
||||
{
|
||||
SheetName = DateTime.Now.ToString("yyyy-MM-dd"),
|
||||
Data = ret.List
|
||||
};
|
||||
|
||||
|
||||
Func<ProductOrderEntity, object> refundTypeFormat = (order) =>
|
||||
{
|
||||
switch (order.OrderState)
|
||||
{
|
||||
case OrderStatus.RequestRefund:
|
||||
return "未自动退款";
|
||||
case OrderStatus.UserRefundOver:
|
||||
return "已人工处理";
|
||||
case OrderStatus.AutoRefundOver:
|
||||
return "已自动退款";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
};
|
||||
|
||||
var title = new List<ExcelTitle>(){
|
||||
new ExcelTitle { Property = "CreateTime", Title = "创建日期" ,Format=(val)=>((DateTime) val).ToString("yyyy-MM-dd hh:mm:ss") },
|
||||
//new ExcelTitle { Property = "OrderNo", Title = "订单号" },
|
||||
//new ExcelTitle { Property = "OrderType", Title = "类型", Format=(val)=>((OrderType)val).GetEnumDisplayName() },
|
||||
//new ExcelTitle { Property = "UserName", Title = "用户" },
|
||||
new ExcelTitle { Property = "ProductName", Title = "产品" },
|
||||
new ExcelTitle { Property = "PackageName", Title = "套餐" },
|
||||
new ExcelTitle { Property = "ConnectCount", Title = "连接数",Expr=(p)=>((ProductOrderEntity)p).ConnectCount*((ProductOrderEntity)p).AccountCount},
|
||||
new ExcelTitle { Property = "Accounts", Title = "账号" },
|
||||
new ExcelTitle { Property = "RefundRestTime", Title = "剩余时间" }
|
||||
};
|
||||
var fileBytes = ExcelHelper.ExportListToExcel(data, title);
|
||||
|
||||
var fileName = $"{DateTime.Now.ToString("yyyyMMdd")}退款明细.xlsx";
|
||||
Response.Headers.Add("X-Suggested-Filename", fileName.UrlEncode());
|
||||
return File(fileBytes, "application/octet-stream", fileName);
|
||||
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public async Task<ApiResult> RefundProcess([FromBody]RefundProcessRequest request)
|
||||
{
|
||||
var entity=await m_ProductOrderService.GetById(request.Id);
|
||||
if (entity.OrderState != OrderStatus.RequestRefund)
|
||||
{
|
||||
return Error("无需处理");
|
||||
}
|
||||
entity.Remark += request.Remark;
|
||||
entity.OrderState = OrderStatus.UserRefundOver;
|
||||
await m_ProductOrderService.Update(entity);
|
||||
return Success();
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public async Task<ApiResult> CouponOrders([FromQuery] CouponOrderQueryRequest request)
|
||||
{
|
||||
var data = await this.m_ProductOrderService
|
||||
.Query(m => m.CouponId == request.CouponId
|
||||
&& m.OrderState == OrderStatus.Complete)
|
||||
.ListPagerAsync(request.PageSize, request.PageIndex, true);
|
||||
return data.ToApiResult();
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public async Task<ApiResult> TakeOrder([FromQuery]string phone, [FromQuery] decimal amount)
|
||||
{
|
||||
var manager = this.Request.GetManageUserInfo();
|
||||
|
||||
var datas = await this.m_ProductOrderService
|
||||
.Query(m => m.UserName == phone
|
||||
&& m.OrderState == OrderStatus.Complete
|
||||
&& m.OrderAmount == amount
|
||||
&& string.IsNullOrEmpty(m.Channel))
|
||||
.OrderByDescending(m => m.Id)
|
||||
.ToListAsync();
|
||||
var data = datas.Where(m => (DateTime.Now - m.UpdateTime).TotalMinutes < 30).FirstOrDefault();
|
||||
if (data != null)
|
||||
{
|
||||
data.Channel = manager.LoginName;
|
||||
await m_ProductOrderService.Update(data);
|
||||
return Success();
|
||||
}
|
||||
return Error("没有订单");
|
||||
}
|
||||
|
||||
|
||||
[HttpGet]
|
||||
public async Task<ApiResult> SellerOrders([FromQuery]OrderQueryRequest request)
|
||||
{
|
||||
var manager = this.Request.GetManageUserInfo();
|
||||
|
||||
var managerEntity = await m_ManageService.GetById(manager.OperaterId);
|
||||
Expression<Func<ProductOrderEntity, bool>> expr = m => !string.IsNullOrEmpty(m.Channel);
|
||||
if (managerEntity != null && managerEntity.IsRoot == 0)
|
||||
{
|
||||
expr = m => m.Channel == manager.LoginName;
|
||||
}
|
||||
|
||||
if (request.KeyWord.Has())
|
||||
{
|
||||
expr = expr.And(m => m.Accounts.Contains(request.KeyWord)|| m.OrderNo.Contains(request.KeyWord)|| m.UserName.Contains(request.KeyWord));
|
||||
}
|
||||
if (request.ProductId.HasValue)
|
||||
{
|
||||
expr = expr.And(m => m.ProductId == request.ProductId);
|
||||
}
|
||||
if (request.OrderTypes != null && request.OrderTypes.Count > 0)
|
||||
{
|
||||
expr = expr.And(m => request.OrderTypes.Contains((int)m.OrderType));
|
||||
}
|
||||
if (request.BTime.HasValue && request.ETime.HasValue)
|
||||
{
|
||||
expr = expr.And(m => m.CreateTime >= request.BTime && m.CreateTime <= request.ETime);
|
||||
}
|
||||
|
||||
var ret = await this.m_ProductOrderService.PageDesc(request.PageIndex, request.PageSize, expr, true, m => m.Id);
|
||||
|
||||
return ret.ToApiResult();
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public async Task<IActionResult> ExportSellerOrders([FromQuery]OrderQueryRequest request)
|
||||
{
|
||||
var manager = this.Request.GetManageUserInfo();
|
||||
|
||||
var managerEntity = await m_ManageService.GetById(manager.OperaterId);
|
||||
Expression<Func<ProductOrderEntity, bool>> expr = m => !string.IsNullOrEmpty(m.Channel);
|
||||
if (managerEntity != null && managerEntity.IsRoot == 0)
|
||||
{
|
||||
expr = m => m.Channel == manager.LoginName;
|
||||
}
|
||||
|
||||
if (request.KeyWord.Has())
|
||||
{
|
||||
expr = expr.And(m => m.Accounts.Contains(request.KeyWord) || m.OrderNo.Contains(request.KeyWord) || m.UserName.Contains(request.KeyWord));
|
||||
}
|
||||
if (request.ProductId.HasValue)
|
||||
{
|
||||
expr = expr.And(m => m.ProductId == request.ProductId);
|
||||
}
|
||||
if (request.OrderTypes != null && request.OrderTypes.Count > 0)
|
||||
{
|
||||
expr = expr.And(m => request.OrderTypes.Contains((int)m.OrderType));
|
||||
}
|
||||
if (request.BTime.HasValue && request.ETime.HasValue)
|
||||
{
|
||||
expr = expr.And(m => m.CreateTime >= request.BTime && m.CreateTime <= request.ETime);
|
||||
}
|
||||
|
||||
var ret = await this.m_ProductOrderService.PageDesc(request.PageIndex,10000, expr, true, m => m.Id);
|
||||
|
||||
var data = new ExcelData<ProductOrderEntity>
|
||||
{
|
||||
SheetName = DateTime.Now.ToString("yyyy-MM-dd"),
|
||||
Data = ret.List
|
||||
};
|
||||
|
||||
|
||||
Func<ProductOrderEntity, object> refundTypeFormat = (order) =>
|
||||
{
|
||||
switch (order.OrderState)
|
||||
{
|
||||
case OrderStatus.RequestRefund:
|
||||
return "未自动退款";
|
||||
case OrderStatus.UserRefundOver:
|
||||
return "已人工处理";
|
||||
case OrderStatus.AutoRefundOver:
|
||||
return "已自动退款";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
};
|
||||
|
||||
var title = new List<ExcelTitle>(){
|
||||
new ExcelTitle { Property = "CreateTime", Title = "创建日期" ,Format=(val)=>((DateTime) val).ToString("yyyy-MM-dd hh:mm:ss") },
|
||||
new ExcelTitle { Property = "OrderNo", Title = "订单号" },
|
||||
new ExcelTitle { Property = "OrderType", Title = "类型", Format=(val)=>((OrderType)val).GetEnumDisplayName() },
|
||||
new ExcelTitle { Property = "UserName", Title = "用户" },
|
||||
new ExcelTitle { Property = "ProductName", Title = "产品" },
|
||||
new ExcelTitle { Property = "PackageName", Title = "套餐" },
|
||||
new ExcelTitle { Property = "ConnectCount", Title = "连接数",Expr=(p)=>((ProductOrderEntity)p).ConnectCount*((ProductOrderEntity)p).AccountCount},
|
||||
new ExcelTitle { Property = "DayPrice", Title = "单价" },
|
||||
new ExcelTitle { Property = "Accounts", Title = "账号" },
|
||||
new ExcelTitle { Property = "OrderAmount", Title = "订单金额" },
|
||||
new ExcelTitle { Property = "CouponAmount", Title = "优惠金额" },
|
||||
new ExcelTitle { Property = "AccountPayAmount", Title = "余额支付" },
|
||||
new ExcelTitle { Property = "OtherPayAmount", Title = "在线支付" },
|
||||
new ExcelTitle { Property = "PaymentAmount", Title = "实付" },
|
||||
new ExcelTitle { Property = "PayType", Title = "付款方式", Format=(val)=>((PayType)val).GetEnumDisplayName() },
|
||||
new ExcelTitle { Property = "PaymentAmount", Title = "支付流水号" },
|
||||
new ExcelTitle { Property = "Channel", Title = "销售人" },
|
||||
|
||||
};
|
||||
var fileBytes = ExcelHelper.ExportListToExcel(data, title);
|
||||
|
||||
var fileName = $"{DateTime.Now.ToString("yyyyMMdd")}销售明细.xlsx";
|
||||
Response.Headers.Add("X-Suggested-Filename", fileName.UrlEncode());
|
||||
return File(fileBytes, "application/octet-stream", fileName);
|
||||
}
|
||||
|
||||
public async Task<ApiResult> UserCountStatistics(DateTime? bTime, DateTime? eTime)
|
||||
{
|
||||
|
||||
var manager = this.Request.GetManageUserInfo();
|
||||
|
||||
var managerInfo = await m_ManageService.GetById(manager.OperaterId);
|
||||
|
||||
var countInfo = m_ProductOrderService.UserCountStatistics(bTime, eTime);
|
||||
|
||||
var totalCountInfo = m_ProductOrderService.UserCountStatistics(null, null);
|
||||
|
||||
var amountInfo = m_ProductOrderService.SellAmountStatistics(bTime, eTime);
|
||||
|
||||
var query = from count in totalCountInfo
|
||||
join amount in amountInfo on count.RealName equals amount.RealName
|
||||
join newCount in countInfo on count.RealName equals newCount.RealName
|
||||
select new ManagerSellStatisticModel { RealName = count.RealName, Amount = amount.Amount, UserCount = count.UserCount, NewUserCount = newCount.UserCount };
|
||||
|
||||
|
||||
if (managerInfo.IsRoot != 1)
|
||||
{
|
||||
query = query.Where(m => m.RealName == managerInfo.RealName);
|
||||
}
|
||||
|
||||
var totalOrderAmount = m_ProductOrderService.Query(true).Where(m => m.OrderState == OrderStatus.PayOk || m.OrderState == OrderStatus.Complete).Sum(m => m.OrderAmount);
|
||||
|
||||
var totalUser = m_BaseUserService.Query(true).Count();
|
||||
|
||||
var ret = new
|
||||
{
|
||||
OrderAmount = totalOrderAmount,
|
||||
UserTotal = totalUser,
|
||||
List = query.ToList()
|
||||
};
|
||||
|
||||
return Success(ret);
|
||||
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public async Task<IActionResult> ExportUserConsumeStatistics([FromQuery]UserConsumeRequest request)
|
||||
{
|
||||
|
||||
var loginInfo = this.Request.GetManageUserInfo();
|
||||
int id = loginInfo.OperaterId;
|
||||
var managerInfo = await m_ManageService.GetById(loginInfo.OperaterId);
|
||||
if (managerInfo.IsRoot == 1) id = 0;
|
||||
var ret = m_ProductOrderService.ExportUserConsumeStatisticsData(request.KeyWord, request.bTime1, request.eTime1, request.bTime2, request.eTime2, id, request.SortLable, request.SortOrder, request.Profile);
|
||||
|
||||
|
||||
var data = new ExcelData<UserConsumeStatisticsModel>
|
||||
{
|
||||
SheetName = DateTime.Now.ToString("yyyy-MM-dd"),
|
||||
Data = ret
|
||||
};
|
||||
|
||||
var title = new List<ExcelTitle>(){
|
||||
new ExcelTitle { Property = "Profile", Title = "状态" , Expr=(p)=>((UserConsumeStatisticsModel)p).UserInfo.Profile},
|
||||
new ExcelTitle { Property = "UserName", Title = "用户" },
|
||||
new ExcelTitle { Property = "CreateTime", Title = "注册时间", Format=(val)=>((DateTime)val).ToString("yyyy-MM-dd") },
|
||||
new ExcelTitle { Property = "PrevMonthAmount", Title = "消费金额A" },
|
||||
new ExcelTitle { Property = "MonthAmount", Title = "消费金额B" },
|
||||
new ExcelTitle { Property = "AddAmount", Title = "对比增长金额" },
|
||||
new ExcelTitle { Property = "TotalAccountCount", Title = "账户总数" },
|
||||
new ExcelTitle { Property = "UsingAccountCount", Title = "过期个数" },
|
||||
new ExcelTitle { Property = "UserName", Title = "联系信息" , Expr=(p)=>{
|
||||
var user=((UserConsumeStatisticsModel)p).UserInfo;
|
||||
var subret=new List<string>();
|
||||
if(user.Wx.Has()) subret.Add($"微信:{user.Wx}");
|
||||
if(user.QQ.Has()) subret.Add($"QQ:{user.QQ}");
|
||||
if(user.Wx.Has()) subret.Add($"淘宝:{user.TaoBao}");
|
||||
if(user.Wx.Has()) subret.Add($"旺旺:{user.WangWang}");
|
||||
return string.Join(",",subret);
|
||||
} }
|
||||
};
|
||||
var fileBytes = ExcelHelper.ExportListToExcel(data, title);
|
||||
|
||||
var fileName = $"{DateTime.Now.ToString("yyyyMMdd")}消费统计.xlsx";
|
||||
Response.Headers.Add("X-Suggested-Filename", fileName.UrlEncode());
|
||||
return File(fileBytes, "application/octet-stream", fileName);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
149
Services/Hncore.Pass.Vpn/Controllers/ProductRouteController.cs
Normal file
149
Services/Hncore.Pass.Vpn/Controllers/ProductRouteController.cs
Normal file
@@ -0,0 +1,149 @@
|
||||
using Hncore.Infrastructure.Common;
|
||||
using Hncore.Infrastructure.EntitiesExtension;
|
||||
using Hncore.Infrastructure.Extension;
|
||||
using Hncore.Infrastructure.WebApi;
|
||||
using Hncore.Pass.Vpn.Domain;
|
||||
using Hncore.Pass.Vpn.Request.Product;
|
||||
using Hncore.Pass.Vpn.Service;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Hncore.Pass.Vpn.Controllers
|
||||
{
|
||||
[ApiVersion("1.0")]
|
||||
[Route("api/course/v{version:apiVersion}/productroute/[action]")]
|
||||
public class ProductRouteController : HncoreControllerBase
|
||||
{
|
||||
private ProductRouteService m_ProductRouteService;
|
||||
|
||||
private ProductService m_ProductService;
|
||||
|
||||
public ProductRouteController(ProductRouteService _ProductRouteService, ProductService _ProductService)
|
||||
{
|
||||
m_ProductRouteService = _ProductRouteService;
|
||||
m_ProductService = _ProductService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<ApiResult> Post([FromBody]ProductRouteEntity request)
|
||||
{
|
||||
var product = await m_ProductService.GetById(request.ProductId);
|
||||
request.ProductName = product?.Name;
|
||||
await m_ProductRouteService.Add(request);
|
||||
return Success();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 修改
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<ApiResult> Put([FromBody]ProductRouteEntity request)
|
||||
{
|
||||
var product = await m_ProductService.GetById(request.ProductId);
|
||||
request.ProductName = product?.Name;
|
||||
await m_ProductRouteService.Update(request);
|
||||
return Success();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<ApiResult> Delete([FromQuery]int id)
|
||||
{
|
||||
var flag = await m_ProductRouteService.DeleteById(id);
|
||||
if (flag)
|
||||
return Success();
|
||||
else
|
||||
return Error("删除失败");
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 详情
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet]
|
||||
public async Task<ApiResult> Get([FromQuery]int id)
|
||||
{
|
||||
var data = await m_ProductRouteService.GetById(id);
|
||||
return Success(data);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 分页查询
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet]
|
||||
public async Task<ApiResult> Page([FromQuery]RoutePageRequest request)
|
||||
{
|
||||
Expression<Func<ProductRouteEntity, bool>> expr = m => 1 == 1;
|
||||
if (request.KeyWord.Has())
|
||||
{
|
||||
expr = expr.And(m => m.Province.Contains(request.KeyWord) || m.Name.Contains(request.KeyWord) || m.City.Contains(request.KeyWord) || m.ServerUrl.Contains(request.KeyWord));
|
||||
}
|
||||
if (request.ProductId.HasValue&& request.ProductId>0)
|
||||
{
|
||||
expr = expr.And(m => m.ProductId==request.ProductId);
|
||||
}
|
||||
var ret = await m_ProductRouteService.PageAsc(request.PageIndex, request.PageSize, expr, true,m=>m.Sort);
|
||||
var data = ret.ToApiResult();
|
||||
return data;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 导入
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost, AllowAnonymous]
|
||||
public async Task<ApiResult> Import(IFormFile file)
|
||||
{
|
||||
// var file = this.Request.Form.Files.First();
|
||||
var stream = file.OpenReadStream();// this.Request.Body;
|
||||
//stream.Position = 0;
|
||||
var data = ExcelHelper.ReadFromStream(stream);
|
||||
|
||||
var products = await m_ProductService.GetAll();
|
||||
|
||||
var list = new List<ProductRouteEntity>();
|
||||
|
||||
var dataRows = data.Skip(1);
|
||||
foreach (var row in dataRows)
|
||||
{
|
||||
var model = new ProductRouteEntity();
|
||||
model.ProductName = row[0];
|
||||
model.Province = row[1];
|
||||
model.Name = row[2];
|
||||
model.ServerUrl = row[3];
|
||||
model.Status = row[4];
|
||||
model.LineType = row[5];
|
||||
model.BandWidth = row[6];
|
||||
model.IpRemark = row[7];
|
||||
model.ProductId = products.FirstOrDefault(m => m.Name == model.ProductName)?.Id;
|
||||
}
|
||||
if (list.Count > 1)
|
||||
{
|
||||
await m_ProductRouteService.Adds(list);
|
||||
}
|
||||
return Success();
|
||||
}
|
||||
}
|
||||
}
|
||||
188
Services/Hncore.Pass.Vpn/Controllers/ProductSchemeController.cs
Normal file
188
Services/Hncore.Pass.Vpn/Controllers/ProductSchemeController.cs
Normal file
@@ -0,0 +1,188 @@
|
||||
using Hncore.Infrastructure.EntitiesExtension;
|
||||
using Hncore.Infrastructure.Extension;
|
||||
using Hncore.Infrastructure.WebApi;
|
||||
using Hncore.Pass.Vpn.Domain;
|
||||
using Hncore.Pass.Vpn.Request.Product;
|
||||
using Hncore.Pass.Vpn.Service;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Hncore.Pass.Vpn.Controllers
|
||||
{
|
||||
[ApiVersion("1.0")]
|
||||
[Route("api/course/v{version:apiVersion}/scheme/[action]")]
|
||||
public class ProductSchemeController : HncoreControllerBase
|
||||
{
|
||||
private ProductService m_ProductService;
|
||||
private ProductPackageService m_ProductPackageService;
|
||||
private ProductUserPriceService m_ProductUserPriceService;
|
||||
private ProductPriceSchemeService m_PriceSchemeService;
|
||||
private ProductPriceDiscountService m_PriceDiscountService;
|
||||
public ProductSchemeController(ProductService _ProductServic
|
||||
, ProductPackageService _ProductPackageService
|
||||
, ProductUserPriceService _ProductUserPriceService
|
||||
,ProductPriceSchemeService _PriceSchemeService
|
||||
,ProductPriceDiscountService _PriceDiscountService
|
||||
)
|
||||
{
|
||||
m_ProductService = _ProductServic;
|
||||
m_ProductPackageService = _ProductPackageService;
|
||||
m_ProductUserPriceService = _ProductUserPriceService;
|
||||
m_PriceSchemeService = _PriceSchemeService;
|
||||
m_PriceDiscountService = _PriceDiscountService;
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<ApiResult> Post([FromBody]ProductPriceSchemeEntity request)
|
||||
{
|
||||
await m_PriceSchemeService.Add(request);
|
||||
return Success();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 修改
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<ApiResult> Put([FromBody]ProductPriceSchemeEntity request)
|
||||
{
|
||||
var entity = await m_PriceSchemeService.GetById(request.Id);
|
||||
entity.Name = request.Name;
|
||||
entity.Remark = request.Remark;
|
||||
entity.UpdateTime = DateTime.Now;
|
||||
await m_PriceSchemeService.Update(entity);
|
||||
return Success();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 删除
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<ApiResult> Delete([FromQuery]int id)
|
||||
{
|
||||
var flag = await m_PriceSchemeService.DeleteById(id);
|
||||
if (flag)
|
||||
return Success();
|
||||
else
|
||||
return Error("删除失败");
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 详情
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet]
|
||||
public async Task<ApiResult> Get([FromQuery]int id)
|
||||
{
|
||||
var data = await m_PriceSchemeService.GetById(id);
|
||||
return Success(data);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 分页查询
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet]
|
||||
public async Task<ApiResult> Page([FromQuery]PageRequestBase request)
|
||||
{
|
||||
Expression<Func<ProductPriceSchemeEntity, bool>> expr = m => 1 == 1;
|
||||
if (request.KeyWord.Has())
|
||||
{
|
||||
expr = expr.And(m => m.Name.Contains(request.KeyWord));
|
||||
}
|
||||
var ret = await m_PriceSchemeService.Page(request.PageIndex, request.PageSize, expr,true);
|
||||
var data = ret.ToApiResult();
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
[HttpGet]
|
||||
public async Task<ApiResult> GetProductDiscount(int id)
|
||||
{
|
||||
var ret = await this.m_PriceDiscountService.GetPriceDiscount(id);
|
||||
return Success(ret);
|
||||
}
|
||||
|
||||
|
||||
[HttpPost]
|
||||
public async Task<ApiResult> PutProductDiscount([FromBody]ProductPriceDiscountEntity request)
|
||||
{
|
||||
var priceDiscountEntity = await m_PriceDiscountService.Query(m => m.PackageId == request.PackageId && m.SchemeId == request.SchemeId).FirstOrDefaultAsync();
|
||||
|
||||
if (priceDiscountEntity == null)
|
||||
{
|
||||
await m_PriceDiscountService.Add(request);
|
||||
}
|
||||
else
|
||||
{
|
||||
priceDiscountEntity.BuyPriceDiscount = request.BuyPriceDiscount;
|
||||
priceDiscountEntity.RefundDayPriceDiscount = request.RefundDayPriceDiscount;
|
||||
await m_PriceDiscountService.Update(priceDiscountEntity);
|
||||
}
|
||||
return Success(1);
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public async Task<ApiResult> SetUserDiscount([FromBody] SetUserDiscountRequest request)
|
||||
{
|
||||
var priceDiscountEntitys = await m_PriceDiscountService.Query(m => m.SchemeId == request.SchemeId).ToListAsync();
|
||||
var schemaEntity = await m_PriceSchemeService.GetById(request.SchemeId);
|
||||
var produccts = await m_ProductService.GetAll(true);
|
||||
var packages = await m_ProductPackageService.GetAll(true);
|
||||
|
||||
var userPrices = await m_ProductUserPriceService.GetPackageUserPrice(request.UserId);
|
||||
foreach (var item in priceDiscountEntitys)
|
||||
{
|
||||
var product = produccts.FirstOrDefault(m => m.Id == item.ProductId);
|
||||
var package = packages.FirstOrDefault(m => m.Id == item.PackageId);
|
||||
var userPakcagePrices = userPrices.FirstOrDefault(m => m.Product.Id == item.ProductId)?.PackageUserPrices;
|
||||
var userPrice = userPakcagePrices?.FirstOrDefault(uPrice => uPrice.Package.Id == item.PackageId && uPrice.UserPrice.UserId == request.UserId)?.UserPrice;
|
||||
if (userPrice != null && userPrice.Id > 0)
|
||||
{
|
||||
userPrice.Status = 1;
|
||||
userPrice.UserPrice = item.BuyPriceDiscount / 100m * package.Price;
|
||||
userPrice.RefundDayPrice = item.RefundDayPriceDiscount / 100m * product.RefundDayPrice;
|
||||
userPrice.Remark = schemaEntity.Name;
|
||||
userPrice.UserPrice = Math.Max(userPrice.UserPrice, package.MinPrice);
|
||||
userPrice.RefundDayPrice = Math.Max(userPrice.RefundDayPrice.Value, product.DayLimitPrice.Value);
|
||||
await m_ProductUserPriceService.Update(userPrice);
|
||||
}
|
||||
else
|
||||
{
|
||||
userPrice = new ProductUserPriceEntity()
|
||||
{
|
||||
PackageId = item.PackageId,
|
||||
ProductId = item.ProductId,
|
||||
Status = 1,
|
||||
Remark = schemaEntity.Name,
|
||||
TenantId = 0,
|
||||
UserId = request.UserId,
|
||||
UserPrice = item.BuyPriceDiscount / 100m * package.Price,
|
||||
RefundDayPrice = item.RefundDayPriceDiscount / 100m * product.RefundDayPrice,
|
||||
};
|
||||
userPrice.UserPrice = Math.Max(userPrice.UserPrice, package.MinPrice);
|
||||
userPrice.RefundDayPrice = Math.Max(userPrice.RefundDayPrice.Value, product.DayLimitPrice.Value);
|
||||
await m_ProductUserPriceService.Add(userPrice);
|
||||
}
|
||||
}
|
||||
return Success(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
25
Services/Hncore.Pass.Vpn/Domain/Article.cs
Normal file
25
Services/Hncore.Pass.Vpn/Domain/Article.cs
Normal file
@@ -0,0 +1,25 @@
|
||||
using Hncore.Infrastructure.DDD;
|
||||
using System;
|
||||
|
||||
namespace Hncore.Pass.Vpn.Domain
|
||||
{
|
||||
public partial class ArticleEntity : EntityWithDelete<int>, ITenant
|
||||
{
|
||||
public int TenantId { get; set; }
|
||||
public string Title { get; set; }
|
||||
public ArticleCatalog CatalogId { get; set; } = ArticleCatalog.Top;
|
||||
public string SubTitle { get; set; }
|
||||
public string Thumb { get; set; }
|
||||
public string Keyword { get; set; }
|
||||
public string Content { get; set; }
|
||||
public int AccessCount { get; set; }
|
||||
public int Publish { get; set; }
|
||||
|
||||
public string Tag { get; set; }
|
||||
public DateTime CreateTime { get; set; } = DateTime.Now;
|
||||
public int LinkType { get; set; }
|
||||
public int LinkId { get; set; }
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
132
Services/Hncore.Pass.Vpn/Domain/CourseContext.cs
Normal file
132
Services/Hncore.Pass.Vpn/Domain/CourseContext.cs
Normal file
@@ -0,0 +1,132 @@
|
||||
using Hncore.Infrastructure.EF;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Hncore.Pass.Vpn.Domain
|
||||
{
|
||||
public partial class CourseContext : DbContextBase
|
||||
{
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="options">上下文实体</param>
|
||||
/// <param name="httpContextAccessor">http请求上下文</param>
|
||||
public CourseContext(DbContextOptions<CourseContext> options, IHttpContextAccessor httpContextAccessor) :
|
||||
base(options, httpContextAccessor)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||
{
|
||||
modelBuilder.Entity<ArticleEntity>(entity =>
|
||||
{
|
||||
entity.ToTable("article");
|
||||
|
||||
entity.HasKey(p => p.Id);
|
||||
entity.Property(e => e.Id).ValueGeneratedOnAdd();
|
||||
});
|
||||
|
||||
|
||||
modelBuilder.Entity<ProductEntity>(entity =>
|
||||
{
|
||||
entity.ToTable("product");
|
||||
|
||||
entity.HasKey(p => p.Id);
|
||||
entity.Property(e => e.Id).ValueGeneratedOnAdd();
|
||||
});
|
||||
|
||||
|
||||
modelBuilder.Entity<ProductAccountEntity>(entity =>
|
||||
{
|
||||
entity.ToTable("product_account");
|
||||
|
||||
entity.HasKey(p => p.Id);
|
||||
entity.Property(e => e.Id).ValueGeneratedOnAdd();
|
||||
entity.Ignore(e => e.RestTime);
|
||||
entity.Ignore(e => e.RestDay);
|
||||
});
|
||||
|
||||
|
||||
modelBuilder.Entity<UserEntity>(entity =>
|
||||
{
|
||||
entity.ToTable("user");
|
||||
|
||||
entity.HasKey(p => p.Id);
|
||||
entity.Property(e => e.Id).ValueGeneratedOnAdd();
|
||||
});
|
||||
|
||||
modelBuilder.Entity<ProductPackageEntity>(entity =>
|
||||
{
|
||||
entity.ToTable("product_package");
|
||||
|
||||
entity.HasKey(p => p.Id);
|
||||
entity.Property(e => e.Id).ValueGeneratedOnAdd();
|
||||
});
|
||||
|
||||
modelBuilder.Entity<ProductOrderEntity>(entity =>
|
||||
{
|
||||
entity.ToTable("product_order");
|
||||
|
||||
entity.HasKey(p => p.Id);
|
||||
entity.Property(e => e.Id).ValueGeneratedOnAdd();
|
||||
});
|
||||
modelBuilder.Entity<ProductOrderItemEntity>(entity =>
|
||||
{
|
||||
entity.ToTable("product_order_items");
|
||||
|
||||
entity.HasKey(p => p.Id);
|
||||
entity.Property(e => e.Id).ValueGeneratedOnAdd();
|
||||
});
|
||||
modelBuilder.Entity<ProductUserPriceEntity>(entity =>
|
||||
{
|
||||
entity.ToTable("product_user_price");
|
||||
|
||||
entity.HasKey(p => p.Id);
|
||||
entity.Property(e => e.Id).ValueGeneratedOnAdd();
|
||||
});
|
||||
modelBuilder.Entity<ProductPackageUnitEntity>(entity =>
|
||||
{
|
||||
entity.ToTable("product_package_unit");
|
||||
|
||||
entity.HasKey(p => p.Id);
|
||||
entity.Property(e => e.Id).ValueGeneratedOnAdd();
|
||||
});
|
||||
modelBuilder.Entity<ProductAccountChargeEntity>(entity =>
|
||||
{
|
||||
entity.ToTable("product_account_recharge");
|
||||
|
||||
entity.HasKey(p => p.Id);
|
||||
entity.Property(e => e.Id).ValueGeneratedOnAdd();
|
||||
});
|
||||
modelBuilder.Entity<ProductRouteEntity>(entity =>
|
||||
{
|
||||
entity.ToTable("product_route");
|
||||
|
||||
entity.HasKey(p => p.Id);
|
||||
entity.Property(e => e.Id).ValueGeneratedOnAdd();
|
||||
});
|
||||
modelBuilder.Entity<WxAppUserEntity>(entity =>
|
||||
{
|
||||
entity.ToTable("wx_app_user");
|
||||
|
||||
entity.HasKey(p => p.Id);
|
||||
entity.Property(e => e.Id).ValueGeneratedOnAdd();
|
||||
});
|
||||
modelBuilder.Entity<ProductPriceSchemeEntity>(entity =>
|
||||
{
|
||||
entity.ToTable("product_price_scheme");
|
||||
|
||||
entity.HasKey(p => p.Id);
|
||||
entity.Property(e => e.Id).ValueGeneratedOnAdd();
|
||||
});
|
||||
modelBuilder.Entity<ProductPriceDiscountEntity>(entity =>
|
||||
{
|
||||
entity.ToTable("product_price_discount");
|
||||
|
||||
entity.HasKey(p => p.Id);
|
||||
entity.Property(e => e.Id).ValueGeneratedOnAdd();
|
||||
});
|
||||
base.OnModelCreating(modelBuilder);
|
||||
}
|
||||
}
|
||||
}
|
||||
207
Services/Hncore.Pass.Vpn/Domain/Enums.cs
Normal file
207
Services/Hncore.Pass.Vpn/Domain/Enums.cs
Normal file
@@ -0,0 +1,207 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Hncore.Pass.Vpn.Domain
|
||||
{
|
||||
public enum AccountType
|
||||
{
|
||||
[DisplayName("新开")]
|
||||
New = 1,
|
||||
[DisplayName("批量新开")]
|
||||
News = 2,
|
||||
[DisplayName("续费")]
|
||||
AgainBuy = 3,
|
||||
[DisplayName("批量续费")]
|
||||
AgainBuys = 4,
|
||||
|
||||
[DisplayName("原系统认证")]
|
||||
Origin =100,
|
||||
|
||||
[DisplayName("测试账号")]
|
||||
Test = 200,
|
||||
}
|
||||
|
||||
public enum OrderType
|
||||
{
|
||||
[DisplayName("新开")]
|
||||
New = 1,
|
||||
[DisplayName("批量新开")]
|
||||
News = 2,
|
||||
[DisplayName("续费")]
|
||||
AgainBuy = 3,
|
||||
[DisplayName("批量续费")]
|
||||
AgainBuys = 4,
|
||||
[DisplayName("退款")]
|
||||
Refund = 5,
|
||||
}
|
||||
public enum ClientType
|
||||
{
|
||||
WxMp = 1,
|
||||
WxMiniApp = 2,
|
||||
Pc = 3,
|
||||
}
|
||||
|
||||
public enum PayType
|
||||
{
|
||||
/// <summary>
|
||||
/// 默认
|
||||
/// </summary>
|
||||
[Display(Name = "默认")]
|
||||
None = 10,
|
||||
/// <summary>
|
||||
/// 余额
|
||||
/// </summary>
|
||||
[Display(Name = "余额")]
|
||||
Amount = 10,
|
||||
|
||||
/// <summary>
|
||||
/// 微信
|
||||
/// </summary>
|
||||
[Display(Name = "微信")]
|
||||
Wechat = 70,
|
||||
/// <summary>
|
||||
/// 支付宝
|
||||
/// </summary>
|
||||
[Display(Name = "支付宝")]
|
||||
Ali = 100,
|
||||
}
|
||||
|
||||
public enum OrderStatus
|
||||
{
|
||||
[Display(Name = "默认")]
|
||||
None = 0,
|
||||
/// <summary>
|
||||
/// 待支付
|
||||
/// </summary>
|
||||
[Display(Name = "待付款")]
|
||||
NoPay = 10,
|
||||
/// <summary>
|
||||
/// 已支付
|
||||
/// </summary>
|
||||
[Display(Name = "已付款")]
|
||||
PayOk = 20,
|
||||
/// <summary>
|
||||
/// 申请退款
|
||||
/// </summary>
|
||||
[Display(Name = "申请退款")]
|
||||
RequestRefund = 30,
|
||||
/// <summary>
|
||||
/// 人工退款
|
||||
/// </summary>
|
||||
[Display(Name = "人工退款")]
|
||||
UserRefundOver = 40,
|
||||
/// <summary>
|
||||
/// 自送退款
|
||||
/// </summary>
|
||||
[Display(Name = "自动退款")]
|
||||
AutoRefundOver = 50,
|
||||
/// <summary>
|
||||
/// 订单超时关闭
|
||||
/// </summary>
|
||||
[Display(Name = "超时关闭")]
|
||||
TimeOutClose = 80,
|
||||
|
||||
/// <summary>
|
||||
/// 订单完成
|
||||
/// </summary>
|
||||
[Display(Name = "订单完成")]
|
||||
Complete = 90,
|
||||
|
||||
}
|
||||
|
||||
public enum PackageType
|
||||
{
|
||||
[DisplayName("基本套餐")]
|
||||
Base = 1,
|
||||
[DisplayName("组合套餐")]
|
||||
Group = 2
|
||||
}
|
||||
|
||||
public enum ChargeOperationType
|
||||
{
|
||||
[DisplayName("新开")]
|
||||
New = 1,
|
||||
[DisplayName("批量新开")]
|
||||
News = 2,
|
||||
[DisplayName("续费")]
|
||||
ReNew = 3,
|
||||
[DisplayName("退款")]
|
||||
Refund = 4,
|
||||
}
|
||||
|
||||
public enum ChargeStatus
|
||||
{
|
||||
[DisplayName("成功")]
|
||||
Ok = 1,
|
||||
[DisplayName("失败")]
|
||||
Faild = 2,
|
||||
[DisplayName("关闭")]
|
||||
Close = 3,
|
||||
[DisplayName("超时")]
|
||||
Outtime = 4,
|
||||
}
|
||||
|
||||
public enum AccountChargeStatus
|
||||
{
|
||||
[DisplayName("正常")]
|
||||
Normal = 1,
|
||||
[DisplayName("异常")]
|
||||
Exception = 2,
|
||||
}
|
||||
|
||||
public enum AccountStatus
|
||||
{
|
||||
[DisplayName("正常")]
|
||||
Normal = 1,
|
||||
[DisplayName("退款")]
|
||||
Refund = 2,
|
||||
}
|
||||
|
||||
public enum ArticleCatalog
|
||||
{
|
||||
|
||||
[DisplayName("聚IP头条")]
|
||||
Top = 1,
|
||||
[DisplayName("优惠活动")]
|
||||
Activity = 2,
|
||||
[DisplayName("常见问题")]
|
||||
QA = 3,
|
||||
[DisplayName("新手教程")]
|
||||
Help = 4,
|
||||
}
|
||||
|
||||
public enum PayChannel
|
||||
{
|
||||
/// <summary>
|
||||
/// 微信H5
|
||||
/// </summary>
|
||||
[Display(Name = "微信H5")]
|
||||
WxH5 = 10,
|
||||
/// <summary>
|
||||
/// 微信公众号
|
||||
/// </summary>
|
||||
[Display(Name = "微信公众号")]
|
||||
WxMp = 20,
|
||||
|
||||
/// <summary>
|
||||
/// 微信公众号
|
||||
/// </summary>
|
||||
[Display(Name = "微信Pc")]
|
||||
WxPc = 30,
|
||||
|
||||
/// <summary>
|
||||
/// 支付宝H5
|
||||
/// </summary>
|
||||
[Display(Name = "支付宝H5")]
|
||||
AliH5 = 40,
|
||||
/// <summary>
|
||||
/// 支付宝
|
||||
/// </summary>
|
||||
[Display(Name = "支付宝Pc")]
|
||||
AliPc = 50,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
using Hncore.Infrastructure.DDD;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Hncore.Pass.Vpn.Domain
|
||||
{
|
||||
public partial class ProductAccountChargeEntity : EntityWithTime<int>
|
||||
{
|
||||
public int OrderId { get; set; }
|
||||
public int? ProductId { get; set; }
|
||||
public string ProductGroup { get; set; }
|
||||
public int? PackageId { get; set; }
|
||||
public string PackageOriginKey { get; set; }
|
||||
public string Account { get; set; }
|
||||
public int AccountType { get; set; }
|
||||
public string Pwd { get; set; }
|
||||
public int ConnectCount { get; set; } = 0;
|
||||
public ChargeStatus Status { get; set; } = 0;
|
||||
public int DayCount { get; set; } = 1;
|
||||
public int TryTimes { get; set; } = 1;
|
||||
public ChargeOperationType OperationType { get; set; } = ChargeOperationType.New;
|
||||
}
|
||||
}
|
||||
53
Services/Hncore.Pass.Vpn/Domain/ProductAccountEntity.cs
Normal file
53
Services/Hncore.Pass.Vpn/Domain/ProductAccountEntity.cs
Normal file
@@ -0,0 +1,53 @@
|
||||
using Hncore.Infrastructure.DDD;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Hncore.Pass.Vpn.Domain
|
||||
{
|
||||
public partial class ProductAccountEntity : EntityWithTime<int>, ITenant
|
||||
{
|
||||
public int TenantId { get; set; }
|
||||
public int? UserId { get; set; }
|
||||
public int? ProductId { get; set; }
|
||||
public int? PackageId { get; set; }
|
||||
public string UserCode { get; set; }
|
||||
public string UserPhone { get; set; }
|
||||
public string ProductName { get; set; }
|
||||
public string PackageName { get; set; }
|
||||
public int? AccountType { get; set; }
|
||||
public string Account { get; set; }
|
||||
public string Pwd { get; set; }
|
||||
public int ConnectCount { get; set; } = 0;
|
||||
public AccountStatus Status { get; set; } = AccountStatus.Normal;
|
||||
public AccountChargeStatus? ChargeStatus { get; set; } = AccountChargeStatus.Normal;
|
||||
public DateTime? StartTime { get; set; }
|
||||
public DateTime? EndTime { get; set; }
|
||||
|
||||
public string Remark { get; set; }
|
||||
|
||||
public string RestTime
|
||||
{
|
||||
get
|
||||
{
|
||||
if (EndTime < DateTime.Now)
|
||||
return "已过期";
|
||||
var bTime = StartTime > DateTime.Now ? StartTime : DateTime.Now;
|
||||
var time = (EndTime - bTime).Value;
|
||||
return time.ToString(@"d\天hh\时mm\分");
|
||||
}
|
||||
}
|
||||
public int RestDay
|
||||
{
|
||||
get
|
||||
{
|
||||
if (EndTime < DateTime.Now)
|
||||
return 0;
|
||||
var bTime = StartTime > DateTime.Now ? StartTime : DateTime.Now;
|
||||
var time = (EndTime - bTime).Value;
|
||||
return time.Days;
|
||||
}
|
||||
}
|
||||
|
||||
public string Raw { get; set; }
|
||||
}
|
||||
}
|
||||
50
Services/Hncore.Pass.Vpn/Domain/ProductEntity.cs
Normal file
50
Services/Hncore.Pass.Vpn/Domain/ProductEntity.cs
Normal file
@@ -0,0 +1,50 @@
|
||||
using Hncore.Infrastructure.DDD;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Hncore.Pass.Vpn.Domain
|
||||
{
|
||||
public partial class ProductEntity : EntityWithDelete<int>, ITenant
|
||||
{
|
||||
public int TenantId { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string Image { get; set; }
|
||||
public int Sort { get; set; } = 0;
|
||||
public string Account { get; set; }
|
||||
public string Pwd { get; set; }
|
||||
public string BaseUrl { get; set; }
|
||||
public int? Status { get; set; } = 0;
|
||||
public string LoginUrl { get; set; }
|
||||
public string LoginCodeUrl { get; set; }
|
||||
public string RefrushTokenUrl { get; set; }
|
||||
public string PcClientDownloadUrl { get; set; }
|
||||
public string DroidDownloadUrl { get; set; }
|
||||
public string IosDownloadUrl { get; set; }
|
||||
public string SimulatorDownloadUrl { get; set; }
|
||||
public string Content { get; set; }
|
||||
public string Profile { get; set; }
|
||||
public string GroupNO { get; set; }
|
||||
public string Token { get; set; }
|
||||
|
||||
public int? AutoRefund { get; set; } = 0;
|
||||
|
||||
public decimal? RefundDayPrice { get; set; } = 0;
|
||||
public decimal? DayLimitPrice { get; set; } = 0;
|
||||
|
||||
public int OnLine { get; set; } = 1;
|
||||
|
||||
public string L2TPPwd { get; set; } = "";
|
||||
|
||||
public string SSTPPort { get; set; } = "";
|
||||
/// <summary>
|
||||
/// 记录添加(创建)时间
|
||||
/// </summary>
|
||||
public virtual DateTime CreateTime { get; set; } = DateTime.Now;
|
||||
|
||||
/// <summary>
|
||||
/// 记录最后更新时间
|
||||
/// </summary>
|
||||
public virtual DateTime UpdateTime { get; set; } = DateTime.Now;
|
||||
|
||||
}
|
||||
}
|
||||
55
Services/Hncore.Pass.Vpn/Domain/ProductOrderEntity.cs
Normal file
55
Services/Hncore.Pass.Vpn/Domain/ProductOrderEntity.cs
Normal file
@@ -0,0 +1,55 @@
|
||||
using Hncore.Infrastructure.DDD;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Hncore.Pass.Vpn.Domain
|
||||
{
|
||||
public partial class ProductOrderEntity : EntityWithTime<int>, ITenant
|
||||
{
|
||||
public int TenantId { get; set; }
|
||||
public int UserId { get; set; }
|
||||
public string UserName { get; set; }
|
||||
public int ProductId { get; set; }
|
||||
public string ProductName { get; set; }
|
||||
public int PackageId { get; set; }
|
||||
public string PackageName { get; set; }
|
||||
public int? CouponId { get; set; } = 0;
|
||||
public decimal? CouponAmount { get; set; }
|
||||
public string OriginKey { get; set; }
|
||||
public string OrderName { get; set; }
|
||||
public string OrderNo { get; set; }
|
||||
public string TradeNo { get; set; }
|
||||
public OrderStatus OrderState { get; set; }
|
||||
public OrderType OrderType { get; set; }
|
||||
public PayType PayType { get; set; }
|
||||
|
||||
public PayChannel PayChannel { get; set; } = PayChannel.WxPc;
|
||||
public int PayState { get; set; }
|
||||
public int ConnectCount { get; set; }
|
||||
public decimal OrderAmount { get; set; }
|
||||
public decimal PaymentAmount { get; set; }
|
||||
public decimal? AccountPayAmount { get; set; } = 0;
|
||||
public decimal? OtherPayAmount { get; set; } = 0;
|
||||
public decimal? DayPrice { get; set; } = 0;
|
||||
public int DayCount { get; set; } = 1;
|
||||
public int ClientType { get; set; }
|
||||
public int ChannelType { get; set; }
|
||||
public string Channel { get; set; }
|
||||
public int AccountCount { get; set; } = 1;
|
||||
public string Remark { get; set; }
|
||||
public string Accounts { get; set; }
|
||||
public string AccountPwd { get; set; }
|
||||
public int RefundCount { get; set; }
|
||||
public decimal RefundAmount { get; set; }
|
||||
|
||||
public string RefundRestTime { get; set; }
|
||||
|
||||
public DateTime? StartTime { get; set; }
|
||||
public DateTime? EndTime { get; set; }
|
||||
|
||||
public int? IsAutoRefund { get; set; } = 0;
|
||||
|
||||
public decimal? BackAmount { get; set; } = 0;
|
||||
|
||||
}
|
||||
}
|
||||
34
Services/Hncore.Pass.Vpn/Domain/ProductOrderItemEntity.cs
Normal file
34
Services/Hncore.Pass.Vpn/Domain/ProductOrderItemEntity.cs
Normal file
@@ -0,0 +1,34 @@
|
||||
using Hncore.Infrastructure.DDD;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Hncore.Pass.Vpn.Domain
|
||||
{
|
||||
public partial class ProductOrderItemEntity : EntityWithTime<int>, ITenant
|
||||
{
|
||||
public int TenantId { get; set; }
|
||||
public int OrderId { get; set; }
|
||||
public int UserId { get; set; }
|
||||
public string UserName { get; set; }
|
||||
public int ProductId { get; set; }
|
||||
public string ProductName { get; set; }
|
||||
public int PackageId { get; set; }
|
||||
public string PackageName { get; set; }
|
||||
public string Account { get; set; }
|
||||
public string AccountPwd { get; set; }
|
||||
public int ConnectCount { get; set; }
|
||||
public int AccountType { get; set; }
|
||||
public int StartNum { get; set; }
|
||||
public int EndNum { get; set; }
|
||||
public string OrderNo { get; set; }
|
||||
public OrderStatus OrderState { get; set; }
|
||||
public OrderType OrderType { get; set; }
|
||||
public PayType PayType { get; set; }
|
||||
public int PayState { get; set; }
|
||||
|
||||
public decimal Price { get; set; }
|
||||
public decimal DayPrice { get; set; }
|
||||
public int DayCount { get; set; }
|
||||
public string Remark { get; set; }
|
||||
}
|
||||
}
|
||||
27
Services/Hncore.Pass.Vpn/Domain/ProductPackageEntity.cs
Normal file
27
Services/Hncore.Pass.Vpn/Domain/ProductPackageEntity.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
using Hncore.Infrastructure.DDD;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Hncore.Pass.Vpn.Domain
|
||||
{
|
||||
public partial class ProductPackageEntity : EntityWithDelete<int>, ITenant
|
||||
{
|
||||
public int TenantId { get; set; }
|
||||
public int ProductId { get; set; }
|
||||
public PackageType PackageType { get; set; } = PackageType.Base;
|
||||
public string Name { get; set; }
|
||||
public string Title { get; set; }
|
||||
public string Image { get; set; }
|
||||
public int Status { get; set; } = 0;
|
||||
public string Profile { get; set; }
|
||||
public decimal Price { get; set; }
|
||||
public decimal LinePrice { get; set; }
|
||||
public decimal DayPrice { get; set; }
|
||||
public decimal MinPrice { get; set; }
|
||||
public int DayCount { get; set; } = 1;
|
||||
public string OriginKey { get; set; }
|
||||
public string OriginName { get; set; }
|
||||
|
||||
public int? IsTest { get; set; } = 0;
|
||||
}
|
||||
}
|
||||
13
Services/Hncore.Pass.Vpn/Domain/ProductPackageUnitEntity.cs
Normal file
13
Services/Hncore.Pass.Vpn/Domain/ProductPackageUnitEntity.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
using Hncore.Infrastructure.DDD;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Hncore.Pass.Vpn.Domain
|
||||
{
|
||||
public partial class ProductPackageUnitEntity : Entity<int>
|
||||
{
|
||||
public int PackageId { get; set; }
|
||||
public int BasePackageId { get; set; }
|
||||
public int Count { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
using Hncore.Infrastructure.DDD;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Hncore.Pass.Vpn.Domain
|
||||
{
|
||||
public partial class ProductPriceDiscountEntity : EntityWithDelete<int>
|
||||
{
|
||||
public int SchemeId { get; set; }
|
||||
public int TenantId { get; set; }
|
||||
public int ProductId { get; set; }
|
||||
public int PackageId { get; set; }
|
||||
public int Status { get; set; } = 0;
|
||||
public int BuyPriceDiscount { get; set; } = 0;
|
||||
public int RefundDayPriceDiscount { get; set; } = 0;
|
||||
public string Remark { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
13
Services/Hncore.Pass.Vpn/Domain/ProductPriceSchemeEntity.cs
Normal file
13
Services/Hncore.Pass.Vpn/Domain/ProductPriceSchemeEntity.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
using Hncore.Infrastructure.DDD;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Hncore.Pass.Vpn.Domain
|
||||
{
|
||||
public partial class ProductPriceSchemeEntity : EntityWithTime<int>
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public string Remark { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
26
Services/Hncore.Pass.Vpn/Domain/ProductRouteEntity.cs
Normal file
26
Services/Hncore.Pass.Vpn/Domain/ProductRouteEntity.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
using Hncore.Infrastructure.DDD;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Hncore.Pass.Vpn.Domain
|
||||
{
|
||||
public partial class ProductRouteEntity : EntityWithDelete<int>
|
||||
{
|
||||
public int? ProductId { get; set; }
|
||||
public string ProductName { get; set; }
|
||||
public string Province { get; set; }
|
||||
public string City { get; set; }
|
||||
public int Sort { get; set; } = 0;
|
||||
public string Name { get; set; }
|
||||
public string ServerUrl { get; set; }
|
||||
public string Status { get; set; }
|
||||
|
||||
public string LineType { get; set; }
|
||||
public string BandWidth { get; set; }
|
||||
public string IpRemark { get; set; }
|
||||
public string Remark { get; set; }
|
||||
public int OnLine { get; set; } = 1;
|
||||
public string KeyWord { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
19
Services/Hncore.Pass.Vpn/Domain/ProductUserPriceEntity.cs
Normal file
19
Services/Hncore.Pass.Vpn/Domain/ProductUserPriceEntity.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
using Hncore.Infrastructure.DDD;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Hncore.Pass.Vpn.Domain
|
||||
{
|
||||
public partial class ProductUserPriceEntity : EntityWithDelete<int>, ITenant
|
||||
{
|
||||
public int TenantId { get; set; }
|
||||
public int ProductId { get; set; }
|
||||
public int PackageId { get; set; }
|
||||
public int UserId { get; set; }
|
||||
public int Status { get; set; } = 0;
|
||||
public decimal UserPrice { get; set; }
|
||||
public decimal? RefundDayPrice { get; set; } = 0;
|
||||
public string Remark { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
82
Services/Hncore.Pass.Vpn/Domain/UserEntity.cs
Normal file
82
Services/Hncore.Pass.Vpn/Domain/UserEntity.cs
Normal file
@@ -0,0 +1,82 @@
|
||||
using Hncore.Infrastructure.DDD;
|
||||
using System;
|
||||
|
||||
namespace Hncore.Pass.Vpn.Domain
|
||||
{
|
||||
public partial class UserEntity : EntityWithTime<int>, ITenant
|
||||
{
|
||||
/// <summary>
|
||||
/// ID
|
||||
/// <summary>
|
||||
public int TenantId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 管理员登录名[16
|
||||
/// </summary>
|
||||
public string LoginCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 登录密码[20]
|
||||
/// </summary>
|
||||
public string Password { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 微信昵称
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 微信头像
|
||||
/// </summary>
|
||||
public string Phone { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 注册来源
|
||||
/// </summary>
|
||||
public string Profile { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 状态
|
||||
/// </summary>
|
||||
public int Enabled { get; set; } = 1;
|
||||
|
||||
/// <summary>
|
||||
/// 头像地址[30
|
||||
/// </summary>
|
||||
public string PhotoUrl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否主管理员权限
|
||||
/// </summary>
|
||||
public DateTime? LastLoginDate { get; set; } = DateTime.Now;
|
||||
|
||||
public int Sex { get; set; }
|
||||
|
||||
//1:管理员添加 2:自己注册 3:来自淘宝
|
||||
public int CreateType { get; set; }
|
||||
|
||||
public int ProductAccountCount { get; set; }
|
||||
|
||||
public int ExpiredProductAccountCount { get; set; }
|
||||
|
||||
public decimal RestAmount { get; set; }
|
||||
|
||||
public decimal ConsumeAmount { get; set; }
|
||||
|
||||
public string Remark { get; set; }
|
||||
public string Wx { get; set; }
|
||||
public string QQ { get; set; }
|
||||
public string Email { get; set; }
|
||||
public string TaoBao { get; set; }
|
||||
public string WangWang { get; set; }
|
||||
|
||||
public int? TestCountLimit { get; set; } = 0;
|
||||
public int? UseTestCount { get; set; } = 0;
|
||||
|
||||
public int? ManagerId { get; set; } = 0;
|
||||
public string ManagerName { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
28
Services/Hncore.Pass.Vpn/Domain/WxAppEntity.cs
Normal file
28
Services/Hncore.Pass.Vpn/Domain/WxAppEntity.cs
Normal file
@@ -0,0 +1,28 @@
|
||||
using Hncore.Infrastructure.DDD;
|
||||
using System;
|
||||
|
||||
namespace Hncore.Pass.Vpn.Domain
|
||||
{
|
||||
public partial class WxAppEntity : EntityWithDelete<int>, ITenant
|
||||
{
|
||||
public int TenantId { get; set; }
|
||||
public int StoreId { get; set; }
|
||||
public string OpenAppId { get; set; }
|
||||
public string Appid { get; set; }
|
||||
public int AppType { get; set; }
|
||||
|
||||
public string HeadImg { get; set; }
|
||||
public string NickName { get; set; }
|
||||
public string UserName { get; set; }
|
||||
public string PrincipalName { get; set; }
|
||||
public string Bussinessinfo { get; set; }
|
||||
public string Createtime { get; set; }
|
||||
|
||||
public int AuthorizerState { get; set; }
|
||||
public string RefreshToken { get; set; }
|
||||
|
||||
public int ExpiresIn { get; set; }
|
||||
|
||||
public DateTime UpdateTime { get; set; } = DateTime.Now;
|
||||
}
|
||||
}
|
||||
31
Services/Hncore.Pass.Vpn/Domain/WxAppUserEntity.cs
Normal file
31
Services/Hncore.Pass.Vpn/Domain/WxAppUserEntity.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
using Hncore.Infrastructure.DDD;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Hncore.Pass.Vpn.Domain
|
||||
{
|
||||
public partial class WxAppUserEntity : EntityWithDelete<int>, ITenant
|
||||
{
|
||||
public int TenantId { get; set; }
|
||||
public int StoreId { get; set; }
|
||||
public string Appid { get; set; }
|
||||
public int AppType { get; set; }
|
||||
public int UserId { get; set; }
|
||||
public string Unionid { get; set; }
|
||||
public string Openid { get; set; }
|
||||
public string NickName { get; set; }
|
||||
public string UserName { get; set; }
|
||||
public string HeadImgUrl { get; set; }
|
||||
public int Sex { get; set; }
|
||||
public string City { get; set; }
|
||||
public string Country { get; set; }
|
||||
public int IsSubscribe { get; set; }
|
||||
public int InvateUserId { get; set; }
|
||||
public DateTime Createtime { get; set; } = DateTime.Now;
|
||||
|
||||
public DateTime UpdateTime{ get; set; } = DateTime.Now;
|
||||
|
||||
}
|
||||
}
|
||||
37
Services/Hncore.Pass.Vpn/Hncore.Pass.Vpn.csproj
Normal file
37
Services/Hncore.Pass.Vpn/Hncore.Pass.Vpn.csproj
Normal file
@@ -0,0 +1,37 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp2.2</TargetFramework>
|
||||
<AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
<NoWarn>1701;1702;1998</NoWarn>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Aliyun.OSS.SDK.NetCore" Version="2.9.1" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.App">
|
||||
<PrivateAssets Condition="'%(PackageReference.Version)' == ''">all</PrivateAssets>
|
||||
<Publish Condition="'%(PackageReference.Version)' == ''">true</Publish>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Razor.Design" Version="2.2.0" PrivateAssets="All" />
|
||||
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="2.2.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Extension\" />
|
||||
<Folder Include="Properties\" />
|
||||
<Folder Include="Request\Article\" />
|
||||
<Folder Include="Utils\" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Infrastructure\Hncore.Infrastructure\Hncore.Infrastructure.csproj" />
|
||||
<ProjectReference Include="..\..\Infrastructure\ServiceClient\PaymentCenterClient\PaymentCenterClient.csproj" />
|
||||
<ProjectReference Include="..\..\Infrastructure\WxApi\WxApi.csproj" />
|
||||
<ProjectReference Include="..\Hncore.Pass.BaseInfo\Hncore.Pass.BaseInfo.csproj" />
|
||||
<ProjectReference Include="..\Hncore.Pass.Sells\Hncore.Pass.Sells.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
42
Services/Hncore.Pass.Vpn/Job/ChargeTryJob.cs
Normal file
42
Services/Hncore.Pass.Vpn/Job/ChargeTryJob.cs
Normal file
@@ -0,0 +1,42 @@
|
||||
using Hncore.Infrastructure.Common;
|
||||
using Hncore.Pass.Vpn.Service;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Hncore.Infrastructure.Extension;
|
||||
namespace Hncore.Pass.Vpn.Job
|
||||
{
|
||||
/// <summary>
|
||||
/// 充值失败尝试job
|
||||
/// </summary>
|
||||
public class ChargeTryJob
|
||||
{
|
||||
public static void Start(IServiceProvider serviceProvider)
|
||||
{
|
||||
Task.Run(async () => { await Execute(serviceProvider); });
|
||||
}
|
||||
|
||||
private static async Task Execute(IServiceProvider serviceProvider)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
LogHelper.Trace("开始处理订单");
|
||||
try
|
||||
{
|
||||
using (var scope = serviceProvider.CreateScope())
|
||||
{
|
||||
var agentService = scope.ServiceProvider.GetService<AgentService>();
|
||||
await agentService.FaildTry();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LogHelper.Error("处理订单失败", e);
|
||||
break;
|
||||
}
|
||||
await Task.Delay(10 * 1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
118
Services/Hncore.Pass.Vpn/Job/ExpireTipJob.cs
Normal file
118
Services/Hncore.Pass.Vpn/Job/ExpireTipJob.cs
Normal file
@@ -0,0 +1,118 @@
|
||||
using Hncore.Infrastructure.Common;
|
||||
using Hncore.Pass.Vpn.Service;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Hncore.Infrastructure.Extension;
|
||||
using System.Linq;
|
||||
using Hncore.Wx.Open;
|
||||
using Hncore.Infrastructure.SMS;
|
||||
using Hncore.Pass.BaseInfo.Models;
|
||||
using System.Collections.Generic;
|
||||
using Hncore.Pass.Vpn.Domain;
|
||||
|
||||
namespace Hncore.Pass.Vpn.Job
|
||||
{
|
||||
/// <summary>
|
||||
/// 过期提醒job
|
||||
/// </summary>
|
||||
public class ExpireTipJob
|
||||
{
|
||||
public static void Start(IServiceProvider serviceProvider)
|
||||
{
|
||||
Task.Run(async () => { await Execute(serviceProvider); });
|
||||
}
|
||||
|
||||
private static async Task Execute(IServiceProvider serviceProvider)
|
||||
{
|
||||
var doing = false;
|
||||
while (true)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
if (doing||!(DateTime.Now.Hour == 15 && DateTime.Now.Minute < 5))
|
||||
{
|
||||
break;
|
||||
}
|
||||
LogHelper.Trace("开始过期提醒");
|
||||
doing = true;
|
||||
try
|
||||
{
|
||||
using (var scope = serviceProvider.CreateScope())
|
||||
{
|
||||
var accountService = scope.ServiceProvider.GetService<ProductAccountService>();
|
||||
var wxUserService = scope.ServiceProvider.GetService<WxAppUserService>();
|
||||
var userService = scope.ServiceProvider.GetService<UserService>();
|
||||
|
||||
var expireAccounts_1 = await accountService.GetExpireingAccounts(-1);
|
||||
|
||||
var expireAccounts0 = await accountService.GetExpireingAccounts(0);
|
||||
|
||||
var expireAccounts1 = await accountService.GetExpireingAccounts(1);
|
||||
|
||||
await Tip(expireAccounts_1, wxUserService, userService, "已过期1天");
|
||||
await Tip(expireAccounts0, wxUserService, userService, "今天过期");
|
||||
await Tip(expireAccounts1, wxUserService, userService, "明天过期");
|
||||
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LogHelper.Error("处理过期提醒失败", e);
|
||||
break;
|
||||
}
|
||||
finally
|
||||
{
|
||||
doing = false;
|
||||
}
|
||||
await Task.Delay(6*60 * 1000);
|
||||
}
|
||||
await Task.Delay(60 * 1000);
|
||||
}
|
||||
}
|
||||
|
||||
public static async Task Tip(List<ProductAccountEntity> accounts, WxAppUserService wxUserService, UserService userService,string tip="")
|
||||
{
|
||||
var userIds = accounts.Select(m => m.UserId.Value).Distinct().ToList();
|
||||
var wxUsers = await wxUserService.GetWxUsers(userIds);
|
||||
var userInfos = await userService.GetByIds(userIds);
|
||||
|
||||
var tipUsers = new Dictionary<int, bool>();
|
||||
foreach (var account in accounts)
|
||||
{
|
||||
if (tipUsers.ContainsKey(account.UserId.Value)||account.PackageName.IndexOf("测试")!=-1 || account.PackageName.IndexOf("天卡") != -1)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
var userInfo = userInfos.FirstOrDefault(m => m.Id == account.UserId);
|
||||
if (wxUsers != null && wxUsers.Count > 0)
|
||||
{
|
||||
var wxUser = wxUsers.FirstOrDefault(m => m.UserId == account.UserId);
|
||||
if (wxUser != null && wxUser.Openid.Has())
|
||||
{
|
||||
var msg = new TemplateMPModel();
|
||||
msg.first = new TemplateDataItem($"尊敬的用户您好,你的账户{tip}!");
|
||||
msg.Url = "www.juip.com";
|
||||
msg.template_id = "ltm4OfRDoxgdRG4EC8NMzX-NrkfHUz8aGz33TXSbP44";
|
||||
msg.Items.Add(new TemplateDataItem("请登录juip.com查看具体的到期账号!"));
|
||||
msg.Items.Add(new TemplateDataItem(userInfo.Phone));
|
||||
msg.Items.Add(new TemplateDataItem("动态IP账号服务"));
|
||||
msg.Items.Add(new TemplateDataItem(account.EndTime.Value.ToString("yyyy-MM-dd hh:mm:ss")));
|
||||
msg.remark = new TemplateDataItem("请登录官网juip.com,点击个人中心,查看需要续费的动态ip账号");
|
||||
await TemplateApi.SendTemplateMessageAsync(wxUser.Appid, wxUser.Openid, Wx.Open.Enums.ChannelType.MP, msg);
|
||||
}
|
||||
}
|
||||
|
||||
if (userInfo != null && RegexPattern.IsMobile(userInfo.Phone))
|
||||
{
|
||||
var ret = AliSmsService.Send("SMS_193505090", new { date = account.EndTime.Value.ToString("yyyy-MM-dd hh:mm:ss") }, "聚IP商城", userInfo.Phone);
|
||||
}
|
||||
tipUsers[account.UserId.Value] = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
47
Services/Hncore.Pass.Vpn/Job/OrderAccountJob.cs
Normal file
47
Services/Hncore.Pass.Vpn/Job/OrderAccountJob.cs
Normal file
@@ -0,0 +1,47 @@
|
||||
using Hncore.Infrastructure.Common;
|
||||
using Hncore.Pass.Vpn.Service;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Hncore.Infrastructure.Extension;
|
||||
namespace Hncore.Pass.Vpn.Job
|
||||
{
|
||||
/// <summary>
|
||||
/// 支付成功后开通账号的job
|
||||
/// </summary>
|
||||
public class OrderAccountJob
|
||||
{
|
||||
|
||||
public static void Start(IServiceProvider serviceProvider)
|
||||
{
|
||||
Task.Run(async () => { await Execute(serviceProvider); });
|
||||
}
|
||||
|
||||
private static async Task Execute(IServiceProvider serviceProvider)
|
||||
{
|
||||
while (true) // 每轮间隔10分钟
|
||||
{
|
||||
LogHelper.Trace("开始处理订单");
|
||||
try
|
||||
{
|
||||
using (var scope = serviceProvider.CreateScope())
|
||||
{
|
||||
var orderService = scope.ServiceProvider.GetService<ProductOrderService>();
|
||||
var orders = await orderService.GetOrders(Domain.OrderStatus.PayOk);
|
||||
|
||||
await orders.ForEachAsync(async m =>
|
||||
{
|
||||
await orderService.ProcessOrderAccount(m);
|
||||
});
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LogHelper.Error("处理订单失败", e);
|
||||
}
|
||||
await Task.Delay(10 * 1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
67
Services/Hncore.Pass.Vpn/Job/OrderOutTimePayJob.cs
Normal file
67
Services/Hncore.Pass.Vpn/Job/OrderOutTimePayJob.cs
Normal file
@@ -0,0 +1,67 @@
|
||||
using Hncore.Infrastructure.Common;
|
||||
using Hncore.Pass.BaseInfo.Models;
|
||||
using Hncore.Pass.BaseInfo.Request.User;
|
||||
using Hncore.Pass.Vpn.Domain;
|
||||
using Hncore.Pass.Vpn.Request.Product;
|
||||
using Hncore.Pass.Vpn.Service;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Hncore.Pass.Vpn.Job
|
||||
{
|
||||
/// <summary>
|
||||
/// 超时支付的job
|
||||
/// </summary>
|
||||
public class OrderOutTimePayJob
|
||||
{
|
||||
|
||||
public static void Start(IServiceProvider serviceProvider)
|
||||
{
|
||||
Task.Run(async () => { await Execute(serviceProvider); });
|
||||
}
|
||||
|
||||
private static async Task Execute(IServiceProvider serviceProvider)
|
||||
{
|
||||
while (true) // 每轮间隔10分钟
|
||||
{
|
||||
LogHelper.Trace("开始处理超时支付");
|
||||
try
|
||||
{
|
||||
using (var scope = serviceProvider.CreateScope())
|
||||
{
|
||||
var orderService = scope.ServiceProvider.GetService<ProductOrderService>();
|
||||
var userService = scope.ServiceProvider.GetService<Hncore.Pass.BaseInfo.Service.UserService>();
|
||||
var orders = await orderService.GetLimitTimeOrders(Domain.OrderStatus.NoPay, 30);
|
||||
orders.ForEach(async order =>
|
||||
{
|
||||
order.OrderState = Domain.OrderStatus.TimeOutClose;
|
||||
await orderService.Update(order);
|
||||
//返还用户余额支付部分
|
||||
if (order.AccountPayAmount > 0)
|
||||
{
|
||||
var amountInfo = new UpdateAmountRequest()
|
||||
{
|
||||
Amount = order.AccountPayAmount.Value,
|
||||
OpAmountType = ScoreType.AccountRefund,
|
||||
UserId = order.UserId,
|
||||
AttchInfo = order.OrderNo,
|
||||
OperateUserName = order.UserName,
|
||||
};
|
||||
await userService.UpdateAmount(amountInfo);
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LogHelper.Error("处理超时支付失败", e);
|
||||
break;
|
||||
}
|
||||
await Task.Delay(60 * 1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
42
Services/Hncore.Pass.Vpn/Job/RefrushStatusJob.cs
Normal file
42
Services/Hncore.Pass.Vpn/Job/RefrushStatusJob.cs
Normal file
@@ -0,0 +1,42 @@
|
||||
using Hncore.Infrastructure.Common;
|
||||
using Hncore.Pass.Vpn.Service;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Hncore.Pass.Vpn.Job
|
||||
{
|
||||
/// <summary>
|
||||
/// 超时支付的job
|
||||
/// </summary>
|
||||
public class RefrushStatusJob
|
||||
{
|
||||
|
||||
public static void Start(IServiceProvider serviceProvider)
|
||||
{
|
||||
Task.Run(async () => { await Execute(serviceProvider); });
|
||||
}
|
||||
|
||||
private static async Task Execute(IServiceProvider serviceProvider)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
LogHelper.Trace("刷新代理服务器状态");
|
||||
try
|
||||
{
|
||||
using (var scope = serviceProvider.CreateScope())
|
||||
{
|
||||
var agentService = scope.ServiceProvider.GetService<AgentService>();
|
||||
await agentService.RefrushAllStatus();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LogHelper.Error("刷新代理服务器状态失败", e);
|
||||
}
|
||||
await Task.Delay(30 * 1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
76
Services/Hncore.Pass.Vpn/Job/RemoveAccountJob.cs
Normal file
76
Services/Hncore.Pass.Vpn/Job/RemoveAccountJob.cs
Normal file
@@ -0,0 +1,76 @@
|
||||
using Hncore.Infrastructure.Common;
|
||||
using Hncore.Pass.Vpn.Service;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Hncore.Infrastructure.Extension;
|
||||
using System.Linq;
|
||||
using Hncore.Wx.Open;
|
||||
using Hncore.Infrastructure.SMS;
|
||||
using Hncore.Pass.BaseInfo.Models;
|
||||
using System.Collections.Generic;
|
||||
using Hncore.Pass.Vpn.Domain;
|
||||
using Hncore.Infrastructure.WebApi;
|
||||
|
||||
namespace Hncore.Pass.Vpn.Job
|
||||
{
|
||||
/// <summary>
|
||||
/// 删除不存在的账号
|
||||
/// </summary>
|
||||
public class RemoveAccountJob
|
||||
{
|
||||
public static void Start(IServiceProvider serviceProvider)
|
||||
{
|
||||
Task.Run(async () => { await Execute(serviceProvider); });
|
||||
}
|
||||
|
||||
private static async Task Execute(IServiceProvider serviceProvider)
|
||||
{
|
||||
var doing = false;
|
||||
while (true)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
if (doing||!(DateTime.Now.Hour == 23 && DateTime.Now.Minute < 5))
|
||||
{
|
||||
break;
|
||||
}
|
||||
LogHelper.Trace("开始删除过期账号");
|
||||
doing = true;
|
||||
try
|
||||
{
|
||||
using (var scope = serviceProvider.CreateScope())
|
||||
{
|
||||
var accountService = scope.ServiceProvider.GetService<ProductAccountService>();
|
||||
var agentService = scope.ServiceProvider.GetService<AgentService>();
|
||||
var removeAccounts = new List<ProductAccountEntity>();
|
||||
var accounts = await accountService.Query(true).ToListAsync();
|
||||
foreach (var item in accounts)
|
||||
{
|
||||
var ret = await agentService.GetOriginAccountInfo(item.ProductId.Value, item.Account, item.Pwd);
|
||||
if (ret.Code != ResultCode.C_SUCCESS && ret.Code != ResultCode.C_NOT_EXISTS_ERROR)
|
||||
{
|
||||
removeAccounts.Add(item);
|
||||
}
|
||||
}
|
||||
await accountService.Deletes(removeAccounts);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LogHelper.Error("账号删除失败", e);
|
||||
break;
|
||||
}
|
||||
finally
|
||||
{
|
||||
doing = false;
|
||||
}
|
||||
await Task.Delay(6*60 * 1000);
|
||||
}
|
||||
await Task.Delay(60 * 1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
14
Services/Hncore.Pass.Vpn/Map/MapConfig.cs
Normal file
14
Services/Hncore.Pass.Vpn/Map/MapConfig.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
using Hncore.Infrastructure.Extension;
|
||||
using Hncore.Pass.Vpn.Domain;
|
||||
using Hncore.Pass.Vpn.Response.Product;
|
||||
|
||||
namespace Hncore.Pass.Vpn.Map
|
||||
{
|
||||
public class MapConfig
|
||||
{
|
||||
public static void Config()
|
||||
{
|
||||
TinyMapperExtension.Binds<ProductResponse, ProductEntity>();
|
||||
}
|
||||
}
|
||||
}
|
||||
14
Services/Hncore.Pass.Vpn/Model/CatalogUsedModel.cs
Normal file
14
Services/Hncore.Pass.Vpn/Model/CatalogUsedModel.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Hncore.Pass.Vpn.Model
|
||||
{
|
||||
public class CatalogUsedModel
|
||||
{
|
||||
public bool Used { get; set; }
|
||||
|
||||
public List<int> CatalogIds { get; set; }
|
||||
}
|
||||
}
|
||||
21
Services/Hncore.Pass.Vpn/Model/ManagerSellStatisticModel.cs
Normal file
21
Services/Hncore.Pass.Vpn/Model/ManagerSellStatisticModel.cs
Normal file
@@ -0,0 +1,21 @@
|
||||
using Hncore.Infrastructure.Extension;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Hncore.Pass.Vpn.Model
|
||||
{
|
||||
public class ManagerSellStatisticModel
|
||||
{
|
||||
public string RealName { get; set; }
|
||||
|
||||
public string Name => this.RealName.NotHas() ? "无" : this.RealName;
|
||||
public long? UserCount { get; set; } = 0;
|
||||
|
||||
public long? NewUserCount { get; set; } = 0;
|
||||
|
||||
public decimal? Amount { get; set; } = 0;
|
||||
|
||||
}
|
||||
}
|
||||
26
Services/Hncore.Pass.Vpn/Model/OrderStatisticModel.cs
Normal file
26
Services/Hncore.Pass.Vpn/Model/OrderStatisticModel.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Hncore.Pass.Vpn.Model
|
||||
{
|
||||
public class OrderStatisticModel
|
||||
{
|
||||
public string Channel { get; set; }
|
||||
public string ProductName { get; set; }
|
||||
|
||||
public string PackageName { get; set; }
|
||||
|
||||
public int NewBuyCount { get; set; }
|
||||
public decimal NewBuyAmount { get; set; }
|
||||
|
||||
public int AgainBuyCount { get; set; }
|
||||
public decimal AgainBuyAmount { get; set; }
|
||||
|
||||
public int RefundCount { get; set; }
|
||||
public decimal RefundAmount { get; set; }
|
||||
|
||||
public decimal SellAmount => NewBuyAmount + AgainBuyAmount;
|
||||
}
|
||||
}
|
||||
35
Services/Hncore.Pass.Vpn/Model/OriginAccountModel.cs
Normal file
35
Services/Hncore.Pass.Vpn/Model/OriginAccountModel.cs
Normal file
@@ -0,0 +1,35 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Hncore.Pass.Vpn.Model
|
||||
{
|
||||
public class OriginAccountModel
|
||||
{
|
||||
public string Id { get; set; }
|
||||
public string User { get; set; }
|
||||
public string Account { get; set; }
|
||||
|
||||
public string Pwd { get; set; }
|
||||
public string AccountType { get; set; }
|
||||
public string Package { get; set; }
|
||||
public string ConnectCount { get; set; }
|
||||
public string RegistTime { get; set; }
|
||||
public string EndTime { get; set; }
|
||||
public string RestTime { get; set; }
|
||||
public string Amount { get; set; }
|
||||
|
||||
public string IsActive { get; set; }
|
||||
public string Remark { get; set; }
|
||||
|
||||
public DateTime RealEndTime { get; set; }
|
||||
|
||||
public int OnLine { get; set; } = 0;
|
||||
|
||||
public string LoginTime { get; set; }
|
||||
|
||||
public string LoginServer { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
21
Services/Hncore.Pass.Vpn/Model/OriginAccountOnlineModel.cs
Normal file
21
Services/Hncore.Pass.Vpn/Model/OriginAccountOnlineModel.cs
Normal file
@@ -0,0 +1,21 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Hncore.Pass.Vpn.Model
|
||||
{
|
||||
public class OriginAccountOnlineModel
|
||||
{
|
||||
public string Id { get; set; }
|
||||
public string Account { get; set; }
|
||||
public string LoginTime { get; set; }
|
||||
public string OnlineTime { get; set; }
|
||||
|
||||
public string ServerIP { get; set; }
|
||||
public string LoginIP { get; set; }
|
||||
public string UpStream { get; set; }
|
||||
public string DownStream { get; set; }
|
||||
public int OnLine { get; set; } = 0;
|
||||
}
|
||||
}
|
||||
12
Services/Hncore.Pass.Vpn/Model/PackageUnitItemModel.cs
Normal file
12
Services/Hncore.Pass.Vpn/Model/PackageUnitItemModel.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
using Hncore.Pass.Vpn.Domain;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Hncore.Pass.Vpn.Model
|
||||
{
|
||||
public class PackageUnitItemModel
|
||||
{
|
||||
public int Count { get; set; }
|
||||
|
||||
public ProductPackageEntity Package { get; set; }
|
||||
}
|
||||
}
|
||||
35
Services/Hncore.Pass.Vpn/Model/UserConsumeStatisticsModel.cs
Normal file
35
Services/Hncore.Pass.Vpn/Model/UserConsumeStatisticsModel.cs
Normal file
@@ -0,0 +1,35 @@
|
||||
using Hncore.Pass.Vpn.Domain;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Hncore.Pass.Vpn.Model
|
||||
{
|
||||
public class UserConsumeStatisticsModel
|
||||
{
|
||||
public string UserName { get; set; }
|
||||
|
||||
public UserEntity UserInfo {get;set;}
|
||||
|
||||
public DateTime CreateTime { get; set; }
|
||||
public string TotalAmount { get; set; }
|
||||
public string DayAmount { get; set; }
|
||||
|
||||
public decimal PrevMonthAmount { get; set; }
|
||||
public decimal MonthAmount { get; set; }
|
||||
|
||||
public decimal AddAmount => MonthAmount - PrevMonthAmount;
|
||||
|
||||
public string YearAmount { get; set; }
|
||||
|
||||
public int TotalAccountCount=> ExpirdAccountCount + UsingAccountCount;
|
||||
|
||||
public int UsingAccountCount { get; set; } = 0;
|
||||
|
||||
public int ExpirdAccountCount { get; set; } = 0;
|
||||
|
||||
public int TestAccountCount { get; set; } = 0;
|
||||
|
||||
}
|
||||
}
|
||||
17
Services/Hncore.Pass.Vpn/Model/UserDataMode.cs
Normal file
17
Services/Hncore.Pass.Vpn/Model/UserDataMode.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
using Hncore.Pass.BaseInfo.Models;
|
||||
using Hncore.Pass.Vpn.Domain;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Hncore.Pass.Vpn.Model
|
||||
{
|
||||
public class UserDataMode
|
||||
{
|
||||
public string UserName { get; set; }
|
||||
public string Value { get; set; }
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
24
Services/Hncore.Pass.Vpn/Program.cs
Normal file
24
Services/Hncore.Pass.Vpn/Program.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Hncore.Pass.Vpn
|
||||
{
|
||||
public class Program
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
CreateWebHostBuilder(args).Build().Run();
|
||||
}
|
||||
|
||||
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
|
||||
WebHost.CreateDefaultBuilder(args)
|
||||
.UseStartup<Startup>();
|
||||
}
|
||||
}
|
||||
19
Services/Hncore.Pass.Vpn/Properties/launchSettings.json
Normal file
19
Services/Hncore.Pass.Vpn/Properties/launchSettings.json
Normal file
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"iisSettings": {
|
||||
"windowsAuthentication": false,
|
||||
"anonymousAuthentication": true,
|
||||
"iisExpress": {
|
||||
"applicationUrl": "http://localhost:50978/",
|
||||
"sslPort": 0
|
||||
}
|
||||
},
|
||||
"profiles": {
|
||||
"IIS Express": {
|
||||
"commandName": "IISExpress",
|
||||
"launchBrowser": true,
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
using Hncore.Infrastructure.Tree;
|
||||
using Hncore.Infrastructure.WebApi;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Hncore.Pass.Vpn.Request.Product
|
||||
{
|
||||
public class AccountPageRequest : PageRequestBase
|
||||
{
|
||||
public int UserId { get; set; }
|
||||
|
||||
//-1:全部 0 :过期
|
||||
public int ExpirdDay { get; set; }
|
||||
|
||||
public int? ProductId { get; set; }
|
||||
|
||||
public int? PackageId { get; set; }
|
||||
|
||||
public List<int?> AccountTypes { get; set; }
|
||||
|
||||
public DateTime? BTime { get; set; }
|
||||
public DateTime? ETime { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
using Hncore.Infrastructure.Tree;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Hncore.Pass.Vpn.Request.Product
|
||||
{
|
||||
public class AgentLoginRequest
|
||||
{
|
||||
public int ProductId { get; set; }
|
||||
|
||||
public string Code { get; set; }
|
||||
|
||||
public string Key { get; set; }
|
||||
|
||||
public string Account { get; set; }
|
||||
|
||||
public string Pwd { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
13
Services/Hncore.Pass.Vpn/Request/Product/BindUserRequest.cs
Normal file
13
Services/Hncore.Pass.Vpn/Request/Product/BindUserRequest.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
using Hncore.Infrastructure.Tree;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Hncore.Pass.Vpn.Request.Product
|
||||
{
|
||||
public class BindUserRequest
|
||||
{
|
||||
public List<int> AccountIds { get; set; }
|
||||
|
||||
public int UserId { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
using Hncore.Infrastructure.WebApi;
|
||||
|
||||
namespace Hncore.Pass.Vpn.Request.Product
|
||||
{
|
||||
public class CouponOrderQueryRequest : PageRequestBase
|
||||
{
|
||||
public int? CouponId { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
using Hncore.Pass.Vpn.Domain;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Hncore.Pass.Vpn.Request.Product
|
||||
{
|
||||
public class CreateOrderRequest
|
||||
{
|
||||
public OrderType OrderType { get; set; }
|
||||
|
||||
public int PackageId { get; set; }
|
||||
|
||||
//是否使用账户的钱
|
||||
public int UseAccountAmount { get; set; } = 0;
|
||||
|
||||
public string Account { get; set; }
|
||||
|
||||
public string Pwd { get; set; }
|
||||
|
||||
//最小后缀数
|
||||
public int MinPostfix { get; set; }
|
||||
|
||||
//最大后缀数
|
||||
public int MaxPostfix { get; set; }
|
||||
|
||||
//同时在线连接数
|
||||
public int ConnectCount { get; set; }
|
||||
|
||||
//使用的优惠券的Id
|
||||
public int CouponId { get; set; }
|
||||
|
||||
public PayType OPayType { get; set; }
|
||||
|
||||
public PayChannel PayChannel { get; set; }
|
||||
|
||||
public string Channel { get; set; }
|
||||
public string Remark { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using Hncore.Pass.Vpn.Domain;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Hncore.Pass.Vpn.Request.Product
|
||||
{
|
||||
public class CreateTestAccountRequest
|
||||
{
|
||||
public int ProductId { get; set; }
|
||||
|
||||
public int PackageId { get; set; }
|
||||
|
||||
public string Account { get; set; }
|
||||
|
||||
public string Pwd { get; set; }
|
||||
|
||||
public string Remark { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
using Hncore.Infrastructure.WebApi;
|
||||
using Hncore.Pass.Vpn.Domain;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Hncore.Pass.Vpn.Request.Product
|
||||
{
|
||||
public class OrderQueryRequest: PageRequestBase
|
||||
{
|
||||
public List<int> OrderTypes { get; set; }
|
||||
|
||||
public DateTime? BTime { get; set; }
|
||||
|
||||
public DateTime? ETime { get; set; }
|
||||
|
||||
public int? ProductId { get; set; }
|
||||
|
||||
public int? PackageId { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
using Hncore.Infrastructure.WebApi;
|
||||
using Hncore.Pass.Vpn.Domain;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Hncore.Pass.Vpn.Request.Product
|
||||
{
|
||||
public class PutPriceDiscountRequest
|
||||
{
|
||||
public int ProductId { get; set; }
|
||||
public int PackageId { get; set; }
|
||||
public int SchemeId { get; set; }
|
||||
public int BuyPriceDiscount { get; set; }
|
||||
public int RefundDayPriceDiscount { get; set; }
|
||||
public string Remark { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
using Hncore.Infrastructure.WebApi;
|
||||
using Hncore.Pass.Vpn.Domain;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Hncore.Pass.Vpn.Request.Product
|
||||
{
|
||||
public class PutUserPriceRequest
|
||||
{
|
||||
public int ProductId { get; set; }
|
||||
public int PackageId { get; set; }
|
||||
public int UserId { get; set; }
|
||||
public decimal UserPrice { get; set; }
|
||||
public decimal RefundDayPrice { get; set; }
|
||||
public string Remark { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
using Hncore.Infrastructure.WebApi;
|
||||
using Hncore.Pass.Vpn.Domain;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Hncore.Pass.Vpn.Request.Product
|
||||
{
|
||||
public class RefundOrderQueryRequest: PageRequestBase
|
||||
{
|
||||
public List<int> OrderTypes { get; set; }
|
||||
|
||||
public DateTime? BTime { get; set; }
|
||||
|
||||
public DateTime? ETime { get; set; }
|
||||
|
||||
public List<int> ProductIds { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
using Hncore.Pass.Vpn.Domain;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Hncore.Pass.Vpn.Request.Product
|
||||
{
|
||||
public class RefundProcessRequest
|
||||
{
|
||||
public int Id { get; set;}
|
||||
|
||||
public decimal BackAmount { get; set; }
|
||||
|
||||
public string Remark { get; set; }
|
||||
}
|
||||
}
|
||||
12
Services/Hncore.Pass.Vpn/Request/Product/RoutePageRequest.cs
Normal file
12
Services/Hncore.Pass.Vpn/Request/Product/RoutePageRequest.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
using Hncore.Infrastructure.Tree;
|
||||
using Hncore.Infrastructure.WebApi;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Hncore.Pass.Vpn.Request.Product
|
||||
{
|
||||
public class RoutePageRequest : PageRequestBase
|
||||
{
|
||||
public int? ProductId { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using Hncore.Infrastructure.WebApi;
|
||||
using Hncore.Pass.Vpn.Domain;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Hncore.Pass.Vpn.Request.Product
|
||||
{
|
||||
public class SellerOrderQueryRequest : PageRequestBase
|
||||
{
|
||||
public string UserName { get; set; }
|
||||
public DateTime? BTime { get; set; }
|
||||
|
||||
public DateTime? ETime { get; set; }
|
||||
|
||||
public int? ProductId { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
namespace Hncore.Pass.Vpn.Request.Product
|
||||
{
|
||||
public class SetUserDiscountRequest
|
||||
{
|
||||
public int UserId { get; set; }
|
||||
|
||||
public int SchemeId { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
namespace HHncore.Pass.Vpn.Request.Product
|
||||
{
|
||||
public class UpdateAccountPwdRequest
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string Pwd { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
using Hncore.Infrastructure.WebApi;
|
||||
using Hncore.Pass.Vpn.Domain;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Hncore.Pass.Vpn.Request.Product
|
||||
{
|
||||
public class UserConsumeRequest : PageRequestBase
|
||||
{
|
||||
public DateTime? bTime1 { get; set; }
|
||||
public DateTime? eTime1 { get; set; }
|
||||
public DateTime? bTime2 { get; set; }
|
||||
public DateTime? eTime2 { get; set; }
|
||||
|
||||
public string SortLable { get; set; }
|
||||
public int SortOrder { get; set; }
|
||||
public string Profile { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace Hncore.Pass.Oss.Request
|
||||
{
|
||||
public class UploadImageBase64Request
|
||||
{
|
||||
public string Base64 { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
namespace Hncore.Pass.Vpn.Response.Product
|
||||
{
|
||||
public class CodeResponse
|
||||
{
|
||||
public string CodeImage { get; set; }
|
||||
public string Key { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
using Hncore.Pass.Vpn.Domain;
|
||||
|
||||
namespace Hncore.Pass.Vpn.Response.Product
|
||||
{
|
||||
public class PackageInfoResponse
|
||||
{
|
||||
public ProductPackageEntity Package { get; set; }
|
||||
|
||||
public ProductUserPriceEntity UserPrice { get; set; }
|
||||
|
||||
public ProductEntity Product { get; set; }
|
||||
|
||||
public int RestTimes { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
using Hncore.Infrastructure.Tree;
|
||||
using Hncore.Pass.Vpn.Domain;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Hncore.Pass.Vpn.Response.Product
|
||||
{
|
||||
public class PackageUserPriceResponse
|
||||
{
|
||||
public ProductPackageEntity Package { get; set; }
|
||||
|
||||
public ProductUserPriceEntity UserPrice { get; set; }
|
||||
}
|
||||
|
||||
public class ProductWithPackageUserPriceResponse
|
||||
{
|
||||
public ProductResponse Product { get; set; }
|
||||
public List<PackageUserPriceResponse> PackageUserPrices { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
using Hncore.Infrastructure.Tree;
|
||||
using Hncore.Pass.Vpn.Domain;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Hncore.Infrastructure.Extension;
|
||||
namespace Hncore.Pass.Vpn.Response.Product
|
||||
{
|
||||
public class ProductResponse
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string Image { get; set; }
|
||||
public int Sort { get; set; }
|
||||
public string Content { get; set; }
|
||||
public string Profile { get; set; }
|
||||
|
||||
public int OnLine { get; set; } = 1;
|
||||
|
||||
public List<string> ContentLine=> this.Profile.Has()?this.Profile.Split('\n').ToList():new List<string>();
|
||||
|
||||
}
|
||||
|
||||
public class ProductWithPackageResponse
|
||||
{
|
||||
public ProductResponse Product { get; set; }
|
||||
public List<ProductPackageEntity> Packages { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
using Hncore.Infrastructure.Tree;
|
||||
using Hncore.Pass.Vpn.Domain;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Hncore.Infrastructure.Extension;
|
||||
namespace Hncore.Pass.Vpn.Response.Product
|
||||
{
|
||||
public class PackagePriceDiscount
|
||||
{
|
||||
public ProductPackageEntity Package { get; set; }
|
||||
|
||||
public ProductPriceDiscountEntity PriceDiscount { get; set; }
|
||||
}
|
||||
public class ProductWithPriceDiscountResponse
|
||||
{
|
||||
public ProductResponse Product { get; set; }
|
||||
public List<PackagePriceDiscount> PackageDiscounts { get; set; }
|
||||
}
|
||||
}
|
||||
537
Services/Hncore.Pass.Vpn/Service/AgentClient1Service.cs
Normal file
537
Services/Hncore.Pass.Vpn/Service/AgentClient1Service.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
526
Services/Hncore.Pass.Vpn/Service/AgentClient2Service.cs
Normal file
526
Services/Hncore.Pass.Vpn/Service/AgentClient2Service.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
539
Services/Hncore.Pass.Vpn/Service/AgentClient3Service.cs
Normal file
539
Services/Hncore.Pass.Vpn/Service/AgentClient3Service.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
591
Services/Hncore.Pass.Vpn/Service/AgentClient4Service.cs
Normal file
591
Services/Hncore.Pass.Vpn/Service/AgentClient4Service.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
319
Services/Hncore.Pass.Vpn/Service/AgentClient5Service.cs
Normal file
319
Services/Hncore.Pass.Vpn/Service/AgentClient5Service.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
597
Services/Hncore.Pass.Vpn/Service/AgentClient6Service.cs
Normal file
597
Services/Hncore.Pass.Vpn/Service/AgentClient6Service.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
532
Services/Hncore.Pass.Vpn/Service/AgentClient7Service.cs
Normal file
532
Services/Hncore.Pass.Vpn/Service/AgentClient7Service.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
223
Services/Hncore.Pass.Vpn/Service/AgentClientBaseService.cs
Normal file
223
Services/Hncore.Pass.Vpn/Service/AgentClientBaseService.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
21
Services/Hncore.Pass.Vpn/Service/AgentClientLogHandler.cs
Normal file
21
Services/Hncore.Pass.Vpn/Service/AgentClientLogHandler.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
419
Services/Hncore.Pass.Vpn/Service/AgentService.cs
Normal file
419
Services/Hncore.Pass.Vpn/Service/AgentService.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
25
Services/Hncore.Pass.Vpn/Service/ArticleService.cs
Normal file
25
Services/Hncore.Pass.Vpn/Service/ArticleService.cs
Normal 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();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
150
Services/Hncore.Pass.Vpn/Service/ProductAccountService.cs
Normal file
150
Services/Hncore.Pass.Vpn/Service/ProductAccountService.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
63
Services/Hncore.Pass.Vpn/Service/ProductOrderItemService.cs
Normal file
63
Services/Hncore.Pass.Vpn/Service/ProductOrderItemService.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
1321
Services/Hncore.Pass.Vpn/Service/ProductOrderService.cs
Normal file
1321
Services/Hncore.Pass.Vpn/Service/ProductOrderService.cs
Normal file
File diff suppressed because it is too large
Load Diff
34
Services/Hncore.Pass.Vpn/Service/ProductPackageService.cs
Normal file
34
Services/Hncore.Pass.Vpn/Service/ProductPackageService.cs
Normal 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
15
Services/Hncore.Pass.Vpn/Service/ProductRouteService.cs
Normal file
15
Services/Hncore.Pass.Vpn/Service/ProductRouteService.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
78
Services/Hncore.Pass.Vpn/Service/ProductService.cs
Normal file
78
Services/Hncore.Pass.Vpn/Service/ProductService.cs
Normal 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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
68
Services/Hncore.Pass.Vpn/Service/ProductUserPriceService.cs
Normal file
68
Services/Hncore.Pass.Vpn/Service/ProductUserPriceService.cs
Normal 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
30
Services/Hncore.Pass.Vpn/Service/UserService.cs
Normal file
30
Services/Hncore.Pass.Vpn/Service/UserService.cs
Normal 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
49
Services/Hncore.Pass.Vpn/Service/WxAppService.cs
Normal file
49
Services/Hncore.Pass.Vpn/Service/WxAppService.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
34
Services/Hncore.Pass.Vpn/Service/WxAppUserService.cs
Normal file
34
Services/Hncore.Pass.Vpn/Service/WxAppUserService.cs
Normal 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
72
Services/Hncore.Pass.Vpn/Startup.cs
Normal file
72
Services/Hncore.Pass.Vpn/Startup.cs
Normal file
@@ -0,0 +1,72 @@
|
||||
using Hncore.Infrastructure.Service;
|
||||
using Hncore.Infrastructure.WebApi;
|
||||
using Hncore.Pass.Vpn.Domain;
|
||||
using Hncore.Pass.Vpn.Job;
|
||||
using Hncore.Pass.Vpn.Map;
|
||||
using Hncore.Pass.Vpn.Service;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System;
|
||||
using System.Net.Http;
|
||||
|
||||
namespace Hncore.Pass.Vpn
|
||||
{
|
||||
public class Startup
|
||||
{
|
||||
public IConfiguration Configuration { get; }
|
||||
|
||||
private IServiceProvider _IServiceProvider;
|
||||
|
||||
public Startup(IHostingEnvironment env)
|
||||
{
|
||||
Configuration = env.UseAppsettings();
|
||||
}
|
||||
|
||||
public IServiceProvider ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
services.AddDbContext<CourseContext>(opt => { opt.UseMySql(Configuration["MySql"]); });
|
||||
services.AddTransient<AgentClientLogHandler>();
|
||||
services.AddHttpClient("agentClient", c =>
|
||||
{
|
||||
c.DefaultRequestHeaders.Add("hl", "hl");
|
||||
})
|
||||
.AddHttpMessageHandler<AgentClientLogHandler>()
|
||||
.ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler() { UseCookies = false});
|
||||
|
||||
services.AddHttpClient("agentClient1.0", c =>
|
||||
{
|
||||
c.DefaultRequestHeaders.Add("hl", "hl");
|
||||
})
|
||||
.AddHttpMessageHandler<AgentClientLogHandler>()
|
||||
.ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler() { UseCookies = false,AllowAutoRedirect=false });
|
||||
|
||||
services.AddServiceClient(Configuration["Service_BaseUrl"]);
|
||||
services.AutoAddService();
|
||||
return _IServiceProvider=services.Init(Configuration, CompatibilityVersion.Version_2_2, new ServiceOption
|
||||
{
|
||||
UseGlobalManageAuthFilter = false
|
||||
});
|
||||
}
|
||||
|
||||
public void Configure(IApplicationBuilder app, IApplicationLifetime applicationLifetime
|
||||
, ILoggerFactory loggerFactory)
|
||||
{
|
||||
MapConfig.Config();
|
||||
|
||||
app.Init(loggerFactory, applicationLifetime);
|
||||
//启动后台任务
|
||||
applicationLifetime.ApplicationStarted.Register(() =>
|
||||
{
|
||||
// OrderAccountJob.Start(_IServiceProvider);
|
||||
RefrushStatusJob.Start(_IServiceProvider);
|
||||
// ChargeTryJob.Start(_IServiceProvider);
|
||||
ExpireTipJob.Start(_IServiceProvider);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
10
Services/Hncore.Pass.Vpn/appsettings.Development.json
Normal file
10
Services/Hncore.Pass.Vpn/appsettings.Development.json
Normal file
@@ -0,0 +1,10 @@
|
||||
//{
|
||||
// "MySql": "Server=rm-bp12e1533udh1827azo.mysql.rds.aliyuncs.com;Database=etor_property_test;User=etor_test;Password=etor_test!QAZ2wsx;Convert Zero Datetime=True;TreatTinyAsBoolean=false;",
|
||||
// "Redis": "47.92.85.90:6379,password=etor0070x01,defaultDatabase=7,poolsize=1"
|
||||
//}
|
||||
{
|
||||
"Host_BaseUrl": "http://ipistest.etor.top11",
|
||||
"Wx_Mp_Appid": "wxd6b150a17c252fec",
|
||||
"MySql": "Server=47.92.244.89;Database=course;User=root;Password=qaz123!@#;Convert Zero Datetime=True;TreatTinyAsBoolean=false;port=5000;",
|
||||
"Redis": "47.92.85.90:6379,password=etor0070x01,defaultDatabase=10,poolsize=1"
|
||||
}
|
||||
10
Services/Hncore.Pass.Vpn/appsettings.json
Normal file
10
Services/Hncore.Pass.Vpn/appsettings.json
Normal file
@@ -0,0 +1,10 @@
|
||||
//{
|
||||
// "MySql": "Server=rm-bp12e1533udh1827azo.mysql.rds.aliyuncs.com;Database=etor_property_test;User=etor_test;Password=etor_test!QAZ2wsx;Convert Zero Datetime=True;TreatTinyAsBoolean=false;",
|
||||
// "Redis": "47.92.85.90:6379,password=etor0070x01,defaultDatabase=7,poolsize=1"
|
||||
//}
|
||||
{
|
||||
"Host_BaseUrl": "http://ipistest.etor.top11",
|
||||
"Wx_Mp_Appid": "wxd6b150a17c252fec",
|
||||
"MySql": "Server=47.92.244.89;Database=course;User=root;Password=qaz123!@#;Convert Zero Datetime=True;TreatTinyAsBoolean=false;port=5000;",
|
||||
"Redis": "47.92.85.90:6379,password=etor0070x01,defaultDatabase=10,poolsize=1"
|
||||
}
|
||||
1
Services/Hncore.Pass.Vpn/生成模型.txt
Normal file
1
Services/Hncore.Pass.Vpn/生成模型.txt
Normal file
@@ -0,0 +1 @@
|
||||
dotnet ef dbcontext scaffold "Server=47.92.244.89;Database=course;User=root;Password=qaz123!@#;Convert Zero Datetime=True;TreatTinyAsBoolean=false;port=5000;" "Pomelo.EntityFrameworkCore.MySql" -o Domain -t course -t course_catalog -t course_chapter -t course_chapter_learn -t course_chapter_question -t course_comment -t course_group -t course_order
|
||||
Reference in New Issue
Block a user