初始提交

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

View File

@@ -0,0 +1,12 @@
{
"version": 1,
"isRoot": true,
"tools": {
"dotnet-ef": {
"version": "3.1.5",
"commands": [
"dotnet-ef"
]
}
}
}

View File

@@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace Host.Areas.m.Controllers
{
[AllowAnonymous]
[Area("m")]
[Route("m/[controller]/[action]")]
public abstract class MBaseController : Controller
{
}
}

View File

@@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
namespace Host.Areas.m.Controllers
{
public class ProjectController : MBaseController
{
public IActionResult Index()
{
return Content("m/project");
}
}
}

View File

@@ -0,0 +1,89 @@
using Hncore.Pass.Vpn.Domain;
using Hncore.Pass.Vpn.Service;
using Home.Models;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Linq.Expressions;
using Hncore.Infrastructure.Extension;
using Hncore.Infrastructure.EntitiesExtension;
using System.Threading.Tasks;
using System.Linq;
using Microsoft.EntityFrameworkCore;
namespace Home.Controllers
{
public class ArticleController : MvcBaseController
{
ArticleService m_ArticleServce;
public ArticleController(ArticleService _ArticleServce)
{
m_ArticleServce = _ArticleServce;
}
[HttpGet]
public async Task<IActionResult> Index([FromQuery]ArticleSearchModel request)
{
request = request ?? new ArticleSearchModel();
Expression<Func<ArticleEntity, bool>> exp = m => 1 == 1;
if (request.Catalog > 0)
{
exp = exp.And(m => m.CatalogId == request.Catalog);
}
if (request.KeyWord.Has())
{
exp = exp.And(m => m.Title.Contains(request.KeyWord) || m.SubTitle.Contains(request.KeyWord));
}
var ret = await m_ArticleServce.Page(request.PageIndex, request.PageSize, exp);
return View(ret);
}
[HttpGet]
public async Task<IActionResult> Search([FromQuery]ArticleSearchModel request)
{
request = request ?? new ArticleSearchModel();
Expression<Func<ArticleEntity, bool>> exp = m => 1 == 1;
if (request.Catalog > 0)
{
exp = exp.And(m => m.CatalogId == request.Catalog);
}
if (request.KeyWord.Has())
{
exp = exp.And(m => m.Title.Contains(request.KeyWord) || m.SubTitle.Contains(request.KeyWord));
}
var ret = await m_ArticleServce.Page(request.PageIndex, request.PageSize, exp);
return View(ret);
}
[HttpGet]
public async Task<IActionResult> Info(int id)
{
var prev = await m_ArticleServce.Query(m => m.Id < id).OrderByDescending(m => m.Id).FirstOrDefaultAsync();
var ret = await m_ArticleServce.GetById(id);
var next = await m_ArticleServce.Query(m => m.Id > id).OrderBy(m => m.Id).FirstOrDefaultAsync();
return View(new ArticleInfoMode()
{
Prev = prev,
Info = ret,
Next = next
});
}
[HttpGet]
public IActionResult TaoBao()
{
return View();
}
}
}

View File

@@ -0,0 +1,50 @@
using Hncore.Pass.Vpn.Service;
using Home.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using Hncore.Infrastructure.Extension;
namespace Home.Controllers
{
public class HomeController : MvcBaseController
{
ProductService m_ProductService;
ArticleService m_ArticleService;
ProductOrderService m_ProductOrderService;
public HomeController(ProductService _ProductService, ArticleService _ArticleService, ProductOrderService _ProductOrderService)
{
m_ProductService = _ProductService;
m_ArticleService = _ArticleService;
m_ProductOrderService = _ProductOrderService;
}
[Route("/")]
public async Task<IActionResult> Index()
{
var prodectList=await m_ProductService.Query(m=>m.OnLine==1).ToListAsync();
var model = prodectList.MapsTo<ProductModel>();
return View(model);
}
[Route("/h")]
public IActionResult Test()
{
return View();
}
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult Error()
{
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
}
[Route("/Test1")]
public async Task Test1()
{
await m_ProductOrderService.TestProcessOrderAccount();
}
}
}

View File

@@ -0,0 +1,106 @@
using Hncore.Infrastructure.Common;
using Hncore.Infrastructure.EntitiesExtension;
using Hncore.Infrastructure.Extension;
using Hncore.Pass.Vpn.Domain;
using Hncore.Pass.Vpn.Service;
using Home.Models;
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 Home.Controllers
{
public class LineListController : MvcBaseController
{
ProductRouteService m_ProductRouteService;
ProductService m_ProductService;
public LineListController(ProductRouteService _ProductRouteService, ProductService _ProductService)
{
m_ProductRouteService = _ProductRouteService;
m_ProductService = _ProductService;
}
[HttpGet]
public async Task<IActionResult> Index([FromQuery]LineSearchModel request)
{
request = request ?? new LineSearchModel();
Expression<Func<ProductRouteEntity, bool>> exp =null;
if (request.ProductId > 0)
{
exp = m => m.ProductId == request.ProductId;
}
if (request.KeyWord.Has())
{
Expression<Func<ProductRouteEntity, bool>> filterExpr = m =>
m.Province.Contains(request.KeyWord)
|| m.City.Contains(request.KeyWord)
|| m.Name.Contains(request.KeyWord)
|| m.ServerUrl.Contains(request.KeyWord);
if (exp == null)
exp = filterExpr;
else exp=exp.And(filterExpr);
}
var ret = await m_ProductRouteService.Query(exp).OrderBy(m=>m.Sort).ToListAsync();
var products = await m_ProductService.Query(m=>m.OnLine == 1).ToListAsync();
ViewData["products"] = products;
return View(ret);
}
[HttpGet]
public async Task<IActionResult> Excel([FromQuery]LineSearchModel request)
{
request = request ?? new LineSearchModel();
Expression<Func<ProductRouteEntity, bool>> exp = m => 1 == 1;
if (request.ProductId > 0)
{
exp = exp.And(m => m.ProductId == request.ProductId);
}
if (request.KeyWord.Has())
{
exp = exp.Or(m => m.Province.Contains(request.KeyWord));
exp = exp.Or(m => m.City.Contains(request.KeyWord));
exp = exp.Or(m => m.Name.Contains(request.KeyWord));
exp = exp.Or(m => m.KeyWord.Contains(request.KeyWord));
}
var ret = await m_ProductRouteService.Query(exp).ToListAsync();
var data = new ExcelData<ProductRouteEntity>
{
SheetName ="线路表",
Data = ret
};
var title = new List<ExcelTitle>(){
new ExcelTitle { Property = "ProductName", Title = "产品" },
new ExcelTitle { Property = "Province", Title = "省份" },
new ExcelTitle { Property = "City", Title = "城市" },
new ExcelTitle { Property = "Name", Title = "运营商" },
new ExcelTitle { Property = "ServerUrl", Title = "服务器" },
new ExcelTitle { Property = "BandWidth", Title = "实时带宽" },
new ExcelTitle { Property = "IpRemark", Title = "IP量" },
new ExcelTitle { Property = "Status", Title = "状态" },
};
var fileBytes = ExcelHelper.ExportListToExcel(data, title);
var fileName = $"线路表.xlsx";
Response.Headers.Add("X-Suggested-Filename", fileName.UrlEncode());
return File(fileBytes, "application/octet-stream", fileName);
}
}
}

View File

@@ -0,0 +1,13 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace Home.Controllers
{
[Controller]
[AllowAnonymous]
[Route("[Controller]/[Action]")]
public abstract class MvcBaseController : Controller
{
}
}

View File

@@ -0,0 +1,750 @@
using Alipay.AopSdk.Core;
using Alipay.AopSdk.Core.Domain;
using Alipay.AopSdk.Core.Request;
using Alipay.AopSdk.Core.Util;
using Hncore.Infrastructure.Common;
using Hncore.Infrastructure.Serializer;
using Hncore.Infrastructure.WebApi;
using Hncore.Pass.PaymentCenter.Model;
using Hncore.Pass.PaymentCenter.Pay.WxPay;
using Hncore.Pass.PaymentCenter.WxPay.WechatJsPay;
using Hncore.Pass.Vpn.Domain;
using Hncore.Pass.Vpn.Request.Product;
using Hncore.Pass.Vpn.Response.Product;
using Hncore.Pass.Vpn.Service;
using Home.Models;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Linq;
using Hncore.Infrastructure.Extension;
namespace Home.Controllers
{
public class productController : MvcBaseController
{
string Ali_APP_ID ="";
string Ali_APP_PRIVATE_KEY = "";
string ALIPAY_PUBLIC_KEY = "";
string Wx_AppId = "";
string Wx_MchId = "";
string Wx_MchKey = "";
ProductService m_ProductService;
ProductPackageService m_ProductPackageService;
private ProductOrderService m_ProductOrderService;
private IConfiguration m_Configuration;
private WxPayClient m_WxPayClient;
ProductAccountService m_ProductAccountService;
WxAppUserService m_WxAppUserService;
UserService m_UserService;
ProductUserPriceService m_ProductUserPriceService;
public productController(ProductService _ProductService
, ProductOrderService _ProductOrderService
, ProductPackageService _ProductPackageService
, WxPayClient _WxPayClient
,ProductAccountService _ProductAccountService
, WxAppUserService _WxAppUserService
,UserService _UserService
, ProductUserPriceService _ProductUserPriceService
, IConfiguration _Configuration)
{
m_ProductService = _ProductService;
m_ProductOrderService = _ProductOrderService;
m_ProductPackageService = _ProductPackageService;
m_Configuration = _Configuration;
m_WxPayClient = _WxPayClient;
Ali_APP_ID = m_Configuration["Aliyun:Pay:AppId"];
Ali_APP_PRIVATE_KEY = m_Configuration["Aliyun:Pay:PrivateKey"];
ALIPAY_PUBLIC_KEY = m_Configuration["Aliyun:Pay:PublicKey"];//支付宝的公钥,而不是应用的公钥
Wx_AppId = m_Configuration["WxApps:AppID"];
Wx_MchId = m_Configuration["WxApps:MchId"];
Wx_MchKey = m_Configuration["WxApps:MchKey"];
m_ProductAccountService = _ProductAccountService;
m_WxAppUserService = _WxAppUserService;
m_UserService = _UserService;
m_ProductUserPriceService = _ProductUserPriceService;
}
[HttpGet]
public async Task<IActionResult> Index()
{
var respList = await m_ProductService.ProductWithPackage(1);
var userInfo = this.Request.GetUserInfo();
if (userInfo != null)
{
var userPrices = await m_ProductUserPriceService.GetProductUserPrice(userInfo.UserId);
foreach(var product in respList)
{
product.Packages.ForEach(m => {
var userPrice = userPrices.FirstOrDefault(p => p.PackageId == m.Id && p.ProductId == m.ProductId);
if (userPrice != null && userPrice.UserPrice > 0)
{
m.Price = userPrice.UserPrice;
}
});
}
}
return View(respList);
}
[HttpPost,UserAuth]
public async Task<ApiResult> CreateOrder([FromBody]CreateOrderRequest request)
{
var userId = this.Request.GetUserInfo().UserId;
var ret = await m_ProductOrderService.CreateOrder(request, userId);
if (ret.Code != ResultCode.C_SUCCESS)
{
return ret;
}
if (ret.Data.OtherPayAmount == 0)
{
await m_ProductOrderService.ProcessOrderAccount(ret.Data);
return new ApiResult("00");
}
var data = new OrderPayModel()
{
OrderInfo = ret.Data,
};
if (ret.Data.PayType == PayType.Wechat)
{
var url = await CreateWxPayOrder(ret.Data);
data.PayData = url;
return new ApiResult(data);
}
else
{
var body = await CreateAliPayOrder(ret.Data);
data.PayData = body;
}
return new ApiResult(data);
}
#region
private async Task<string> CreateWxPayOrder(ProductOrderEntity request)
{
string callBackUrl = m_Configuration["NotifyUrl"];
var mchInfo = new MchInfo()
{
MchId = Wx_MchId,
Key = Wx_MchKey
};
var createOrderRes = "";
var pName=request.Accounts.Split(",").FirstOrDefault();
var oName = $"{request.ProductName}-{request.PackageName}";
if (pName.Has()) oName = $"{oName}-{pName}";
if (request.PayChannel == PayChannel.WxPc)
{
var payRequest = new WxScanPayCreateOrderRequest()
{
AppId = Wx_AppId,
Body = oName,
MchId = Wx_MchId,
NotifyUrl = callBackUrl,
OutTradeNo = request.OrderNo,
StoreId = 2,
TenantId = 1157,
TotalFee = (int)(request.OtherPayAmount * 100),
ProductId = request.ProductId.ToString(),
TimeExpire=DateTime.Now.AddMinutes(15).ToString("yyyyMMddHHmmss")
};
createOrderRes = await m_WxPayClient.ScanPayCreateOrderAsync(payRequest, mchInfo);
}
else if (request.PayChannel == PayChannel.WxH5)
{
var payRequest = new WxH5PayCreateOrderRequest()
{
AppId = Wx_AppId,
Body = oName,
MchId = Wx_MchId,
NotifyUrl = callBackUrl,
OutTradeNo = request.OrderNo,
StoreId = 2,
TenantId = 1157,
TotalFee = (int)(request.OtherPayAmount * 100),
ProductId = request.ProductId.ToString(),
TimeExpire = DateTime.Now.AddMinutes(15).ToString("yyyyMMddHHmmss")
};
createOrderRes = await m_WxPayClient.H5PayCreateOrderAsync(payRequest, mchInfo);
}
else
{
var wxUserInfo = await m_WxAppUserService.GetWxUser(Wx_AppId, request.UserId);
var payRequest = new WxJsPayCreateOrderRequest()
{
AppId = Wx_AppId,
Body = oName,
MchId = Wx_MchId,
NotifyUrl = callBackUrl,
OutTradeNo = request.OrderNo,
StoreId = 2,
TenantId = 1157,
TotalFee = (int)(request.OtherPayAmount * 100),
UserOpenId = wxUserInfo.Openid,
TimeExpire = DateTime.Now.AddMinutes(15).ToString("yyyyMMddHHmmss")
};
createOrderRes = await m_WxPayClient.JsPayCreateOrderAsync(payRequest, mchInfo);
}
return createOrderRes;
}
[HttpPost, AllowAnonymous]
public async Task<string> WxOrderCallBack()
{
try
{
string xml = "";
LogHelper.Trace("微信支付回调开始", "Notify");
if (Request.Body.CanSeek)
{
Request.Body.Position = 0;
}
using (System.IO.StreamReader reader = new System.IO.StreamReader(Request.Body))
{
xml = reader.ReadToEnd();
}
LogHelper.Trace("微信支付回调,原始数据:", $"{xml}");
WxPayChecker payData = new WxPayChecker();
payData.FromXmlNoCheckSign(xml);
if (!payData.IsSet("out_trade_no"))
{
return FailXml();
}
// 给支付平台的订单号为支付记录id
string orderId = payData["out_trade_no"];
string TransactionId = payData["transaction_id"];
var order = await m_ProductOrderService.GetOrderByNo(orderId);
if(order.OrderState== OrderStatus.Complete|| order.OrderState == OrderStatus.PayOk)
return SuccessXml();
var queryRet = await m_WxPayClient.OrderQuery(new WxJsPayOrderQueryRequest()
{
AppId = Wx_AppId,
NonceStr = payData.GenerateNonceStr(),
TransactionId = TransactionId
}, new MchInfo() { MchId = Wx_MchId, Key = Wx_MchKey });
if (!queryRet) return FailXml();
payData.MchKey = Wx_MchKey;
if (!payData.CheckSign()) return FailXml();
order.OrderState = OrderStatus.PayOk;
order.TradeNo = TransactionId;
order.UpdateTime = DateTime.Now;
await m_ProductOrderService.Update(order);
await m_ProductOrderService.ProcessOrderAccount(order);
}
catch (Exception e)
{
LogHelper.Error("微信支付通知处理失败", e);
return FailXml();
}
return SuccessXml();
}
public string FailXml()
{
return "<xml><return_code>FAIL</return_code> </xml>";
}
private string SuccessXml()
{
return "<xml><return_code>SUCCESS</return_code> </xml>";
}
#endregion
#region
private async Task<string> CreateAliPayOrder(ProductOrderEntity request)
{
string callBackUrl = m_Configuration["Aliyun:Pay:NotifyUrl"];
string ReturnUrl = m_Configuration["Aliyun:Pay:ReturnUrl"];
var pName = request.Accounts.Split(",").FirstOrDefault();
var oName = $"{request.ProductName}-{request.PackageName}";
if (pName.Has()) oName = $"{oName}-{pName}";
if (request.PayChannel == PayChannel.AliPc)
{
// 组装业务参数model
AlipayTradePagePayModel model = new AlipayTradePagePayModel
{
Body = request.PackageName,
Subject = oName,
TotalAmount = request.OtherPayAmount.ToString(),
OutTradeNo = request.OrderNo,
ProductCode = "FAST_INSTANT_TRADE_PAY",//QUICK_WAP_PAY
TimeoutExpress="15m"
};
AlipayTradePagePayRequest aliRequest = new AlipayTradePagePayRequest();
// 设置同步回调地址
aliRequest.SetReturnUrl(ReturnUrl);
// 设置异步通知接收地址
aliRequest.SetNotifyUrl(callBackUrl);
// 将业务model载入到request
aliRequest.SetBizModel(model);
var _aopClient = new DefaultAopClient("https://openapi.alipay.com/gateway.do", Ali_APP_ID, Ali_APP_PRIVATE_KEY);
var response = await _aopClient.PageExecuteAsync(aliRequest);
return response.Body;
}
else if (request.PayChannel == PayChannel.AliH5)
{
Ali_APP_ID = m_Configuration["Aliyun:PayH5:AppId"];
Ali_APP_PRIVATE_KEY = m_Configuration["Aliyun:PayH5:PrivateKey"];
ALIPAY_PUBLIC_KEY = m_Configuration["Aliyun:PayH5:PublicKey"];
callBackUrl = m_Configuration["Aliyun:PayH5:NotifyUrl"];
ReturnUrl = m_Configuration["Aliyun:PayH5:ReturnUrl"];
// 组装业务参数model
AlipayTradeWapPayModel model = new AlipayTradeWapPayModel
{
Body = request.PackageName,
Subject = oName,
TotalAmount = request.OtherPayAmount.ToString(),
OutTradeNo = request.OrderNo,
ProductCode = "QUICK_WAP_PAY",
QuitUrl =this.Request.GetUrl(),
TimeoutExpress = "15m"
};
AlipayTradeWapPayRequest aliRequest = new AlipayTradeWapPayRequest();
// 设置同步回调地址
aliRequest.SetReturnUrl(ReturnUrl);
// 设置异步通知接收地址
aliRequest.SetNotifyUrl(callBackUrl);
// 将业务model载入到request
aliRequest.SetBizModel(model);
var _aopClient = new DefaultAopClient("https://openapi.alipay.com/gateway.do", Ali_APP_ID, Ali_APP_PRIVATE_KEY);
var response = await _aopClient.PageExecuteAsync(aliRequest);
return response.Body;
}
return "";
}
/// <summary>
/// 支付同步回调
/// </summary>
[HttpGet, AllowAnonymous]
public IActionResult AliReturn()
{
/* 实际验证过程建议商户添加以下校验。
1、商户需要验证该通知数据中的out_trade_no是否为商户系统中创建的订单号
2、判断total_amount是否确实为该订单的实际金额即商户订单创建时的金额
3、校验通知中的seller_id或者seller_email) 是否为out_trade_no这笔单据的对应的操作方有的时候一个商户可能有多个seller_id/seller_email
4、验证app_id是否为该商户本身。
*/
Dictionary<string, string> sArray = GetRequestGet();
if (sArray.Count != 0)
{
bool flag = AlipaySignature.RSACheckV2(sArray, ALIPAY_PUBLIC_KEY, "utf-8", "RSA2", false);
if (flag)
{
var ordereNo = sArray["out_trade_no"];
// var order = await m_ProductOrderService.GetOrderByNo(ordereNo);
Console.WriteLine($"同步验证通过,订单号:{sArray["out_trade_no"]}");
ViewData["PayResult"] = "同步验证通过";
}
else
{
Console.WriteLine($"同步验证失败,订单号:{sArray["out_trade_no"]}");
ViewData["PayResult"] = "同步验证失败";
}
}
return Redirect("~/User/MyAccounts");
}
[HttpPost, AllowAnonymous]
public async Task AliNotify()
{
/* 实际验证过程建议商户添加以下校验。
1、商户需要验证该通知数据中的out_trade_no是否为商户系统中创建的订单号
2、判断total_amount是否确实为该订单的实际金额即商户订单创建时的金额
3、校验通知中的seller_id或者seller_email) 是否为out_trade_no这笔单据的对应的操作方有的时候一个商户可能有多个seller_id/seller_email
4、验证app_id是否为该商户本身。
*/
Dictionary<string, string> sArray = GetRequestPost();
LogHelper.Info("AliNotify", AlipaySignature.GetSignContent(sArray));
if (sArray.Count != 0)
{
// bool flag = AlipaySignature.RSA2Check(sArray, ALIPAY_PUBLIC_KEY);
bool flag = AlipaySignature.RSACheckV2(sArray, ALIPAY_PUBLIC_KEY, "utf-8", "RSA2", false);
if (flag)
{
//交易状态
//判断该笔订单是否在商户网站中已经做过处理
//如果没有做过处理根据订单号out_trade_no在商户网站的订单系统中查到该笔订单的详细并执行商户的业务程序
//请务必判断请求时的total_amount与通知时获取的total_fee为一致的
//如果有做过处理,不执行商户的业务程序
//注意:
//退款日期超过可退款期限后(如三个月可退款),支付宝系统发送该交易状态通知
try
{
var ordereNo = sArray["out_trade_no"];
var order = await m_ProductOrderService.GetOrderByNo(ordereNo);
if (order.OrderState == OrderStatus.Complete|| order.OrderState == OrderStatus.PayOk)
{
await Response.WriteAsync("success");
return;
}
order.OrderState = OrderStatus.PayOk;
order.TradeNo = sArray["trade_no"];
order.UpdateTime = DateTime.Now;
await m_ProductOrderService.Update(order);
await m_ProductOrderService.ProcessOrderAccount(order);
Console.WriteLine(Request.Form["trade_status"]);
await Response.WriteAsync("success");
}catch(Exception ex)
{
LogHelper.Error("AliNotify.Exception", ex.Message);
await Response.WriteAsync("fail");
}
}
else
{
LogHelper.Error("AliNotify.Error", "签名校验失败");
await Response.WriteAsync("fail");
}
}
}
/// <summary>
/// 支付同步回调
/// </summary>
[HttpGet, AllowAnonymous]
public IActionResult AliReturnH5()
{
/* 实际验证过程建议商户添加以下校验。
1、商户需要验证该通知数据中的out_trade_no是否为商户系统中创建的订单号
2、判断total_amount是否确实为该订单的实际金额即商户订单创建时的金额
3、校验通知中的seller_id或者seller_email) 是否为out_trade_no这笔单据的对应的操作方有的时候一个商户可能有多个seller_id/seller_email
4、验证app_id是否为该商户本身。
*/
ALIPAY_PUBLIC_KEY = m_Configuration["Aliyun:PayH5:PublicKey"];
Dictionary<string, string> sArray = GetRequestGet();
if (sArray.Count != 0)
{
bool flag = AlipaySignature.RSACheckV2(sArray, ALIPAY_PUBLIC_KEY, "utf-8", "RSA2", false);
if (flag)
{
var ordereNo = sArray["out_trade_no"];
// var order = await m_ProductOrderService.GetOrderByNo(ordereNo);
Console.WriteLine($"同步验证通过,订单号:{sArray["out_trade_no"]}");
ViewData["PayResult"] = "同步验证通过";
}
else
{
Console.WriteLine($"同步验证失败,订单号:{sArray["out_trade_no"]}");
ViewData["PayResult"] = "同步验证失败";
}
}
return Redirect("~/User/MyAccounts");
}
[HttpPost, AllowAnonymous]
public async Task AliNotifyH5()
{
/* 实际验证过程建议商户添加以下校验。
1、商户需要验证该通知数据中的out_trade_no是否为商户系统中创建的订单号
2、判断total_amount是否确实为该订单的实际金额即商户订单创建时的金额
3、校验通知中的seller_id或者seller_email) 是否为out_trade_no这笔单据的对应的操作方有的时候一个商户可能有多个seller_id/seller_email
4、验证app_id是否为该商户本身。
*/
ALIPAY_PUBLIC_KEY = m_Configuration["Aliyun:PayH5:PublicKey"];
Dictionary<string, string> sArray = GetRequestPost();
LogHelper.Info("AliNotify", AlipaySignature.GetSignContent(sArray));
if (sArray.Count != 0)
{
// bool flag = AlipaySignature.RSA2Check(sArray, ALIPAY_PUBLIC_KEY);
bool flag = AlipaySignature.RSACheckV2(sArray, ALIPAY_PUBLIC_KEY, "utf-8", "RSA2", false);
if (flag)
{
//交易状态
//判断该笔订单是否在商户网站中已经做过处理
//如果没有做过处理根据订单号out_trade_no在商户网站的订单系统中查到该笔订单的详细并执行商户的业务程序
//请务必判断请求时的total_amount与通知时获取的total_fee为一致的
//如果有做过处理,不执行商户的业务程序
//注意:
//退款日期超过可退款期限后(如三个月可退款),支付宝系统发送该交易状态通知
try
{
var ordereNo = sArray["out_trade_no"];
var order = await m_ProductOrderService.GetOrderByNo(ordereNo);
if (order.OrderState == OrderStatus.Complete || order.OrderState == OrderStatus.PayOk)
{
await Response.WriteAsync("success");
return;
}
order.OrderState = OrderStatus.PayOk;
order.TradeNo = sArray["trade_no"];
order.UpdateTime = DateTime.Now;
await m_ProductOrderService.Update(order);
await m_ProductOrderService.ProcessOrderAccount(order);
Console.WriteLine(Request.Form["trade_status"]);
await Response.WriteAsync("success");
}
catch (Exception ex)
{
LogHelper.Error("AliNotify.Exception", ex.Message);
await Response.WriteAsync("fail");
}
}
else
{
LogHelper.Error("AliNotify.Error", "签名校验失败");
await Response.WriteAsync("fail");
}
}
}
private Dictionary<string, string> GetRequestGet()
{
Dictionary<string, string> sArray = new Dictionary<string, string>();
ICollection<string> requestItem = Request.Query.Keys;
foreach (var item in requestItem)
{
sArray.Add(item, Request.Query[item]);
}
return sArray;
}
private Dictionary<string, string> GetRequestPost()
{
Dictionary<string, string> sArray = new Dictionary<string, string>();
ICollection<string> requestItem = Request.Form.Keys;
foreach (var item in requestItem)
{
sArray.Add(item, Request.Form[item]);
}
return sArray;
}
#endregion
//[HttpGet]
//public async Task<IActionResult> Success()
//{
// return Content("Success");
//}
//[HttpGet]
//public async Task<IActionResult> ErrorInfo()
//{
// return Content("Error");
//}
[HttpGet, UserAuth]
public async Task<IActionResult> TestIndex(int id)
{
var userId = this.Request.GetUserInfo().UserId;
var product = await m_ProductService.GetById(id);
var package = await m_ProductPackageService.Query(m => m.IsTest == 1 && m.ProductId == id).FirstOrDefaultAsync();
var restTimes = await m_ProductAccountService.GetRestTestCount(userId);
return View("Test", new PackageInfoResponse()
{
Package = package,
Product = product,
RestTimes = restTimes
});
}
[HttpGet, UserAuth]
public async Task<IActionResult> Test(int id)
{
var product = await m_ProductService.GetById(id);
var package = await m_ProductPackageService.Query(m => m.IsTest == 1 && m.ProductId == id).FirstOrDefaultAsync();
var restTimes = 0;
var userInfo = this.Request.GetUserInfo();
if (userInfo != null)
{
var userId = userInfo.UserId;
restTimes = await m_ProductAccountService.GetRestTestCount(userId);
}
return View("Test", new PackageInfoResponse()
{
Package = package,
Product = product,
RestTimes = restTimes
});
}
[HttpGet]
public async Task<IActionResult> Soft()
{
var ret = await m_ProductService.Query(true).ToListAsync();
return View(ret);
}
[HttpGet, AllowAnonymous]
public async Task<ApiResult> IsPay(string orderNo)
{
var orderInfo=await m_ProductOrderService.GetOrderByNo(orderNo);
if (orderInfo.OrderState == OrderStatus.PayOk || orderInfo.OrderState == OrderStatus.Complete)
return new ApiResult(1);
else
return new ApiResult(0);
}
[HttpGet,UserAuth]
public async Task<IActionResult> Buy(int id)
{
var userId = this.Request.GetUserInfo().UserId;
var package = await m_ProductPackageService.GetById(id);
var product = await m_ProductService.GetById(package.ProductId);
var userPrice = await m_ProductUserPriceService.GetPackageUserPrice(package.Id, userId);
if (userPrice != null && userPrice.UserPrice > 0)
{
package.Price = userPrice.UserPrice;
}
return View("buy", new PackageInfoResponse()
{
Package = package,
Product = product
});
}
[HttpGet]
public async Task<IActionResult> ReBuyIndex(string accounts,int productId=0)
{
ViewBag.accounts = "";
ViewBag.errorTip = "";
var model = new ProductWithPackageResponse();
if (accounts.NotHas())
{
ViewBag.errorTip = "请选择账号";
return View(model);
}
var accountList = await m_ProductAccountService.GetAccounts(accounts);
if (productId > 0)
accountList = accountList.Where(m => m.ProductId == productId).ToList();
var productIds = accountList.Select(m => m.ProductId);
var connectCountList = accountList.Select(m => m.ConnectCount);
if (productIds.Distinct().Count() != 1 || connectCountList.Distinct().Count() != 1)
{
ViewBag.errorTip = "续费账号必须为同一种产品且相同的连接数";
return View(model);
}
ViewBag.accounts = accounts;
var id = productIds.First().Value;
var respList = await m_ProductService.GetOneProductWithPackage(id);
var userInfo = this.Request.GetUserInfo();
if (userInfo != null)
{
var userPrices = await m_ProductUserPriceService.GetProductUserPrice(id, userInfo.UserId);
respList.Packages.ForEach(m =>
{
var userPrice = userPrices.FirstOrDefault(p => p.PackageId == m.Id);
if (userPrice != null && userPrice.UserPrice > 0)
{
m.Price = userPrice.UserPrice;
}
});
}
return View(respList);
}
[HttpGet,UserAuth]
public async Task<IActionResult> ReBuy(int packageId, string accounts)
{
var package = await m_ProductPackageService.GetById(packageId);
var product = await m_ProductService.GetById(package.ProductId);
var account = "";
if (accounts.IndexOf(",") == -1)
{
account = accounts;
}
else
{
account = accounts.Split(',')[0];
}
var accountEntity = await m_ProductAccountService.GetProductAccountInfo(package.ProductId, account);
var userId = this.Request.GetUserInfo().UserId;
var userPrice = await m_ProductUserPriceService.GetPackageUserPrice(packageId, userId);
if (userPrice != null && userPrice.UserPrice > 0)
{
package.Price = userPrice.UserPrice;
}
var model = new PackageInfoResponse()
{
Package = package,
Product = product
};
ViewBag.accounts = accounts;
ViewBag.orderType = accounts.Split(",").Count() > 1 ? 4 : 3;
ViewBag.ConnectCount = accountEntity == null ? 1 : accountEntity.ConnectCount;
return View(model);
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,120 @@
using Hncore.Infrastructure.Common;
using Hncore.Infrastructure.Extension;
using Hncore.Pass.BaseInfo.Service;
using Hncore.Pass.Sells.Service;
using Hncore.Wx.Open;
using Home.Models;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Senparc.NeuChar.App.Entities;
using Senparc.Weixin.MP;
using System;
using System.Threading.Tasks;
namespace Home.Controllers
{
[AllowAnonymous]
[Controller]
[Route("[Controller]/[Action]")]
public class WeiXinController : Controller
{
WxAppUserService m_WxAppUserService;
CouponService m_CouponService;
IConfiguration m_Configuration;
public WeiXinController(IConfiguration _Configuration
, WxAppUserService _WxAppUserService
, CouponService _CouponService)
{
m_WxAppUserService = _WxAppUserService;
m_CouponService = _CouponService;
m_Configuration = _Configuration;
}
[HttpGet]
[ActionName("Index")]
public ActionResult Get(string signature, string timestamp, string nonce, string echostr)
{
if (CheckSignature.Check(signature, timestamp, nonce, "hualian"))
{
return Content(echostr); //返回随机字符串则表示验证通过
}
else
{
return Content("failed");
}
}
/// <summary>
/// 最简化的处理流程(不加密)
/// </summary>
[HttpPost]
[ActionName("Index")]
public ActionResult Post(PostModel postModel)
{
if (!CheckSignature.Check(postModel.Signature, postModel.Timestamp, postModel.Nonce, "hualian"))
{
return Content("参数错误!");
}
postModel.Token ="hualian";
postModel.EncodingAESKey = m_Configuration["WxApps:EncodingAESKey"];//根据自己后台的设置保持一致
postModel.AppId = m_Configuration["WxApps:AppID"];//根据自己后台的设置保持一致
var messageHandler = new MyMessageHandler(Request.Body, m_WxAppUserService,m_CouponService);
messageHandler.Execute();//执行微信处理过程
return Content(messageHandler.ResponseDocument.ToString());//v0.7-
//return new WeixinResult(messageHandler);//v0.8+
// return new FixWeixinBugWeixinResult(messageHandler);//v0.8+
}
/// <summary>
/// 微信后台推送过来的用户与公众号交互的信息 消息和事件
/// </summary>
/// <param name="timestamp"></param>
/// <param name="nonce"></param>
/// <param name="encrypt_type"></param>
/// <param name="msg_signature"></param>
/// <returns></returns>
[HttpPost("{appid}"), AllowAnonymous]
public async Task<string> msg_notice(string appid, string timestamp, string nonce, string encrypt_type, string msg_signature)
{
LogHelper.Debug("公众号交互消息", $"appid={appid}{timestamp},{nonce},{encrypt_type},{msg_signature}");
var msg = await this.Request.Body.ReadAsStringAsync();
LogHelper.Debug("公众号交互消息-加密", msg);
var token = m_Configuration["WxOpen:Token"];
var decyptKey = m_Configuration["WxOpen:DecyptKey"];
var appID = m_Configuration["WxOpen:AppID"];
string decMsg = "";
var wxcpt = new WxOpenCrypt(token, decyptKey, appID);
var ret = wxcpt.DecryptMsg(msg_signature, timestamp, nonce, msg, ref decMsg);
if (ret != 0)
{
LogHelper.Error("开放平台推送的消息-解密失败", ret);
return "faild";
}
var flag = false;
try
{
var requestMessage = MessageFactory.GetRequestEntity(decMsg);
if (requestMessage != null)
{
requestMessage.AppId = appid;
flag = await requestMessage.Handler();
}
}
catch (Exception ex)
{
LogHelper.Fatal("微信开放平台的消息-解析失败", ex.Message);
LogHelper.Error("开放平台推送的消息-解密的消息", decMsg);
flag = false;
}
return flag ? "success" : "faild";
}
}
}

4
Host/Dockerfile Normal file
View File

@@ -0,0 +1,4 @@
FROM mcr.microsoft.com/dotnet/core/aspnet:2.2-stretch-slim AS base
WORKDIR /app
COPY . .
ENTRYPOINT ["dotnet", "Host.dll"]

66
Host/Host.csproj Normal file
View File

@@ -0,0 +1,66 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp2.2</TargetFramework>
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
<!--<AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>-->
</PropertyGroup>
<ItemGroup>
<None Remove="sh.cmd" />
</ItemGroup>
<ItemGroup>
<Content Include="sh.cmd" />
</ItemGroup>
<ItemGroup>
<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="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.10.9" />
<PackageReference Include="Senparc.Weixin.MP" Version="16.9.0" />
<PackageReference Include="Senparc.Weixin.MP.MvcExtension" Version="4.1.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Infrastructure\Hncore.Infrastructure\Hncore.Infrastructure.csproj" />
<ProjectReference Include="..\Infrastructure\WxApi\WxApi.csproj" />
<ProjectReference Include="..\Services\Hncore.Pass.BaseInfo\Hncore.Pass.BaseInfo.csproj" />
<ProjectReference Include="..\Services\Hncore.Pass.PaymentCenter\Hncore.Pass.PaymentCenter.csproj" />
<ProjectReference Include="..\Services\Hncore.Pass.Vpn\Hncore.Pass.Vpn.csproj" />
<ProjectReference Include="..\Services\Hncore.Pass.Manage\Hncore.Pass.Manage.csproj" />
<ProjectReference Include="..\Services\Hncore.Pass.OSS\Hncore.Pass.OSS.csproj" />
<ProjectReference Include="..\Services\Hncore.Pass.Sells\Hncore.Pass.Sells.csproj" />
</ItemGroup>
<ItemGroup>
<None Update="Dockerfile">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="upload\readme.txt">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<Folder Include="Areas\m\Data\" />
<Folder Include="Areas\m\Models\" />
<Folder Include="Areas\m\Views\" />
<Folder Include="wwwroot\codes\" />
</ItemGroup>
<ItemGroup>
<None Include="wwwroot\css\.DS_Store" />
<None Include="wwwroot\img\.DS_Store" />
<None Include="wwwroot\js\.DS_Store" />
<None Include="wwwroot\js\bootstrap.min.js" />
<None Include="wwwroot\js\jquery.min.js" />
<None Include="wwwroot\js\swiper.min.js" />
</ItemGroup>
<ProjectExtensions><VisualStudio><UserProperties appsettings_1production_1json__JsonSchema="http://json.schemastore.org/bower" appsettings_1json__JsonSchema="" /></VisualStudio></ProjectExtensions>
</Project>

18
Host/Map/MapConfig.cs Normal file
View File

@@ -0,0 +1,18 @@
using Hncore.Infrastructure.Extension;
using Hncore.Pass.Sells.Domain;
using Hncore.Pass.Vpn.Domain;
using Home.Models;
using Host.Models;
namespace Home.Map
{
public class MapConfig
{
public static void Config()
{
TinyMapperExtension.Binds<ProductModel, ProductEntity>();
TinyMapperExtension.Binds<TaoBaoNotifyModel, TaoBaoOrderEntity>();
}
}
}

View File

@@ -0,0 +1,58 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Razor;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace Host
{
public class MobileViewLocationExpander : IViewLocationExpander
{
public MobileViewLocationExpander()
{
}
private static Regex _detectmobilebrowserregex_b = new Regex(@"(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino", RegexOptions.IgnoreCase | RegexOptions.Multiline);
private static Regex _detectmobilebrowserregex_v = new Regex(@"1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-", RegexOptions.IgnoreCase | RegexOptions.Multiline);
public void PopulateValues([FromServices]ViewLocationExpanderContext context)
{
var userAgent = context.ActionContext.HttpContext.Request.Headers["User-Agent"];
object area = "";
if (context.ActionContext.RouteData.Values.TryGetValue("area", out area) && area.ToString().Equals("admin", StringComparison.CurrentCultureIgnoreCase))
{
context.Values["mobile"] = "";
return;
}
if (IsMobile(userAgent))
{
context.Values["mobile"] = ".Mobile";
}
else
{
context.Values["mobile"] = "";
}
}
private bool IsMobile(string userAgent)
{
if (string.IsNullOrEmpty(userAgent))
return false;
if ((_detectmobilebrowserregex_b.IsMatch(userAgent) || _detectmobilebrowserregex_v.IsMatch(userAgent.Substring(0, 4))))
return true;
return false;
}
public virtual IEnumerable<string> ExpandViewLocations(ViewLocationExpanderContext context,
IEnumerable<string> viewLocations)
{
return viewLocations.Select(f => f.Replace("/Views/", $"/Views{context.Values["mobile"]}/"));
}
}
}

View File

@@ -0,0 +1,17 @@
using Hncore.Infrastructure.WebApi;
using Hncore.Pass.Vpn.Domain;
using System;
namespace Home.Models
{
public class AccountSearchModel : PageRequestBase
{
public DateTime? BTime { get; set; }
public DateTime? ETime { get; set; }
public int? ExpiredDay { get; set; } = -1;//OrderType
public int ProductId { get; set; } = 0;
public int PackageId { get; set; } = 0;
}
}

View File

@@ -0,0 +1,14 @@
using Hncore.Infrastructure.WebApi;
using Hncore.Pass.Vpn.Domain;
using System;
namespace Home.Models
{
public class ArticleInfoMode
{
public ArticleEntity Prev { get; set; }
public ArticleEntity Info { get; set; }
public ArticleEntity Next { get; set; }
}
}

View File

@@ -0,0 +1,12 @@
using Hncore.Infrastructure.WebApi;
using Hncore.Pass.Vpn.Domain;
using System;
namespace Home.Models
{
public class ArticleSearchModel : PageRequestBase
{
public ArticleCatalog Catalog { get; set; } = ArticleCatalog.Top;
}
}

View File

@@ -0,0 +1,13 @@
using Hncore.Infrastructure.WebApi;
using Hncore.Pass.BaseInfo.Models;
using Hncore.Pass.Vpn.Domain;
using System;
namespace Home.Models
{
public class ChargeOrderPayModel
{
public UserChargeOrderEntity OrderInfo { get; set; }
public string PayData { get; set; }
}
}

View File

@@ -0,0 +1,11 @@
using System;
namespace Home.Models
{
public class ErrorViewModel
{
public string RequestId { get; set; }
public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
}
}

View File

@@ -0,0 +1,11 @@
using Hncore.Infrastructure.WebApi;
using Hncore.Pass.Vpn.Domain;
using System;
namespace Home.Models
{
public class LineSearchModel : PageRequestBase
{
public int ProductId { get; set; } = 0;
}
}

View File

@@ -0,0 +1,12 @@
using Hncore.Infrastructure.WebApi;
using Hncore.Pass.Vpn.Domain;
using System;
namespace Home.Models
{
public class OrderPayModel
{
public ProductOrderEntity OrderInfo { get; set; }
public string PayData { get; set; }
}
}

View File

@@ -0,0 +1,18 @@
using Hncore.Infrastructure.WebApi;
using Hncore.Pass.Vpn.Domain;
using System;
namespace Home.Models
{
public class OrderSearchModel: PageRequestBase
{
public DateTime? BTime { get; set; }
public DateTime? ETime { get; set; }
public int? OrderType { get; set; } = 0;//OrderType
public int ProductId { get; set; } = 0;
public int PackageId { get; set; } = 0;
public int IsRefund { get; set; }
}
}

View File

@@ -0,0 +1,15 @@
namespace Home.Models
{
public class OriginAccountAuthRequest
{
public int ProductId { get; set; }
public string Account { get; set; }
public string Pwd { get; set; }
public int StartNum { get; set; } = 0;
public int Count { get; set; } = 0;
}
}

View File

@@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Home.Models
{
public class ProductModel
{
public int Id { get; set; }
public string Name { get; set; }
public string Image { get; set; }
public int Sort { get; set; } = 0;
public string Content { get; set; }
public string Profile { get; set; }
public string Identify { get; set; }
}
}

View File

@@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Home.Models
{
public class PhoneModel
{
public string Phone { get; set; }
public string Pwd { get; set; }
public string Code { get; set; }
public string Wx { get; set; }
public string QQ { get; set; }
}
}

View File

@@ -0,0 +1,58 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Host.Models
{
public class TaoBaoNotifyModel
{
public string Platform { get; set; }
public string PlatformUserId { get; set; }
public string ReceiverName { get; set; }
public string ReceiverMobile { get; set; }
public string ReceiverPhone { get; set; }
public string ReceiverAddress { get; set; }
public string BuyerArea { get; set; }
public string Tid { get; set; }
public string Status { get; set; }
public string SellerNick { get; set; }
public string BuyerNick { get; set; }
public object Type { get; set; }
public string BuyerMessage { get; set; }
public string Price { get; set; }
public int Num { get; set; }
public string TotalFee { get; set; }
public string Payment { get; set; }
public string PayTime { get; set; }
public object PicPath { get; set; }
public object PostFee { get; set; }
public string Created { get; set; }
public object TradeFrom { get; set; }
public List<TaoBaoOrder> Orders { get; set; }
public string SellerMemo { get; set; }
public int SellerFlag { get; set; }
public string CreditCardFee { get; set; }
}
public class TaoBaoOrder
{
public string Oid { get; set; }
public long NumIid { get; set; }
public string OuterIid { get; set; }
public string OuterSkuId { get; set; }
public string Title { get; set; }
public string Price { get; set; }
public int Num { get; set; }
public string TotalFee { get; set; }
public string Payment { get; set; }
public string PicPath { get; set; }
public string SkuId { get; set; }
public string SkuPropertiesName { get; set; }
public string DivideOrderFee { get; set; }
public string PartMjzDiscount { get; set; }
}
}

View File

@@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Home.Models
{
public class UpdateAccountPwdModel
{
public int ProductId { get; set; }
public int UserId { get; set; }
public string Account { get; set; }
public string Pwd { get; set; }
}
}

View File

@@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Home.Models
{
public class UpdatePwdModel
{
public string OldPwd { get; set; }
public string NewPwd { get; set; }
public string ConfirmPwd { get; set; }
}
}

View File

@@ -0,0 +1,46 @@
using Hncore.Pass.BaseInfo.Models;
using Hncore.Pass.Vpn.Domain;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Home.Models
{
public class UserHomeModel
{
public User UserModel { get; set; }
public AccountModel AccountModel { get; set; } = new AccountModel();
public List<ArticleEntity> TopNewsModel { get; set; }
public StatisticModel Statistic { get; set; } = new StatisticModel();
}
public class AccountModel
{
public int TotalCount { get; set; }
public int ExpriedCount { get; set; }
}
public class StatisticModel
{
public decimal TodayExpend { get; set; }
public decimal TodayRefund { get; set; }
public decimal TodayCharege { get; set; }
public decimal MonthExpend { get; set; }
public decimal MonthRefund { get; set; }
public decimal MonthCharege { get; set; }
public decimal YearExpend { get; set; }
}
}

View File

@@ -0,0 +1,113 @@
using Senparc.Weixin.MP.MessageHandlers;
using Senparc.Weixin.MP.Entities;
using System;
using System.IO;
using System.Linq;
using System.Xml.Linq;
using Senparc.Weixin.MP.MessageContexts;
using Senparc.NeuChar.Entities;
using Senparc.Weixin.MP.Entities.Request;
using Hncore.Pass.BaseInfo.Service;
using Hncore.Pass.Sells.Service;
using Hncore.Wx.Open;
using Hncore.Infrastructure.Common;
namespace Home.Models
{
public class MyMessageHandler : MessageHandler<DefaultMpMessageContext>
{
WxAppUserService m_WxAppUserService;
CouponService m_CouponService;
public MyMessageHandler(Stream inputStream
, WxAppUserService _WxAppUserService
, CouponService _CouponService
, PostModel postModel = null
, int maxRecordCount = 0) : base(inputStream, postModel)
{
m_WxAppUserService = _WxAppUserService;
m_CouponService = _CouponService;
}
public override IResponseMessageBase OnTextRequest(RequestMessageText requestMessage)
{
string openid = requestMessage.FromUserName;
if (requestMessage.Content == "Hi")
{
var responseMessage = this.CreateResponseMessage<ResponseMessageText>();
responseMessage.Content = "hello";
return responseMessage;
}
return base.OnTextRequest(requestMessage);
}
/// <summary>
/// 菜单按钮
/// </summary>
/// <param name="requestMessage"></param>
/// <returns></returns>
public override IResponseMessageBase OnEvent_ClickRequest(RequestMessageEvent_Click requestMessage)
{
switch (requestMessage.EventKey)
{
case "haibao": return null;
}
return base.OnEvent_ClickRequest(requestMessage);
}
/// <summary>
/// 关注
/// </summary>
/// <param name="requestMessage"></param>
/// <returns></returns>
public override IResponseMessageBase OnEvent_SubscribeRequest(RequestMessageEvent_Subscribe requestMessage)
{
LogHelper.Info("OnEvent_SubscribeRequest", requestMessage.FromUserName);
string appId = requestMessage.ToUserName;
string openid = requestMessage.FromUserName;
var appWxinfo = m_WxAppUserService.GetByOpenId(openid);
if (appWxinfo == null)
{
var mpUserInfo = WxOpenApi.GetUserinfoByOpenId(appId, openid).Result;
var wx = new Hncore.Pass.BaseInfo.Models.WxAppUserEntity()
{
Appid = requestMessage.ToUserName,
UserId = 0,
HeadImgUrl = mpUserInfo.headimgurl,
NickName = mpUserInfo.nickname,
City = mpUserInfo.city,
Country = mpUserInfo.country,
Openid = openid,
UserName = mpUserInfo.nickname,
IsSubscribe=1,
};
m_WxAppUserService.Add(wx).Wait();
}
else if (appWxinfo.UserId>0 &&appWxinfo.IsSubscribe == 0)
{
appWxinfo.IsSubscribe = 1;
m_WxAppUserService.Update(appWxinfo).Wait();
m_CouponService.Give(5, "", appWxinfo.UserId, 1, Hncore.Pass.Sells.Domain.Enums.CouponOriginType.MP, "关注公众号赠送").Wait();
}
return base.OnEvent_SubscribeRequest(requestMessage);
}
/// <summary>
/// 默认消息
/// </summary>
/// <param name="requestMessage"></param>
/// <returns></returns>
public override IResponseMessageBase DefaultResponseMessage(IRequestMessageBase requestMessage)
{
// var responseMessage = this.CreateResponseMessage<ResponseMessageText>();
// responseMessage.Content = "Hi";
//return responseMessage;
return null;
}
}
}

View File

@@ -0,0 +1,18 @@
using Hncore.Infrastructure.WebApi;
using Hncore.Pass.Vpn.Domain;
using System;
namespace Home.Models
{
public class WxUserCallbackInfo
{
public string openid { get; set; }
public string nickname { get; set; }
public string sex { get; set; }
public string province { get; set; }
public string city { get; set; }
public string country { get; set; }
public string headimgurl { get; set; }
public string unionid { get; set; }
}
}

32
Host/Program.cs Normal file
View File

@@ -0,0 +1,32 @@
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using System;
using System.Text;
namespace Host
{
public class Program
{
public static void Main(string[] args)
{
CreateWebHostBuilder(args).Build().Run();
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args){
var hsot = WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>();
if (args.Length > 0)
{
if (args[0] == "-u")
{
hsot.UseUrls(args[1]);
}
}
return hsot;
}
// .UseStartup<Etor.PSIP.BaseInfo.Startup>();
// .UseStartup<Etor.PSIP.Manage.Startup>();
}
}

View File

@@ -0,0 +1,33 @@
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:60989",
"sslPort": 0
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"Host": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"applicationUrl": "http://localhost:5000"
},
"Docker": {
"commandName": "Docker",
"launchBrowser": true,
"launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}",
"publishAllPorts": true
}
}
}

View File

@@ -0,0 +1,12 @@
Scaffolding has generated all the files and added the required dependencies.
However the Application's Startup code may required additional changes for things to work end to end.
Add the following code to the Configure method in your Application's Startup class if not already done:
app.UseMvc(routes =>
{
routes.MapRoute(
name : "areas",
template : "{area:exists}/{controller=Home}/{action=Index}/{id?}"
);
});

131
Host/Startup.cs Normal file
View File

@@ -0,0 +1,131 @@
using Hncore.Infrastructure.AliYun;
using Hncore.Infrastructure.WebApi;
using Hncore.Wx.Open;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Razor;
using Microsoft.AspNetCore.Rewrite;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using System;
using System.Net.Http;
using System.Text;
using Hncore.Wx.Open;
using Senparc.Weixin.MP.Containers;
using Senparc.CO2NET.RegisterServices;
using Senparc.Weixin.RegisterServices;
using Microsoft.Extensions.Options;
using Senparc.CO2NET;
using Senparc.Weixin;
using Senparc.Weixin.Entities;
using Senparc.Weixin.MP;
namespace Host
{
public class Startup
{
public IConfiguration Configuration { get; }
Hncore.Pass.BaseInfo.Startup _BaseInfoStartup;
Hncore.Pass.Manage.Startup _ManageStartup;
Hncore.Pass.OSS.Startup _OssStartup;
Hncore.Pass.Vpn.Startup _CourseStartup;
Hncore.Pass.Sells.Startup _SellStartup;
Hncore.Pass.PaymentCenter.Startup _PaymentCenterStartup;
public Startup(IHostingEnvironment env)
{
Configuration = env.UseAppsettings();
_BaseInfoStartup = new Hncore.Pass.BaseInfo.Startup(env);
_ManageStartup = new Hncore.Pass.Manage.Startup(env);
_OssStartup = new Hncore.Pass.OSS.Startup(env);
_CourseStartup= new Hncore.Pass.Vpn.Startup(env);
_SellStartup = new Hncore.Pass.Sells.Startup(env);
_PaymentCenterStartup = new Hncore.Pass.PaymentCenter.Startup(env);
}
public IServiceProvider ConfigureServices(IServiceCollection services)
{
services.AddWxApi();
//删除cookie需要
//services.Configure<CookiePolicyOptions>(options =>
//{
// options.CheckConsentNeeded = context => false;
// options.MinimumSameSitePolicy = SameSiteMode.None;
//});
services.Configure<RazorViewEngineOptions>(options =>
{
options.ViewLocationExpanders.Add(new MobileViewLocationExpander());
});
services.AddSingleton<AliDayu>();
_OssStartup.ConfigureServices(services);
_ManageStartup.ConfigureServices(services);
_CourseStartup.ConfigureServices(services);
_SellStartup.ConfigureServices(services);
_PaymentCenterStartup.ConfigureServices(services);
//foreach(var service in services)
//{
// Console.WriteLine(service.ServiceType.FullName);
//}
services.AddSenparcGlobalServices(Configuration)//Senparc.CO2NET 全局注册
.AddSenparcWeixinServices(Configuration);//Senparc.Weixin 注册
return _BaseInfoStartup.ConfigureServices(services);
}
public void Configure(IApplicationBuilder app
, IApplicationLifetime applicationLifetime
,ILoggerFactory loggerFactory
, IHostingEnvironment env
, IHttpClientFactory httpFactory
, IServiceProvider serviceProvider
,IOptions<SenparcSetting> senparcSetting
, IOptions<SenparcWeixinSetting> senparcWeixinSetting)
{
app.UseStaticFiles();
_ManageStartup.Configure(app, env, loggerFactory, applicationLifetime);
_BaseInfoStartup.Configure(app, applicationLifetime, loggerFactory);
_CourseStartup.Configure(app, applicationLifetime,loggerFactory);
_OssStartup.Configure(app, applicationLifetime, loggerFactory);
_SellStartup.Configure(app, applicationLifetime, loggerFactory);
_PaymentCenterStartup.Configure(app, applicationLifetime, loggerFactory);
Home.Map.MapConfig.Config();
app.MapWhen(context =>
{
return context.Request.Path.Value.StartsWith("/admin");
}, appBuilder =>
{
var option = new RewriteOptions();
option.AddRewrite(".*", "/admin/index.html", true);
appBuilder.UseRewriter(option);
appBuilder.UseStaticFiles();
//appBuilder.Run(async c =>
//{
// var file = env.WebRootFileProvider.GetFileInfo("index.html");
// c.Response.ContentType = "text/html";
// using (var fileStream = new FileStream(file.PhysicalPath, FileMode.Open, FileAccess.Read))
// {
// await StreamCopyOperation.CopyToAsync(fileStream, c.Response.Body, null, BufferSize, c.RequestAborted);
// }
//});
});
app.UseWxApi();
//关于 UseSenparcGlobal() 的更多用法见 CO2NET Demohttps://github.com/Senparc/Senparc.CO2NET/blob/master/Sample/Senparc.CO2NET.Sample.netcore/Startup.cs
//IRegisterService register = RegisterService.Start(env, senparcSetting.Value)
// .UseSenparcGlobal();
//register.UseSenparcWeixin(senparcWeixinSetting.Value, senparcSetting.Value)
// .RegisterMpAccount(senparcWeixinSetting.Value, "【盛派网络小助手】公众号");
AccessTokenContainer.RegisterAsync(Configuration["WxApps:AppID"], Configuration["WxApps:AppSecret"]);
}
}
}

View File

@@ -0,0 +1,28 @@
using Hncore.Infrastructure.WebApi;
using Hncore.Pass.Vpn.Domain;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Threading.Tasks;
namespace ViewComponents
{
public class PagerModel
{
public int Total { get; set; }
public int PageSize { get; set; } = 50;
public int PageIndex { get; set; } = 1;
public string Param { get; set; }
public int TotalPage { get => (int)Math.Ceiling(this.Total / (this.PageSize * 1.0d)); }
}
public class PagerViewComponent: ViewComponent
{
public async Task<IViewComponentResult> InvokeAsync(PagerModel model)
{
return View(model);
}
}
}

View File

@@ -0,0 +1,13 @@
using Microsoft.AspNetCore.Mvc;
using System.Threading.Tasks;
namespace ViewComponents
{
public class PayOkViewComponent : ViewComponent
{
public async Task<IViewComponentResult> InvokeAsync()
{
return View();
}
}
}

View File

@@ -0,0 +1,13 @@
using Microsoft.AspNetCore.Mvc;
using System.Threading.Tasks;
namespace ViewComponents
{
public class PayWaitViewComponent : ViewComponent
{
public async Task<IViewComponentResult> InvokeAsync()
{
return View();
}
}
}

View File

@@ -0,0 +1,13 @@
using Microsoft.AspNetCore.Mvc;
using System.Threading.Tasks;
namespace ViewComponents
{
public class RedirecctLoginViewComponent : ViewComponent
{
public async Task<IViewComponentResult> InvokeAsync()
{
return View();
}
}
}

View File

@@ -0,0 +1,60 @@
@using Hncore.Pass.Vpn.Domain
@using Hncore.Infrastructure.Data
@using Hncore.Infrastructure.Extension
@model PageData<ArticleEntity>
@{
var type = this.Context.Request.GetInt("Catalog");
}
<div class="quanjushousuo">
<form asp-action="Search" asp-controller="Article" method="get">
<p><input type="text" name="KeyWord" placeholder="请输入问题关键词" /><button type="submit" class="btnOrange">搜索全部</button></p>
<p class="hot">搜索热词:<span>账号无法登录</span><span>如何充值</span></p>
</form>
</div>
<div class="jiaocheng">
<div class="item">
<p><a asp-action="info" asp-controller="article" asp-route-id="3"><img src="~/m/img/ios.png"></a></p>
<p>苹果手机教程</p>
</div>
<div class="item">
<p><a asp-action ="info" asp-controller="article" asp-route-id="4"><img src="~/m/img/az.png"></a></p>
<p>安卓手机教程</p>
</div>
<div class="item">
<p><a asp-action="info" asp-controller="article" asp-route-id="5"><img src="~/m/img/mnq.png"></a></p>
<p>安卓模拟器教程</p>
</div>
<div class="item">
<p><a asp-action="info" asp-controller="article" asp-route-id="6"><img src="~/m/img/pc.png"></a></p>
<p>windows电脑教程</p>
</div>
</div>
<div class="newsList">
<!-- Nav tabs -->
<ul class="nav nav-tabs" role="tablist">
<li role="presentation" class="@(type==1?"active":"")"><a href="?Catalog=1">聚IP头条</a></li>
<li role="presentation" class="@(type==2?"active":"")"><a href="?Catalog=2">优惠活动</a></li>
<li role="presentation" class="@(type==3?"active":"")"><a href="?Catalog=3">常见问题</a></li>
<li role="presentation" class="@(type==4?"active":"")"><a href="?Catalog=4">新手教程</a></li>
</ul>
<!-- Tab panes -->
<div class="tab-content">
<div role="tabpanel" class="tab-pane active" id="home">
<ul class="news">
@foreach (var item in Model.List)
{
<li><a asp-action="info" asp-controller="article" asp-route-id="@item.Id">@item.Title</a><span>@item.CreateTime.ToString("yyyy.MM.dd")</span></li>
}
</ul>
</div>
@*<div role="tabpanel" class="tab-pane" id="profile">2</div>
<div role="tabpanel" class="tab-pane" id="messages">3</div>
<div role="tabpanel" class="tab-pane" id="settings">4</div>*@
</div>
</div>

View File

@@ -0,0 +1,45 @@
@using Hncore.Pass.Vpn.Domain
@using Hncore.Infrastructure.Data
@using Hncore.Infrastructure.Extension
@model PageData<ArticleEntity>
@{
var type = this.Context.Request.GetInt("Catalog");
}
<div class="quanjushousuo">
<form asp-action="Search" asp-controller="Article" method="get">
<p><input type="text" name="KeyWord" placeholder="请输入问题关键词" /><button type="submit" class="btnOrange">搜索全部</button></p>
<p class="hot">搜索热词:<span>账号无法登录</span><span>如何充值</span></p>
</form>
</div>
<div class="jiaocheng">
<div class="item">
<p><a asp-action="info" asp-controller="article" asp-route-id="3"><img src="~/m/img/ios.png"></a></p>
<p>苹果手机教程</p>
</div>
<div class="item">
<p><a asp-action="info" asp-controller="article" asp-route-id="4"><img src="~/m/img/az.png"></a></p>
<p>安卓手机教程</p>
</div>
<div class="item">
<p><a asp-action="info" asp-controller="article" asp-route-id="5"><img src="~/m/img/mnq.png"></a></p>
<p>安卓模拟器教程</p>
</div>
<div class="item">
<p><a asp-action="info" asp-controller="article" asp-route-id="6"><img src="~/m/img/pc.png"></a></p>
<p>windows电脑教程</p>
</div>
</div>
<div class="newsList">
<div class="tab-content">
<div role="tabpanel" class="tab-pane active">
<ul class="news">
@foreach (var item in Model.List)
{
<li><a asp-action="info" asp-controller="article" asp-route-id="@item.Id">@item.Title</a><span>@item.CreateTime.ToString("yyyy.MM.dd")</span></li>
}
</ul>
</div>
</div>
</div>

View File

@@ -0,0 +1,26 @@
@using Hncore.Pass.Vpn.Domain
@using Hncore.Infrastructure.Extension
@model ArticleInfoMode
@{
}
<div class="quanjushousuo">
<form asp-action="Search" asp-controller="Article" method="get">
<p><input type="text" name="KeyWord" placeholder="请输入问题关键词" /><button type="submit" class="btnOrange">搜索全部</button></p>
<p class="hot">搜索热词:<span>账号无法登录</span><span>如何充值</span></p>
</form>
</div>
<div class="lujing">
<a href="/">首页</a>><span>@Model.Info.CatalogId.GetEnumDisplayName()</span>
</div>
<div class="lineBar">
</div>
<div class="dmain">
<p class="dtit">@Model.Info.Title</p>
<p class="dtime grayText">@Model.Info.CreateTime.ToString("yyyy.MM.dd")</p>
<p class="dcon">
@Html.Raw(Model.Info.Content)
</p>
</div>

View File

@@ -0,0 +1,39 @@
<div class="container-fluid tAd">
<img src="~/img/tBanner.png">
</div>
<div class="container-fluid taobao_tintro text-center">
<p>您可通过淘宝付款系统自动赠送1元无限制优惠券。</p>
<p>购买任意套餐都可以使用相当于天卡半价每隔30天可参加一次即得1张。</p>
</div>
<div class="container tPeitu">
<img src="~/img/peitu.png">
</div>
<div class="container ttishi text-center">
—— 为方便充值及开通,请选择自己需要的产品的对应店铺 ——
</div>
<div class="container">
<div class="row tlink">
<div class="col-lg-3 col-xs-6 col-sm-6">
<a href="https://item.taobao.com/item.htm?spm=a230r.7195193.1997079397.8.5a165f8bWrye7I&id=537279953649&abbucket=4
" target="_blank"><img src="~/img/t1.png"></a>
</div>
<div class="col-lg-3 col-xs-6 col-sm-6">
<a href="https://item.taobao.com/item.htm?spm=a230r.7195193.1997079397.8.5a165f8b9jMT39&id=557842664450&abbucket=4
" target="_blank"><img src="~/img/t2.png"></a>
</div>
</div>
<div class="row tlink">
<div class="col-lg-3 col-xs-6 col-sm-6">
<a href="https://item.taobao.com/item.htm?spm=a230r.7195193.1997079397.8.5a165f8b9jMT39&id=557842664450&abbucket=4
" target="_blank"><img src="~/img/t3.png"></a>
</div>
<div class="col-lg-3 col-xs-6 col-sm-6">
<a href="https://item.taobao.com/item.htm?spm=a230r.7195193.1997079397.28.72145f8bwi5F1r&id=613389354570&abbucket=4" target="_blank"><img src="~/img/t4.png"></a>
</div>
</div>
</div>

View File

@@ -0,0 +1,303 @@
@model List<ProductModel>
@using Hncore.Pass.BaseInfo.Response
@using Hncore.Infrastructure.Serializer
@using Hncore.Pass.Vpn.Service
@using Hncore.Pass.Vpn.Domain
@using Microsoft.Extensions.Configuration
@inject ArticleService m_ArticleService
@inject IConfiguration m_Configuration
@{
ViewData["Title"] = "聚IP JUIP.COM-千万动态ip切换自建机房ip代理覆盖全国多款市面热销产品";
Layout = "_Layout";
UserLoginModel user = null;
if (this.Context.Request.Cookies.TryGetValue("userInfo", out string userCookie))
{
user = userCookie.FromJsonTo<UserLoginModel>();
}
var articleNews = await m_ArticleService.GetTop(12, ArticleCatalog.Top);
var activityNews = await m_ArticleService.GetTop(12, ArticleCatalog.Activity);
var helpsNews = await m_ArticleService.GetTop(12, ArticleCatalog.Help);
var QANews = await m_ArticleService.GetTop(12, ArticleCatalog.QA);
var baseUrl = m_Configuration["BaseInfoUrl"];
Func<string, string> P = (path) => $"{baseUrl}{path}";
var epoch = (DateTime.Now.ToUniversalTime().Ticks - 621355968000000000) / 10000000;
var countStr = epoch.ToString().Substring(0, 8);
}
<style>
.swiper-container-youshi .swiper-slide-active{
background:rgba(0,0,0.8);
}
</style>
<div class="banner">
<div class="buttonList">
<div class="item">
<a asp-action="soft" asp-controller="product"> <button type="button" class="btnBlue">客户端下载</button></a>
</div>
<div class="item">
<a asp-action="index" asp-controller="linelist"> <button type="button" class="btnBlue">PPTP线路表</button></a>
</div>
<div class="item">
<a asp-action="index" asp-controller="product"> <button type="button" class="btnOrange">免费试用</button></a>
</div>
</div>
</div>
<div class="titProducts">
<p>PRODUCTS</p>
<p>产品介绍</p>
</div>
<div class="conProducts">
<!-- Swiper -->
<div class="swiper-container">
<div class="swiper-wrapper">
@foreach (var item in Model.Where(m => m.Sort != 1000))
{
<div class="swiper-slide">
<div class="productCard">
@*<div class="item">
<img src="@P(item.Image)" />
</div>*@
<div class="item pName">
@item.Name
</div>
<div class="item">
@item.Profile
</div>
<div class="item showLine">
<a asp-action="index" asp-controller="linelist" asp-route-ProductId="@item.Id">查看线路表→</a>
</div>
<div class="item">
<a asp-action="index" asp-controller="product" asp-route-id="@item.Id"><button type="button" class="btnBlue">测试与购买</button></a>
</div>
</div>
</div>
}
</div>
<!-- Add Arrows -->
<div class="swiper-button-next"></div>
<div class="swiper-button-prev"></div>
</div>
</div>
<div class="youshi">
<!-- Swiper -->
<div class="swiper-container-youshi">
<div class="swiper-wrapper">
<div class="swiper-slide" style="background-image:url(./m/img/youshi-bg.png)">
<div class="youshiList">
<div class="item">
<img src="~/m/img/y1.png">
</div>
<div class="item">
全网产品最多IP库最大
</div>
<div class="item">
旗下有强子PPTP老鹰PPTP先锋PPTP星星PPTP等十几种动态IP多产品组合畅享IP库翻倍可用IP超1亿
</div>
</div>
</div>
<div class="swiper-slide" style="background-image:url(./img/youshi-bg.png)">
<div class="youshiList">
<div class="item">
<img src="~/m/img/y2.png">
</div>
<div class="item">
全设备全协议支持
</div>
<div class="item">
支持安卓iOS电脑windowslinux等系统。支持PPTPL2TPSSTP等协议
</div>
</div>
</div>
<div class="swiper-slide" style="background-image:url(./img/youshi-bg.png)">
<div class="youshiList">
<div class="item">
<img src="~/m/img/y3.png">
</div>
<div class="item">
用户独享宽带
</div>
<div class="item">
一号一拨绝不超拨快速切换平均带宽6-10兆最高可达50兆
</div>
</div>
</div>
<div class="swiper-slide" style="background-image:url(./img/youshi-bg.png)">
<div class="youshiList">
<div class="item">
<img src="~/m/img/y4.png">
</div>
<div class="item">
价低质优,免费测试
</div>
<div class="item">
全自营机房一手资源,价低质优,量大可联系客服获取最低价
</div>
</div>
</div>
<div class="swiper-slide" style="background-image:url(./img/youshi-bg.png)">
<div class="youshiList">
<div class="item">
<img src="~/m/img/y5.png">
</div>
<div class="item">
专属产品定制
</div>
<div class="item">
支持定制独立服务器,可针对特定的项目需求定制专用产品
</div>
</div>
</div>
<div class="swiper-slide" style="background-image:url(./img/youshi-bg.png)">
<div class="youshiList">
<div class="item">
<img src="~/m/img/y6.png">
</div>
<div class="item">
专业的服务团队
</div>
<div class="item">
资深售前售后1对1指导7*24小时实时响应竭诚为您服务
</div>
</div>
</div>
</div>
<!-- Add Pagination -->
<div class="swiper-pagination"></div>
</div>
</div>
<div class="map">
</div>
<div class="use">
</div>
<div class="titProducts">
<p>INFORMATION</p>
<p>资讯&帮助</p>
</div>
<div class="newsList">
<!-- Nav tabs -->
<ul class="nav nav-tabs" role="tablist">
<li role="presentation" class="active"><a href="#home" aria-controls="home" role="tab" data-toggle="tab">聚IP头条</a></li>
<li role="presentation"><a href="#profile" aria-controls="profile" role="tab" data-toggle="tab">常见问题</a></li>
<li role="presentation"><a href="#messages" aria-controls="messages" role="tab" data-toggle="tab">新手教程</a></li>
<li role="presentation"><a href="#settings" aria-controls="settings" role="tab" data-toggle="tab">优惠活动</a></li>
</ul>
<!-- Tab panes -->
<div class="tab-content">
<div role="tabpanel" class="tab-pane active" id="home">
<ul class="news">
@foreach (var item in articleNews)
{
<li><a asp-action="info" asp-controller="article" asp-route-id="@item.Id"><span>@item.CreateTime.ToString("yyyy.MM.dd")</span>@item.Title</a></li>
}
</ul>
</div>
<div role="tabpanel" class="tab-pane" id="profile">
<ul class="news">
@foreach (var item in activityNews)
{
<li><a asp-action="info" asp-controller="article" asp-route-id="@item.Id"><span>@item.CreateTime.ToString("yyyy.MM.dd")</span>@item.Title</a></li>
}
</ul>
</div>
<div role="tabpanel" class="tab-pane" id="messages">
<ul class="news">
@foreach (var item in QANews)
{
<li><a asp-action="info" asp-controller="article" asp-route-id="@item.Id"><span>@item.CreateTime.ToString("yyyy.MM.dd")</span>@item.Title</a></li>
}
</ul>
</div>
<div role="tabpanel" class="tab-pane" id="settings">
<ul class="news">
@foreach (var item in helpsNews)
{
<li><a asp-action="info" asp-controller="article" asp-route-id="@item.Id"><span>@item.CreateTime.ToString("yyyy.MM.dd")</span>@item.Title</a></li>
}
</ul>
</div>
</div>
</div>
<div class="qixia">
<p>旗下产品</p>
<ul>
@foreach (var item in Model.Where(m => m.Sort != 1000))
{
<li><a asp-action="index" asp-controller="product" asp-route-id="@item.Id">@item.Name</a></li>
}
</ul>
</div>
<div class="linkus">
<div class="item">
<p>联系我们</p>
<p>企业电话400 800 9925</p>
<p>工作时间周一到周日8:00-24:00</p>
</div>
<div class="item">
<p>商务合作</p>
<p>电话/微信18039519517</p>
<p>QQ508095081</p>
</div>
</div>
<div class="ewm">
<p><img src="~/m/img/ewm.png"></p>
<p class="banquan">copyright 2020 聚IP JUIP.COM 版权所有</p>
</div>
<script type="text/javascript">
$('#myTabs a').click(function (e) {
e.preventDefault()
$(this).tab('show')
})
</script>
<!-- Initialize Swiper -->
<script>
var swiper = new Swiper('.swiper-container', {
slidesPerView: 3,
spaceBetween: 30,
slidesPerGroup: 1,
loop: false,
loopFillGroupWithBlank: true,
pagination: {
el: '.swiper-pagination',
clickable: true,
},
navigation: {
nextEl: '.swiper-button-next',
prevEl: '.swiper-button-prev',
},
});
</script>
<script>
var swiper = new Swiper('.swiper-container-youshi', {
effect: 'coverflow',
grabCursor: true,
centeredSlides: true,
slidesPerView: 'auto',
coverflowEffect: {
rotate: 50,
stretch: 0,
depth: 100,
modifier: 1,
slideShadows: true,
},
pagination: {
el: '.swiper-pagination',
},
});
</script>

View File

@@ -0,0 +1,172 @@
@using Hncore.Pass.Vpn.Domain
@using Hncore.Infrastructure.Extension
@using Hncore.Pass.Vpn.Service
@inject ProductService m_ProductService
@model List<ProductRouteEntity>
@{
var pid = this.Context.Request.GetInt("ProductId");
var product = ViewData["products"] as List<ProductEntity>;
var currentProduct = (await m_ProductService.GetById(pid)) ?? new ProductEntity();
var lineTotalCount = Model.Count;
var lineCount = Model.Where(m => m.Status == "正常").Count();
}
<div class="quanjushousuo">
<form asp-action="index" asp-controller="linelist" method="get">
<p><input type="text" name="KeyWord" placeholder="输入地区/名称/服务器" id="KeyWord" /><button type="submit" class="btnOrange">搜索全部</button></p>
<p><img src="~/m/img/shuju.png"> 实时总线路:@(lineTotalCount)条 <img src="~/m/img/shuju.png"> 实时可用线路:@(lineCount)条</p>
<p>所有线路均支持:【电脑/安卓/苹果】【PPTP/L2TP/SSTP】</p>
</form>
</div>
<div class="zhilian">
<div class="item">
<span class="btnZhilian">
<a asp-index="" asp-controller="article" asp-route-Catalog="4"><img src="~/m/img/zhilian.png">直连教程</a>
</span>
</div>
<div class="item">
@*<p class="blueText">已购产品:<span>老鹰b组</span></p>*@
<p class="grayText" style="font-size: 25px;">线路表与账号必须为同一产品才能使用</p>
</div>
</div>
<div class="lineBar"></div>
<div class="cpList">
<ul>
@foreach (var item in product.Where(m => m.Id != 3 && m.Id != 7 && m.Id != 9))
{
<li class="item @(item.Id==pid?"cpActive":"")" a-pid="@item.Id" a-name="@item.Name">@item.Name</li>
}
</ul>
</div>
<div class="dangqianshousuo">
<form asp-action="index" asp-controller="linelist" method="get">
<p>
<input type="hidden" name="ProductId" id="ProductId" value="@pid" />
<input type="text" name="KeyWord" placeholder="输入地区/名称/服务器" id="KeyWord" />
<button type="submit" class="btnBlue">搜索当前</button>
</p>
</form>
</div>
<div class="daochu">
<div class="item">
<p><img src="~/m/img/miyao.png"> L2TP密钥@currentProduct.L2TPPwd</p>
<p><img src="~/m/img/dk.png"> SSTP端口@currentProduct.SSTPPort</p>
</div>
<div class="item">
<span><img src="~/m/img/excel.png"> 导出Excel</span>
</div>
</div>
<div class="tableTit">
<div class="item">
地区
</div>
<div class="item">
运营商
</div>
<div class="item">
服务器域名
</div>
<div class="item">
详情
</div>
</div>
@foreach (var group in Model.GroupBy(m => m.Province))
{
<p class="city">@group.Key</p>
@foreach (var item in group)
{
<div class="cityData" style="@(item.Status=="正常"?"":"color:red")">
<div class="item">
@item.City
</div>
<div class="item">
@item.Name
</div>
<div class="item">
@item.ServerUrl
</div>
<div class="item">
<button type="button" class="btnDetail"
a-City="@item.City"
a-Name="@item.Name"
a-ServerUrl="@item.ServerUrl"
a-BandWidth="@item.BandWidth"
a-IpRemark="@item.IpRemark"
a-Status="@item.Status">详情</button>
</div>
</div>
}
}
<!-- 弹窗详情 -->
<div class="layerTable">
<table border="0" cellspacing="0" cellpadding="0">
<tr>
<td>城市:</td>
<td id="layer_city"></td>
</tr>
<tr>
<td>运营商:</td>
<td id="layer_name"></td>
</tr>
<tr>
<td>服务器域名:</td>
<td id="layer_server"></td>
</tr>
<tr>
<td>实时带宽:</td>
<td id="layer_brand"></td>
</tr>
<tr>
<td>IP量</td>
<td id="layer_ip"></td>
</tr>
<tr>
<td>状态:</td>
<td id="layer_status"></td>
</tr>
</table>
<div class="back">
<img src="~/m/img/arrowback.png"> 返回列表
</div>
</div>
<script type="text/javascript">
var pid =@pid;
var productName=""
$(function () {
$(".cpList ul li").click(function(){
$(this).addClass("cpActive");
$(this).siblings().removeClass("cpActive");
pid = $(this).attr("a-pid");
productName = $(this).attr('a-name')
$("#pName").text(productName);
$("#ProductId").val(pid);
window.location.href = "/linelist/index?ProductId=" + pid;
})
$(".daochu").click(function () {
var p = $("#ProductId").val()||0;
var KeyWord = $("#KeyWord").val() || "";
window.location.href = "/linelist/Excel?ProductId=" + p + "&KeyWord=" + KeyWord;
})
$(".btnDetail").click(function () {
$(".layerTable").show();
$("#layer_city").text($(this).attr("a-City"));
$("#layer_name").text($(this).attr("a-Name"));
$("#layer_server").text($(this).attr("a-ServerUrl"));
$("#layer_brand").text($(this).attr("a-BandWidth"));
$("#layer_ip").text($(this).attr("a-IpRemark"));
$("#layer_status").text($(this).attr("a-Status"));
})
$(".back").click(function () { $(".layerTable").hide(); });
})
</script>

View File

@@ -0,0 +1,95 @@
@using Hncore.Pass.Vpn.Response.Product
@using Microsoft.Extensions.Configuration
@using Hncore.Pass.BaseInfo.Response
@using Hncore.Infrastructure.Serializer;
@inject IConfiguration m_Configuration
@model List<ProductWithPackageResponse>
@{
ViewData["Title"] = "购买产品";
UserLoginModel user = null;
if (this.Context.Request.Cookies.TryGetValue("userInfo", out string userCookie))
{
user = userCookie.FromJsonTo<UserLoginModel>();
}
var pid = this.Context.Request.Query.ContainsKey("id") ? this.Context.Request.Query["id"].ToString() : "";
var defaultProduct = Model.Select(m => m.Product).FirstOrDefault();
if (pid == "")
{
pid = Model.Select(m => m.Product).FirstOrDefault().Id.ToString();
}
else
{
defaultProduct = Model.Select(m => m.Product).FirstOrDefault(m => m.Id.ToString() == pid);
}
var defaultPackage = Model.Where(m => m.Product.Id == defaultProduct.Id).Select(m => m.Packages.FirstOrDefault()).FirstOrDefault();
var baseUrl = m_Configuration["BaseInfoUrl"];
Func<string, string> P = (path) => $"{baseUrl}{path}";
}
<div class="cpBanner">
<img src="~/m/img/cpBanner.png">
</div>
<div class="cpNav">
<div class="item">
<ul class="nav nav-tabs cpName" role="tablist">
@foreach (var item in Model)
{
<li role="presentation" class="@(item.Product.Id==defaultProduct.Id?"active":"")">
<a href="#@item.Product.Id" role="tab" data-toggle="tab">@item.Product.Name</a>
</li>
}
</ul>
</div>
<div class="item">
<div class="tab-content">
@foreach (var item in Model)
{
<div role="tabpanel" class="tab-pane @(item.Product.Id==defaultProduct.Id?"active":"")" id="@item.Product.Id">
<p class="texing">@item.Product.Name</p>
<ul class="texingList">
@foreach (var str in item.Product.ContentLine)
{
<li>·@str</li>
}
</ul>
<p style="color: #ec6e58;font-size:30px;font-weight: bold;">
需求5个以上可联系客服设置优惠价<br />
若之前享优惠价,请联系客服帮你改价
</p>
@foreach (var package in item.Packages.Where(m => m.Status == 1))
{
if (package.IsTest == 1)
{
<a asp-action="test" asp-controller="product" asp-route-id="@package.ProductId">
<div class="card color_@((item.Packages.IndexOf(package)+1)%5)">
<div class="item">
<p>@package.Name</p>
<p>@(package.DayPrice)元/天</p>
<p>@package.Profile</p>
</div>
<div class="item">
<p>¥<span>@package.Price</span></p>
</div>
</div>
</a>
}
else
{
<a asp-action="buy" asp-controller="product" asp-route-id="@package.Id">
<div class="card color_@((item.Packages.IndexOf(package)+1)%5)">
<div class="item">
<p>@package.Name</p>
<p>@(package.DayPrice)元/天</p>
<p>@package.Profile</p>
</div>
<div class="item">
<p>¥<span>@package.Price</span></p>
</div>
</div>
</a>
}
}
</div>
}
</div>
</div>
</div>

View File

@@ -0,0 +1,60 @@
@using Hncore.Pass.Vpn.Response.Product
@using Microsoft.Extensions.Configuration
@using Hncore.Pass.BaseInfo.Response
@using Hncore.Infrastructure.Serializer;
@inject IConfiguration m_Configuration
@model ProductWithPackageResponse
@{
ViewData["Title"] = "购买产品";
UserLoginModel user = null;
if (this.Context.Request.Cookies.TryGetValue("userInfo", out string userCookie))
{
user = userCookie.FromJsonTo<UserLoginModel>();
}
var defaultProduct = Model.Product;
var defaultPackage = Model.Packages.FirstOrDefault();
var baseUrl = m_Configuration["BaseInfoUrl"];
Func<string, string> P = (path) => $"{baseUrl}{path}";
}
<div class="cpBanner">
<img src="~/m/img/cpBanner.png">
</div>
<div class="cpNav">
<div class="item">
<ul class="nav nav-tabs cpName" role="tablist">
<li role="presentation" class="active">
<a href="#@Model.Product.Id">@Model.Product.Name</a>
</li>
</ul>
</div>
<div class="item">
<div class="tab-content">
<div role="tabpanel" class="tab-pane active" id="@Model.Product.Id">
<p class="texing">@Model.Product.Name</p>
<ul class="texingList">
<p>·不限速网速最高可达50兆</p>
<p>·支持手机,电脑,模拟器</p>
<p>·200多个城市+全国混波量ip千万级</p>
<p>·带宽6-10兆</p>
<p>·断开再链接换ip</p>
</ul>
@foreach (var package in Model.Packages.Where(m=>m.IsTest==0&&m.Status==1))
{
<a asp-action="rebuy" asp-controller="Product" asp-route-packageId="@package.Id" asp-route-accounts=@ViewBag.accounts>
<div class="card color_@((Model.Packages.IndexOf(package)+1)%5)">
<div class="item">
<p>@package.Name</p>
<p>@(package.DayPrice)元/天</p>
<p>@package.Profile</p>
</div>
<div class="item">
<p>¥<span>@package.Price</span></p>
</div>
</div>
</a>
}
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,36 @@
@using Hncore.Pass.Vpn.Domain
@using Microsoft.Extensions.Configuration
@inject IConfiguration m_Configuration
@model List<ProductEntity>
@{
var baseUrl = m_Configuration["BaseInfoUrl"];
Func<string, string> P = (path) => $"{baseUrl}{path}";
}
<div class="container-fluid softBg">
<div class="container">
<div class="row">
<div class="col-sm-4">
</div>
<div class="col-sm-4 text-center">
<p class="simg"><img src="~/img/img_soft.png"></p>
<p class="sintro">软件和账户必须为同一产品才能使用</p>
</div>
<div class="col-sm-4 text-right">
<a href="#" class="jiaocheng">使用教程→</a>
</div>
</div>
</div>
</div>
<div class="softList">
@foreach (var item in Model.Where(m=>m.Sort != 1000))
{
<div class="item">
@*<p><img src="@P(item.Image)"></p>*@
<p>@item.Name</p>
<p><a href="@item.SimulatorDownloadUrl"> <button type="button" class="btnBlue">SSTP客户端下载</button></a></p>
</div>
}
</div>

View File

@@ -0,0 +1,103 @@
@using Hncore.Pass.Vpn.Response.Product
@using Hncore.Infrastructure.Extension
@using Microsoft.Extensions.Configuration
@using Hncore.Infrastructure.Common
@model PackageInfoResponse
@inject IConfiguration m_Configuration
@inject Hncore.Pass.Vpn.Service.ProductAccountService m_AccountService
@{
ViewData["Title"] = "购买产品";
var t = this.Context.Request.GetInt("t");
var baseUrl = m_Configuration["BaseInfoUrl"];
Func<string, string> P = (path) => $"{baseUrl}{path}";
var randomPwd = ValidateCodeHelper.MakeNumCode(3).ToLower();
var randomAccount = ValidateCodeHelper.MakeCharCode(2).ToLower() + ValidateCodeHelper.MakeNumCode(4).ToLower();
while (m_AccountService.Exist(m => m.Account == randomAccount))
{
randomAccount = ValidateCodeHelper.MakeCharCode(2).ToLower() + ValidateCodeHelper.MakeNumCode(4).ToLower();
}
}
<vc:redirecct-login></vc:redirecct-login>
<div class="cpTop">
<p class="choose">当前已选产品:</p>
<div class="kArea">
<div class="cpKuang">
<div class="item">
<p><img src="@P(Model.Product.Image)"></p>
<p>@Model.Product.Name</p>
</div>
<div class="item">
<p class="kaci">@Model.Package.Name</p>
<p class="grayText">@(Model.Package.DayPrice)元/天</p>
<p class="grayText">@Model.Package.Profile</p>
</div>
<div class="item">
¥ <span class="price">@Model.Package.Price</span>
</div>
</div>
</div>
<div class="chongxin">
<div class="item redText">
*请确认好所需产品,买错产品换货将产生费用
</div>
<div class="item">
<a asp-action="index" asp-controller="product"><button type="button" class="btnBlue">返回重新选择</button></a>
</div>
</div>
</div>
<div class="biaodan">
PPTP账号前缀<input type="text" name="" id="account" value="@randomAccount" />
</div>
<div class="biaodan">
PPTP账号密码<input type="text" name="" id="pwd" value="@randomPwd" />
</div>
<p class="grayText text-center shengyu">剩余试用次数:<span>@(Model.RestTimes)</span></p>
<p class="text-center redText tip"></p>
<p class="text-center">
@if (Model.RestTimes > 0 && Model.Package.Status == 1)
{
<button type="button" class="btnBlue large" onclick="create()">领取试用</button>
}
@if (Model.Package.Status == 0)
{
<span style="color:red;">
该产品暂不能测试
</span>
}
</p>
@section Scripts{
<script>
function create() {
var data = {
ProductId:@(Model.Product.Id),
PackageId: @(Model.Package.Id),
Account: $('#account').val(),
Pwd: $('#pwd').val()
};
if (data.Account == '' || data.Pwd == '') {
$(".tip").text("账户和密码不能为空");
return;
}
$.ajax({
type: 'POST',
url: '/api/course/v1/productaccount/CreateTestAccount',
contentType: "application/json",
data: JSON.stringify(data),
success: function (res) {
console.log(res);
if (res.Code == 10000) {
alert("领取成功")
window.location.href = "/user/myaccounts";
} else {
$(".tip").text(res.Message);
}
},
dataType: "json"
});
}
</script>
}

View File

@@ -0,0 +1,701 @@
@using Hncore.Pass.Vpn.Response.Product
@using Hncore.Infrastructure.Extension
@using Hncore.Pass.BaseInfo.Response
@using Hncore.Infrastructure.Serializer;
@using Hncore.Pass.BaseInfo.Service
@using Hncore.Infrastructure.Common
@model PackageInfoResponse
@inject UserService m_UserService
@inject Hncore.Pass.Vpn.Service.ProductAccountService m_AccountService
@{
ViewData["Title"] = "购买产品";
UserLoginModel user = null;
Hncore.Pass.BaseInfo.Models.User userEntity = new Hncore.Pass.BaseInfo.Models.User();
if (this.Context.Request.Cookies.TryGetValue("userInfo", out string userCookie))
{
user = userCookie.FromJsonTo<UserLoginModel>();
userEntity = await m_UserService.GetById(user.Id);
}
var randomPwd = ValidateCodeHelper.MakeNumCode(3).ToLower();
var randomAccount1 = ValidateCodeHelper.MakeCharCode(2).ToLower() + ValidateCodeHelper.MakeNumCode(4).ToLower();
while (m_AccountService.Exist(m => m.Account == randomAccount1))
{
randomAccount1 = ValidateCodeHelper.MakeCharCode(2).ToLower() + ValidateCodeHelper.MakeNumCode(4).ToLower();
}
var randomAccountMutil = ValidateCodeHelper.MakeCharCode(3).ToLower();
while (m_AccountService.Exist(m => m.Account.StartsWith(randomAccountMutil)))
{
randomAccountMutil = ValidateCodeHelper.MakeCharCode(3).ToLower();
}
}
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>
<script type="text/javascript">
$(function () {
$(".btnNav").click(function () {
$(".mask").fadeIn();
});
$(".btnClose").click(function () {
$(".mask").fadeOut();
});
$(".dan").click(function () {
$(this).addClass("zActive");
$(".pi").removeClass("zActive");
$(".conDan").show();
$(".conPi").hide();
});
$(".pi").click(function () {
$(this).addClass("zActive");
$(".dan").removeClass("zActive");
$(".conDan").hide();
$(".conPi").show();
})
})
</script>
<vc:redirecct-login></vc:redirecct-login>
<vc:pay-wait></vc:pay-wait>
<div id="app">
<div class="cpTop">
<p class="choose">当前已选产品:</p>
<div class="kArea">
<div class="cpKuang">
<div class="item">
<p><img src="/@Model.Product.Image"></p>
<p>@Model.Product.Name</p>
</div>
<div class="item">
<p class="kaci">@Model.Package.Name</p>
<p class="grayText">@(Model.Package.DayPrice)元/天</p>
<p class="grayText">@Model.Package.Profile</p>
</div>
<div class="item">
¥ <span class="price">@Model.Package.Price</span>
</div>
</div>
</div>
<div class="chongxin">
<div class="item redText">
*请确认好所需产品,买错产品换货将产生费用
@if (Model.Package.Name == "天卡")
{
<p class="item redText" style="text-align:center">*天卡不支持退款,请谨慎购买</p>
}
</div>
<div class="item">
<button type="button" class="btnBlue" onclick="history.go(-1)">返回重新选择</button>
</div>
</div>
</div>
<div class="row mytab">
<div class="col-sm-6 col-xs-6 text-right">
<span class="dan zActive">单个注册</span>
</div>
<div class="col-sm-6 col-xs-6 text-left">
<span class="pi">批量注册</span>
</div>
</div>
<div class="conDan">
<div class="row">
<div class="col-sm-5 col-xs-5">
PPTP账号前缀
</div>
<div class="col-sm-7 col-xs-7 shuru">
<input type="text" v-model="OneBuyModel.Account" />
</div>
</div>
<div class="row">
<div class="col-sm-5 col-xs-5">
PPTP账号密码
</div>
<div class="col-sm-7 col-xs-7 shuru">
<input type="text" v-model="OneBuyModel.Pwd" v-on:blur="checkOnePwd" />
</div>
</div>
<div class="row">
<div class="col-sm-5 col-xs-5">
连接数:
</div>
<div class="col-sm-7 col-xs-7">
<div class="jiajian">
<div class="item" v-on:click="OneBuyModel.ConnectCount>1&&OneBuyModel.ConnectCount--">
-
</div>
<div class="item">
<input type="text" style="width:100%;height:60px;border:0;padding-left:20px" v-model="OneBuyModel.ConnectCount" />
@*<span>{{OneBuyModel.ConnectCount}}</span>*@
</div>
<div class="item" v-on:click="OneBuyModel.ConnectCount++">
+
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-5 col-xs-5">
选择优惠券:
</div>
<div class="col-sm-7 col-xs-7 select">
<select class="chooseYhq" v-model="OneBuyModel.CouponId">
<option value="volvo">选择优惠券</option>
<option v-for="item in Coupons" :value="item.Id">{{item.Name}}</option>
</select>
</div>
</div>
<div class="row">
<div class="col-sm-5 col-xs-5">
余额:
</div>
<div class="col-sm-7 col-xs-7">
<div class="">
当前账户余额<span class="blueText">@(userEntity.RestAmount)</span>元
<a href="/User/Index">前往充值</a>
</div>
</div>
</div>
<div class="row" v-if="showPayType">
<div class="col-sm-5 col-xs-5">
支付方式:
</div>
<div class="col-sm-7 col-xs-7 pay">
<div class="radio" v-on:click="OneBuyModel.OPayType=100">
<input name="OPayType" type="radio" v-model="OneBuyModel.OPayType" checked value="100">
<label class="radio-label"><img src="~/m/img/zfb.png"> 支付宝支付</label>
</div>
<div class="radio" v-on:click="OneBuyModel.OPayType=70">
<input name="OPayType" type="radio" v-model="OneBuyModel.OPayType" value="70">
<label class="radio-label"><img src="~/m/img/wx.png"> 微信支付</label>
</div>
<div class="radio" >
<input id="UseAccountAmount" name="OPayType" type="radio" v-model="OneBuyModel.UseAccountAmount" value="1">
<label for="UseAccountAmount" class="radio-label" style="line-height:150%"> 余额支付</label>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-5 col-xs-5">
应付款:
</div>
<div class="col-sm-7 col-xs-7">
<span>{{OneTotalAmount}}</span>元
</div>
</div>
@* <div class="row">
<div class="col-sm-5 col-xs-5">
应付款:
</div>
<div class="col-sm-7 col-xs-7">
<span class="yingfu" style="font-size: 35px;font-weight: bold;">{{OnePayAmount}}</span>元
</div>
</div> *@
<p class="grayText songquan">每隔30天淘宝下单可获得一张优惠券</p>
<p class="redText songquan">{{Tip}}</p>
<div class="ok">
<button type="button" class="btnPay" v-on:click="onePay">确认支付</button>
</div>
</div>
<div class="conPi">
<p class="shuoming">批量注册的账号会使用【账号前缀】+【开始数】+【个数】顺序进行注册,</p>
<p class="shuoming">如:注册账号前缀为【user】开始数为【6】个数为【10】则注册的账号为user06user07user08....user14</p>
<div class="row">
<div class="col-sm-5 col-xs-5">
PPTP账号前缀
</div>
<div class="col-sm-7 col-xs-7 shuru">
<input type="text" v-model="MoreBuyModel.Account" />
</div>
</div>
<div class="row">
<div class="col-sm-5 col-xs-5">
PPTP开始号
</div>
<div class="col-sm-7 col-xs-7 shuru">
<input type="number" v-model="MoreBuyModel.MinPostfix" />
</div>
</div>
<div class="row">
<div class="col-sm-5 col-xs-5">
PPTP注册个数
</div>
<div class="col-sm-7 col-xs-7 shuru">
<input type="number" v-model="MoreBuyModel.MaxPostfix" />
</div>
</div>
<div class="row">
<div class="col-sm-5 col-xs-5">
PPTP账号密码
</div>
<div class="col-sm-7 col-xs-7 shuru">
<input type="text" v-model="MoreBuyModel.Pwd" />
</div>
</div>
<div class="row">
<div class="col-sm-5 col-xs-5">
连接数:
</div>
<div class="col-sm-5 col-xs-5">
<div class="jiajian">
<div class="item" @@click="MoreBuyModel.ConnectCount>1&&MoreBuyModel.ConnectCount--">
-
</div>
<div class="item">
<input type="text" style="width:100%;height:60px;border:0;padding-left:20px" v-model="MoreBuyModel.ConnectCount" />
</div>
<div class="item" @@click="MoreBuyModel.ConnectCount++">
+
</div>
</div>
</div>
<div class="col-sm-7 col-xs-7">
@*<span class="quanxian">超过10个请联系客服开通</span>*@
</div>
</div>
<div class="row">
<div class="col-sm-5 col-xs-5">
选择优惠券:
</div>
<div class="col-sm-7 col-xs-7 select">
<select class="chooseYhq" v-model="MoreBuyModel.CouponId">
<option value="volvo">选择优惠券</option>
<option v-for="item in Coupons" :value="item.Id">{{item.Name}}</option>
</select>
</div>
</div>
<div class="row">
<div class="col-sm-5 col-xs-5">
余额:
</div>
<div class="col-sm-7 col-xs-7">
<div class="">
当前账户余额<span class="blueText">@(userEntity.RestAmount)</span>元
<a href="/User/Index">前往充值</a>
</div>
</div>
</div>
<div class="row" v-if="showPayType">
<div class="col-sm-5 col-xs-5">
支付方式:
</div>
<div class="col-sm-7 col-xs-7 pay">
<div class="radio" v-on:click="MoreBuyModel.OPayType=100">
<input name="radio" type="radio" value="100" checked v-model="MoreBuyModel.OPayType">
<label class="radio-label"><img src="~/m/img/zfb.png"> 支付宝支付</label>
</div>
<div class="radio" v-on:click="MoreBuyModel.OPayType=70">
<input name="radio" type="radio" value="70" v-model="MoreBuyModel.OPayType">
<label class="radio-label"><img src="~/m/img/wx.png"> 微信支付</label>
</div>
<div class="radio" >
<input id="UseAccountAmount_s" name="radio" type="radio" v-model="MoreBuyModel.UseAccountAmount" value="1">
<label for="UseAccountAmount_s" class="radio-label" style="line-height:150%"> 余额支付</label>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-5 col-xs-5">
总金额:
</div>
<div class="col-sm-7 col-xs-7">
<span>{{MoreTotalAmount}}</span>元
</div>
</div>
<div class="row">
<div class="col-sm-5 col-xs-5">
应付款:
</div>
<div class="col-sm-7 col-xs-7">
<span class="yingfu">{{MorePayAmount}}</span>元
</div>
</div>
<p class="grayText songquan">每隔30天淘宝下单可获得一张优惠券</p>
<p class="redText songquan">{{Tip}}</p>
<div class="ok">
<button type="button" class="btnPay" @@click="morePay">确认支付</button>
</div>
</div>
</div>
<!-- 支付弹窗结束 -->
<div id="aliPayBox" style="display:none"></div>
@section Scripts{
<script>
var productId =@(Model.Product.Id);
/** 表单序列化成json字符串的方法 */
function form2JsonString(formId) {
var paramArray = $('#' + formId).serializeArray();
var jsonObj = {};
$(paramArray).each(function () {
jsonObj[this.name] = this.value;
});
console.log(jsonObj);
return JSON.stringify(jsonObj);
}
var app = new Vue({
el: '#app',
data: {
showPayType:true,
payHandler:null,
Tip:'',
RestAmount: @(userEntity.RestAmount),
Coupons: [],
SelectCoupon: {},
OrderInfo: {},
OneChecker: {
AccountOk: true,
PwdOk:true
},
MoreChecker: {
AccountOk: true,
PwdOk: true,
Max:10,
},
OneBuyModel: {
Price:@(Model.Package.Price),
PackageId:@(Model.Package.Id),
CouponAmount: 0,
OrderType: 1,
Account: '@(randomAccount1)',
Pwd: '@(randomPwd)',
ConnectCount: 1,
CouponId: 0,
UseAccountAmount: 0,
OPayType: 100,
PayChannel:40,
},
MoreBuyModel: {
Price:@(Model.Package.Price),
PackageId:@(Model.Package.Id),
CouponAmount: 0,
OrderType: 2,
Account: '@(randomAccountMutil)',
Pwd: '@(randomPwd)',
ConnectCount: 1,
CouponId: 0,
UseAccountAmount: 0,
OPayType: 100,
MinPostfix: 1,
MaxPostfix: 1,
PayChannel:40,
}
},
computed: {
OneTotalAmount: function () {
var total= this.OneBuyModel.Price * this.OneBuyModel.ConnectCount
return total.toFixed(2);
},
OnePayAmount: function () {
var restAmout = this.OneBuyModel.UseAccountAmount == 1 ?this.RestAmount:0;
var total = this.OneBuyModel.Price * this.OneBuyModel.ConnectCount - this.OneBuyModel.CouponAmount - restAmout;
total= total < 0 ? 0 : total;
return total.toFixed(2);
},
MoreTotalAmount: function () {
var total= this.MoreBuyModel.Price * this.MoreBuyModel.ConnectCount * this.MoreBuyModel.MaxPostfix;
return total.toFixed(2);
},
MorePayAmount: function () {
var restAmout = this.MoreBuyModel.UseAccountAmount == 1 ? this.RestAmount : 0;
var total = this.MoreBuyModel.Price * this.MoreBuyModel.ConnectCount * this.MoreBuyModel.MaxPostfix - this.MoreBuyModel.CouponAmount - restAmout;
total= total < 0 ? 0 : total;
return total.toFixed(2);
}
},
watch: {
'OneBuyModel.CouponId': { //加引号监听对象里的属性
handler: function (newValue, oldValue) {
var totalAmount = this.OneBuyModel.Price * this.OneBuyModel.ConnectCount;
for (var i = 0; i < this.Coupons.length; i++) {
var item = this.Coupons[i];
if (totalAmount < item.AllowMinAmount) {
continue;
}
if (item.Id == newValue) {
if (item.CouponType == 1) {//满减
this.OneBuyModel.CouponAmount = item.CouponValue;
} else {
this.OneBuyModel.CouponAmount = totalAmount * item.CouponValue * 0.1;
}
return;
}
}
},
immediate: true
},
'MoreBuyModel.CouponId': { //加引号监听对象里的属性
handler: function (newValue, oldValue) {
var totalAmount = this.MoreBuyModel.Price * this.MoreBuyModel.ConnectCount;
for (var i = 0; i < this.Coupons.length; i++) {
var item = this.Coupons[i];
if (totalAmount < item.AllowMinAmount) {
continue;
}
if (item.Id == newValue) {
if (item.CouponType == 1) {//满减
this.MoreBuyModel.CouponAmount = item.CouponValue;
} else {
this.MoreBuyModel.CouponAmount = totalAmount * item.CouponValue * 0.1;
}
return;
}
}
},
immediate: true
},
'OneBuyModel.OPayType': { //加引号监听对象里的属性
handler: function (newValue, oldValue) {
var wx = 10;
this.OneBuyModel.UseAccountAmount = false;
if (isWeiXin()) wx = 20;
this.OneBuyModel.PayChannel = newValue == 70 ? wx : 40;
},
immediate: true
},
'MoreBuyModel.OPayType': { //加引号监听对象里的属性
handler: function (newValue, oldValue) {
var wx = 10;
this.MoreBuyModel.UseAccountAmount = false;
if (isWeiXin()) wx = 20;
this.MoreBuyModel.PayChannel = newValue == 70 ? wx : 40;
},
immediate: true
}
},
mounted: function () {
if (isWeiXin()) {
this.OneBuyModel.PayChannel = 20;
this.OneBuyModel.OPayType = 70;
this.MoreBuyModel.PayChannel = 20;
this.MoreBuyModel.OPayType = 70;
this.showPayType = false;
}
@if(user != null) {
<text>this.getCoupons()</text>
}
},
methods: {
isNum(value) {
return typeof value === 'number' && !isNaN(value);
},
selectFn: function (e) {
console.log(e.target.value) // 选择项的value
},
getCoupons: function () {
var that = this;
var url = '/api/sells/v1/coupon/GetAvailableCoupon';
$.ajax({
type: 'GET',
url: url,
success: function (res) {
console.log(res);
if (res.Code == 10000) {
that.Coupons = res.Data.map(m => m.Coupon);
}
}
})
},
checkOneAccount() {
if (this.OneBuyModel.Account.length > 10 || this.OneBuyModel.Account.length < 5) {
this.OneChecker.AccountOk = false;
return false;
}
this.OneChecker.AccountOk = true;
return true;
},
checkOnePwd() {
if (this.OneBuyModel.Pwd.length > 6 || this.OneBuyModel.Pwd.length <1) {
this.OneChecker.PwdOk = false;
return false;
}
this.OneChecker.PwdOk = true;
return true;
},
checkMoreAccount() {
if (this.MoreBuyModel.Account.length > 10 || this.MoreBuyModel.Account.length < 3) {
this.MoreChecker.AccountOk = false;
return false;
}
this.MoreChecker.AccountOk = true;
return true;
},
checkMorePwd() {
if (this.MoreBuyModel.Pwd.length > 6 || this.MoreBuyModel.Pwd.length < 1) {
this.MoreChecker.PwdOk = false;
return false;
}
this.MoreChecker.PwdOk = true;
return true;
},
onePay: function () {
this.OneBuyModel.ConnectCount = parseInt(this.OneBuyModel.ConnectCount)
if (!this.isNum(this.OneBuyModel.ConnectCount)) return;
if (!this.checkOneAccount() || !this.checkOnePwd()) return;
if (this.OnePayAmount > 0 ) {
if (this.OneBuyModel.UseAccountAmount){
alert('余额不足,请充值!');return;
}
}
var that = this;
if (this.OneBuyModel.UseAccountAmount === true) this.OneBuyModel.UseAccountAmount = 1;
if (this.OneBuyModel.UseAccountAmount === false) this.OneBuyModel.UseAccountAmount = 0;
showPayWait();
$.ajax({
type: 'POST',
url: '/product/CreateOrder',
dataType: "json",
contentType: "application/json",
data: JSON.stringify(this.OneBuyModel),
success: function (res) {
console.log(res);
if (res.Code == 10000) {
hidePayWait();
if (res.Data == "00") {
//alert('购买成功')
showPayOk();
} else {
that.payCallback(res.Data)
that.isPay(res.Data.OrderInfo.OrderNo);
}
} else {
//that.Tip = res.Message;
tipPayWait(res.Message);
}
}
});
},
morePay: function () {
this.MoreBuyModel.ConnectCount = parseInt(this.MoreBuyModel.ConnectCount)
if (!this.isNum(this.MoreBuyModel.ConnectCount)) return;
if (!this.checkMoreAccount() || !this.checkMorePwd() || this.MoreBuyModel.MaxPostfix>500) return;
var that = this;
if (this.OnePayAmount > 0 ) {
if (this.MoreBuyModel.UseAccountAmount){
alert('余额不足,请充值!');return;
}
}
if (this.MoreBuyModel.UseAccountAmount === true) this.MoreBuyModel.UseAccountAmount = 1;
if (this.MoreBuyModel.UseAccountAmount === false) this.MoreBuyModel.UseAccountAmount = 0;
showPayWait();
$.ajax({
type: 'POST',
url: '/product/CreateOrder',
dataType: "json",
contentType: "application/json",
data: JSON.stringify(this.MoreBuyModel),
success: function (res) {
if (res.Code == 10000) {
hidePayWait();
if (res.Data == "00") {
//alert('购买成功')
showPayOk();
} else {
that.payCallback(res.Data)
that.isPay(res.Data.OrderInfo.OrderNo);
}
} else {
//that.Tip = res.Message;
tipPayWait(res.Message);
}
}
});
},
payCallback: function (data) {
this.OrderInfo = data.OrderInfo;
if (!data.PayData) { alert("下单失败");return; }
var payChannel = this.OrderInfo.PayChannel;
if (payChannel == 10) {
this.h5WxPay(data.PayData)
} else if (payChannel == 20) {
this.jsWxPay(data.PayData);
} else if (payChannel == 40) {
this.aliPay(data.PayData);
}
},
h5WxPay(payData) {
window.location.href = payData;
},
jsWxPay(payData) {
WeixinJSBridge.invoke(
'getBrandWCPayRequest',
JSON.parse(payData),
function (res) {
if (res.err_msg == "get_brand_wcpay_request:ok") {
window.location.href = "/User/MyAccounts";
} else if (res.err_msg == "get_brand_wcpay_request:cancel") {
} else {
alert("支付失败" + res.err_msg);
}
});
},
aliPay(payData) {
$("#aliPayBox").html(payData);
//window.location.href = payData;
},
checkAccount: function () {
var account = $("#sAccount").val()
var url = '/api/course/v1/productaccount/ExistAccount?productId=' + productId + '&accounts=' + account;
$.ajax({
type: 'GET',
url: url,
success: function (res) {
console.log(res);
if (res.Code != 10000) {
$("#sAccountTip").text(res.Message)
}
}
})
},
isPay: function (orderNo) {
var that = this;
this.payHandler= setInterval(function () {
var url = '/product/IsPay?orderNo=' + orderNo;
$.ajax({
type: 'GET',
url: url,
success: function (res) {
if (res.Code == 10000 && res.Data ==1) {
clearInterval(that.payHandler);
$(".payMask").hide();
showPayOk();
//window.location.href = "/user/myaccounts";
}
}
})
}, 3000)
},
close() {
clearInterval(this.payHandler);
$('.payMask').hide();
$('#qrcode').empty();
}
}
})
function checkAccount() {
var account = $("#sAccount").val()
var url = '/api/course/v1/productaccount/ExistAccount?productId=' + productId+ '&accounts=' + account;
$.ajax({
type: 'GET',
url: url,
success: function (res) {
console.log(res);
if (res.Code != 10000) {
$("#sAccountTip").text(res.Message)
}
}
})
}
</script>
}

View File

@@ -0,0 +1,328 @@
@using Hncore.Pass.Vpn.Response.Product
@using Hncore.Infrastructure.Extension
@using Hncore.Pass.BaseInfo.Response
@using Hncore.Infrastructure.Serializer;
@using Hncore.Pass.BaseInfo.Service
@model PackageInfoResponse
@inject UserService m_UserService
@{
ViewData["Title"] = "购买产品";
UserLoginModel user = null;
Hncore.Pass.BaseInfo.Models.User userEntity = new Hncore.Pass.BaseInfo.Models.User();
if (this.Context.Request.Cookies.TryGetValue("userInfo", out string userCookie))
{
user = userCookie.FromJsonTo<UserLoginModel>();
userEntity = await m_UserService.GetById(user.Id);
}
}
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>
<vc:redirecct-login></vc:redirecct-login>
<vc:pay-wait></vc:pay-wait>
<div id="app">
<div class="cpTop">
<p class="choose">当前已选产品:</p>
<div class="kArea">
<div class="cpKuang">
<div class="item">
<p><img src="~/@Model.Product.Image"></p>
<p>@Model.Product.Name</p>
</div>
<div class="item">
<p class="kaci">@Model.Package.Name</p>
<p class="grayText">@(Model.Package.DayPrice)元/天</p>
<p class="grayText">@Model.Package.Profile</p>
</div>
<div class="item">
¥ <span class="price">@Model.Package.Price</span>
</div>
</div>
</div>
<div class="chongxin">
<div class="item redText">
*请确认好所需产品,买错产品换货将产生费用
</div>
<div class="item">
<button type="button" class="btnBlue" onclick="history.go(-1)">返回重新选择</button>
</div>
</div>
</div>
<!-- con -->
<div class="container zhuce">
<div class="reg_tab">
<div class="item dan active_dan">
续费
</div>
</div>
</div>
<div class="conDan">
<div class="row">
<div class="col-sm-5 col-xs-5">
PPTP产品账号
</div>
<div class="col-sm-7 col-xs-7 shuru">
<input type="text" v-model="OneBuyModel.Account" disabled />
</div>
</div>
@*<div class="row">
<div class="col-sm-5 col-xs-5">
PPTP账号密码
</div>
<div class="col-sm-7 col-xs-7 shuru">
<input type="text" v-model="OneBuyModel.Pwd" />
</div>
</div>*@
<div class="row">
<div class="col-sm-5 col-xs-5">
连接数:
</div>
<div class="col-sm-7 col-xs-7">
<div class="jiajian">
<div class="item">
</div>
<div class="item">
<span>{{OneBuyModel.ConnectCount}}</span>
</div>
<div class="item">
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-5 col-xs-5">
选择优惠券:
</div>
<div class="col-sm-7 col-xs-7 select">
<select class="chooseYhq" v-model="OneBuyModel.CouponId">
<option value="0">请选择优惠券</option>
<option v-for="item in Coupons" :value="item.Id">{{item.Name}}</option>
</select>
</div>
</div>
<div class="row">
<div class="col-sm-5 col-xs-5">
余额抵扣:
</div>
<div class="col-sm-7 col-xs-7">
<div class="radio">
<input type="checkbox" v-model="OneBuyModel.UseAccountAmount" value="1"> 当前账户余额<span class="blueText">@(userEntity.RestAmount)</span>元
@*<input id="radio-1" name="radio" type="radio">
<label for="radio-1" class="radio-label">使用余额抵扣,当前账户余额@(userEntity.RestAmount)元</label>*@
</div>
</div>
</div>
<div class="row" v-if="showPayType">
<div class="col-sm-5 col-xs-5">
支付方式:
</div>
<div class="col-sm-7 col-xs-7 pay">
<div class="radio" v-on:click="OneBuyModel.OPayType=100">
<input type="radio" v-model="OneBuyModel.OPayType" value="100">
<label class="radio-label"><img src="~/m/img/zfb.png"> 支付宝支付</label>
</div>
<div class="radio" v-on:click="OneBuyModel.OPayType=70">
<input type="radio" v-model="OneBuyModel.OPayType" value="70">
<label class="radio-label"><img src="~/m/img/wx.png"> 微信支付</label>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-5 col-xs-5">
总金额:
</div>
<div class="col-sm-7 col-xs-7">
<span>{{TotalAmount}}</span>元
</div>
</div>
<div class="row">
<div class="col-sm-5 col-xs-5">
应付款:
</div>
<div class="col-sm-7 col-xs-7">
<span class="yingfu" style="font-size: 35px;font-weight: bold;">{{PayAmount}}</span>元
</div>
</div>
<p class="grayText songquan">每隔30天淘宝下单可获得一张优惠券</p>
<p class="grayText songquan" style="color:red">{{Tip}}</p>
<div class="ok">
<button type="button" class="btnPay" v-on:click="onePay">确认支付</button>
</div>
</div>
</div>
<div id="aliPayBox" style="display:none"></div>
@section Scripts{
<script>
var productId =@(Model.Product.Id);
var app = new Vue({
el: '#app',
data: {
showPayType: true,
Tip:'',
RestAmount: @(userEntity.RestAmount),
Coupons: [],
SelectCoupon: {},
OrderInfo: {},
OneBuyModel: {
Price:@(Model.Package.Price),
PackageId:@(Model.Package.Id),
OrderType: @ViewBag.orderType,
Account: '@ViewBag.accounts',
CouponAmount: 0,
Pwd: '',
ConnectCount: @(ViewBag.ConnectCount),
CouponId: 0,
UseAccountAmount: 0,
OPayType: 100,
PayChannel:40,
}
},
computed: {
TotalAmount: function () {
var count = this.OneBuyModel.Account.split(',').length;
var total = this.OneBuyModel.Price * this.OneBuyModel.ConnectCount * count;
return total.toFixed(2);
},
PayAmount: function () {
var count = this.OneBuyModel.Account.split(',').length;
var restAmout = this.OneBuyModel.UseAccountAmount == 1 ? this.RestAmount : 0;
var total = this.OneBuyModel.Price * this.OneBuyModel.ConnectCount * count - this.OneBuyModel.CouponAmount - restAmout;
total= total < 0 ? 0 : total;
return total.toFixed(2);
}
},
watch: {
'OneBuyModel.CouponId': { //加引号监听对象里的属性
handler: function (newValue, oldValue) {
var totalAmount = this.OneBuyModel.Price * this.OneBuyModel.ConnectCount;
for (var i = 0; i < this.Coupons.length; i++) {
var item = this.Coupons[i];
if (totalAmount < item.AllowMinAmount) {
continue;
}
if (item.Id == newValue) {
if (item.CouponType == 1) {//满减
this.OneBuyModel.CouponAmount = item.CouponValue;
} else {
this.OneBuyModel.CouponAmount = totalAmount * item.CouponValue * 0.1;
}
return;
}
}
},
immediate: true
},
'OneBuyModel.OPayType': { //加引号监听对象里的属性
handler: function (newValue, oldValue) {
var wx = 10;
if (isWeiXin()) wx = 20;
this.OneBuyModel.PayChannel = newValue == 70 ? wx : 40;
},
immediate: true
}
},
mounted: function () {
if (isWeiXin()) {
this.OneBuyModel.PayChannel = 20;
this.OneBuyModel.OPayType = 70;
this.showPayType = false;
}
this.getCoupons();
},
methods: {
getCoupons: function () {
var that = this;
var url = '/api/sells/v1/coupon/GetAvailableCoupon';
$.ajax({
type: 'GET',
url: url,
success: function (res) {
console.log(res);
if (res.Code == 10000) {
that.Coupons = res.Data.map(m => m.Coupon);
}
}
})
},
onePay: function () {
if (this.PayAmount == 0 || this.OneBuyModel.UseAccountAmount) {
if (!confirm('余额和微信支付宝组合支付时,余额将立即扣除,请务必完成后续差额支付!')) return;
}
var that = this;
if (this.OneBuyModel.UseAccountAmount === true) this.OneBuyModel.UseAccountAmount = 1;
if (this.OneBuyModel.UseAccountAmount === false) this.OneBuyModel.UseAccountAmount = 0;
var that = this;
showPayWait();
$.ajax({
type: 'POST',
url: '/product/CreateOrder',
dataType: "json",
contentType: "application/json",
data: JSON.stringify(this.OneBuyModel),
success: function (res) {
console.log(res);
if (res.Code == 10000) {
hidePayWait();
that.payCallback(res.Data)
//that.isPay(res.Data.OrderInfo.OrderNo);
} else {
//that.Tip = res.Message;
tipPayWait(res.Message);
}
}
});
},
payCallback: function (data) {
this.OrderInfo = data.OrderInfo;
if (!data.PayData) { alert("下单失败"); return; }
var payChannel = this.OrderInfo.PayChannel;
if (payChannel == 10) {
this.h5WxPay(data.PayData)
} else if (payChannel == 20) {
this.jsWxPay(data.PayData);
} else if (payChannel == 40) {
this.aliPay(data.PayData);
}
},
h5WxPay(payData) {
window.location.href = payData;
},
jsWxPay(payData) {
WeixinJSBridge.invoke(
'getBrandWCPayRequest',
JSON.parse(payData),
function (res) {
if (res.err_msg == "get_brand_wcpay_request:ok") {
window.location.href = "/User/MyAccounts";
} else if (res.err_msg == "get_brand_wcpay_request:cancel") {
} else {
alert("支付失败" + res.err_msg);
}
});
},
aliPay(payData) {
$("#aliPayBox").html(payData);
},
isPay: function (orderNo) {
var handler = setInterval(function () {
var url = '/product/IsPay?orderNo=' + orderNo;
$.ajax({
type: 'GET',
url: url,
success: function (res) {
if (res.Code == 10000 && res.Data == 1) {
clearInterval(handler);
// $(".payMask").hide();
window.location.href = "/user/myaccounts";
}
}
})
}, 3000)
}
}
})
</script>
}

View File

@@ -0,0 +1,35 @@
@using Hncore.Infrastructure.Extension
@model ViewComponents.PagerModel
@{
Model.PageIndex = Model.PageIndex == 0 ? 1 : Model.PageIndex;
var q = this.Context.Request.Remove("PageIndex");
if (string.IsNullOrEmpty(q))
{
q = "?";
}
else
{
q += "&";
}
}
@if (Model.TotalPage > 1)
{
<ul class="pagination">
@if (Model.PageIndex > 1)
{
string href = $"{q}PageIndex={Model.PageIndex - 1}";
<li class="page-item"><a class="page-link" href="@href">上一页</a></li>
}
@for (var i = 1; i <= Model.TotalPage; i++)
{
<li class="page-item"><a class="page-link @(Model.PageIndex==i?"fenyeActive2":"")" href="@(q)PageIndex=@i">@i</a></li>
}
@if (Model.PageIndex < Model.TotalPage)
{
string href = $"{q}PageIndex={Model.PageIndex + 1}";
<li class="page-item"><a class="page-link" href="@href">下一页</a></li>
}
</ul>
}

View File

@@ -0,0 +1,79 @@
<style>
/* 支付等待弹窗开始 */
.paywait {
position: fixed;
z-index: 999;
width: 360px;
height: 500px;
top: 50%;
margin-top: -200px;
left: 50%;
margin-left: -180px;
display: none;
}
.plTop img {
width: 100%;
}
.plFour {
background: #fff;
margin: 0;
padding-bottom: 20px;
}
.plFour img {
width: 90%;
margin: 10px 0;
}
.plClose {
position: absolute;
top: 30px;
right: 10px;
z-index: 999;
}
.errorTip{
margin-top:30px;
color:red;
}
/* 支付等待弹窗结束 */
</style>
<!-- 支付等待 -->
<div class="paywait">
<img src="~/img/close.png" class="plClose">
<div class="plTop">
<img src="~/img/paywait.png">
</div>
<div class="row plFour">
<div class="col-lg-12 text-center loadingBox">
<img src="~/img/loading.gif" style="width:100px;height:20px">
<p>账号检测中请耐心等待</p>
</div>
<div class="col-lg-12 text-center errorTip">
</div>
</div>
</div>
<script>
function showPayWait() {
$(".popmask").show()
$(".paywait").show();
$(".loadingBox").show();
$(".errorTip").text("");
}
function hidePayWait() {
$(".popmask").hide()
$(".paywait").hide();
}
function tipPayWait(info) {
showPayWait();
$(".loadingBox").hide();
$(".errorTip").text(info)
}
$(".plClose").on("click", function () { hidePayWait() })
</script>
<!-- 支付等待弹窗结束 -->

View File

@@ -0,0 +1,44 @@
@using Hncore.Pass.BaseInfo.Response
@using Hncore.Infrastructure.Serializer;
@using Hncore.Pass.BaseInfo.Service
@using Hncore.Infrastructure.Common
@using Microsoft.Extensions.Configuration
@using Hncore.Infrastructure.Extension
@inject IConfiguration m_Configuration
@inject UserService m_UserService
@{
var act = this.Context.Request.Get("act");
var WxAppId = m_Configuration["WxApps:AppID"];
var BaseUrl = m_Configuration["Service_BaseUrl"];
var requestUrl =this.Context.Request.GetUrl().UrlEncode();
UserLoginModel user = null;
Hncore.Pass.BaseInfo.Models.User userEntity = new Hncore.Pass.BaseInfo.Models.User();
if (this.Context.Request.Cookies.TryGetValue("userInfo", out string userCookie))
{
user = userCookie.FromJsonTo<UserLoginModel>();
userEntity = await m_UserService.GetById(user.Id);
}
}
@if (user == null)
{
<script>
function isWeiXin() {
var ua = window.navigator.userAgent.toLowerCase();
if (ua.indexOf('micromessenger')!=-1) {
return true;
} else {
return false;
}
}
if (!isWeiXin() || "login" =="@act") {
window.location.href = "/User/WebLogin?redirect=@requestUrl";
} else {
window.location.href = "@(BaseUrl)User/MP_GetUserInfo?appid=@WxAppId&callbakUrl=@requestUrl";
}
</script>
}

View File

@@ -0,0 +1,25 @@
@model ErrorViewModel
@{
ViewData["Title"] = "Error";
}
<h1 class="text-danger">Error.</h1>
<h2 class="text-danger">An error occurred while processing your request.</h2>
@if (Model.ShowRequestId)
{
<p>
<strong>Request ID:</strong> <code>@Model.RequestId</code>
</p>
}
<h3>Development Mode</h3>
<p>
Swapping to <strong>Development</strong> environment will display more detailed information about the error that occurred.
</p>
<p>
<strong>The Development environment shouldn't be enabled for deployed applications.</strong>
It can result in displaying sensitive information from exceptions to end users.
For local debugging, enable the <strong>Development</strong> environment by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong>
and restarting the app.
</p>

View File

@@ -0,0 +1,25 @@
@using Microsoft.AspNetCore.Http.Features
@{
var consentFeature = Context.Features.Get<ITrackingConsentFeature>();
var showBanner = !consentFeature?.CanTrack ?? false;
var cookieString = consentFeature?.CreateConsentCookie();
}
@if (showBanner)
{
<div id="cookieConsent" class="alert alert-info alert-dismissible fade show" role="alert">
Use this space to summarize your privacy and cookie use policy. <a asp-area="" asp-controller="Home" asp-action="Privacy">Learn More</a>.
<button type="button" class="accept-policy close" data-dismiss="alert" aria-label="Close" data-cookie-string="@cookieString">
<span aria-hidden="true">Accept</span>
</button>
</div>
<script>
(function () {
var button = document.querySelector("#cookieConsent button[data-cookie-string]");
button.addEventListener("click", function (event) {
document.cookie = button.dataset.cookieString;
}, false);
})();
</script>
}

View File

@@ -0,0 +1,226 @@
@using Hncore.Pass.BaseInfo.Response
@using Hncore.Infrastructure.Serializer;
@using Hncore.Pass.Vpn.Service
@inject ProductService m_ProductService
@{
UserLoginModel user = null;
if (this.Context.Request.Cookies.TryGetValue("userInfo", out string userCookie))
{
user = userCookie.FromJsonTo<UserLoginModel>();
}
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta content="yes" name="apple-mobile-web-app-capable" />
<meta content="yes" name="apple-touch-fullscreen" />
<meta content="telephone=no,email=no" name="format-detection" />
<meta content="maximum-dpr=2" name="flexible" />
<title>聚IP JUIP.COM-产品购买</title>
<link rel="stylesheet" type="text/css" href="~/m/css/base.css" />
<link rel="stylesheet" type="text/css" href="~/m/css/swiper.min.css" />
<link rel="stylesheet" type="text/css" href="~/m/css/bootstrap.css" />
<link rel="Shortcut Icon" href="/img/favicon.ico" type="image/x-icon" />
<script src="~/m/js/jquery.min.js" type="text/javascript" charset="utf-8"></script>
<script src="http://g.tbcdn.cn/mtb/lib-flexible/0.3.4/??flexible_css.js,flexible.js"></script>
<script src="~/js/vue.js"></script>
<script src="~/m/js/swiper.min.js" type="text/javascript" charset="utf-8"></script>
<script src="~/m/js/bootstrap.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
$.ajaxSetup({
complete: function (XMLHttpRequest, textStatus) {
console.log(textStatus);
//var sessionstatus = XMLHttpRequest.getResponseHeader("sessionstatus");
if (textStatus == "parsererror") {
//如果超时就处理 ,指定要跳转的页面(比如登陆页)
window.location.href="/user/weblogin"
}
}
});
$(function () {
$(".btnNav").click(function () {
$(".mask").fadeIn();
console.log(1)
});
$(".btnClose").click(function () {
$(".mask").fadeOut();
console.log(2)
});
$(".on_q").click(function () {
$(".side_q").toggle();
});
//$(".item_on_q").mouseover(function () {
// $(".side_q").stop().show();
//});
//$(".item_on_q").mouseleave(function () {
// $(".side_q").stop().hide();
//});
//$(".on_wx").click(function () {
// $(".side_kefu").toggle();
//});
$(".item_on_wx").mouseover(function () {
$(".side_kefu").stop().fadeIn();
});
$(".item_on_wx").mouseleave(function () {
$(".side_kefu").stop().fadeOut();
});
$(".on_gzh").mouseover(function () {
$(".side_gzh").stop().fadeIn();
});
$(".on_gzh").mouseleave(function () {
$(".side_gzh").stop().fadeOut();
});
$(".on_tel").mouseover(function () {
$(".side_tel").stop().fadeIn();
});
$(".on_tel").mouseleave(function () {
$(".side_tel").stop().fadeOut();
});
})
function isWeiXin() {
var ua = window.navigator.userAgent.toLowerCase();
if (ua.indexOf('micromessenger') != -1) {
return true;
} else {
return false;
}
}
</script>
</head>
<body>
<div class="popmask"></div>
<div class="sideBar">
<div class="item item_on_q">
<img src="~/img/qq.png" class="on_q"><div class="kefu_tit">QQ</div>
<div class="side_q">
<h4 style="border-bottom:1px solid #ccc;text-align:center;width:100%;padding:15px 0;">实时响应 在线时间8:00-24:00</h4>
<div class="item">
<a href="https://admin.qidian.qq.com/template/blue/mp/menu/qr-code-jump.html?linkType=0&env=ol&kfuin=2852138148&fid=299&key=f377ec024ca45115a03a7632c7bda230&cate=1&source=&isLBS=&isCustomEntry=&type=16&ftype=1&_type=wpa&qidian=true" target="_blank">
<div class="ileft">
<img src="~/img/q.png">
</div>
<div class="iright">
<span>人工客服:售前</span>
</div>
</a>
</div>
<div class="item">
<a href="https://admin.qidian.qq.com/template/blue/mp/menu/qr-code-jump.html?linkType=0&env=ol&kfuin=2852138148&fid=299&key=f377ec024ca45115a03a7632c7bda230&cate=1&source=&isLBS=&isCustomEntry=&type=16&ftype=1&_type=wpa&qidian=true" target="_blank">
<div class="ileft">
<img src="~/img/q.png">
</div>
<div class="iright">
<span>人工客服:售后</span>
</div>
</a>
</div>
</div>
</div>
<div class="item item_on_wx">
<img src="~/img/weixin.png" class="on_wx"><div class="kefu_tit">微信</div>
<div class="side_kefu">
<!-- Nav tabs -->
<ul class="nav nav-tabs" role="tablist" style="padding-top: 10px;padding-left:10px">
<li role="presentation" class="active"><a href="#xx" aria-controls="xx" role="tab" data-toggle="tab" style="border-color:#ccc">售前</a></li>
<li role="presentation"><a href="#qq" aria-controls="qq" role="tab" data-toggle="tab" style="border-color:#ccc">售后</a></li>
@*<li role="presentation"><a href="#ss" aria-controls="ss" role="tab" data-toggle="tab" style="border-color:#ccc">珊珊</a></li>
<li role="presentation"><a href="#tt" aria-controls="tt" role="tab" data-toggle="tab" style="border-color:#ccc">兔兔</a></li>*@
</ul>
<!-- Tab panes -->
<div class="tab-content" style="margin-top: 60px;">
<div role="tabpanel" class="tab-pane active" id="xx">
<img src="~/img/kf_sq.jpg">
<p style="color:#f90">实时响应 在线时间 8:00-24:00</p>
</div>
<div role="tabpanel" class="tab-pane" id="qq">
<img src="~/img/kf_sh.jpg">
<p style="color:#f90">实时响应 在线时间 8:00-24:00</p>
</div>
@*<div role="tabpanel" class="tab-pane" id="ss">
<img src="~/img/w3.png">
<p style="color:#f90">实时响应 在线时间 8:00-24:00</p>
</div>
<div role="tabpanel" class="tab-pane" id="tt">
<img src="~/img/w4.png">
<p style="color:#f90">实时响应 在线时间 8:00-24:00</p>
</div>*@
</div>
</div>
</div>
<div class="item">
<img src="~/img/gzh.png" class="on_gzh"><div class="kefu_tit">公众号</div>
<div class="side_gzh">
<p><img src="~/img/ewm.png"></p>
<p style="color:#f90">实时响应 在线时间 8:00-24:00</p>
<p style="color:#f90">关注公众号可获取免费的到期提醒服务</p>
</div>
</div>
<div class="item">
<img src="~/img/tel.png" class="on_tel"><div class="kefu_tit">电话</div>
<div class="side_tel">
<p><b>400 800 9925</b></p>
<p>实时接通</p>
<p>电话值班时间 8:00-24:00</p>
</div>
</div>
<div class="item">
<a href="#top"><img src="~/img/top.png"></a>
</div>
</div>
<!-- 弹窗导航 -->
<div class="mask">
<ul class="layNav">
<li><a href="/">首页</a></li>
<li><a asp-action="index" asp-controller="product">产品购买</a> </li>
<li><a asp-action="index" asp-controller="LineList" asp-route-Catalog="1">线路表</a> </li>
<li><a asp-action="soft" asp-controller="product">软件下载</a> </li>
<li><a asp-action="index" asp-controller="article">资讯&帮助</a></li>
<li><a asp-action="taobao" asp-controller="article">淘宝充值活动</a></li>
@if (user != null)
{
<li><a asp-action="index" asp-controller="user">个人中心</a></li>
<li><a asp-action="LoginOut" asp-controller="user">退出</a></li>
}
else
{
<li><a asp-action="WebLogin" asp-controller="user">登录</a></li>
}
<li><img src="~/m/img/close.png" class="btnClose"></li>
</ul>
</div>
<div class="mynav">
<div class="item">
<img src="~/m/img/back.png" onclick="history.go(-1)">
</div>
<div class="item mlogo">
<img src="~/m/img/logo.png">
</div>
<div class="item">
<img src="~/m/img/nav.png" class="btnNav">
</div>
</div>
@RenderBody()
@RenderSection("Scripts", required: false)
<!-- WPA start -->
<script id="qd28521381485d6faa97edf5ad07d7e159f6cb902af0" src="https://wp.qiye.qq.com/qidian/2852138148/5d6faa97edf5ad07d7e159f6cb902af0" charset="utf-8" async defer></script>
<!-- WPA end -->
</body>
</html>

View File

@@ -0,0 +1,84 @@
@using Hncore.Pass.BaseInfo.Response
@using Hncore.Infrastructure.Serializer;
@using Hncore.Pass.Vpn.Service
@inject ProductService m_ProductService
@{
UserLoginModel user = null;
if (this.Context.Request.Cookies.TryGetValue("userInfo", out string userCookie))
{
user = userCookie.FromJsonTo<UserLoginModel>();
}
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta content="yes" name="apple-mobile-web-app-capable" />
<meta content="yes" name="apple-touch-fullscreen" />
<meta content="telephone=no,email=no" name="format-detection" />
<meta content="maximum-dpr=2" name="flexible" />
<title>聚IP JUIP.COM-产品购买</title>
<link rel="stylesheet" type="text/css" href="~/m/css/base.css" />
<link rel="stylesheet" type="text/css" href="~/m/css/swiper.min.css" />
<link rel="stylesheet" type="text/css" href="~/m/css/bootstrap.css" />
<link href="~/m/css/LCalendar.css" rel="stylesheet" />
<link rel="Shortcut Icon" href="/img/favicon.ico" type="image/x-icon" />
<script src="~/m/js/jquery.min.js" type="text/javascript" charset="utf-8"></script>
<script src="http://g.tbcdn.cn/mtb/lib-flexible/0.3.4/??flexible_css.js,flexible.js"></script>
<script src="~/js/vue.js"></script>
<script src="~/m/js/swiper.min.js" type="text/javascript" charset="utf-8"></script>
<script src="~/m/js/bootstrap.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
$(function () {
$(".btnNav").click(function () {
$(".mask").fadeIn();
console.log(1)
});
$(".btnClose").click(function () {
$(".mask").fadeOut();
console.log(2)
})
})
</script>
</head>
<body>
<vc:redirecct-login></vc:redirecct-login>
<!-- 弹窗导航 -->
<div class="mask">
<ul class="layNav">
<li><a href="/">首页</a></li>
<li><a asp-action="index" asp-controller="product">产品购买</a> </li>
<li><a asp-action="index" asp-controller="LineList">线路表</a> </li>
<li><a asp-action="soft" asp-controller="product">软件下载</a> </li>
<li><a asp-action="index" asp-controller="article">资讯&帮助</a></li>
<li>
@if (user != null)
{
<a asp-action="index" asp-controller="user">个人中心</a>
}
else
{
<a asp-action="WebLogin" asp-controller="user">登录</a>
}
</li>
<li><img src="~/m/img/close.png" class="btnClose"></li>
</ul>
</div>
<div class="mynav">
<div class="item">
<img src="~/m/img/back.png" onclick="history.go(-1)">
</div>
<div class="item">
<img src="~/m/img/logo.png">
</div>
<div class="item">
<img src="~/m/img/nav.png" class="btnNav">
</div>
</div>
@RenderBody()
@RenderSection("Scripts", required: false)
</body>
</html>

View File

@@ -0,0 +1,18 @@
<environment include="Development">
<script src="~/lib/jquery-validation/dist/jquery.validate.js"></script>
<script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js"></script>
</environment>
<environment exclude="Development">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.17.0/jquery.validate.min.js"
asp-fallback-src="~/lib/jquery-validation/dist/jquery.validate.min.js"
asp-fallback-test="window.jQuery && window.jQuery.validator"
crossorigin="anonymous"
integrity="sha256-F6h55Qw6sweK+t7SiOJX+2bpSAa3b/fnlrVCJvmEj1A=">
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validation-unobtrusive/3.2.11/jquery.validate.unobtrusive.min.js"
asp-fallback-src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"
asp-fallback-test="window.jQuery && window.jQuery.validator && window.jQuery.validator.unobtrusive"
crossorigin="anonymous"
integrity="sha256-9GycpJnliUjJDVDqP0UEu/bsm9U+3dnQUH8+3W10vkY=">
</script>
</environment>

View File

@@ -0,0 +1,80 @@
@using Home.Models
@model UserHomeModel
@{
Layout = "_Layout";
}
<div class="loginArea">
<div class="loginTop">
<p> <img src="~/m/img/logoBlue.png"></p>
<p class="logoTit">找回密码</p>
</div>
<div class="loginCenter">
<p><img src="~/m/img/phone.png"><input type="text" name="" id="username" value="" placeholder="手机号" /></p>
<p><img src="~/m/img/password.png"><input type="text" name="" id="password" value="" placeholder="密码" /></p>
<p class="yzm"><img src="~/m/img/yanzhengma.png"><input type="text" name="" id="yanzhengma" value="" placeholder="验证码" /><button type="button" class="btnBlue" onclick="getCode(this)">获取验证码</button></p>
</div>
<p><button type="button" class="btnLogin" onclick="reg()">找回密码</button></p>
<p class="tixing">*手机号不是PPTP账号请登录后开通PPTP账号*</p>
<p class="bianjie">已有账号?<a asp-action="WebLogin" asp-controller="User">立即登录</a></p>
</div>
<script>
var time = 60;
function getCode(_self) {
var name = $("#username").val()
if(name == '') { alert('手机号不能为空'); return; }
if (!timing(_self)) return;
var url = '/User/SendPhoneCode?key=FindUser_Code&phone=' + name;
$.ajax({
type: 'GET',
url: url,
success: function (res) {
alert(res.Message)
//if (res.Code == 10000) {
// alert(res.Message)
//}
}
});
}
function timing(_self) {
if (time != 60) return false
var timerHandler = setInterval(function () {
time--;
if (time <= 1) {
clearInterval(timerHandler);
time = 60;
$(_self).text("获取验证码")
} else {
$(_self).text(time + "s");
}
}, 1000)
return true;
}
function reg() {
var name = $("#username").val()
var pwd = $("#password").val()
var code = $("#yanzhengma").val()
if (name == '') { alert('手机号不能为空'); return; }
if (code == '') { alert('验证码不能为空'); return; }
var data = { Phone: name, Pwd: pwd, Code: code };
$.ajax({
type: 'POST',
url: '/User/FindPwd',
contentType: "application/json",
data: JSON.stringify(data),
success: function (res) {
console.log(res);
if (res.Code == 10000) {
alert("密码重置成功,请重新登录")
window.location.href="/User/WebLogin"
} else {
alert(res.Message)
}
}
});
}
</script>

View File

@@ -0,0 +1,19 @@
@using Home.Models
@using Hncore.Pass.BaseInfo.Response
@model UserHomeModel
@{
Layout = "_Layout";
}
<vc:redirecct-login></vc:redirecct-login>
<div class="ptop">
<a class="pname">@Model.UserModel.LoginCode</a>
</div>
<ul class="plist">
<li><img src="~/m/img/p1.png"><a asp-action="indexInfo" asp-controller="user">个人信息<img src="~/m/img/arrow.png"></a></li>
<li><img src="~/m/img/p1.png"><a asp-action="myorders" asp-controller="user">我的订单<img src="~/m/img/arrow.png"></a></li>
<li><img src="~/m/img/p2.png"><a asp-action="myrefundorders" asp-controller="user">退货订单<img src="~/m/img/arrow.png"></a></li>
<li><img src="~/m/img/p3.png"><a asp-action="myaccounts" asp-controller="user">PPTP账号管理<img src="~/m/img/arrow.png"></a></li>
<li><img src="~/m/img/p4.png"><a asp-action="mycoupons" asp-controller="user">我的优惠券<img src="~/m/img/arrow.png"></a></li>
</ul>

View File

@@ -0,0 +1,361 @@
@using Home.Models
@using Hncore.Pass.BaseInfo.Response
@model UserHomeModel
@{
Layout = "_Layout";
}
<style type="text/css">
body {
background: #f5f5f5;
}
.msg {
margin-top: 1.466666rem;
}
.lineBar {
background: #3c5eb5;
width: 5px;
height: 30px;
display: inline-block;
vertical-align: middle;
margin-right: 10px;
}
.accout_tit {
height: 1.2rem;
line-height: 1.2rem;
border-bottom: 1px solid #eee;
font-size: 30px;
}
.model {
display: flex;
flex-direction: row;
width: 100%;
height: 0.933333rem;
line-height: 0.933333rem;
background: #fff;
flex-wrap: wrap;
height: auto;
}
.model .item {
border-bottom: 1px solid #f5f5f5;
height: 0.933333rem;
line-height: 0.933333rem;
}
.model .item:nth-child(odd) {
width: 30%;
text-align: right;
}
.model .item:nth-child(even) {
width: 70%;
text-align: center;
color: #ccc;
}
.red {
color: red;
}
.inputBox {
width: 330px;
}
</style>
<vc:redirecct-login></vc:redirecct-login>
<div class="container msg">
<!-- 账户信息 -->
<div class="accout_tit"><span class="lineBar"></span>账户信息 <button class="btnXq" onclick="$('#infoBox').show()">完善信息</button> <button class="btnXq" onclick="$('#pwdBox').show()">修改密码</button></div>
<div class="model">
<div class="item">
用户名:
</div>
<div class="item">
@(Model.UserModel.Phone??Model.UserModel.LoginCode)
</div>
<div class="item">
密码:
</div>
<div class="item">
<span>********</span>
</div>
<div class="item">
QQ
</div>
<div class="item">
@(Model.UserModel.QQ??"--")
</div>
<div class="item">
微信号:
</div>
<div class="item">
@(Model.UserModel.Wx??"--")
</div>
<div class="item">
淘宝会员名:
</div>
<div class="item">
@(Model.UserModel.TaoBao??"--")
</div>
<div class="item">
邮箱:
</div>
<div class="item">
@(Model.UserModel.Email??"--")
</div>
</div>
<!-- 余额 -->
<div class="accout_tit"><span class="lineBar"></span>余额 <button class="btnXq" onclick="$('#chargeBox').show()">充值</button></div>
<div class="model">
<div class="item">
余额:
</div>
<div class="item">
@Model.UserModel.RestAmount
</div>
</div>
<!-- pptv账号 -->
<div class="accout_tit"><span class="lineBar"></span>PPTV账号</div>
<div class="model">
<div class="item">
使用中:
</div>
<div class="item">
@(Model.AccountModel.TotalCount-Model.AccountModel.ExpriedCount)
</div>
<div class="item">
总个数:
</div>
<div class="item">
@Model.AccountModel.TotalCount
</div>
<div class="item">
已过期:
</div>
<div class="item">
@Model.AccountModel.ExpriedCount
</div>
</div>
<!-- 消费信息 -->
<div class="accout_tit"><span class="lineBar"></span>消费信息</div>
<div class="model">
<div class="item">
今日消费:
</div>
<div class="item">
@Model.Statistic.TodayExpend
</div>
<div class="item">
今日退款:
</div>
<div class="item">
@Model.Statistic.TodayRefund
</div>
<div class="item">
今日充值:
</div>
<div class="item">
@Model.Statistic.TodayCharege
</div>
<div class="item">
当月消费:
</div>
<div class="item">
@Model.Statistic.MonthExpend
</div>
<div class="item">
当月退款:
</div>
<div class="item">
@Model.Statistic.MonthRefund
</div>
<div class="item">
当月充值:
</div>
<div class="item">
@Model.Statistic.MonthCharege
</div>
<div class="item">
本年消费:
</div>
<div class="item">
@Model.Statistic.YearExpend
</div>
</div>
</div>
<!-- 修改个人详情 -->
<div class="layerTable" id="infoBox">
<form asp-action="UpdateInfo" asp-controller="User" method="post">
<table border="0" cellspacing="0" cellpadding="0">
<tr>
<td>QQ</td>
<td><input type="text" name="QQ" value="@(Model.UserModel.QQ)" /></td>
</tr>
<tr>
<td>微信号:</td>
<td><input type="text" name="Wx" value="@(Model.UserModel.Wx)" /></td>
</tr>
<tr>
<td>淘宝会员名:</td>
<td><input type="text" name="TaoBao" value="@(Model.UserModel.TaoBao)" /></td>
</tr>
<tr>
<td>邮箱:</td>
<td><input type="text" name="Email" value="@(Model.UserModel.Email)" /></td>
</tr>
</table>
<div class="" style="text-align:center;">
<button type="button" class="btnXq" onclick="$('#infoBox').hide()">返回</button>
<button type="submit" class="btnXq">确定</button>
</div>
</form>
</div>
<!-- 修改密码 -->
<div class="layerTable" id="pwdBox">
<form id="pwdForm">
<table border="0" cellspacing="0" cellpadding="0">
<tr>
<td>原密码:</td>
<td><input type="text" class="inputBox" name="OldPwd" /></td>
</tr>
<tr>
<td>新密码:</td>
<td><input type="text" class="inputBox" name="NewPwd" /></td>
</tr>
<tr>
<td>确认新密码:</td>
<td><input type="text" class="inputBox" name="ConfirmPwd" /></td>
</tr>
</table>
<div class="" style="text-align:center;">
<button type="button" class="btnXq" onclick="$('#pwdBox').hide()">返回</button>
<button type="button" class="btnXq" onclick="updatePwd()">确定</button>
</div>
</form>
</div>
<!-- 充值 -->
<div class="layerTable" id="chargeBox">
<form id="pwdForm">
<table border="0" cellspacing="0" cellpadding="0">
<tr>
<td>充值金额:</td>
<td><input type="number" class="inputBox" id="orderAmount" value="100" /></td>
</tr>
<tr>
<td>支付方式:</td>
<td>
<input type="radio" name="PayChannel" value="40" checked> <img src="~/img/zfb.png">支付宝支付<br />
<input type="radio" name="PayChannel" value="10"> <img src="~/img/wx.png">微信支付
</td>
</tr>
</table>
<div class="" style="text-align:center;">
<button type="button" class="btnXq" onclick="$('#chargeBox').hide()">返回</button>
<button type="button" class="btnXq" onclick="charge()">确定</button>
</div>
</form>
</div>
<!-- 支付弹窗 -->
<div id="aliPayBox" style="display:none"></div>
<script>
/** 表单序列化成json字符串的方法 */
function form2JsonString(formId) {
var paramArray = $('#' + formId).serializeArray();
var jsonObj = {};
$(paramArray).each(function () {
jsonObj[this.name] = this.value;
});
console.log(jsonObj);
return JSON.stringify(jsonObj);
}
function updatePwd() {
var that = this;
$.ajax({
type: 'POST',
url: '/user/UpdatePwd',
dataType: "json",
contentType: "application/json",
data: form2JsonString("pwdForm"),
success: function (res) {
console.log(res);
if (res.Code == 10000) {
$("#pwdBox").hide();
} else {
alert(res.Message)
}
}
});
}
function h5WxPay(payData) {
window.location.href = payData;
}
function jsWxPay(payData) {
WeixinJSBridge.invoke(
'getBrandWCPayRequest',
JSON.parse(payData),
function (res) {
if (res.err_msg == "get_brand_wcpay_request:ok") {
window.location.href = "/User/indexInfo";
} else if (res.err_msg == "get_brand_wcpay_request:cancel") {
} else {
alert("支付失败" + res.err_msg);
}
});
}
function aliPay(payData) {
$("#aliPayBox").html(payData);
}
function payCallback(data) {
var orderInfo = data.OrderInfo;
if (!data.PayData) { alert("下单失败"); return; }
var payChannel = orderInfo.PayChannel;
if (payChannel == 10) {
h5WxPay(data.PayData)
} else if (payChannel == 20) {
jsWxPay(data.PayData);
} else if (payChannel == 40) {
aliPay(data.PayData);
}
}
function charge() {
var chargeData = {
ChargeAmount: $('#orderAmount').val(),
PayChannel: $('input[name="PayChannel"]:checked').val()
}
if (isWeiXin()) {
chargeData.PayChannel = 20;
}
$.ajax({
type: 'POST',
url: '/user/CreateOrder',
dataType: "json",
contentType: "application/json",
data: JSON.stringify(chargeData),
success: function (res) {
console.log(res);
if (res.Code == 10000) {
payCallback(res.Data)
} else {
alert(res.Message);
}
}
});
}
</script>

View File

@@ -0,0 +1,73 @@
@using Home.Models
@using Microsoft.Extensions.Configuration
@using Hncore.Infrastructure.Extension
@inject IConfiguration m_Configuration
@model UserHomeModel
@{
Layout = "_Layout";
var BaseUrl = m_Configuration["Service_BaseUrl"];
var WxAppId = m_Configuration["WxApps:AppID"];
}
<div class="loginArea">
<div class="loginTop">
<p> <img src="~/m/img/logoBlue.png"></p>
<p class="logoTit">用户登录</p>
<p><span class="xinyonghu">新用户免费赠送3次测试机会</span></p>
</div>
<div class="loginCenter">
<p><img src="~/m/img/phone.png"><input type="text" name="" id="rLogin_Name" value="" placeholder="会员手机号" /></p>
<p><img src="~/m/img/password.png"><input type="password" name="" id="rLogin_Pwd" value="" placeholder="密码" /></p>
</div>
<p>@*<span><input type="checkbox" name="" id="" value="" />自动登录</span>*@<span class="pull-right"><a asp-action="FindPwd" asp-controller="User">忘记密码?</a></span></p>
<p class="denglu"><button type="button" class="btnLogin" onclick="login()">登录</button></p>
<p class="tixing">*手机号不是PPTP账号请登录后开通PPTP账号*</p>
<p class="bianjie">还没有账号?<a asp-action="Regist" asp-controller="User">立即注册</a></p>
</div>
<script>
var redirect = "@ViewBag.redirect" || "/user/index";
function isWeiXin() {
var ua = window.navigator.userAgent.toLowerCase();
if (ua.match(/micromessenger/i) == 'micromessenger') {
return true;
} else {
return false;
}
}
function login() {
var name = $("#rLogin_Name").val()
var pwd = $("#rLogin_Pwd").val()
var data = { Logincode: name, Password: pwd, Code: 1 };
$.ajax({
type: 'POST',
url: '/user/login',
contentType: "application/json",
data: JSON.stringify(data),
success: function (res) {
console.log(res);
if (res.Code == 10000) {
loginSuccess(res.Data.User)
} else {
alert(res.Message)
}
}
});
}
function loginSuccess(user) {
if (!isWeiXin()) {
window.location.href = redirect;
return;
}
window.location.href = "@(BaseUrl)User/MP_GetUserInfo?appid=@WxAppId&callbakUrl=" + redirect + "&state=" + user.Id;
//if (!user.OpenId) {
//} else {
// window.location.href = "/User/Index";
//}
}
</script>

View File

@@ -0,0 +1,518 @@
@using Hncore.Infrastructure.Data
@using Hncore.Pass.Vpn.Domain
@using Hncore.Infrastructure.Extension
@using ViewComponents
@model List<ProductAccountEntity>
@{
Layout = "_UserLayout";
}
<div id="app">
@*<div class="qq">
<img src="~/m/img/smile.png"> 为给您带来更好的服务体验请完善QQ号和微信号
</div>*@
<div class="chaxun2">
<input type="text" v-model="searchModel.Keyword" placeholder="账号" /><button type="button" class="btnOrange" v-on:click="search">查询</button>
</div>
<div class="row riqi">
<div class="col-sm-4 col-xs-4">
日期查询:
</div>
<div class="col-sm-4 col-xs-4">
<input type="text" name="start_date" id="start_date" placeholder="选择开通日期" readonly="readonly" v-model="searchModel.BTime" />
</div>
<div class="col-sm-4 col-xs-4">
<input type="text" name="end_date" id="end_date" placeholder="选择到期日期" readonly="readonly" v-model="searchModel.ETime" />
</div>
</div>
<div class="row shaixuan">
<div class="col-sm-4 col-xs-4">
<select v-model="searchModel.ProductId">
<option value="0">全部产品</option>
<option v-for="item in productWithPackage" :value="item.Product.Id">{{item.Product.Name}}</option>
</select>
</div>
<div class="col-sm-4 col-xs-4">
<select v-model="searchModel.PackageId">
<option value="0">全部套餐</option>
<option v-for="item in packages" :value="item.Id">{{item.Name}}</option>
</select>
</div>
<div class="col-sm-4 col-xs-4">
<button type="button" class="btnRenzheng"><img src="~/m/img/renzheng.png">老账号认证</button>
</div>
</div>
<table border="0" cellspacing="0" cellpadding="0" class="orderTable">
<tr>
<th><input type="checkbox" name="" id="checkAll" value="" style="width: 0.4rem;height: 0.4rem;" /></th>
<th>套餐</th>
<th>账号</th>
<th>操作</th>
</tr>
@foreach (var item in Model)
{
<tr>
<td><input type="checkbox" class="selectAccount" value="@item.Account" a-pid="@(item.ProductId)" a-connectCount="@item.ConnectCount" a-aType="@item.AccountType" style="width: 0.4rem;height: 0.4rem;" /></td>
<td>@item.ProductName/@item.PackageName</td>
<td>@item.Account</td>
<td>
<button type="button" class="btnXq toDetail"
a-UserCode="@item.UserCode"
a-ProductName="@item.ProductName"
a-PackageName="@item.PackageName"
a-Account="@item.Account"
a-Pwd="@item.Pwd"
a-ConnectCount="@item.ConnectCount"
a-StartTime="@item.StartTime"
a-EndTime="@item.EndTime"
a-RestTime="@item.RestTime">
详情
</button>
<a class="btnXq" asp-action="OnLine" asp-controller="User" asp-route-productId="@item.ProductId" asp-route-account="@item.Account">
<button type="button" class="btnXq" style="margin-top:3px">查看</button>
</a>
</td>
</tr>
}
</table>
@*<div class="fenye" style="margin-top: -210px;margin-bottom: 200px;">
@await Component.InvokeAsync("Pager", new PagerModel() { Total = Model.RowCount, PageIndex = this.Context.Request.GetInt("PageIndex") })
</div>*@
<div class="bottomBar">
<button type="button" class="btnXu btn-rebuy"><img src="~/m/img/xufei.png">续费</button><button type="button" class="btnTui btn-refund"><img src="~/m/img/tui.png">退货</button>
</div>
<!-- 认证弹窗 -->
<div class="renzhengMask">
<div class="renzhenKuang">
<img src="~/m/img/close.png" class="renzhengClose">
<!-- Nav tabs -->
<ul class="nav nav-tabs renzhengTab" role="tablist">
<li role="presentation" class="active"><a href="#home" aria-controls="home" role="tab" data-toggle="tab">单个认证</a></li>
<li role="presentation"><a href="#profile" aria-controls="profile" role="tab" data-toggle="tab">批量认证</a></li>
</ul>
<!-- Tab panes -->
<div class="tab-content">
<div role="tabpanel" class="tab-pane active" id="home">
<div class="renzhengModel">
<div class="item">
选择产品
</div>
<div class="item chooseCp">
<select v-model="oneAuthModel.ProductId">
<option v-for="item in productWithPackage" :value="item.Product.Id">{{item.Product.Name}}</option>
</select>
</div>
</div>
<div class="renzhengModel">
<div class="item">
输入账号
</div>
<div class="item renzhengInput">
<input type="text" v-model="oneAuthModel.Account" />
</div>
</div>
<div class="renzhengModel">
<div class="item">
验证密码
</div>
<div class="item renzhengInput">
<input type="text" v-model="oneAuthModel.Pwd" />
</div>
</div>
<p class="btnRz" v-on:click="accountOneAuth">认证账号</p>
</div>
<div role="tabpanel" class="tab-pane" id="profile">
<div class="renzhengModel">
<div class="item">
选择产品
</div>
<div class="item chooseCp">
<select v-model="mutilAuthModel.ProductId">
<option v-for="item in productWithPackage" :value="item.Product.Id">{{item.Product.Name}}</option>
</select>
</div>
</div>
<div class="renzhengModel">
<div class="item">
账号前缀
</div>
<div class="item renzhengInput">
<input type="text" v-model="mutilAuthModel.Account" />
</div>
</div>
<div class="renzhengModel">
<div class="item">
开始数
</div>
<div class="item renzhengInput">
<input type="number" v-model="mutilAuthModel.StartNum" />
</div>
</div>
<div class="renzhengModel">
<div class="item">
认证个数
</div>
<div class="item renzhengInput">
<input type="number" v-model="mutilAuthModel.Count" />
</div>
</div>
<div class="renzhengModel">
<div class="item">
验证密码
</div>
<div class="item renzhengInput">
<input type="text" v-model="mutilAuthModel.Pwd" />
</div>
</div>
<p v-if="mutilAuthLoading" style="margin:8px;color:red;text-align:center">认证中,请耐心等待...</p>
<p class="btnRz" v-on:click="accountMutilAuth">认证账号</p>
</div>
</div>
</div>
</div>
<!-- 弹窗详情 -->
<div class="layerTable">
<table border="0" cellspacing="0" cellpadding="0">
<tr>
<td>用户:</td>
<td>{{currentAccount.UserCode}}</td>
</tr>
<tr>
<td>产品:</td>
<td>{{currentAccount.ProductName}}</td>
</tr>
<tr>
<td>套餐:</td>
<td>{{currentAccount.PackageName}}</td>
</tr>
<tr>
<td>账号:</td>
<td>{{currentAccount.Account}}</td>
</tr>
<tr>
<td>密码:</td>
<td>{{currentAccount.Pwd}}</td>
</tr>
<tr>
<td>连接数:</td>
<td>{{currentAccount.ConnectCount}}</td>
</tr>
<tr>
<td>开通时间:</td>
<td>{{currentAccount.StartTime}}</td>
</tr>
<tr>
<td>到期时间:</td>
<td>{{currentAccount.EndTime}}</td>
</tr>
<tr>
<td>剩余时间:</td>
<td>{{currentAccount.RestTime}}</td>
</tr>
</table>
<div class="back">
<img src="~/m/img/arrowback.png"> 返回列表
</div>
</div>
</div>
<script src="~/m/js/LCalendar.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
var app = new Vue({
el: '#app',
data: {
mutilAuthLoading: false,
productWithPackage: [],
packages: [],
searchModel: {
ExpiredDay:-1,
ProductId:@this.Context.Request.GetInt("ProductId"),
PackageId:@this.Context.Request.GetInt("PackageId"),
Keyword:'@this.Context.Request.Get("Keyword")',
BTime: '@this.Context.Request.Get("BTime")',
ETime: '@this.Context.Request.Get("ETime")',
},
oneAuthModel: {
ProductId: 0,
Account: "",
Pwd:""
},
mutilAuthModel: {
ProductId: 0,
Account: "",
Pwd: "",
StartNum: 0,
Count:0
},
currentAccount: {
UserCode: "",
ProductName: "",
PackageName: "",
Account: "",
Pwd: "",
ConnectCount: "",
StartTime: "",
EndTime: "",
RestTime: "",
}
},
computed: {
},
watch: {
'searchModel.ProductId': { //加引号监听对象里的属性
handler: function (newValue, oldValue) {
for (var i = 0; i < this.productWithPackage.length; i++) {
var item = this.productWithPackage[i];
if (item.Product.Id == newValue) {
this.packages = item.Packages
return;
}
}
},
immediate: true
}
},
mounted: function () {
this.getProducts();
},
methods: {
initPackages: function () {
var productId = this.searchModel.ProductId;
if (productId == 0) return;
for (var i = 0; i < this.productWithPackage.length; i++) {
var item = this.productWithPackage[i];
if (item.Product.Id == productId) {
this.packages = item.Packages
return;
}
}
},
getProducts() {
var that = this;
$.ajax({
type: 'GET',
url: '/api/course/v1/product/ProductWithPackage',
success: function (res) {
if (res.Code == 10000) {
that.productWithPackage = res.Data;
that.initPackages();
}
}
});
},
search() {
var ps = [];
for (var item in this.searchModel) {
var p = item + "=" + this.searchModel[item];
ps.push(p);
}
window.location.href = "?" + ps.join("&");
},
accountOneAuth() {
if (this.oneAuthModel.ProductId ==0) {
alert('请选择产品')
return;
}
if (this.oneAuthModel.Account == '' || this.oneAuthModel.Pwd == '') {
alert('账号和密码不能为空')
return;
}
$.ajax({
type: 'POST',
url: '/user/OrginAccountAuth',
dataType: "json",
contentType: "application/json",
data: JSON.stringify(this.oneAuthModel),
success: function (res) {
console.log(res);
if (res.Code == 10000) {
alert('认证成功')
window.location.reload();
} else {
alert(res.Message)
}
}
});
},
accountMutilAuth() {
if (this.mutilAuthModel.ProductId == 0) {
alert('请选择产品')
return;
}
if (this.mutilAuthModel.Account == '' || this.mutilAuthModel.Pwd == '') {
alert('账号和密码不能为空')
return;
}
if (this.mutilAuthLoading) return;
this.mutilAuthLoading = true;
var that = this;
$.ajax({
type: 'POST',
url: '/user/OrginAccountAuth',
dataType: "json",
contentType: "application/json",
data: JSON.stringify(this.mutilAuthModel),
success: function (res) {
that.mutilAuthLoading = false;
console.log(res);
if (res.Code == 10000) {
alert('认证成功')
window.location.reload();
} else {
alert(res.Message)
}
}
});
},
setAccountInfo(info) {
this.currentAccount = info;
}
}
})
function showDetail(_self) {
var currentOrder = {
UserCode: $(_self).attr('a-UserCode'),
ProductName: $(_self).attr('a-ProductName'),
PackageName: $(_self).attr('a-PackageName'),
Account: $(_self).attr('a-Account'),
Pwd: $(_self).attr('a-Pwd'),
ConnectCount: $(_self).attr('a-ConnectCount'),
StartTime: $(_self).attr('a-StartTime'),
EndTime: $(_self).attr('a-EndTime'),
RestTime: $(_self).attr('a-RestTime'),
}
app.setAccountInfo(currentOrder);
$(_self).show();
}
$(function () {
//退款
function caclRefund(account,refundFun) {
$.ajax({
type: 'GET',
url: '/api/course/v1/order/CaclRefund?account=' + account,
success: function (res) {
if (res.Code == 10000) {
var msg ="剩余:"+res.Data.RefundRestTime+",还需退款:"+ res.Data.RefundAmount+",确定要退款吗?"
if (!confirm(msg)) { return; }
refundFun(account);
} else {
alert(res.Message)
}
}
});
}
function refund(account) {
$.ajax({
type: 'GET',
url: '/api/course/v1/order/Refund?account=' +account,
success: function (res) {
if (res.Code == 10000) {
alert('退款成功')
window.location.reload()
} else {
alert(res.Message)
}
}
});
}
$(".btn-refund").on('click', function () {
var accounts = [];
$.each($('input:checkbox:checked'), function () {
accounts.push($(this).val())
});
if (accounts.length >1) { alert('一次只能退款一个账号'); return; }
if (accounts.length == 0) { alert('请选择账号'); return; }
caclRefund(accounts[0],refund)
})
function isSame(data, property) {
if (data.length == 0) return true;
var first = data[0];
for (var i = 1; i < data.length; i++) {
var item = data[i];
if (first[property] != item[property])
return false;
}
return true;
}
//续费
$(".btn-rebuy").on('click', function () {
var accounts = [];
var accountModels = [];
var isTest = false
$.each($('input:checkbox:checked'), function () {
var account = $(this).val();
if (account) {
var accountItem = {
account: account,
pid: $(this).attr('a-pid'),
connectCount: $(this).attr('a-connectCount'),
isTest: $(this).attr('a-aType') == 200
}
accountModels.push(accountItem)
accounts.push(account)
if (accountItem.isTest) isTest = true;
}
});
if (accountModels.length == 0) { alert('请选择账号'); return; }
if (!isSame(accountModels, 'pid')) { alert('必须选择相同的产品'); return; }
if (!isSame(accountModels, 'connectCount')) { alert('必须选择相同的连接数'); return; }
if (isTest) { alert('测试账号暂不支持续费,请新开正式账号'); return; }
window.location.href = "/product/rebuyindex?productId=" + accountModels[0].pid + "&accounts=" + accounts.join(",");
})
$(".toDetail").click(function () {
showDetail($(this))
$(".layerTable").show();
});
$(".back").click(function () {
$(".layerTable").hide();
})
$(".btnRenzheng").click(function () {
$(".renzhengMask").show();
});
$(".renzhengClose").click(function () {
$(".renzhengMask").hide();
});
$("#checkAll").on('click', function () {
console.log($(this).prop("checked"), "check")
$("td > input:checkbox").prop("checked", $(this).prop("checked"))
})
});
</script>
<script type="text/javascript">
var calendar = new LCalendar();
calendar.init({
'trigger': '#start_date', //标签id
'type': 'date', //date 调出日期选择 datetime 调出日期时间选择 time 调出时间选择 ym 调出年月选择,
'minDate': (new Date().getFullYear() - 3) + '-' + 1 + '-' + 1, //最小日期
'maxDate': (new Date().getFullYear() + 3) + '-' + 12 + '-' + 31 //最大日期
});
var calendar = new LCalendar();
calendar.init({
'trigger': '#end_date', //标签id
'type': 'date', //date 调出日期选择 datetime 调出日期时间选择 time 调出时间选择 ym 调出年月选择,
'minDate': (new Date().getFullYear() - 3) + '-' + 1 + '-' + 1, //最小日期
'maxDate': (new Date().getFullYear() + 3) + '-' + 12 + '-' + 31 //最大日期
});
</script>

View File

@@ -0,0 +1,68 @@
@using Hncore.Pass.Sells.Model
@model List<UserCouponModel>
@{
Layout = "_UserLayout";
Func<UserCouponModel, string> format = (item) =>
{
if (item.IsExpired) return "已过期";
if (item.IsUsed) return "已使用";
return "可使用";
};
}
<div class="kong">
</div>
@foreach (var item in Model)
{
<div class="yhq">
@if (item.Coupon.CouponType == ECouponType.Discount)
{
<div class="item">
<span class="jiage">@(item.Coupon.CouponValue)折</span> <span class="zhuangtai">@format(item)</span>
</div>
}
@if (item.Coupon.CouponType == ECouponType.Minus)
{
<div class="item">
<span class="jiage">¥@(item.Coupon.CouponValue)</span><span class="zhuangtai">@format(item)</span>
</div>
}
<div class="item">
<p>@item.Coupon.Name</p>
<p>使用规则:<span>@(item.Coupon.AllowMinAmount > 0 ? $"满{item.Coupon.AllowMinAmount}元可用" : "无限制")</span></p>
<p>有效时间:<span>@(item.Orgin.StartTime.Value.ToString("yyyy.MM.dd"))至@(item.Orgin.EndTime.Value.ToString("yyyy.MM.dd"))</span></p>
<p>获取途径:<span>@(item.Orgin.Remark)</span></p>
</div>
</div>
}
@*<div class="yhq">
<div class="item">
<span class="jiage">¥6</span><span class="zhuangtai">可使用</span>
</div>
<div class="item">
<p>优惠券名称</p>
<p>使用规则:<span>无限制</span></p>
<p>有效时间:<span>2020.1.1至2020.3.1</span></p>
<p>获取途径:<span>淘宝下单赠送</span></p>
</div>
</div>
<div class="yhq gray">
<div class="item">
<span class="jiage">¥6</span><span class="zhuangtai">已使用</span>
</div>
<div class="item">
<p>优惠券名称</p>
<p>使用规则:<span>无限制</span></p>
<p>有效时间:<span>2020.1.1至2020.3.1</span></p>
<p>获取途径:<span>淘宝下单赠送</span></p>
</div>
</div>*@

View File

@@ -0,0 +1,281 @@
@using Hncore.Infrastructure.Data
@using Hncore.Pass.Vpn.Domain
@using Hncore.Infrastructure.Extension
@using ViewComponents
@model PageData<ProductOrderEntity>
@{
Layout = "_UserLayout";
Func<string, string> cut = word =>
{
if (word.Length > 15)
return word.Substring(0, 15) + "...";
return word;
};
}
<div id="app">
<form asp-action="myorders" asp-controller="user" method="get">
<div class="chaxun2">
<input type="text" v-model="searchModel.KeyWord" /><button type="button" class="btnOrange" v-on:click="search">查询</button>
</div>
<div class="row riqi">
<div class="col-sm-4 col-xs-4">
日期查询:
</div>
<div class="col-sm-4 col-xs-4">
<input type="text" name="start_date" id="start_date" v-model="searchModel.BTime" placeholder="选择开始日期" readonly="readonly" />
</div>
<div class="col-sm-4 col-xs-4">
<input type="text" name="end_date" id="end_date" v-model="searchModel.ETime" placeholder="选择结束日期" readonly="readonly" />
</div>
</div>
<div class="row shaixuan">
<div class="col-sm-4 col-xs-4">
<select v-model="searchModel.OrderType">
<option value="0">全部类型</option>
<option value="1">新开</option>
<option value="2">续费</option>
<option value="3">批量新开</option>
<option value="4">批量续费</option>
</select>
</div>
<div class="col-sm-4 col-xs-4">
<select v-model="searchModel.ProductId">
<option value="0">全部产品</option>
<option v-for="item in productWithPackage" :value="item.Product.Id">{{item.Product.Name}}</option>
</select>
</div>
<div class="col-sm-4 col-xs-4">
<select v-model="searchModel.PackageId">
<option value="0">全部套餐</option>
<option v-for="item in packages" :value="item.Id">{{item.Name}}</option>
</select>
</div>
</div>
</form>
<table border="0" cellspacing="0" cellpadding="0" class="orderTable">
<tr><th>类型</th><th>产品</th><th>套餐</th><th>详情</th></tr>
@foreach (var item in Model.List)
{
<tr>
<td>@item.OrderType.GetEnumDisplayName()</td>
<td>@item.ProductName</td>
<td>@item.PackageName</td>
<td>
<button type="button" class="btnXq toDetail" onclick="showDetail(this)"
a-date="@item.CreateTime.ToString("yyyy.MM.dd")"
a-orderno="@item.OrderNo"
a-ordertype="@item.OrderType.GetEnumDisplayName()"
a-product="@item.ProductName"
a-package="@item.PackageName"
a-price="@item.DayPrice"
a-conncount="@(item.AccountCount*item.ConnectCount)"
a-account="@item.Accounts"
a-orderamount="@item.OrderAmount"
a-couponamount="@item.CouponAmount"
a-payamount="@item.PaymentAmount">
详情
</button>
</td>
</tr>
}
</table>
<div class="fenye">
@await Component.InvokeAsync("Pager", new PagerModel() { Total = Model.RowCount, PageIndex = this.Context.Request.GetInt("PageIndex") })
</div>
<!-- 弹窗详情 -->
<div class="layerTable">
<table border="0" cellspacing="0" cellpadding="0">
<tr>
<td>日期:</td>
<td>{{currentOrder.date}}</td>
</tr>
<tr>
<td>订单编号:</td>
<td>{{currentOrder.orderno}}</td>
</tr>
<tr>
<td>类型:</td>
<td>{{currentOrder.ordertype}}</td>
</tr>
<tr>
<td>产品:</td>
<td>{{currentOrder.product}}</td>
</tr>
<tr>
<td>套餐:</td>
<td>{{currentOrder.package}}</td>
</tr>
<tr>
<td>单价:</td>
<td>{{currentOrder.price}}</td>
</tr>
<tr>
<td>总连接数:</td>
<td>{{currentOrder.conncount}}</td>
</tr>
<tr>
<td>账号:</td>
<td>{{currentOrder.account}}</td>
</tr>
<tr>
<td>订单金额:</td>
<td>{{currentOrder.orderamount}}</td>
</tr>
<tr>
<td>优惠金额:</td>
<td>{{currentOrder.couponamount}}</td>
</tr>
<tr>
<td>实付金额:</td>
<td>{{currentOrder.payamount}}</td>
</tr>
</table>
<div class="back">
<img src="~/m/img/arrowback.png"> 返回列表
</div>
</div>
</div>
<script src="~/m/js/LCalendar.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
var app = new Vue({
el: '#app',
data: {
productWithPackage: [],
packages: [],
searchModel: {
OrderType:0,
ProductId:@this.Context.Request.GetInt("ProductId"),
PackageId:@this.Context.Request.GetInt("PackageId"),
KeyWord:'',
BTime: '@this.Context.Request.Get("BTime")',
ETime: '@this.Context.Request.Get("ETime")',
},
oneAuthModel: {
ProductId: 0,
Account: "",
Pwd:""
},
mutilAuthModel: {
ProductId: 0,
Account: "",
Pwd: "",
StartNum: 0,
Count:0
},
currentOrder: {
date:"",
orderno:"",
ordertype:"",
product:"",
package:"",
price:"",
conncount:"",
account:"",
orderamount:"",
couponamount:"",
payamount:""
}
},
computed: {
},
watch: {
'searchModel.ProductId': { //加引号监听对象里的属性
handler: function (newValue, oldValue) {
for (var i = 0; i < this.productWithPackage.length; i++) {
var item = this.productWithPackage[i];
if (item.Product.Id == newValue) {
this.packages = item.Packages
return;
}
}
},
immediate: true
}
},
created: function () {
this.getProducts();
},
methods: {
getProducts() {
var that = this;
$.ajax({
type: 'GET',
url: '/api/course/v1/product/ProductWithPackage',
success: function (res) {
if (res.Code == 10000) {
that.productWithPackage = res.Data;
}
}
});
},
search() {
var ps = [];
this.searchModel.BTime = $("#BTime").val();
this.searchModel.ETime = $("#ETime").val();
for (var item in this.searchModel) {
var p = item + "=" + this.searchModel[item];
ps.push(p);
}
window.location.href = "?" + ps.join("&");
},
setOrderInfo(info) {
this.currentOrder = info;
}
}
})
function showDetail(_self) {
var currentOrder = {
date: $(_self).attr('a-date'),
orderno: $(_self).attr('a-orderno'),
ordertype: $(_self).attr('a-ordertype'),
product: $(_self).attr('a-product'),
package: $(_self).attr('a-package'),
price: $(_self).attr('a-price'),
conncount: $(_self).attr('a-conncount'),
account: $(_self).attr('a-account'),
orderamount: $(_self).attr('a-orderamount'),
couponamount: $(_self).attr('a-couponamount'),
payamount: $(_self).attr('a-payamount'),
}
app.setOrderInfo(currentOrder);
$(_self).show();
}
</script>
<script type="text/javascript">
var calendar = new LCalendar();
calendar.init({
'trigger': '#start_date', //标签id
'type': 'date', //date 调出日期选择 datetime 调出日期时间选择 time 调出时间选择 ym 调出年月选择,
'minDate': (new Date().getFullYear() - 3) + '-' + 1 + '-' + 1, //最小日期
'maxDate': (new Date().getFullYear() + 3) + '-' + 12 + '-' + 31 //最大日期
});
var calendar = new LCalendar();
calendar.init({
'trigger': '#end_date', //标签id
'type': 'date', //date 调出日期选择 datetime 调出日期时间选择 time 调出时间选择 ym 调出年月选择,
'minDate': (new Date().getFullYear() - 3) + '-' + 1 + '-' + 1, //最小日期
'maxDate': (new Date().getFullYear() + 3) + '-' + 12 + '-' + 31 //最大日期
});
$(".toDetail").click(function () {
showDetail($(this))
$(".layerTable").show();
});
$(".back").click(function () {
$(".layerTable").hide();
})
</script>

View File

@@ -0,0 +1,271 @@
@using Hncore.Infrastructure.Data
@using Hncore.Pass.Vpn.Domain
@using Hncore.Infrastructure.Extension
@using ViewComponents
@model PageData<ProductOrderEntity>
@{
Layout = "_UserLayout";
}
<div id="app">
<form asp-action="myorders" asp-controller="user" method="get">
<div class="chaxun2">
<input type="text" v-model="searchModel.KeyWord" /><button type="button" class="btnOrange" v-on:click="search">查询</button>
</div>
<div class="row riqi">
<div class="col-sm-4 col-xs-4">
日期查询:
</div>
<div class="col-sm-4 col-xs-4">
<input type="text" name="start_date" id="start_date" v-model="searchModel.BTime" placeholder="选择开始日期" readonly="readonly" />
</div>
<div class="col-sm-4 col-xs-4">
<input type="text" name="end_date" id="end_date" v-model="searchModel.ETime" placeholder="选择结束日期" readonly="readonly" />
</div>
</div>
<div class="row shaixuan">
<div class="col-sm-4 col-xs-4">
<select v-model="searchModel.OrderType">
<option value="0">全部类型</option>
<option value="1">新开</option>
<option value="2">续费</option>
<option value="3">批量新开</option>
<option value="4">批量续费</option>
</select>
</div>
<div class="col-sm-4 col-xs-4">
<select v-model="searchModel.ProductId">
<option value="0">全部产品</option>
<option v-for="item in productWithPackage" :value="item.Product.Id">{{item.Product.Name}}</option>
</select>
</div>
<div class="col-sm-4 col-xs-4">
<select v-model="searchModel.PackageId">
<option value="0">全部套餐</option>
<option v-for="item in packages" :value="item.Id">{{item.Name}}</option>
</select>
</div>
</div>
</form>
<table border="0" cellspacing="0" cellpadding="0" class="orderTable">
<tr><th>类型</th><th>产品</th><th>套餐</th><th>详情</th></tr>
@foreach (var item in Model.List)
{
<tr>
<td>@item.OrderType.GetEnumDisplayName()</td>
<td>@item.ProductName</td>
<td>@item.PackageName</td>
<td>
<button type="button" class="btnXq toDetail" onclick="showDetail(this)"
a-date="@item.CreateTime.ToString("yyyy.MM.dd")"
a-orderno="@item.OrderNo"
a-ordertype="@item.OrderType.GetEnumDisplayName()"
a-product="@item.ProductName"
a-package="@item.PackageName"
a-price="@item.DayPrice"
a-dayprice="@item.DayPrice"
a-conncount="@(item.AccountCount*item.ConnectCount)"
a-account="@item.Accounts"
a-orderamount="@item.OrderAmount"
a-refundamount="@item.RefundAmount"
a-payamount="@item.PaymentAmount"
a-refundresttime="@item.RefundRestTime">
详情
</button>
</td>
</tr>
}
</table>
<div class="fenye">
@await Component.InvokeAsync("Pager", new PagerModel() { Total = Model.RowCount, PageIndex = this.Context.Request.GetInt("PageIndex") })
</div>
<!-- 弹窗详情 -->
<div class="layerTable">
<table border="0" cellspacing="0" cellpadding="0">
<tr>
<td>日期:</td>
<td>{{currentOrder.date}}</td>
</tr>
<tr>
<td>订单编号:</td>
<td>{{currentOrder.orderno}}</td>
</tr>
<tr>
<td>类型:</td>
<td>{{currentOrder.ordertype}}</td>
</tr>
<tr>
<td>产品:</td>
<td>{{currentOrder.product}}</td>
</tr>
<tr>
<td>套餐:</td>
<td>{{currentOrder.package}}</td>
</tr>
<tr>
<td>总连接数:</td>
<td>{{currentOrder.conncount}}</td>
</tr>
<tr>
<td>账号:</td>
<td>{{currentOrder.account}}</td>
</tr>
<tr>
<td>退款单价:</td>
<td>{{currentOrder.dayprice}}</td>
</tr>
<tr>
<td>退款时长:</td>
<td>{{currentOrder.refundresttime}}</td>
</tr>
<tr>
<td>实付金额:</td>
<td>{{currentOrder.paymentamount}}</td>
</tr>
<tr>
<td>退款金额:</td>
<td>{{currentOrder.refundamount}}</td>
</tr>
</table>
<div class="back">
<img src="~/m/img/arrowback.png"> 返回列表
</div>
</div>
</div>
<script src="~/m/js/LCalendar.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
var app = new Vue({
el: '#app',
data: {
productWithPackage: [],
packages: [],
searchModel: {
OrderType:0,
ProductId:@this.Context.Request.GetInt("ProductId"),
PackageId:@this.Context.Request.GetInt("PackageId"),
KeyWord:'',
BTime: '@this.Context.Request.Get("BTime")',
ETime: '@this.Context.Request.Get("ETime")',
},
oneAuthModel: {
ProductId: 0,
Account: "",
Pwd:""
},
mutilAuthModel: {
ProductId: 0,
Account: "",
Pwd: "",
StartNum: 0,
Count:0
},
currentOrder: {
date:"",
orderno:"",
ordertype:"",
product:"",
package:"",
price:"",
conncount:"",
account:"",
orderamount:"",
couponamount:"",
payamount:""
}
},
computed: {
},
watch: {
'searchModel.ProductId': { //加引号监听对象里的属性
handler: function (newValue, oldValue) {
for (var i = 0; i < this.productWithPackage.length; i++) {
var item = this.productWithPackage[i];
if (item.Product.Id == newValue) {
this.packages = item.Packages
return;
}
}
},
immediate: true
}
},
created: function () {
this.getProducts();
},
methods: {
getProducts() {
var that = this;
$.ajax({
type: 'GET',
url: '/api/course/v1/product/ProductWithPackage',
success: function (res) {
if (res.Code == 10000) {
that.productWithPackage = res.Data;
}
}
});
},
search() {
var ps = [];
this.searchModel.BTime = $("#BTime").val();
this.searchModel.ETime = $("#ETime").val();
for (var item in this.searchModel) {
var p = item + "=" + this.searchModel[item];
ps.push(p);
}
window.location.href = "?" + ps.join("&");
},
setOrderInfo(info) {
this.currentOrder = info;
}
}
})
function showDetail(_self) {
var currentOrder = {
date: $(_self).attr('a-date'),
orderno: $(_self).attr('a-orderno'),
ordertype: $(_self).attr('a-ordertype'),
product: $(_self).attr('a-product'),
package: $(_self).attr('a-package'),
dayprice: $(_self).attr('a-dayprice'),
conncount: $(_self).attr('a-conncount'),
account: $(_self).attr('a-account'),
orderamount: $(_self).attr('a-orderamount'),
couponamount: $(_self).attr('a-couponamount'),
payamount: $(_self).attr('a-payamount'),
refundresttime: $(_self).attr('a-refundresttime'),
payamount: $(_self).attr('a-payamount'),
}
app.setOrderInfo(currentOrder);
$(_self).show();
}
</script>
<script type="text/javascript">
var calendar = new LCalendar();
calendar.init({
'trigger': '#start_date', //标签id
'type': 'date', //date 调出日期选择 datetime 调出日期时间选择 time 调出时间选择 ym 调出年月选择,
'minDate': (new Date().getFullYear() - 3) + '-' + 1 + '-' + 1, //最小日期
'maxDate': (new Date().getFullYear() + 3) + '-' + 12 + '-' + 31 //最大日期
});
var calendar = new LCalendar();
calendar.init({
'trigger': '#end_date', //标签id
'type': 'date', //date 调出日期选择 datetime 调出日期时间选择 time 调出时间选择 ym 调出年月选择,
'minDate': (new Date().getFullYear() - 3) + '-' + 1 + '-' + 1, //最小日期
'maxDate': (new Date().getFullYear() + 3) + '-' + 12 + '-' + 31 //最大日期
});
$(".toDetail").click(function () {
showDetail($(this))
$(".layerTable").show();
});
$(".back").click(function () {
$(".layerTable").hide();
})
</script>

View File

@@ -0,0 +1,149 @@
@using Home.Models
@using Hncore.Pass.BaseInfo.Response
@using Hncore.Pass.Vpn.Model
@using Hncore.Infrastructure.Extension
@model List<OriginAccountOnlineModel>
@{
Layout = "_Layout";
var productId = this.Context.Request.GetInt("productId");
}
<style type="text/css">
body {
background: #f5f5f5;
}
.msg {
margin-top: 1.466666rem;
}
.lineBar {
background: #3c5eb5;
width: 5px;
height: 30px;
display: inline-block;
vertical-align: middle;
margin-right: 10px;
}
.accout_tit {
height: 1.2rem;
line-height: 1.2rem;
border-bottom: 1px solid #eee;
font-size: 30px;
}
.model {
display: flex;
flex-direction: row;
width: 100%;
height: 0.933333rem;
line-height: 0.933333rem;
background: #fff;
flex-wrap: wrap;
height: auto;
}
.model .item {
border-bottom: 1px solid #f5f5f5;
height: 0.933333rem;
line-height: 0.933333rem;
}
.model .item:nth-child(odd) {
width: 30%;
text-align: right;
}
.model .item:nth-child(even) {
width: 70%;
text-align: center;
color: #ccc;
}
.red {
color: red;
}
.inputBox {
width: 330px;
}
</style>
<vc:redirecct-login></vc:redirecct-login>
<div class="container msg">
@if (Model.Count == 0)
{
<div class="red" style="text-align:center">暂无数据</div>
}
@foreach (var item in Model)
{
<div class="accout_tit"><span class="lineBar"></span>#@(Model.IndexOf(item)+1) <button class="btnXq" onclick="killout(@item.Id)">强制离线</button> </div>
<div class="model">
<div class="item">
账号:
</div>
<div class="item">
@item.Account
</div>
<div class="item">
登录时间:
</div>
<div class="item">
@item.LoginTime
</div>
<div class="item">
在线时间:
</div>
<div class="item">
@item.OnlineTime
</div>
<div class="item">
服务器Ip
</div>
<div class="item">
@item.ServerIP
</div>
<div class="item">
登录ip
</div>
<div class="item">
@item.LoginIP
</div>
<div class="item">
上/下行:
</div>
<div class="item">
@item.UpStream / @item.UpStream
</div>
</div>
}
</div>
<script>
/** 表单序列化成json字符串的方法 */
function form2JsonString(formId) {
var paramArray = $('#' + formId).serializeArray();
var jsonObj = {};
$(paramArray).each(function () {
jsonObj[this.name] = this.value;
});
console.log(jsonObj);
return JSON.stringify(jsonObj);
}
function killout(productId,id) {
var that = this;
$.ajax({
type: 'GET',
url: '/api/course/v1/productaccount/KillOut?productId=@productId&id=' + id,
success: function (res) {
if (res.Code == 10000) {
alert("操作成功");
window.location.reload();
}
}
});
}
</script>

View File

@@ -0,0 +1,97 @@
@using Home.Models
@using Microsoft.Extensions.Configuration
@using Hncore.Infrastructure.Extension
@inject IConfiguration m_Configuration
@model UserHomeModel
@{
Layout = "_Layout";
var BaseUrl = m_Configuration["Service_BaseUrl"];
var WxAppId = m_Configuration["WxApps:AppID"];
}
<div class="loginArea">
<div class="loginTop">
<p> <img src="~/m/img/logoBlue.png"></p>
<p class="logoTit">用户注册</p>
<p><span class="xinyonghu">新用户免费赠送3次测试机会</span></p>
</div>
<div class="loginCenter">
<p><img src="~/m/img/phone.png"><input type="text" name="" id="username" value="" placeholder="手机号" /></p>
<p><img src="~/m/img/password.png"><input type="password" name="" id="password" value="" placeholder="密码" /></p>
<p class="yzm"><img src="~/m/img/yanzhengma.png"><input type="text" name="" id="yanzhengma" value="" placeholder="验证码" /><button type="button" class="btnBlue" onclick="getCode(this)">获取验证码</button></p>
<p><img src="~/m/img/phone.png"><input type="text" name="" id="wxhao" value="" placeholder="微信号" /></p>
<p><img src="~/m/img/phone.png"><input type="text" name="" id="wxhao" value="" placeholder="QQ号" /></p>
</div>
<p class="xieyi"><input type="checkbox" name="" id="" value="" />我同意<span>《聚IP JUIP.COM用户注册协议》</span></p>
<p><button type="button" class="btnLogin" onclick="reg()">注册</button></p>
<p class="tixing">*手机号不是PPTP账号请登录后开通PPTP账号*</p>
<p class="bianjie">已有账号?<a href="#">立即登录</a></p>
</div>
<script>
var redirect = "@ViewBag.redirect" || "/user/index";
var time = 60;
function getCode(_self) {
var name = $("#username").val()
if(name == '') { alert('手机号不能为空'); return; }
if (!timing(_self)) return;
var url = '/user/SendPhoneCode?key=User_Code&phone=' + name;
$.ajax({
type: 'GET',
url: url,
success: function (res) {
alert(res.Message)
}
});
}
function timing(_self) {
if (time != 60) return false
var timerHandler = setInterval(function () {
time--;
if (time <= 1) {
clearInterval(timerHandler);
time = 60;
$(_self).text("获取验证码")
} else {
$(_self).text(time + "s");
}
}, 1000)
return true;
}
function reg() {
var name = $("#username").val()
var pwd = $("#password").val()
var code = $("#yanzhengma").val()
if (name == '') { alert('手机号不能为空'); return; }
if (code == '') { alert('验证码不能为空'); return; }
var wx = $("#wxhao").val()
var qq = $("#qqhao").val()
var data = { Phone: name, Pwd: pwd, Code: code, Wx: wx, QQ: qq };
$.ajax({
type: 'POST',
url: '/user/Regist',
contentType: "application/json",
data: JSON.stringify(data),
success: function (res) {
console.log(res);
if (res.Code == 10000) {
loginSuccess(res.Data.User)
} else {
alert(res.Message)
}
}
});
}
function loginSuccess(user) {
if (!isWeiXin()) {
window.location.href = redirect;
return;
}
if (!user.OpenId) {
window.location.href = "@(BaseUrl)User/MP_GetUserInfo?appid=@WxAppId&callbakUrl="+redirect+"&state="+user.Id;
}
}
</script>

View File

@@ -0,0 +1,4 @@
@using Home
@using Home.Models
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@addTagHelper *, Host

View File

@@ -0,0 +1,3 @@
@{
Layout = "_Layout";
}

View File

@@ -0,0 +1,141 @@
@using Hncore.Pass.Vpn.Domain
@using Hncore.Infrastructure.Data
@using Hncore.Infrastructure.Extension
@using ViewComponents
@model PageData<ArticleEntity>
@{
var type = this.Context.Request.GetInt("Catalog");
}
<div class="container-fluid softBg">
<div class="container">
<form asp-action="Search" asp-controller="Article" method="get">
<div class="row">
<div class="col-lg-3 zxbz">
<img src="~/img/img_news.png">
</div>
<div class="col-lg-6 searchInput">
<input type="text" name="KeyWord" />
<p class="hot">搜索热词:<span>账号无法登录</span><span>如何充值</span></p>
</div>
<div class="col-lg-3 searchBtn text-left">
<button type="submit" class="btn btn-search">立即搜索</button>
</div>
</div>
</form>
</div>
</div>
<div class="container-fluid conBg">
<div class="container">
<div class="fourModel">
<div class="item">
<p><a asp-action="info" asp-controller="article" asp-route-id="3"><img src="~/img/ios.png"></a></p>
<p>苹果手机教程</p>
</div>
<div class="item">
<p><a asp-action="info" asp-controller="article" asp-route-id="4"><img src="~/img/az.png"></a></p>
<p>安卓手机教程</p>
</div>
<div class="item">
<p><a asp-action="info" asp-controller="article" asp-route-id="5"><img src="~/img/mnq.png"></a></p>
<p>安卓模拟器教程</p>
</div>
<div class="item">
<p><a asp-action="info" asp-controller="article" asp-route-id="6"><img src="~/img/pc.png"></a></p>
<p>Windows电脑教程</p>
</div>
</div>
<div class="mylist">
<ul class="nav nav-tabs newsList" role="tablist">
<li role="presentation" class="@(type==1?"active":"")"><a href="?Catalog=1"><img src="~/img/tab1.png">聚头条</a></li>
<li role="presentation" class="@(type==2?"active":"")"><a href="?Catalog=2"> <img src="~/img/tab2.png">优惠活动</a></li>
<li role="presentation" class="@(type==3?"active":"")"><a href="?Catalog=3"><img src="~/img/tab3.png">常见问题</a></li>
<li role="presentation" class="@(type==4?"active":"")"><a href="?Catalog=4"><img src="~/img/tab4.png">新手教程</a></li>
@*<li role="presentation" class="@(type==0?"active":"")"><a href="?Catalog=0"><img src="~/img/tab4.png">全部</a></li>*@
</ul>
<div class="tab-content listcon">
<div role="tabpanel" class="tab-pane active" id="home">
<ul class="listUl">
@foreach (var item in Model.List)
{
<li>
<div class="newsTit">
<div class="item">
@item.Title
</div>
<div class="item">
@item.CreateTime.ToString("yyyy.MM.dd")
</div>
</div>
<p class="gaiyao">@item.SubTitle</p>
<p><a asp-action="info" asp-controller="article" asp-route-id="@item.Id">查看全文→</a></p>
</li>
}
@*<li>
<div class="newsTit">
<div class="item">
如何查看IP代理地址是否启动成功
</div>
<div class="item">
2020.1.1
</div>
</div>
<p class="gaiyao">概要文字概要文字概要文字概要文字概要文字概要文字概要文字概要文字概要文字概要文字概要文字概要文字概要文字概要文字概要文字概要文字概要文字概要文字概要文字概要文字概要文字概要文字概要文字概要文字概要文字概要文字概要文字概要文字</p>
<p><a href="#">查看全文→</a></p>
</li>
<li>
<div class="newsTit">
<div class="item">
如何查看IP代理地址是否启动成功
</div>
<div class="item">
2020.1.1
</div>
</div>
<p class="gaiyao">概要文字概要文字概要文字概要文字概要文字概要文字概要文字概要文字概要文字概要文字概要文字概要文字概要文字概要文字概要文字概要文字概要文字概要文字概要文字概要文字概要文字概要文字概要文字概要文字概要文字概要文字概要文字概要文字</p>
<p><a href="#">查看全文→</a></p>
</li>
<li>
<div class="newsTit">
<div class="item">
如何查看IP代理地址是否启动成功
</div>
<div class="item">
2020.1.1
</div>
</div>
<p class="gaiyao">概要文字概要文字概要文字概要文字概要文字概要文字概要文字概要文字概要文字概要文字概要文字概要文字概要文字概要文字概要文字概要文字概要文字概要文字概要文字概要文字概要文字概要文字概要文字概要文字概要文字概要文字概要文字概要文字</p>
<p><a href="#">查看全文→</a></p>
</li>
<li>
<div class="newsTit">
<div class="item">
如何查看IP代理地址是否启动成功
</div>
<div class="item">
2020.1.1
</div>
</div>
<p class="gaiyao">概要文字概要文字概要文字概要文字概要文字概要文字概要文字概要文字概要文字概要文字概要文字概要文字概要文字概要文字概要文字概要文字概要文字概要文字概要文字概要文字概要文字概要文字概要文字概要文字概要文字概要文字概要文字概要文字</p>
<p><a href="#">查看全文→</a></p>
</li>*@
</ul>
</div>
</div>
<div class="fenye">
@await Component.InvokeAsync("Pager", new PagerModel() { Total = Model.RowCount, PageIndex = this.Context.Request.GetInt("PageIndex") })
@*<ul class="pagination">
<li class="page-item"><a class="page-link" href="#">上一页</a></li>
<li class="page-item"><a class="page-link fenyeActive" href="#">1</a></li>
<li class="page-item"><a class="page-link" href="#">2</a></li>
<li class="page-item"><a class="page-link" href="#">3</a></li>
<li class="page-item"><a class="page-link" href="#">下一页</a></li>
</ul>*@
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,77 @@
@using Hncore.Pass.Vpn.Domain
@using Hncore.Infrastructure.Data
@using Hncore.Infrastructure.Extension
@using ViewComponents
@model PageData<ArticleEntity>
@{
var type = this.Context.Request.GetInt("Catalog");
}
<div class="container-fluid softBg">
<div class="container">
<form asp-action="Search" asp-controller="Article" method="get">
<div class="row">
<div class="col-lg-3 zxbz">
<img src="~/img/img_news.png">
</div>
<div class="col-lg-6 searchInput">
<input type="text" name="KeyWord" />
<p class="hot">搜索热词:<span>账号无法登录</span><span>如何充值</span></p>
</div>
<div class="col-lg-3 searchBtn text-left">
<button type="submit" class="btn btn-search">立即搜索</button>
</div>
</div>
</form>
</div>
</div>
<div class="container-fluid conBg">
<div class="container">
<div class="fourModel">
<div class="item">
<p><a asp-action="info" asp-controller="article" asp-route-id="3"><img src="~/img/ios.png"></a></p>
<p>苹果手机教程</p>
</div>
<div class="item">
<p><a asp-action="info" asp-controller="article" asp-route-id="4"><img src="~/img/az.png"></a></p>
<p>安卓手机教程</p>
</div>
<div class="item">
<p><a asp-action="info" asp-controller="article" asp-route-id="5"><img src="~/img/mnq.png"></a></p>
<p>安卓模拟器教程</p>
</div>
<div class="item">
<p><a asp-action="info" asp-controller="article" asp-route-id="6"><img src="~/img/pc.png"></a></p>
<p>Windows电脑教程</p>
</div>
</div>
<div class="mylist">
<div class="tab-content listcon">
<div role="tabpanel" class="tab-pane active">
<ul class="listUl">
@foreach (var item in Model.List)
{
<li>
<div class="newsTit">
<div class="item">
@item.Title
</div>
<div class="item">
@item.CreateTime.ToString("yyyy.MM.dd")
</div>
</div>
<p class="gaiyao">@item.SubTitle</p>
<p><a asp-action="info" asp-controller="article" asp-route-id="@item.Id">查看全文→</a></p>
</li>
}
</ul>
</div>
</div>
<div class="fenye">
@await Component.InvokeAsync("Pager", new PagerModel() { Total = Model.RowCount, PageIndex = this.Context.Request.GetInt("PageIndex") })
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,59 @@
@using Hncore.Pass.Vpn.Domain
@using Hncore.Infrastructure.Extension
@model ArticleInfoMode
@{
}
<div class="container-fluid softBg">
<div class="container">
<form asp-action="Search" asp-controller="Article" method="get">
<div class="row">
<div class="col-lg-3 zxbz">
<img src="~/img/img_news.png">
</div>
<div class="col-lg-6 searchInput">
<input type="text" name="KeyWord" />
<p class="hot">搜索热词:<span>账号无法登录</span><span>如何充值</span></p>
</div>
<div class="col-lg-3 searchBtn text-left">
<button type="submit" class="btn btn-search">立即搜索</button>
</div>
</div>
</form>
</div>
</div>
<div class="container-fluid newsCon">
<div class="container">
<ol class="breadcrumb">
<li><a href="#">资讯&帮助</a></li>
@*<li><a href="#" class="active">华连头条</a></li>*@
</ol>
</div>
<div class="container articleTit">
<h3>@Model.Info.Title</h3>
<p class="grayText">@Model.Info.CreateTime.ToString("yyyy.MM.dd")</p>
</div>
<div class="container articleCon">
@*<img src="img/wenzhangpeitu.png">*@
@Html.Raw(Model.Info.Content)
</div>
<div class="container preNext">
<div class="row">
@if (Model.Prev != null)
{
<div class="col-lg-6 text-left">
上一条:<a asp-action="info" asp-controller="article" asp-route-Id="@Model.Prev.Id">@Model.Prev.Title</a>
</div>
}
@if (Model.Next != null)
{
<div class="col-lg-6 text-right">
下一条:<a asp-action="info" asp-controller="article" asp-route-Id="@Model.Next.Id">@Model.Next.Title</a>
</div>
}
</div>
</div>
</div>

View File

@@ -0,0 +1,34 @@
<div class="container-fluid tAd">
<a href="#taobaodian"> <img src="~/img/tBanner.png"></a>
</div>
<div class="container-fluid tintro text-center" style="font-size:18px">
<p>您付款后并未直接开通账号,因系统无法判定您是新开账号还是续费,也无法判定您想定制什么账号和密码。</p>
<p>所以会把您付款金额充进官网,然后在官网新开账号或是续费,用余额支付即可。</p>
<p>当然您也可以付款后联系我们帮您开通或续费。</p>
</div>
<div class="container tPeitu">
<img src="~/img/peitu.png">
</div>
<div class="container ttishi text-center" style="font-size: 20px;">
——以下店铺任选一个,在淘宝所需金额,系统将自动为您充值,下单时收货人的手机号要与官网会员号一致——
</div>
<div class="container" id="taobaodian">
<div class="row tlink">
<div class="col-lg-4">
<a href="https://item.taobao.com/item.htm?spm=a230r.1.14.37.74175197C4nNeX&id=623503691377" target="_blank"><img src="~/img/t1.png"></a>
</div>
<div class="col-lg-4">
<a href="https://shop466932443.taobao.com/search.htm?spm=a1z10.1-c.0.0.2feb535aiwF0iN&search=y&orderType=hotsell_desc" target="_blank"><img src="~/img/t2.png"></a>
</div>
<div class="col-lg-4">
<a href="https://item.taobao.com/item.htm?spm=a1z10.3-c.w4002-16678284713.15.13c8364aciVbN7&id=624222057325" target="_blank"><img src="~/img/t3.png"></a>
</div>
@*<div class="col-lg-3">
<a href="https://item.taobao.com/item.htm?spm=a230r.7195193.1997079397.28.72145f8bwi5F1r&id=613389354570&abbucket=4" target="_blank"><img src="~/img/t4.png"></a>
</div>*@
</div>
</div>

View File

@@ -0,0 +1,814 @@
@model List<ProductModel>
@using Hncore.Pass.BaseInfo.Response
@using Hncore.Infrastructure.Serializer
@using Hncore.Pass.Vpn.Service
@using Hncore.Pass.Vpn.Domain
@using Microsoft.Extensions.Configuration
@inject ArticleService m_ArticleService
@inject IConfiguration m_Configuration
@{
ViewData["Title"] = "聚IP JUIP.COM-千万动态ip切换自建机房ip代理覆盖全国多款市面热销产品";
Layout = null;
UserLoginModel user = null;
if (this.Context.Request.Cookies.TryGetValue("userInfo", out string userCookie))
{
user = userCookie.FromJsonTo<UserLoginModel>();
}
var articleNews = await m_ArticleService.GetTop(12, ArticleCatalog.Top);
var activityNews = await m_ArticleService.GetTop(12, ArticleCatalog.Activity);
var helpsNews = await m_ArticleService.GetTop(12, ArticleCatalog.Help);
var QANews = await m_ArticleService.GetTop(12, ArticleCatalog.QA);
var baseUrl = m_Configuration["BaseInfoUrl"];
Func<string, string> P = (path) => $"{baseUrl}{path}";
//var epoch = (DateTime.Now.ToUniversalTime().Ticks - 621355968000000000)/10000000;
//var countStr = epoch.ToString().Substring(0, 8);
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>聚IP JUIP.COM-千万动态ip切换自建机房ip代理覆盖全国多款市面热销产品</title>
<link rel="stylesheet" type="text/css" href="css/bootstrap.min.css" />
<link rel="stylesheet" type="text/css" href="css/base.css" />
<link rel="stylesheet" type="text/css" href="css/swiper.min.css" />
<link rel="stylesheet" type="text/css" href="css/flash.css" />
<link rel="stylesheet" type="text/css" href="css/animate.min.css" />
<link rel="Shortcut Icon" href="/img/favicon.ico" type="image/x-icon" />
<script src="js/jquery.min.js" type="text/javascript" charset="utf-8"></script>
<script src="js/bootstrap.min.js" type="text/javascript" charset="utf-8"></script>
<script src="js/swiper.min.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
$(document).ready(function () {
// 注册登录弹窗开始
$(".regLink").click(function () {
$(".main").hide();
$(".main_reg").show();
});
$(".loginLink").click(function () {
$(".main_reg").hide();
$(".main_find").hide();
$(".main").show();
});
$(".findLink").click(function () {
$(".main").hide();
$(".main_find").show();
});
$(".login").click(function () {
$(".mask").show();
$(".main").show();
$(".main").addClass("animated bounceInDown");
});
$(".reg").click(function () {
$(".mask").show();
$(".main_reg").show();
$(".main_reg").addClass("animated bounceInDown");
});
$(".btnClose").click(function () {
$(".main").addClass("animated bounceOutDown");
$(".mask").hide();
$(".main_find").hide();
setTimeout(function () {
$(".main").removeClass("animated bounceOutDown");
$(".main").hide();
}, 1000)
});
$(".regClose").click(function () {
$(".main_reg").addClass("animated bounceOutDown");
$(".mask").hide();
setTimeout(function () {
$(".main_reg").removeClass("animated bounceOutDown");
$(".main_reg").hide();
}, 1000)
});
// 新闻选项卡
$("#myTab a").click(function (e) {
e.preventDefault();
$(this).tab('show');
});
// 侧边栏
//$(".on_q").click(function () {
// $(".side_q").toggle();
//});
$(".item_on_q").mouseover(function () {
$(".side_q").stop().fadeIn();
});
$(".item_on_q").mouseleave(function () {
$(".side_q").stop().fadeOut();
});
//$(".on_wx").click(function () {
// $(".side_kefu").toggle();
//});
$(".item_on_wx").mouseover(function () {
$(".side_kefu").stop().fadeIn();
});
$(".item_on_wx").mouseleave(function () {
$(".side_kefu").stop().fadeOut();
});
$(".on_gzh").mouseover(function () {
$(".side_gzh").stop().fadeIn();
});
$(".on_gzh").mouseleave(function () {
$(".side_gzh").stop().fadeOut();
});
$(".on_tel").mouseover(function () {
$(".side_tel").stop().fadeIn();
});
$(".on_tel").mouseleave(function () {
$(".side_tel").stop().fadeOut();
});
// 动画
$(".d1").show();
$(".d1").addClass("animated slideInDown");
$(".threeButton").show();
$(".threeButton").addClass("animated slideInUp");
$(window).scroll(function () {
var topp = $(document).scrollTop();
if (topp > 800) {
$(".d3").show();
$(".d3").addClass("animated slideInLeft");
$(".d4").show();
$(".d4").addClass("animated slideInRight");
}
if (topp > 400) {
$(".d2").show();
$(".d2").addClass("animated slideInUp");
}
if (topp > 1600) {
$(".d5").show();
$(".d5").addClass("animated bounceInDown");
}
if (topp > 2600) {
$(".d_use").show();
$(".d_use").addClass("animated flipInX");
}
if (topp > 3200) {
$(".d6").show();
$(".d6").addClass("animated slideInRight");
}
})
})
</script>
</head>
<body id="top">
<!-- register -->
<div class="mask"></div>
<div class="main_reg" id="regBox" style="height: 580px">
<img src="~/img/close.png" class="regClose">
<div class="logoLogin">
<img src="~/img/logoBlue.png">
</div>
<div class="award">
<img src="~/img/award.png">
</div>
<div class="user">
<img src="~/img/phone.png"><input type="text" name="" id="username" value="" placeholder="请输入手机号码" />
</div>
<div class="pwd">
<img src="~/img/password.png"><input type="password" name="" id="password" value="" placeholder="请输入密码" />
</div>
<div class="yzm">
<img src="~/img/yanzhengma.png"><input type="text" name="" id="yanzhengma" value="" placeholder="请输入验证码" /><button class="btn btn-primary" onclick="getCode(this)">获取验证码</button>
</div>
<div class="user">
<img src="~/img/phone.png"><input type="text" name="" id="wxhao" value="" placeholder="请输入微信号" />
</div>
<div class="user">
<img src="~/img/phone.png"><input type="text" name="" id="qqhao" value="" placeholder="请输入QQ" />
</div>
<p class="tixing">*手机号不是PPTP账号请登录后开通PPTP账号*</p>
<p class="tixing"><input type="checkbox" name="" id="" value="" />我同意<a href="#">聚IP JUIP.COM用户注册协议</a></p>
<p class="denglu"><button type="button" class="btn btn-login" onclick="reg()">注册</button></p>
<p class="zhiyin grayText">已有账号?<a href="#" class="loginLink">立即登录</a></p>
</div>
<!-- login -->
<div class="mask"></div>
<div class="main" id="loginBox">
<img src="~/img/close.png" class="btnClose">
<div class="logoLogin">
<img src="~/img/logoBlue.png">
</div>
<div class="award">
<img src="~/img/award.png">
</div>
<div class="user">
<img src="~/img/user.png"><input type="text" name="" id="rLogin_Name" value="" placeholder="请输入会员手机号码" />
</div>
<div class="pwd">
<img src="~/img/password.png"><input type="password" name="" id="rLogin_Pwd" value="" placeholder="请输入密码" />
</div>
<div class="fuzhu">
@*<div class="item">
<input type="checkbox" name="" id="" value="" />自动登录
</div>*@
<div class="item">
<a href="#" class="grayText findLink">忘记密码?</a>
</div>
</div>
<p class="tixing">*手机号不是PPTP账号请登录后开通PPTP账号*</p>
<p class="denglu"><button type="button" class="btn btn-login" onclick="login()">登录</button></p>
<p class="zhiyin grayText">还没有账号?<a href="#" class="regLink">立即注册</a></p>
</div>
<!-- findpwd -->
<div class="mask"></div>
<div class="main_find" id="FindBox">
<img src="~/img/close.png" class="regClose">
<div class="logoLogin">
<img src="~/img/logoBlue.png">
</div>
<div class="award">
<img src="~/img/award.png">
</div>
<div class="user">
<img src="~/img/phone.png"><input type="text" id="fusername" value="" placeholder="请输入手机号码" />
</div>
<div class="pwd">
<img src="~/img/password.png"><input type="password" id="fpassword" value="" placeholder="请输入新密码" />
</div>
<div class="yzm">
<img src="~/img/yanzhengma.png"><input type="text" id="fyanzhengma" value="" placeholder="请输入验证码" /><button class="btn btn-primary" onclick="getFindCode(this)">获取验证码</button>
</div>
<p class="tixing">*手机号不是PPTP账号请登录后开通PPTP账号*</p>
<p class="denglu"><button type="button" class="btn btn-reset">重置</button></p>
<p class="zhiyin grayText">已有账号?<a href="#" class="loginLink">立即登录</a></p>
</div>
<!-- sideBar -->
<div class="sideBar">
<div class="item item_on_q">
<img src="~/img/qq.png" class="on_q"> <div class="kefu_tit">QQ</div>
<div class="side_q">
<h4 style="border-bottom:1px solid #ccc;text-align:center;width:100%;padding:5px;">实时响应 在线时间8:00-24:00</h4>
<div class="item">
<a href="https://admin.qidian.qq.com/template/blue/mp/menu/qr-code-jump.html?linkType=0&env=ol&kfuin=2852138148&fid=299&key=f377ec024ca45115a03a7632c7bda230&cate=1&source=&isLBS=&isCustomEntry=&type=16&ftype=1&_type=wpa&qidian=true" target="_blank">
<div class="ileft">
<img src="~/img/q.png">
</div>
<div class="iright">
<span>人工客服:售前</span>
</div>
</a>
</div>
<div class="item">
<a href="https://admin.qidian.qq.com/template/blue/mp/menu/qr-code-jump.html?linkType=0&env=ol&kfuin=2852138148&fid=299&key=f377ec024ca45115a03a7632c7bda230&cate=1&source=&isLBS=&isCustomEntry=&type=16&ftype=1&_type=wpa&qidian=true" target="_blank">
<div class="ileft">
<img src="~/img/q.png">
</div>
<div class="iright">
<span>人工客服:售后</span>
</div>
</a>
</div>
</div>
</div>
<div class="item item_on_wx">
<img src="~/img/weixin.png" class="on_wx"><div class="kefu_tit">微信</div>
<div class="side_kefu">
<!-- Nav tabs -->
<ul class="nav nav-tabs" role="tablist" style="padding-top: 10px;padding-left:10px">
<li role="presentation" class="active"><a href="#xx" aria-controls="xx" role="tab" data-toggle="tab" style="border-color:#ccc">售前</a></li>
<li role="presentation"><a href="#qq" aria-controls="qq" role="tab" data-toggle="tab" style="border-color:#ccc">售后</a></li>
@*<li role="presentation"><a href="#ss" aria-controls="ss" role="tab" data-toggle="tab" style="border-color:#ccc">珊珊</a></li>
<li role="presentation"><a href="#tt" aria-controls="tt" role="tab" data-toggle="tab" style="border-color:#ccc">兔兔</a></li>*@
</ul>
<!-- Tab panes -->
<div class="tab-content" style="margin-top: 60px;">
<div role="tabpanel" class="tab-pane active" id="xx">
<img src="~/img/kf_sq.jpg">
<p style="color:#f90">实时响应 在线时间 8:00-24:00</p>
</div>
<div role="tabpanel" class="tab-pane" id="qq">
<img src="~/img/kf_sh.jpg">
<p style="color:#f90">实时响应 在线时间 8:00-24:00</p>
</div>
@*<div role="tabpanel" class="tab-pane" id="ss">
<img src="~/img/w3.png">
<p style="color:#f90">实时响应 在线时间 8:00-24:00</p>
</div>
<div role="tabpanel" class="tab-pane" id="tt">
<img src="~/img/w4.png">
<p style="color:#f90">实时响应 在线时间 8:00-24:00</p>
</div>*@
</div>
</div>
</div>
<div class="item">
<img src="~/img/gzh.png" class="on_gzh"><div class="kefu_tit">公众号</div>
<div class="side_gzh">
<p><img src="~/img/ewm.png"></p>
<p style="color:#f90">实时响应 在线时间 8:00-24:00</p>
<p style="color:#f90">关注公众号可获取免费的到期提醒服务</p>
</div>
</div>
<div class="item">
<img src="~/img/tel.png" class="on_tel"><div class="kefu_tit">电话</div>
<div class="side_tel">
<p><b>400 800 9925</b></p>
<p>实时接通</p>
<p>电话值班时间 8:00-24:00</p>
</div>
</div>
<div class="item">
<a href="#top"><img src="~/img/top.png"></a>
</div>
</div>
<!-- banner&nav -->
<div class="container-fluid banner" id="top">
<div class="bg">
<img src="~/img/banner.png">
</div>
<div class="container d1">
<img src="~/img/d1.png">
</div>
<div class="container-fluid nav">
<div class="row">
<div class="col-lg-2 col-md-2 logo">
<a href="#"><img src="~/img/logo.png"></a>
</div>
<div class="col-lg-10 col-md-10">
<ul class="navList pull-right">
<li><a href="/">首页</a></li>
<li><a href="/product/index">产品购买</a></li>
<li><a href="/LineList/index">PPTP线路表</a></li>
<li><a href="/product/soft">软件下载</a></li>
<li><a href="/article/index">资讯&帮助</a></li>
<li><a href="/article/taobao">淘宝充值活动</a></li>
<li>
@if (user == null)
{
<button type="button" class="btn btn-primary reg">注册</button>
<button type="button" class="btn btn-primary login">登录</button>
}
else
{
<img src="/img/account.png" onmouseover="$('.exitBox').show()">
<div class="exitBox" onmouseleave="$('.exitBox').hide()">
<div class="item">
<a asp-action="index" asp-controller="user">个人中心</a>
</div>
<div class="item">
<a asp-action="LoginOut" asp-controller="user">退出登录</a>
</div>
</div>
}
</li>
</ul>
</div>
</div>
</div>
<div class="container threeButton">
<div class="col-lg-4">
</div>
<div class="col-lg-4">
<div class="row">
<div class="col-lg-4 text-right">
<a asp-action="soft" asp-controller="product"> <button type="button" class="btn btn-primary">客户端下载</button></a>
</div>
<div class="col-lg-4 text-center">
<a asp-action="index" asp-controller="linelist"> <button type="button" class="btn btn-primary">PPTP线路表</button></a>
</div>
<div class="col-lg-4 text-left">
<a asp-action="index" asp-controller="product"> <button type="button" class="btn btn-danger">免费试用</button></a>
</div>
</div>
</div>
<div class="col-lg-4">
</div>
</div>
</div>
<!-- products -->
<div class="container-fluid pro">
<p class="tit tit_cp text-center">
<span><img src="~/img/tit_chanpin.png"></span>
<span class="modelTit">我们的产品</span>
</p>
<p class="chanpinText">冰点价格,开通后任何问题可无理由退款</p>
<p class="chanpinText">温馨提示:在国外,香港,台湾,澳门,城市使用不稳定;移动网络,长城宽带以及校园网使用会不稳定,因此不建议亲使用哦</p>
<div class="container-fluid d2">
<ul class="newProduct">
@foreach (var item in Model.Where(m => m.Sort != 1000))
{
<li>
@*<p><img src="@P(item.Image)"></p>*@
<p class="titCard">@item.Name</p>
<p class="jieshao">@item.Profile</p>
@*<p class="chakan"> <a asp-action="index" asp-controller="linelist" asp-route-ProductId="@item.Id">查看线路表→</a></p>
<p><a asp-action="index" asp-controller="product" asp-route-id="@item.Id"><button type="button" class="btn btn-primary gm">立即购买</button></a></p>*@
<div class="buyBar">
<div class="item ck"><a asp-action="index" asp-controller="linelist" asp-route-ProductId="@item.Id">查看线路表</a></div>
<div class="item">
<a asp-action="index" asp-controller="product" asp-route-id="@item.Id">
<button type="button" class="btn btn-primary btn-warning">
测试与购买
</button>
</a>
</div>
</div>
</li>
}
</ul>
</div>
</div>
<!-- Swiper -->
@*<div class="swiper-container">
<div class="swiper-wrapper">
@foreach (var item in Model.Where(m => m.Sort != 1000))
{
<div class="swiper-slide">
<p><img src="@P(item.Image)"></p>
<p class="titCard">@item.Name</p>
<p class="jieshao">@item.Profile</p>
<p> <a asp-action="index" asp-controller="linelist" asp-route-ProductId="@item.Id">查看线路表→</a></p>
<p><a asp-action="index" asp-controller="product" asp-route-id="@item.Id"><button type="button" class="btn btn-primary">立即购买</button></a></p>
</div>
}
</div>
<div class="swiper-button-next"><img src="~/img/btnR.png"></div>
<div class="swiper-button-prev"><img src="~/img/btnL.png"></div>
</div>*@
</div>
<!-- youshi -->
<div class="container-fluid youshi">
<div class="youshiBg">
<img src="~/img/youshi.png">
</div>
<div class="container">
<p class="tit tit_youshi text-center">
<span><img src="~/img/tit_youshi.png"></span>
<span class="youshiTit">我们的优势</span>
</p>
</div>
<div class="container imgYoushi">
<div class="row">
<div class="col-lg-6 text-center">
<img src="~/img/youshiL.png" class="d3">
</div>
<div class="col-lg-6 text-center">
<img src="~/img/youshiR.png" class="d4">
</div>
</div>
</div>
</div>
<!-- map -->
<div class="container modelMap">
<div class="yuan1">
@*<div class="nei animation"></div>*@
<div class="wai animation mapCicle"></div>
</div>
<div class="yuan2">
@*<div class="nei2 animation"></div>*@
<div class="wai2 animation mapCicle"></div>
</div>
<div class="yuan3">
@*<div class="nei animation"></div>*@
<div class="wai animation mapCicle"></div>
</div>
<div class="yuan4">
@*<div class="nei2 animation"></div>*@
<div class="wai2 animation mapCicle"></div>
</div>
<div class="yuan5">
@*<div class="nei2 animation"></div>*@
<div class="wai animation mapCicle"></div>
</div>
<div class="yuan6">
<div class="wai2 animation mapCicle"></div>
</div>
<div class="yuan7">
<div class="wai animation mapCicle"></div>
</div>
<div class="yuan8">
<div class="wai2 animation mapCicle"></div>
</div>
<div class="yuan9">
<div class="wai animation mapCicle"></div>
</div>
<p class="tit tit_map text-center">
<span><img src="~/img/tit_map.png"></span>
<span class="dituTit">全国覆盖范围地图</span>
</p>
<p class="text-center map"><img src="~/img/map.png" class="d5"></p>
<div class="row lianjie">
<div class="col-lg-5 text-right">
今日IP连接数
</div>
<div class="col-lg-7 text-left">
<div class="num">
<div class="item"></div>
</div>
</div>
</div>
</div>
<!-- use -->
<div class="container-fluid use">
<img src="~/img/tit_use.png" class="dailiImg">
<div class="useBg">
<img src="~/img/use.png">
<p class="useTit">这些人正在使用IP代理</p>
</div>
<div class="d_use">
<img src="~/img/d_use.png">
</div>
</div>
<!-- news -->
<div class="container newsArea">
<p class="tit tit_news text-center">
<span><img src="~/img/tit_news.png"></span>
<span class="helpTit">资讯&帮助</span>
</p>
<div class="d6">
<!-- Nav tabs -->
<ul class="nav nav-tabs newsList" role="tablist">
<li role="presentation" class="active"><a href="#home" aria-controls="home" role="tab" data-toggle="tab"><img src="~/img/tab1.png">聚IP头条</a></li>
<li role="presentation"><a href="#profile" aria-controls="profile" role="tab" data-toggle="tab"> <img src="~/img/tab2.png">优惠活动</a></li>
<li role="presentation"><a href="#messages" aria-controls="messages" role="tab" data-toggle="tab"><img src="~/img/tab3.png">常见问题</a></li>
<li role="presentation"><a href="#settings" aria-controls="settings" role="tab" data-toggle="tab"><img src="~/img/tab4.png">新手教程</a></li>
<li class="pull-right more" role="presentation"><a asp-action="index" asp-controller="article" aria-controls="settings" role="tab"><img src="~/img/more.png"></a></li>
</ul>
<!-- Tab panes -->
<div class="tab-content listcon">
<div role="tabpanel" class="tab-pane active" id="home">
<ul class="xinwen">
@foreach (var item in articleNews)
{
<li><a asp-action="info" asp-controller="article" asp-route-id="@item.Id"><span>@item.CreateTime.ToString("yyyy.MM.dd")</span>@item.Title</a></li>
}
</ul>
</div>
<div role="tabpanel" class="tab-pane" id="profile">
<ul class="xinwen">
@foreach (var item in activityNews)
{
<li><a asp-action="info" asp-controller="article" asp-route-id="@item.Id"><span>@item.CreateTime.ToString("yyyy.MM.dd")</span>@item.Title</a></li>
}
</ul>
</div>
<div role="tabpanel" class="tab-pane" id="messages">
<ul class="xinwen">
@foreach (var item in QANews)
{
<li><a asp-action="info" asp-controller="article" asp-route-id="@item.Id"><span>@item.CreateTime.ToString("yyyy.MM.dd")</span>@item.Title</a></li>
}
</ul>
</div>
<div role="tabpanel" class="tab-pane" id="settings">
<ul class="xinwen">
@foreach (var item in helpsNews)
{
<li><a asp-action="info" asp-controller="article" asp-route-id="@item.Id"><span>@item.CreateTime.ToString("yyyy.MM.dd")</span>@item.Title</a></li>
}
</ul>
</div>
</div>
</div>
</div>
<!-- footer -->
<div class="container-fluid footer">
<div class="container">
<div class="col-lg-3 text-left">
<p class="cpTit">旗下产品</p>
<ul class="cp">
@foreach (var item in Model.Where(m => m.Sort != 1000))
{
<li><a asp-action="index" asp-controller="product" asp-route-id="@item.Id">@item.Name</a></li>
}
</ul>
</div>
<div class="col-lg-3">
<p class="cpTit">联系我们</p>
<ul class="cp">
<li>公司电话400 800 9925</li>
<li>工作时间: 8:00-24:00</li>
</ul>
</div>
<div class="col-lg-3">
<p class="cpTit">商务合作</p>
<ul class="cp">
<li>电话/微信18039519517</li>
<li>QQ508095081</li>
</ul>
</div>
<div class="col-lg-3 text-right">
<p class="cpTit">公众号</p>
<p class="ewm"><img src="~/img/ewm.png"></p>
<p class="sao">关注公众号即可获取</p>
<p class="sao">免费的到期提醒服务</p>
</div>
</div>
</div>
<!-- copyright -->
<div class="container-fluid copyr">
<div class="container text-center">
<p>
聚IP仅提供IP服务用户使用聚IP从事的任何行为均不代表聚IP的意志和观点与聚IP的立场无关。严禁用户使用聚IP从事任何违法犯罪行为
产生的相关责任用户自负对此聚IP不承担任何法律责任。
</p>
<p>
版权所有 河南华连网络科技有限公司|<a href="http://www.beian.miit.gov.cn" target="_blank">豫ICP备17004061号-15</a>增值电信业务经营许可证B1-20190663
</p>
<p class="logoD_"><img src="~/img/logogD.png"><a target="cyxyv" href="https://v.yunaq.com/certificate?domain=www.juip.com&from=label&code=90020"> <img src="https://aqyzmedia.yunaq.com/labels/label_sm_90020.png" style="width:70px;height:25px;"></a></p>
</div>
</div>
<script>
var swiper = new Swiper('.swiper-container', {
slidesPerView: 6,
spaceBetween: 36,
slidesPerGroup: 4,
loop: false,
loopFillGroupWithBlank: true,
pagination: {
el: '.swiper-pagination',
clickable: true,
},
navigation: {
nextEl: '.swiper-button-next',
prevEl: '.swiper-button-prev',
},
});
</script>
<script>
function login() {
var name = $("#rLogin_Name").val()
var pwd = $("#rLogin_Pwd").val()
var data = { Logincode: name, Password: pwd, Code: 1 };
$.ajax({
type: 'POST',
url: '/user/login',
contentType: "application/json",
data: JSON.stringify(data),
success: function (res) {
console.log(res);
if (res.Code == 10000) {
window.location.reload();
} else {
alert(res.Message)
}
}
});
}
var time = 60;
function getCode(_self) {
if (!timing(_self)) return;
var name = $("#username").val()
var url = '/user/SendPhoneCode?key=User_Code&phone=' + name;
var timerHandler;
$.ajax({
type: 'GET',
url: url,
success: function (res) {
alert(res.Message)
}
});
}
function getFindCode(_self) {
if (!timing(_self)) return;
var name = $("#fusername").val()
var url = '/user/SendPhoneCode?key=FindUser_Code&phone=' + name;
$.ajax({
type: 'GET',
url: url,
success: function (res) {
alert(res.Message)
}
});
}
function timing(_self) {
if (time != 60) return false
var timerHandler = setInterval(function () {
time--;
if (time <= 1) {
clearInterval(timerHandler);
time = 60;
$(_self).text("获取验证码")
} else {
$(_self).text(time + "s");
}
}, 1000)
return true;
}
function reg() {
var name = $("#username").val()
var pwd = $("#password").val()
var code = $("#yanzhengma").val()
var wx = $("#wxhao").val()
var qq = $("#qqhao").val()
var data = { Phone: name, Pwd: pwd, Code: code,Wx:wx,QQ:qq };
$.ajax({
type: 'POST',
url: '/user/Regist',
contentType: "application/json",
data: JSON.stringify(data),
success: function (res) {
console.log(res);
if (res.Code == 10000) {
window.location.reload();
} else {
alert(res.Message)
}
}
});
}
function reset() {
var name = $("#fusername").val()
var pwd = $("#fpassword").val()
var code = $("#fyanzhengma").val()
if (name == '') { alert('手机号不能为空'); return; }
if (code == '') { alert('验证码不能为空'); return; }
var data = { Phone: name, Pwd: pwd, Code: code };
$.ajax({
type: 'POST',
url: '/user/FindPwd',
contentType: "application/json",
data: JSON.stringify(data),
success: function (res) {
console.log(res);
if (res.Code == 10000) {
alert("重置成功,请登录");
} else {
alert(res.Message)
}
}
});
}
$(function () {
$("#loginBox").bind("keydown", function (e) {
var theEvent = e || window.event;
var code = theEvent.keyCode || theEvent.which || theEvent.charCode;
if (code == 13) {
login();
}
});
$("#regBox").bind("keydown", function (e) {
var theEvent = e || window.event;
var code = theEvent.keyCode || theEvent.which || theEvent.charCode;
if (code == 13) {
reg();
}
});
$(".btn-reset").click(function () {
reset();
})
function changeIpcount() {
var items = [];
for (var i = 1; i <= 8; i++) {
var item = [];
var count = i;
if (i > 2)
count = Math.floor(Math.random() * 10)
item.push("<div class='item'>");
item.push(count);
item.push(" </div>");
items.push(item.join(""));
}
$(".num").html(items);
}
changeIpcount();
setInterval(changeIpcount, 5000);
})
</script>
<!-- WPA start -->
<script id="qd28521381485d6faa97edf5ad07d7e159f6cb902af0" src="https://wp.qiye.qq.com/qidian/2852138148/5d6faa97edf5ad07d7e159f6cb902af0" charset="utf-8" async defer></script>
<!-- WPA end -->
</body>
</html>

View File

@@ -0,0 +1,8 @@
@using Hncore.Pass.Vpn.Response.Product
@using Hncore.Infrastructure.Extension
@using Hncore.Pass.BaseInfo.Response
@using Hncore.Infrastructure.Serializer;
@using Hncore.Pass.BaseInfo.Service
@using Hncore.Infrastructure.Common
<vc:pay-wait></vc:pay-wait>

View File

@@ -0,0 +1,133 @@
@using Hncore.Pass.Vpn.Domain
@using Hncore.Infrastructure.Extension
@using Hncore.Pass.Vpn.Service
@inject ProductService m_ProductService
@model List<ProductRouteEntity>
@{
var pid = this.Context.Request.GetInt("ProductId");
var product = ViewData["products"] as List<ProductEntity>;
var currentProduct =(await m_ProductService.GetById(pid)) ?? new ProductEntity();
var lineTotalCount = Model.Count;
var lineCount = Model.Where(m=>m.Status== "正常").Count();
}
<style>
.blueLine img {
display: inline !important;
}
</style>
<div class="container-fluid softBg">
<div class="container">
<div class="row">
<form asp-action="index" asp-controller="linelist" method="get">
<div class="col-lg-3 zxbz">
<img src="~/img/img_xinalu.png">
</div>
<div class="col-lg-5 searchInput">
<input type="text" name="KeyWord" placeholder="输入地区/名称/服务器" id="KeyWord" />
</div>
<div class="col-lg-2 searchBtn text-left">
<button type="submit" class="btn btn-search">搜索全部</button>
</div>
<div class="col-lg-2">
<span class="btnZhilian cursor"><a asp-index="" asp-controller="article" asp-route-Catalog="4" style="color:white"><img src="~/img/zhilian.png">直连教程</a></span>
</div>
</form>
</div>
<div class="row">
<div class="col-lg-3">
</div>
<div class="col-lg-9">
<p class="hot"><img src="~/img/shuju.png">实时总线路:@(lineTotalCount)条<img src="~/img/shuju.png">实时可用线路:@(lineCount)条 所有线路均支持:【电脑/安卓/苹果】【PPTP/L2TP/SSTP】</p>
</div>
</div>
</div>
</div>
<div class="container">
<p class="xianluIntro" style="text-align: center;font-size: 25px;">*线路表和账号必须为同一产品才能使用。@*(已购产品:<span>老鹰b组</span>*@</p>
<div class="xianlu">
@foreach (var item in product.Where(m => m.Id != 3 && m.Id != 7 && m.Id != 9))
{
<div class="item @(item.Id==pid?"blueLine":"")" a-pid="@item.Id" a-name="@item.Name">
<span>@item.Name</span><img src="~/img/check.png">
</div>
}
</div>
</div>
<div class="container">
<div class="row">
<div class="col-lg-2 miyao">
<p><img src="~/img/miyao.png"> L2TP密钥<b style="color:red;">@currentProduct.L2TPPwd</b></p>
<p><img src="~/img/dk.png"> SSTP端口<b style="color:red;">@currentProduct.SSTPPort</b></p>
</div>
<div class="col-lg-2 fanwei">
搜索范围:<span id="pName">@currentProduct.Name</span>
</div>
<div class="col-lg-8">
<form asp-action="index" asp-controller="linelist" method="get">
<input type="hidden" name="ProductId" id="ProductId" value="@pid" />
<input type="text" name="KeyWord" class="searchDq" placeholder="输入地区/名称/服务器" id="KeyWord" />
<button type="submit" class="btn btn-primary">搜索当前线路表</button>
<span class="daochu"><img src="~/img/excel.png">导出Excel</span>
</form>
</div>
</div>
</div>
<div class="container">
<table class="table table-striped xianluTable">
<tr>
<th><img src="~/img/chengshi.png">产品</th>
<th><img src="~/img/chengshi.png">城市</th>
<th><img src="~/img/yunyingshang.png"> 运营商</th>
<th><img src="~/img/yuming.png"> 服务器域名</th>
<th><img src="~/img/daikuan.png"> 实时带宽</th>
<th><img src="~/img/ipliang.png"> IP量</th>
<th><img src="~/img/zhuangtai.png"> 状态</th>
<th><img src="~/img/xianlushuoming.png"> 线路说明</th>
</tr>
@foreach (var group in Model.GroupBy(m => m.Province))
{
<tr><td style="background:#dedede;"></td><td colspan="7" style="background:#dedede;text-align:left;padding-left: 50px;">@group.Key</td></tr>
@foreach (var item in group)
{
<tr style="@(item.Status=="正常"?"":"color:red")">
<td>@item.ProductName</td>
<td>@item.City</td>
<td>@item.Name</td>
<td class="blueT">@item.ServerUrl</td>
<td>@item.BandWidth</td>
<td>@item.IpRemark</td>
<td class="greenT">@item.Status</td>
<td>评分★★★★★</td>
</tr>
}
}
</table>
</div>
<script type="text/javascript">
var pid =@pid;
var productName=""
$(function(){
$(".xianlu .item").click(function(){
$(this).addClass("blueLine");
$(this).siblings().removeClass("blueLine");
pid = $(this).attr("a-pid");
productName = $(this).attr('a-name')
$("#pName").text(productName);
$("#ProductId").val(pid);
window.location.href = "/linelist/index?ProductId="+pid;
})
$(".daochu").click(function () {
var p = $("#ProductId").val()||0;
var KeyWord = $("#KeyWord").val() || "";
window.location.href = "/linelist/Excel?ProductId=" + p + "&KeyWord=" + KeyWord;
})
})
</script>

View File

@@ -0,0 +1,292 @@
@using Hncore.Pass.Vpn.Response.Product
@using Microsoft.Extensions.Configuration
@using Hncore.Pass.BaseInfo.Response
@using Hncore.Infrastructure.Serializer;
@inject IConfiguration m_Configuration
@model List<ProductWithPackageResponse>
@{
ViewData["Title"] = "购买产品";
UserLoginModel user = null;
if (this.Context.Request.Cookies.TryGetValue("userInfo", out string userCookie))
{
user = userCookie.FromJsonTo<UserLoginModel>();
}
var pid = this.Context.Request.Query.ContainsKey("id") ? this.Context.Request.Query["id"].ToString() : "";
var defaultProduct = Model.Select(m => m.Product).FirstOrDefault();
if (pid == "")
{
pid = Model.Select(m => m.Product).FirstOrDefault().Id.ToString();
}
else
{
defaultProduct = Model.Select(m => m.Product).FirstOrDefault(m => m.Id.ToString() == pid);
}
var productPackages = Model.Where(m => m.Product.Id == defaultProduct.Id).FirstOrDefault().Packages.Where(p => p.Status == 1 && p.IsTest == 0);//.Select(m => m.Packages.Where(p => p.Status == 1 && p.IsTest == 0).FirstOrDefault());
var defaultPackage = productPackages.FirstOrDefault();// Model.Where(m => m.Product.Id == defaultProduct.Id).Select(m => m.Packages.FirstOrDefault()).FirstOrDefault();
var baseUrl = m_Configuration["BaseInfoUrl"];
Func<string, string> P = (path) => $"{baseUrl}{path}";
}
<style>
.clear {
clear: both;
}
.clearfix:after {
content: ".";
display: block;
visibility: hidden;
height: 0;
clear: both
}
.main-page {
margin: 0 auto;
width: 1170px;
padding-bottom:50px;
}
.main-page .left {
width:15%;
border-right: 1px #ccc solid;
margin-top: 25px;
padding-right:10px;
}
.main-page .left, .main-page .right {
float: left;
}
.main-page .nav-back {
height: 300px;
}
.main-page .nav {
position: relative;
margin-top: -300px;
width: 136px;
text-align: center;
font-size: 18px;
font-family: "微软雅黑";
color: #000;
}
.main-page .nav div {
height: 47px;
line-height: 47px;
margin-bottom: 8px;
border-radius: 2px;
cursor: pointer;
}
.main-page .nav div.on {
background: #0c215d;
color: #fff;
}
.main-page .right {
width: 85%;
height: 800px;
}
.main-page .content {
position: relative;
overflow: hidden;
}
.contentNew {
border:none;
}
.youhuiNew {
font-size:14px;
border:none;
text-align:center;
padding:5px 0;
color:red;
}
.mtop {
margin-top:30px;
}
</style>
<!-- ad -->
<div class="container-fluid ad">
<a asp-action="taobao" asp-controller="article"> <img src="~/img/acBanner.png"></a>
</div>
@*新布局*@
<p class="text-center tit"><img src="~/img/titi_choose.png"></p>
<div class="main-page">
<div class="left">
<div class="nav-back"></div>
<div class="nav">
@foreach (var item in Model)
{
<div class="productItem" id="@("p"+item.Product.Id)" a-pid="@item.Product.Id" a-pkg-id="@(item.Packages.FirstOrDefault(m=>m.Status==1).Id)">@item.Product.Name</div>
}
</div>
</div>
<div class="right">
<div class="contentNew">
@foreach (var item in Model)
{
<div class="container stepOne packagebox" id="@("box"+item.Product.Id)">
<div class="container bg_taocan">
<div class="row">
<div class="col-lg-3 text-center photo">
<div class="photoK">
@*<img src="/@item.Product.Image">*@
<p>@item.Product.Name</p>
</div>
</div>
<div class="col-lg-6 intro">
<p>@item.Product.Name</p>
@foreach (var str in item.Product.ContentLine)
{
<p>·@str</p>
}
</div>
<div class="col-lg-3 text-center twoButton">
@if (user == null)
{
<p><button type="button" class="btn btn-warning testLogin" a-productId="@item.Product.Id">免费试用</button></p>
<p><button type="button" class="btn btn-warning reBuy">续费通道</button></p>
}
else
{
<p>
<a asp-action="test" asp-controller="product" asp-route-id="@item.Product.Id"><button type="button" class="btn btn-warning">免费试用</button></a>
</p>
<p>
<a asp-action="myaccounts" asp-controller="user"><button type="button" class="btn btn-warning">续费通道</button></a>
</p>
}
</div>
</div>
</div>
<p class="text-center nameSmall">—<span>@item.Product.Name</span>—</p>
<div class="card">
@foreach (var package in item.Packages.Where(m => m.IsTest == 0 && m.Status == 1))
{
<div class="item packageitem" id="@("pkg"+package.Id)" a-pkg-id="@package.Id">
<p class="tianka">@package.Name</p>
<p><span class="price">@package.Price</span>元</p>
<p class="yuanjia">原价:<span>@package.LinePrice</span>元</p>
<p>@(package.DayPrice)元/天</p>
<p class="qixian">@package.Profile</p>
<img src="~/img/check.png" class="cardCheck">
</div>
}
</div>
<p class="youhuiNew mtop">需求5个以上可以联系客服设置优惠价</p>
<p class="youhuiNew">温馨提示:若您之前享优惠价,请联系客服帮你改价哦</p>
@if (user == null)
{
<p class="tijiao"><button type="button" class="btn btn-primary login">提交</button></p>
}
else
{
<p class="tijiao"><button type="button" class="btn btn-primary btn-submit">提交</button></p>
}
</div>
}
</div>
</div>
<div class="clear"></div>
</div>
@section Scripts{
<script type="text/javascript">
var currentPkgId = 0;
var testProductId = 0;
function select(id) {
var el = "#p" + id;
var packageBox = "#box" + id;
$(".packagebox").hide();
$(packageBox).show();
$(el).addClass("on");
$(el).siblings().removeClass("on");
var pkgid = $(el).attr("a-pkg-id");
selectPackage(pkgid);
}
function selectPackage(id) {
currentPkgId = id;
var el = "#pkg" + id;
//$(".packageitem").hide();
//$(el).show()
$(el).addClass("kuang");
$(el).siblings().removeClass("kuang");
$(el).find(".cardCheck").show();
$(el).siblings().find(".cardCheck").hide();
}
function loginSuccess(data) {
window.location.href = "Buy?id=" + currentPkgId;
}
function testLoginSuccess(data) {
window.location.href = "Test?id=" + testProductId;
}
function reBuyLoginSuccess(data) {
window.location.href = "/User/MyAccounts";
}
$(function () {
$(".productItem").click(function () {
//$(this).addClass("kuang");
//$(this).siblings().removeClass("kuang");
//$(this).find(".check").show();
//$(this).siblings().find(".check").hide();
var pid = $(this).attr('a-pid');
select(pid);
});
$(".card .item").click(function () {
currentPkgId = $(this).attr('a-pkg-id');
selectPackage(currentPkgId)
//$(this).addClass("kuang");
//$(this).siblings().removeClass("kuang");
//$(this).find(".cardCheck").show();
//$(this).siblings().find(".cardCheck").hide();
})
$(".btn-submit").click(function () {
window.location.href = "Buy?id=" + currentPkgId;
})
$(".testLogin").click(function () {
loginCallback = testLoginSuccess;
testProductId = $(this).attr("a-productId");
$(".mask").show();
$(".main").show();
$(".main").addClass("animated bounceInDown");
});
$(".reBuy").click(function () {
loginCallback = reBuyLoginSuccess;
$(".mask").show();
$(".main").show();
$(".main").addClass("animated bounceInDown");
});
})
select(@defaultProduct.Id)
</script>
@*<script type="text/javascript">
$(".main-page .nav div").mouseenter(function () {
var $this = $(this);
var index = $this.index();
}).mouseleave(function () {
var $this = $(this);
var index = $this.index();
}).click(function () {
var $this = $(this);
var index = $this.index();
var l = -(index * 800);
$(".main-page .nav div").removeClass("on");
$(".main-page .nav div").eq(index).addClass("on");
$(".main-page .content .con-ggh:eq(0)").stop().animate({ "margin-top": l }, 500);
});
</script>*@
}

View File

@@ -0,0 +1,197 @@
@using Hncore.Pass.Vpn.Response.Product
@using Microsoft.Extensions.Configuration
@using Hncore.Pass.BaseInfo.Response
@using Hncore.Infrastructure.Serializer;
@inject IConfiguration m_Configuration
@model List<ProductWithPackageResponse>
@{
ViewData["Title"] = "购买产品";
UserLoginModel user = null;
if (this.Context.Request.Cookies.TryGetValue("userInfo", out string userCookie))
{
user = userCookie.FromJsonTo<UserLoginModel>();
}
var pid = this.Context.Request.Query.ContainsKey("id") ? this.Context.Request.Query["id"].ToString() : "";
var defaultProduct = Model.Select(m => m.Product).FirstOrDefault();
if (pid == "")
{
pid = Model.Select(m => m.Product).FirstOrDefault().Id.ToString();
}
else
{
defaultProduct = Model.Select(m => m.Product).FirstOrDefault(m => m.Id.ToString() == pid);
}
var productPackages = Model.Where(m => m.Product.Id == defaultProduct.Id).FirstOrDefault().Packages.Where(p=>p.Status == 1 && p.IsTest == 0);//.Select(m => m.Packages.Where(p => p.Status == 1 && p.IsTest == 0).FirstOrDefault());
var defaultPackage = productPackages.FirstOrDefault();// Model.Where(m => m.Product.Id == defaultProduct.Id).Select(m => m.Packages.FirstOrDefault()).FirstOrDefault();
var baseUrl = m_Configuration["BaseInfoUrl"];
Func<string, string> P = (path) => $"{baseUrl}{path}";
}
<!-- ad -->
<div class="container-fluid ad">
<a asp-action="taobao" asp-controller="article"> <img src="~/img/acBanner.png"></a>
</div>
<!-- con -->
<div class="container">
<p class="text-center tit"><img src="~/img/titi_choose.png"></p>
<div class="cpshow">
@foreach (var item in Model)
{
<div class="item" id="@("p"+item.Product.Id)" a-pid="@item.Product.Id" a-pkg-id="@(item.Packages.FirstOrDefault(m=>m.Status==1).Id)">
<p class="cpimg"><img src="@P(item.Product.Image)" /></p>
<p>@item.Product.Name</p>
<img src="~/img/check.png" class="check">
</div>
}
</div>
</div>
<!-- form -->
@foreach (var item in Model)
{
<div class="container stepOne packagebox" id="@("box"+item.Product.Id)">
<div class="container bg_taocan">
<div class="row">
<div class="col-lg-3 text-center photo">
<div class="photoK">
<img src="/@item.Product.Image">
<p>@item.Product.Name</p>
</div>
</div>
<div class="col-lg-6 intro">
<p>@item.Product.Name</p>
@foreach (var str in item.Product.ContentLine)
{
<p>·@str</p>
}
@*<p>·不限速网速最高可达50兆</p>
<p>·支持手机,电脑,模拟器</p>
<p>·200多个城市+全国混波量ip千万级</p>
<p>·带宽6-10兆</p>
<p>·断开再链接换ip</p>*@
</div>
<div class="col-lg-3 text-center twoButton">
@if (user == null)
{
<p><button type="button" class="btn btn-warning testLogin" a-productId="@item.Product.Id">免费试用</button></p>
<p><button type="button" class="btn btn-warning reBuy">续费通道</button></p>
}
else
{
<p>
<a asp-action="test" asp-controller="product" asp-route-id="@item.Product.Id"><button type="button" class="btn btn-warning">免费试用</button></a>
</p>
<p>
<a asp-action="myaccounts" asp-controller="user"><button type="button" class="btn btn-warning">续费通道</button></a>
</p>
}
</div>
</div>
</div>
<p class="text-center nameSmall">—<span>@item.Product.Name</span>—</p>
<div class="card">
@foreach (var package in item.Packages.Where(m => m.IsTest == 0 && m.Status == 1))
{
<div class="item packageitem" id="@("pkg"+package.Id)" a-pkg-id="@package.Id">
<p class="tianka">@package.Name</p>
<p><span class="price">@package.Price</span>元</p>
<p class="yuanjia">原价:<span>@package.LinePrice</span>元</p>
<p>@(package.DayPrice)元/天</p>
<p class="qixian">@package.Profile</p>
<img src="~/img/check.png" class="cardCheck">
</div>
}
</div>
<p class="youhui">需求5个以上可以联系客服设置优惠价</p>
<p class="youhui">温馨提示:若您之前享优惠价,请联系客服帮你改价哦</p>
@if (user == null)
{
<p class="tijiao"><button type="button" class="btn btn-primary login">提交</button></p>
}
else
{
<p class="tijiao"><button type="button" class="btn btn-primary btn-submit">提交</button></p>
}
</div>
}
@section Scripts{
<script type="text/javascript">
var currentPkgId = 0;
var testProductId = 0;
function select(id) {
var el = "#p" + id;
var el_box = "#box" + id;
$(".packagebox").hide();
$(el_box).show()
$(el).addClass("kuang");
$(el).siblings().removeClass("kuang");
$(el).find(".check").show();
$(el).siblings().find(".check").hide();
var pkgid = $(el).attr("a-pkg-id");
selectPackage(pkgid);
}
function selectPackage(id) {
currentPkgId = id;
var el = "#pkg" + id;
//$(".packageitem").hide();
//$(el).show()
$(el).addClass("kuang");
$(el).siblings().removeClass("kuang");
$(el).find(".cardCheck").show();
$(el).siblings().find(".cardCheck").hide();
}
function loginSuccess(data) {
window.location.href = "Buy?id=" + currentPkgId;
}
function testLoginSuccess(data) {
window.location.href = "Test?id=" + testProductId;
}
function reBuyLoginSuccess(data) {
window.location.href = "/User/MyAccounts";
}
$(function () {
$(".cpshow .item").click(function () {
$(this).addClass("kuang");
$(this).siblings().removeClass("kuang");
$(this).find(".check").show();
$(this).siblings().find(".check").hide();
var pid = $(this).attr('a-pid');
select(pid);
});
$(".card .item").click(function () {
currentPkgId = $(this).attr('a-pkg-id');
selectPackage(currentPkgId)
//$(this).addClass("kuang");
//$(this).siblings().removeClass("kuang");
//$(this).find(".cardCheck").show();
//$(this).siblings().find(".cardCheck").hide();
})
$(".btn-submit").click(function () {
window.location.href = "Buy?id=" + currentPkgId;
})
$(".testLogin").click(function () {
loginCallback = testLoginSuccess;
testProductId = $(this).attr("a-productId");
$(".mask").show();
$(".main").show();
$(".main").addClass("animated bounceInDown");
});
$(".reBuy").click(function () {
loginCallback = reBuyLoginSuccess;
$(".mask").show();
$(".main").show();
$(".main").addClass("animated bounceInDown");
});
})
select(@defaultProduct.Id)
</script>
}

View File

@@ -0,0 +1,308 @@
@using Hncore.Pass.Vpn.Response.Product
@using Microsoft.Extensions.Configuration
@using Hncore.Pass.BaseInfo.Response
@using Hncore.Infrastructure.Serializer;
@inject IConfiguration m_Configuration
@model List<ProductWithPackageResponse>
@{
ViewData["Title"] = "购买产品";
UserLoginModel user = null;
if (this.Context.Request.Cookies.TryGetValue("userInfo", out string userCookie))
{
user = userCookie.FromJsonTo<UserLoginModel>();
}
var pid = this.Context.Request.Query.ContainsKey("id") ? this.Context.Request.Query["id"].ToString() : "";
var defaultProduct = Model.Select(m => m.Product).FirstOrDefault();
if (pid == "")
{
pid = Model.Select(m => m.Product).FirstOrDefault().Id.ToString();
}
else
{
defaultProduct = Model.Select(m => m.Product).FirstOrDefault(m => m.Id.ToString() == pid);
}
var productPackages = Model.Where(m => m.Product.Id == defaultProduct.Id).FirstOrDefault().Packages.Where(p => p.Status == 1 && p.IsTest == 0);//.Select(m => m.Packages.Where(p => p.Status == 1 && p.IsTest == 0).FirstOrDefault());
var defaultPackage = productPackages.FirstOrDefault();// Model.Where(m => m.Product.Id == defaultProduct.Id).Select(m => m.Packages.FirstOrDefault()).FirstOrDefault();
var baseUrl = m_Configuration["BaseInfoUrl"];
Func<string, string> P = (path) => $"{baseUrl}{path}";
}
<style>
.productName {
font-style: oblique;
font-weight: 400;
font-size: 32px;
color: #f49119;
}
.pkgNameCard {
background: #223da4;
height: 90px;
padding: 15px;
}
.clear {
clear: both;
}
.clearfix:after {
content: ".";
display: block;
visibility: hidden;
height: 0;
clear: both
}
.main-page {
margin: 0 auto;
width: 1170px;
padding-bottom:50px;
}
.main-page .left {
width:15%;
border-right: 1px #ccc solid;
margin-top: 25px;
padding-right:10px;
}
.main-page .left, .main-page .right {
float: left;
}
.main-page .nav-back {
height: 300px;
}
.main-page .nav {
position: relative;
margin-top: -300px;
width: 136px;
text-align: center;
font-size: 18px;
font-family: "微软雅黑";
color: #000;
}
.main-page .nav div {
height: 47px;
line-height: 47px;
margin-bottom: 8px;
border-radius: 2px;
cursor: pointer;
}
.main-page .nav div.on {
background: #223da4;
color: #fff;
}
.main-page .right {
width: 85%;
height: 800px;
}
.main-page .content {
position: relative;
overflow: hidden;
}
.contentNew {
border:none;
}
.youhuiNew {
font-size: 16px;
border: none;
text-align: center;
padding: 10px 0;
color: red;
font-weight: bold;
}
.mtop {
margin-top:30px;
}
</style>
<!-- ad -->
<div class="container-fluid ad">
<a asp-action="taobao" asp-controller="article"> <img src="~/img/acBanner.png"></a>
</div>
@*新布局*@
<p class="text-center tit"><img src="~/img/titi_choose.png"></p>
<div class="main-page">
<div class="left">
<div class="nav-back"></div>
<div class="nav">
@foreach (var item in Model)
{
<div class="productItem" id="@("p"+item.Product.Id)" a-pid="@item.Product.Id" a-pkg-id="@(item.Packages.FirstOrDefault(m=>m.Status==1).Id)">@item.Product.Name</div>
}
</div>
</div>
<div class="right">
<div class="contentNew">
@foreach (var item in Model)
{
<div class="container packagebox" id="@("box"+item.Product.Id)">
<div class="container bg_taocan">
<div class="row" style="background:url(/img/products.png) no-repeat; background-size:100% 100%;">
<div class="col-lg-4" style="height:200px;padding-top:30px;padding-left:50px;">
<p class="productName">@item.Product.Name</p>
<p style=" border-bottom: 2px solid #fff;font-size:16px;">@(string.Join("|",item.Packages.Select(m=>m.Name)))</p>
</div>
<div class="col-lg-8" style="height:200px;padding-top:30px">
@foreach (var str in item.Product.ContentLine)
{
<p>@str</p>
}
<div class="row" style="text-align: right; position: absolute; right: 50px; bottom: 10px;">
@if (user == null)
{
<button type="button" class="btn btn-warning testLogin" a-productId="@item.Product.Id">免费试用</button>
<button type="button" class="btn btn-warning reBuy">续费通道</button>
}
else
{
<a asp-action="test" asp-controller="product" asp-route-id="@item.Product.Id"><button type="button" class="btn btn-warning">免费试用</button></a>
<a asp-action="myaccounts" asp-controller="user"><button type="button" class="btn btn-warning">续费通道</button></a>
}
</div>
</div>
</div>
</div>
@*<p class="text-center nameSmall">—<span>@item.Product.Name</span>—</p>*@
<div class="card" style="margin-top:30px;">
@foreach (var package in item.Packages.Where(m => m.IsTest == 0 && m.Status == 1))
{
<div class="item packageitem" id="@("pkg"+package.Id)" a-pkg-id="@package.Id">
<p><span class="price">@package.Price</span>元</p>
<p class="yuanjia">原价:<span>@package.LinePrice</span>元</p>
<p>@(package.DayPrice)元/天</p>
<div class="pkgNameCard">
<p class="tianka">@package.Name</p>
<p class="qixian">@package.Profile</p>
</div>
<img src="~/img/check.png" class="cardCheck">
</div>
}
</div>
<div style="border: 1px dashed #ccc;margin-top:30px;width:90%;margin-left: 63px;">
<p class="youhuiNew">温馨提示需求5个以上可以联系客服设置优惠价若您之前享优惠价请联系客服帮你改价哦开通后有任何问题可无理由退款</p>
</div>
@if (user == null)
{
<p class="tijiao"><button type="button" class="btn btn-primary login">提交</button></p>
}
else
{
<p class="tijiao"><button type="button" class="btn btn-primary btn-submit">提交</button></p>
}
</div>
}
</div>
</div>
<div class="clear"></div>
</div>
@section Scripts{
<script type="text/javascript">
var currentPkgId = 0;
var testProductId = 0;
function select(id) {
var el = "#p" + id;
var packageBox = "#box" + id;
$(".packagebox").hide();
$(packageBox).show();
$(el).addClass("on");
$(el).siblings().removeClass("on");
var pkgid = $(el).attr("a-pkg-id");
selectPackage(pkgid);
}
function selectPackage(id) {
currentPkgId = id;
var el = "#pkg" + id;
//$(".packageitem").hide();
//$(el).show()
$(el).addClass("kuang");
$(el).siblings().removeClass("kuang");
$(el).find(".cardCheck").show();
$(el).siblings().find(".cardCheck").hide();
}
function loginSuccess(data) {
window.location.href = "Buy?id=" + currentPkgId;
}
function testLoginSuccess(data) {
window.location.href = "Test?id=" + testProductId;
}
function reBuyLoginSuccess(data) {
window.location.href = "/User/MyAccounts";
}
$(function () {
$(".productItem").click(function () {
//$(this).addClass("kuang");
//$(this).siblings().removeClass("kuang");
//$(this).find(".check").show();
//$(this).siblings().find(".check").hide();
var pid = $(this).attr('a-pid');
select(pid);
});
$(".card .item").click(function () {
currentPkgId = $(this).attr('a-pkg-id');
selectPackage(currentPkgId)
//$(this).addClass("kuang");
//$(this).siblings().removeClass("kuang");
//$(this).find(".cardCheck").show();
//$(this).siblings().find(".cardCheck").hide();
})
$(".btn-submit").click(function () {
window.location.href = "Buy?id=" + currentPkgId;
})
$(".testLogin").click(function () {
loginCallback = testLoginSuccess;
testProductId = $(this).attr("a-productId");
$(".mask").show();
$(".main").show();
$(".main").addClass("animated bounceInDown");
});
$(".reBuy").click(function () {
loginCallback = reBuyLoginSuccess;
$(".mask").show();
$(".main").show();
$(".main").addClass("animated bounceInDown");
});
})
select(@defaultProduct.Id)
</script>
@*<script type="text/javascript">
$(".main-page .nav div").mouseenter(function () {
var $this = $(this);
var index = $this.index();
}).mouseleave(function () {
var $this = $(this);
var index = $this.index();
}).click(function () {
var $this = $(this);
var index = $this.index();
var l = -(index * 800);
$(".main-page .nav div").removeClass("on");
$(".main-page .nav div").eq(index).addClass("on");
$(".main-page .content .con-ggh:eq(0)").stop().animate({ "margin-top": l }, 500);
});
</script>*@
}

View File

@@ -0,0 +1,132 @@
@using Hncore.Pass.Vpn.Response.Product
@using Microsoft.Extensions.Configuration
@using Hncore.Pass.BaseInfo.Response
@using Hncore.Infrastructure.Serializer;
@inject IConfiguration m_Configuration
@model ProductWithPackageResponse
@{
ViewData["Title"] = "购买产品";
UserLoginModel user = null;
if (this.Context.Request.Cookies.TryGetValue("userInfo", out string userCookie))
{
user = userCookie.FromJsonTo<UserLoginModel>();
}
var defaultProduct = Model.Product;
var defaultPackage = Model.Packages.FirstOrDefault();
var baseUrl = m_Configuration["BaseInfoUrl"];
Func<string, string> P = (path) => $"{baseUrl}{path}";
}
<style>
.productName {
font-style: oblique;
font-weight: 400;
font-size: 32px;
color: #f49119;
}
.pkgNameCard {
background: #223da4;
height: 90px;
padding: 15px;
}
.youhuiNew {
font-size: 16px;
border: none;
text-align: center;
padding: 10px 0;
color: red;
font-weight: bold;
}
</style>
<!-- ad -->
<div class="container-fluid ad">
<a asp-action="taobao" asp-controller="article"> <img src="~/img/acBanner.png"></a>
</div>
<div class="container stepOne packagebox" id="@("box"+defaultProduct.Id)">
<div class="container bg_taocan">
<div class="row" style="background:url(/img/products.png) no-repeat; background-size:100% 100%;">
<div class="col-lg-4" style="height:200px;padding-top:30px;padding-left:50px;">
<p class="productName">@defaultProduct.Name</p>
</div>
<div class="col-lg-8" style="height:200px;padding-top:30px">
<p>@defaultProduct.Name</p>
@foreach (var str in defaultProduct.ContentLine)
{
<p>@str</p>
}
<div class="row" style="text-align: right; position: absolute; right: 50px; bottom: 10px;">
<a asp-action="index" asp-controller="product">
<button type="button" class="btn btn-warning">购买通道</button>
</a>
</div>
</div>
</div>
</div>
<div class="card">
@foreach (var package in Model.Packages.Where(m => m.IsTest == 0 && m.Status == 1))
{
<div class="item packageitem" id="@("pkg"+package.Id)" a-pkg-id="@package.Id">
<p><span class="price">@package.Price</span>元</p>
<p class="yuanjia">原价:<span>@package.LinePrice</span>元</p>
<p>@(package.DayPrice)元/天</p>
<div class="pkgNameCard">
<p class="tianka">@package.Name</p>
<p class="qixian">@package.Profile</p>
</div>
<img src="~/img/check.png" class="cardCheck">
</div>
}
</div>
<div style="border: 1px dashed #ccc;margin-top:30px;width:90%;margin-left: 63px;">
<p class="youhuiNew">温馨提示需求5个以上可以联系客服设置优惠价若您之前享优惠价请联系客服帮你改价哦开通后有任何问题可无理由退款</p>
</div>
@if (user == null)
{
<p class="tijiao"><button type="button" class="btn btn-primary login">提交</button></p>
}
else
{
<p class="tijiao"><button type="button" class="btn btn-primary btn-submit">提交</button></p>
}
</div>
@if(!string.IsNullOrWhiteSpace(ViewBag.errorTip))
{
<script>
alert('@ViewBag.errorTip')
history.go(-1);
</script>
}
@section Scripts{
<script type="text/javascript">
var currentPkgId =@defaultPackage.Id;
function selectPackage(id) {
currentPkgId = id;
var el = "#pkg" + id;
//$(".packageitem").hide();
//$(el).show()
$(el).addClass("kuang");
$(el).siblings().removeClass("kuang");
$(el).find(".cardCheck").show();
$(el).siblings().find(".cardCheck").hide();
}
function loginSuccess(data) {
window.location.href = "rebuy?packageId=" + currentPkgId+"&accounts=@ViewBag.accounts";
}
$(function () {
$(".card .item").click(function () {
currentPkgId = $(this).attr('a-pkg-id');
selectPackage(currentPkgId)
})
$(".btn-submit").click(function () {
window.location.href = "rebuy?packageId=" + currentPkgId+"&accounts=@ViewBag.accounts";
})
selectPackage(currentPkgId)
})
</script>
}

View File

@@ -0,0 +1,50 @@
@using Hncore.Pass.Vpn.Domain
@using Microsoft.Extensions.Configuration
@inject IConfiguration m_Configuration
@model List<ProductEntity>
@{
var baseUrl = m_Configuration["BaseInfoUrl"];
Func<string, string> P = (path) => $"{baseUrl}{path}";
}
<div class="container-fluid softBg">
<div class="container">
<div class="row">
<div class="col-lg-4">
</div>
<div class="col-lg-4 text-center">
<p class="simg"><img src="~/img/img_soft.png"></p>
<p class="sintro">软件和账户必须为同一产品才能使用</p>
</div>
<div class="col-lg-4 text-right">
<a href="#" class="jiaocheng">使用教程→</a>
</div>
</div>
</div>
</div>
<div class="container">
<div class="soft">
@foreach (var item in Model.Where(m=>m.Sort!=1000))
{
<div class="sitem">
<div class="smodel">
<div class="softName" style="width:200px;text-align:center;">
@item.Name
</div>
<div class="item">
<a href="@item.PcClientDownloadUrl"> <button type="button" class="btn btn-sdefault">Windows</button></a>
</div>
@if (item.Id != 3 && item.Id != 7 && item.Id != 9 && item.Id != 12)
{
<div class="item">
<a href="@item.SimulatorDownloadUrl"> <button type="button" class="btn btn-sdefault">SSTP客户端</button></a>
</div>
}
<p>免安装,下载后直接打开</p>
</div>
</div>
}
</div>
</div>

View File

@@ -0,0 +1,128 @@
@using Hncore.Pass.Vpn.Response.Product
@using Hncore.Infrastructure.Extension
@using Hncore.Infrastructure.Common
@model PackageInfoResponse
@inject Hncore.Pass.Vpn.Service.ProductAccountService m_AccountService
@{
ViewData["Title"] = "领取试用";
var t = this.Context.Request.GetInt("t");
var randomPwd = ValidateCodeHelper.MakeNumCode(3).ToLower();
var randomAccount = ValidateCodeHelper.MakeCharCode(2).ToLower() + ValidateCodeHelper.MakeNumCode(4).ToLower();
while (m_AccountService.Exist(m => m.Account == randomAccount))
{
randomAccount = ValidateCodeHelper.MakeCharCode(2).ToLower() + ValidateCodeHelper.MakeNumCode(4).ToLower();
}
}
<style>
.tip {
color: red;
text-align: center
}
</style>
<div class="container-fluid top">
<div class="container">
<div class="row">
<div class="col-lg-3 text-center">
当前已选产品:
</div>
<div class="col-lg-6">
<div class="selectCard">
@*<div class="item">
<p class="selectPhoto"> <img src="/@Model.Product.Image"></p>
<p>@Model.Product.Name</p>
</div>*@
<div class="item">
<p style="padding-top: 40px; font-size: 25px; font-weight: bold; color: #ee7a69;">@Model.Product.Name</p>
</div>
<div class="item">
<p class="sname">@Model.Package.Name</p>
<p class="sprice">0元</p>
<p class="stime">@Model.Package.Profile</p>
</div>
<div class="item">
<p class="zongjia"><span>@Model.Package.Price</span>元</p>
</div>
</div>
<p class="tishi tishika" style="text-align:center">*请务必选好所需商品,换货会产生费用</p>
</div>
<div class="col-lg-3">
<a asp-action="index" asp-controller="product">返回重新选择》</a>
</div>
</div>
</div>
</div>
<!-- 试用 -->
<div class="container biaodan">
<div class="row">
<div class="col-lg-3 text-right shuruname">
<p>PPTP账号名称</p>
<p>PPTP账号密码</p>
</div>
<div class="col-lg-4 text-left shuru">
<p><input type="text" name="" id="account" value="@randomAccount" /></p>
<p><input type="text" name="" id="pwd" value="@randomPwd" /></p>
<div class="btnlingqu">
<div class="item cishu">
剩余试用次数<span style="color:red">@(Model.RestTimes)</span>
</div>
<div class="item tip">
</div>
<div class="item tijiao lingqu">
@if (Model.RestTimes > 0 && Model.Package.Status == 1)
{
<button type="button" class="btn btn-primary" onclick="create()">领取试用</button>
}
@if (Model.Package.Status == 0)
{
<span class="tip">
该产品暂不能测试
</span>
}
</div>
</div>
</div>
@*<div class="col-lg-5 text-left">
<p class="tishi chongfu">*此用户名重复,请重新输入</p>
</div>*@
</div>
</div>
@section Scripts{
<script>
function create() {
var data = {
ProductId:@(Model.Product.Id),
PackageId: @(Model.Package.Id),
Account: $('#account').val(),
Pwd: $('#pwd').val()
};
if (data.Account == '' || data.Pwd == '') {
$(".tip").text("账户和密码不能为空");
return;
}
$.ajax({
type: 'POST',
url: '/api/course/v1/productaccount/CreateTestAccount',
contentType: "application/json",
data: JSON.stringify(data),
success: function (res) {
console.log(res);
if (res.Code == 10000) {
alert("领取成功")
window.location.href = "/user/myaccounts";
} else {
$(".tip").text(res.Message);
}
},
dataType: "json"
});
}
</script>
}

View File

@@ -0,0 +1,744 @@
@using Hncore.Pass.Vpn.Response.Product
@using Hncore.Infrastructure.Extension
@using Hncore.Pass.BaseInfo.Response
@using Hncore.Infrastructure.Serializer;
@using Hncore.Pass.BaseInfo.Service
@using Hncore.Infrastructure.Common
@model PackageInfoResponse
@inject UserService m_UserService
@inject Hncore.Pass.Vpn.Service.ProductAccountService m_AccountService
@{
ViewData["Title"] = "购买产品";
UserLoginModel user = null;
Hncore.Pass.BaseInfo.Models.User userEntity = new Hncore.Pass.BaseInfo.Models.User();
if (this.Context.Request.Cookies.TryGetValue("userInfo", out string userCookie))
{
user = userCookie.FromJsonTo<UserLoginModel>();
userEntity = await m_UserService.GetById(user.Id);
}
var randomPwd = ValidateCodeHelper.MakeNumCode(3).ToLower();
var randomAccount1 = ValidateCodeHelper.MakeCharCode(2).ToLower() + ValidateCodeHelper.MakeNumCode(4).ToLower();
while (m_AccountService.Exist(m => m.Account == randomAccount1)) {
randomAccount1 = ValidateCodeHelper.MakeCharCode(2).ToLower() + ValidateCodeHelper.MakeNumCode(4).ToLower();
}
var randomAccountMutil = ValidateCodeHelper.MakeCharCode(3).ToLower();
while (m_AccountService.Exist(m =>m.Account.StartsWith(randomAccountMutil)))
{
randomAccountMutil = ValidateCodeHelper.MakeCharCode(3).ToLower();
}
}
<script src="~/js/vue.js"></script>
<script type="text/javascript">
$(function () {
$('.spinner .btn:first-of-type').on('click', function () {
$('.spinner input').val(parseInt($('.spinner input').val(), 10) + 1);
});
$('.spinner .btn:last-of-type').on('click', function () {
$('.spinner input').val(parseInt($('.spinner input').val(), 10) - 1);
});
$(".dan").addClass("cu");
$(".dan").click(function () {
$(this).addClass("cu");
$(".pi").removeClass("cu");
$(".t1").show();
$(".t2").hide();
});
$(".pi").click(function () {
$(this).addClass("cu");
$(".dan").removeClass("cu");
$(".t1").hide();
$(".t2").show();
})
})
</script>
<vc:pay-wait></vc:pay-wait>
<vc:pay-ok></vc:pay-ok>
<div class="container-fluid top">
<div class="container">
<div class="row">
<div class="col-lg-3 text-center">
当前已选产品:
</div>
<div class="col-lg-6">
<div class="selectCard">
<div class="item">
<p style="padding-top: 40px; font-size: 25px; font-weight: bold; color: #ee7a69;">@Model.Product.Name</p>
</div>
<div class="item">
<p class="sname">@Model.Package.Name</p>
<p class="sprice">@(Model.Package.DayPrice)元/天</p>
<p class="stime">@Model.Package.Profile</p>
</div>
<div class="item">
<p class="zongjia"><span>@Model.Package.Price</span>元</p>
</div>
</div>
<p class="tishi tishika" style="text-align:center">*请务必选好所需商品,换货会产生费用</p>
@if (Model.Package.Name == "天卡")
{
<p class="tishi " style="text-align:center">*天卡不支持退款,请谨慎购买</p>
}
</div>
<div class="col-lg-3">
<a href="javascript:history.go(-1)">返回重新选择》</a>
</div>
</div>
</div>
</div>
<div id="app">
<!-- con -->
<div class="container zhuce">
<div class="reg_tab">
<div class="item dan active_dan">
单个注册
</div>
<div class="item pi">
批量注册
</div>
</div>
</div>
<div class="container t1" style="font-size: 18px;font-weight: bold;">
<form action="~/product/CreateOrder" method="post" id="accountForm">
<input type="hidden" name="PackageId" value="@Model.Package.Id" />
<input type="hidden" name="OrderType" value="1" />
<div class="row">
<div class="col-lg-4 text-right">
PPTP产品账号
</div>
<div class="col-lg-4 regDan">
<input type="text" name="Account" value="" v-model="OneBuyModel.Account" v-on:blur="checkOneAccount" />
<p class="jinggao" v-if="!OneChecker.AccountOk">5至10位字母或数字或组合</p>
</div>
<div class="col-lg-4 text-left warnText">
<sapn class="grayText">5至10位字母或数字或组合</sapn>
</div>
</div>
<div class="row">
<div class="col-lg-4 text-right">
PPTP产品密码
</div>
<div class="col-lg-4 regDan">
<input type="text" name="Pwd" v-model="OneBuyModel.Pwd" v-on:blur="checkOnePwd" />
<p class="jinggao" v-if="!OneChecker.PwdOk">2至10位字母或数字或组合</p>
</div>
<div class="col-lg-4 text-left">
<span class="grayText">2至10位字母或数字或组合</span>
</div>
</div>
<div class="row">
<div class="col-lg-4 text-right">
连接数:
</div>
<div class="col-lg-4">
<div class="buchang">
<input type="hidden" class="form-control ConnectCount" v-model="OneBuyModel.ConnectCount" name="ConnectCount" value="1">
<div class="item cursor" v-on:click="OneBuyModel.ConnectCount>1&&OneBuyModel.ConnectCount--">
-
</div>
<div class="item">
<input type="text" style="width:100%;height:21px;border:0" v-model="OneBuyModel.ConnectCount" />
</div>
<div class="item cursor" v-on:click="OneBuyModel.ConnectCount++">
+
</div>
</div>
</div>
<div class="col-lg-4 text-left">
<span class="grayText">可同时在线的设备数</span>
</div>
</div>
<div class="row">
<div class="col-lg-4 text-right">
选择优惠券:
</div>
<div class="col-lg-4 regDan">
<div class="dropdown">
<select style="height:40px;" name="" class="btn btn-default dropdown-toggle" v-model="OneBuyModel.CouponId" v-on:change="selectFn">
<option value="0">请选择优惠券</option>
<option v-for="item in Coupons" :value="item.Id">{{item.Name}}</option>
</select>
</div>
</div>
<div class="col-lg-4 text-left">
<span class="grayText">每隔30天淘宝下单可获得一张优惠券</span>
</div>
</div>
<div class="row">
<div class="col-lg-4 text-right">
余额:
</div>
<div class="col-lg-4">
当前账户余额<span class="blueText">@(userEntity.RestAmount)</span>元
<a href="/User/Index">前往充值</a>
</div>
<div class="col-lg-4">
</div>
</div>
<div class="row">
<div class="col-lg-4 text-right">
支付方式:
</div>
<div class="col-lg-4 zhifufangshi">
<input id="zhifubaopay_s1" type="radio" name="OPayType" value="100" checked v-model="OneBuyModel.OPayType"> <img src="~/img/zfb.png"><label for="zhifubaopay_s1">支付宝支付</label>
<input id="weixinpay_s1" type="radio" name="OPayType" value="70" v-model="OneBuyModel.OPayType"> <img src="~/img/wx.png"><label for="weixinpay_s1">微信支付</label>
<input id="UseAccountAmount_s1" type="radio" name="OPayType" value="1" v-model="OneBuyModel.UseAccountAmount"> <label for="UseAccountAmount_s1">余额支付</label>
</div>
<div class="col-lg-4 text-left">
<span></span>
</div>
</div>
<div class="row">
<div class="col-lg-4 text-right">
应付款:
</div>
<div class="col-lg-4">
<span class="blueText">{{OneTotalAmount}}</span>元
</div>
<div class="col-lg-4 text-left">
<span></span>
</div>
</div>
@* <div class="row">
<div class="col-lg-4 text-right">
应付款:
</div>
<div class="col-lg-4">
<span style="font-size: 30px;font-weight: bold;">{{OnePayAmount}}</span>元
</div>
<div class="col-lg-4 text-left">
<span></span>
</div>
</div> *@
<p class="tiijiao-tipjiao" style="color:red">{{Tip}}</p>
<p class="tijiao"><button class="btn btn-primary" type="button" v-on:click="onePay">确认支付</button></p>
</form>
</div>
<div class="container t2" id="moreBuy" style="font-size: 18px;font-weight: bold;">
<form action="~/product/CreateOrder" method="post">
<p class="shuoming">批量注册的账号会使用【账号前缀】+【开始数】+【个数】顺序进行注册,</p>
<p class="shuoming">如:注册账号前缀为【user】开始数为【6】个数为【10】则注册的账号为user06user07user08....user14</p>
<div class="row">
<div class="col-lg-4 text-right">
PPTP账号前缀
</div>
<div class="col-lg-4 regDan">
<input type="text" name="Account" value="" v-model="MoreBuyModel.Account" />
<p class="jinggao" v-if="!MoreChecker.AccountOk">3至8位字母或数字或组合</p>
</div>
<div class="col-lg-4 text-left warnText">
<sapn class="grayText">3至8位字母或数字或组合</sapn>
</div>
</div>
<div class="row">
<div class="col-lg-4 text-right">
开始号:
</div>
<div class="col-lg-4 regDan">
<input type="number" name="MinPostfix" v-model="MoreBuyModel.MinPostfix" />
</div>
<div class="col-lg-4 text-left">
<span class="grayText">本批次账号的起始账号的尾数</span>
</div>
</div>
<div class="row">
<div class="col-lg-4 text-right">
注册个数:
</div>
<div class="col-lg-4 regDan">
<input type="number" name="MaxPostfix" v-model="MoreBuyModel.MaxPostfix" />
<p class="jinggao" v-if="MoreBuyModel.MaxPostfix>500">一次最多注册500个</p>
</div>
<div class="col-lg-4 text-left">
<span class="grayText">本批次的账号个数</span>
</div>
</div>
<div class="row">
<div class="col-lg-4 text-right">
PPTP产品密码
</div>
<div class="col-lg-4 regDan">
<input type="text" name="Pwd" id="" value="" v-model="MoreBuyModel.Pwd" />
<p class="jinggao" v-if="!MoreChecker.PwdOk">2至10位字母或数字或组合</p>
</div>
<div class="col-lg-4 text-left">
<span>2至10位字母或数字或组合</span>
</div>
</div>
<div class="row">
<div class="col-lg-4 text-right">
连接数:
</div>
<div class="col-lg-4">
<div class="buchang">
<input type="hidden" class="form-control" name="ConnectCount" v-model="MoreBuyModel.ConnectCount">
<div class="item" @@click="MoreBuyModel.ConnectCount>1&&MoreBuyModel.ConnectCount--">
-
</div>
<div class="item">
<input type="text" style="width:100%;height:21px;border:0" v-model="MoreBuyModel.ConnectCount" />
</div>
<div class="item" @@click="MoreBuyModel.ConnectCount++">
+
</div>
</div>
</div>
<div class="col-lg-4 text-left">
<span class="grayText">可同时在线的设备数</span>
</div>
</div>
<div class="row">
<div class="col-lg-4 text-right">
选择优惠券:
</div>
<div class="col-lg-4 regDan">
<div class="dropdown">
<select style="height:40px;" name="" class="btn btn-default dropdown-toggle" v-model="MoreBuyModel.CouponId" v-on:change="selectFn">
<option value="0">请选择优惠券</option>
<option v-for="item in Coupons" :value="item.Id">{{item.Name}}</option>
</select>
</div>
</div>
<div class="col-lg-4 text-left">
<span class="grayText">每隔30天淘宝下单可获得一张优惠券</span>
</div>
</div>
<div class="row">
<div class="col-lg-4 text-right">
余额:
</div>
<div class="col-lg-4">
当前账户余额<span class="blueText">@(userEntity.RestAmount)</span>元
<a href="/User/Index">前往充值</a>
</div>
<div class="col-lg-4">
</div>
</div>
<div class="row">
<div class="col-lg-4 text-right">
支付方式:
</div>
<div class="col-lg-4 zhifufangshi">
<input id="zhifubaopay_s" type="radio" name="OPayType" value="100" checked v-model="MoreBuyModel.OPayType"> <img src="~/img/zfb.png"><label for="zhifubaopay_s">支付宝支付</label>
<input id="weixinpay_s" type="radio" name="OPayType" value="70" v-model="MoreBuyModel.OPayType"> <img src="~/img/wx.png"><label for="weixinpay_s">微信支付</label>
<input id="UseAccountAmount" type="radio" name="OPayType" value="1" v-model="MoreBuyModel.UseAccountAmount"> <label for="UseAccountAmount">余额支付</label>
</div>
<div class="col-lg-4 text-left">
<span></span>
</div>
</div>
<div class="row">
<div class="col-lg-4 text-right">
应付款
</div>
<div class="col-lg-4">
<span class="blueText">{{MoreTotalAmount}}</span>元
</div>
<div class="col-lg-4 text-left">
<span></span>
</div>
</div>
@* <div class="row">
<div class="col-lg-4 text-right">
应付款:
</div>
<div class="col-lg-4">
<span style="font-size: 30px;font-weight: bold;">{{MorePayAmount}}</span>元
</div>
<div class="col-lg-4 text-left">
<span></span>
</div>
</div> *@
<p class="ijiao-tip" style="color:red">{{Tip}}</p>
<p class="tijiao"><button class="btn btn-primary" type="button" v-on:click="morePay">确认支付</button></p>
</form>
</div>
<!-- 支付弹窗开始 -->
<div class="payMask">
<div class="payCon">
<img src="~/img/close.png" class="payClose" v-on:click="close">
<p class="payTit"><img src="~/img/wx.png">微信支付 收银台</p>
<div class="row">
<div class="col-lg-6 text-center">
@*<p>订单将在25分钟后关闭请及时付款</p>*@
<p>
@*<img id="wxPayQr" src="img/ewm.png">*@
<div id="qrcode" style="width:200px;height:200px"></div>
</p>
@*<p>二维码已经失效,请刷新后重新扫码支付</p>*@
</div>
<div class="col-lg-6 text-left leftBorder">
<p>新开订单</p>
<p class="payPrice">¥<span>{{OrderInfo.OtherPayAmount}}</span></p>
<p>收款方聚IP</p>
<p>下单时间:<span>{{OrderInfo.CreateTime}}</span></p>
<p>订单号:<span>{{OrderInfo.OrderNo}}</span></p>
</div>
</div>
</div>
</div>
<!-- 支付弹窗结束 -->
<div id="aliPayBox" style="display:none"></div>
</div>
@section Scripts{
<script>
var productId =@(Model.Product.Id);
/** 表单序列化成json字符串的方法 */
function form2JsonString(formId) {
var paramArray = $('#' + formId).serializeArray();
var jsonObj = {};
$(paramArray).each(function () {
jsonObj[this.name] = this.value;
});
console.log(jsonObj);
return JSON.stringify(jsonObj);
}
var app = new Vue({
el: '#app',
data: {
payHandler: null,
Tip: '',
RestAmount: @(userEntity.RestAmount),
Coupons: [],
SelectCoupon: {},
OrderInfo: {},
OneChecker: {
AccountOk: true,
PwdOk: true
},
MoreChecker: {
AccountOk: true,
PwdOk: true,
Max: 10,
},
OneBuyModel: {
Price:@(Model.Package.Price),
PackageId:@(Model.Package.Id),
CouponAmount: 0,
OrderType: 1,
Account: '@(randomAccount1)',
Pwd: '@(randomPwd)',
ConnectCount: 1,
CouponId: 0,
UseAccountAmount: 0,
OPayType: 100,
PayChannel: 50
},
MoreBuyModel: {
Price:@(Model.Package.Price),
PackageId:@(Model.Package.Id),
CouponAmount: 0,
OrderType: 2,
Account: '@(randomAccountMutil)',
Pwd: '@(randomPwd)',
ConnectCount: 1,
CouponId: 0,
UseAccountAmount: 0,
OPayType: 100,
MinPostfix: 1,
MaxPostfix: 1,
PayChannel: 50
}
},
computed: {
OneTotalAmount: function () {
var total = this.OneBuyModel.Price * this.OneBuyModel.ConnectCount
return total.toFixed(2);
},
OnePayAmount: function () {
var restAmout = this.OneBuyModel.UseAccountAmount == 1 ? this.RestAmount : 0;
var total = this.OneBuyModel.Price * this.OneBuyModel.ConnectCount - this.OneBuyModel.CouponAmount - restAmout;
total = total < 0 ? 0 : total;
return total.toFixed(2);
},
MoreTotalAmount: function () {
var total = this.MoreBuyModel.Price * this.MoreBuyModel.ConnectCount * this.MoreBuyModel.MaxPostfix;
return total.toFixed(2);
},
MorePayAmount: function () {
var restAmout = this.MoreBuyModel.UseAccountAmount == 1 ? this.RestAmount : 0;
var total = this.MoreBuyModel.Price * this.MoreBuyModel.ConnectCount * this.MoreBuyModel.MaxPostfix - this.MoreBuyModel.CouponAmount - restAmout;
total = total < 0 ? 0 : total;
return total.toFixed(2);
}
},
watch: {
'OneBuyModel.CouponId': { //加引号监听对象里的属性
handler: function (newValue, oldValue) {
var totalAmount = this.OneBuyModel.Price * this.OneBuyModel.ConnectCount;
for (var i = 0; i < this.Coupons.length; i++) {
var item = this.Coupons[i];
if (totalAmount < item.AllowMinAmount) {
continue;
}
if (item.Id == newValue) {
if (item.CouponType == 1) {//满减
this.OneBuyModel.CouponAmount = item.CouponValue;
} else {
this.OneBuyModel.CouponAmount = totalAmount * item.CouponValue * 0.1;
}
return;
}
}
},
immediate: true
},
'MoreBuyModel.CouponId': { //加引号监听对象里的属性
handler: function (newValue, oldValue) {
var totalAmount = this.MoreBuyModel.Price * this.MoreBuyModel.ConnectCount;
for (var i = 0; i < this.Coupons.length; i++) {
var item = this.Coupons[i];
if (totalAmount < item.AllowMinAmount) {
continue;
}
if (item.Id == newValue) {
if (item.CouponType == 1) {//满减
this.MoreBuyModel.CouponAmount = item.CouponValue;
} else {
this.MoreBuyModel.CouponAmount = totalAmount * item.CouponValue * 0.1;
}
return;
}
}
},
immediate: true
},
'OneBuyModel.OPayType': { //加引号监听对象里的属性
handler: function (newValue, oldValue) {
this.OneBuyModel.UseAccountAmount = false;
this.OneBuyModel.PayChannel = newValue == 70 ? 30 : 50;
},
immediate: true
},
'MoreBuyModel.OPayType': { //加引号监听对象里的属性
handler: function (newValue, oldValue) {
this.MoreBuyModel.UseAccountAmount = false;
this.MoreBuyModel.PayChannel = newValue == 70 ? 30 : 50;
},
immediate: true
}
},
mounted: function () {
@if(user != null) {
<text>this.getCoupons()</text>
}
},
methods: {
// true:数值型的false非数值型
isNum(value) {
return typeof value === 'number' && !isNaN(value);
},
selectFn: function (e) {
console.log(e.target.value) // 选择项的value
},
getCoupons: function () {
var that = this;
var url = '/api/sells/v1/coupon/GetAvailableCoupon';
$.ajax({
type: 'GET',
url: url,
success: function (res) {
console.log(res);
if (res.Code == 10000) {
that.Coupons = res.Data.map(m => m.Coupon);
}
}
})
},
hasNumAndChar(str) {
var zg = /^[0-9a-zA-Z]*$/;
if (!zg.test(str)) {
return false;
} else {
return true;
}
},
checkOneAccount() {
if (this.OneBuyModel.Account.length > 10 || this.OneBuyModel.Account.length < 5 || !this.hasNumAndChar(this.OneBuyModel.Account)) {
this.OneChecker.AccountOk = false;
return false;
}
this.OneChecker.AccountOk = true;
return true;
},
checkOnePwd() {
if (this.OneBuyModel.Pwd.length < 2 || this.OneBuyModel.Pwd.length > 10 || !this.hasNumAndChar(this.OneBuyModel.Pwd)) {
this.OneChecker.PwdOk = false;
return false;
}
this.OneChecker.PwdOk = true;
return true;
},
checkMoreAccount() {
if (this.MoreBuyModel.Account.length < 3 || this.MoreBuyModel.Account.length > 8 || !this.hasNumAndChar(this.MoreBuyModel.Account)) {
this.MoreChecker.AccountOk = false;
return false;
}
this.MoreChecker.AccountOk = true;
return true;
},
checkMorePwd() {
if (this.MoreBuyModel.Pwd.length < 2 || this.MoreBuyModel.Pwd.length > 10 || !this.hasNumAndChar(this.MoreBuyModel.Pwd)) {
this.MoreChecker.PwdOk = false;
return false;
}
this.MoreChecker.PwdOk = true;
return true;
},
onePay: function () {
this.OneBuyModel.ConnectCount = parseInt(this.OneBuyModel.ConnectCount)
if (!this.isNum(this.OneBuyModel.ConnectCount)) return;
if (!this.checkOneAccount() || !this.checkOnePwd()) return;
if (this.OnePayAmount > 0 ) {
if (this.OneBuyModel.UseAccountAmount){
alert('余额不足,请充值!');return;
}
}
var that = this;
if (this.OneBuyModel.UseAccountAmount === true) this.OneBuyModel.UseAccountAmount = 1;
if (this.OneBuyModel.UseAccountAmount === false) this.OneBuyModel.UseAccountAmount = 0;
showPayWait();
$.ajax({
type: 'POST',
url: '/product/CreateOrder',
dataType: "json",
contentType: "application/json",
data: JSON.stringify(this.OneBuyModel),
success: function (res) {
console.log(res);
if (res.Code == 10000) {
hidePayWait();
if (res.Data == "00") {
//alert('购买成功')
showPayOk();
} else {
that.payCallback(res.Data)
that.isPay(res.Data.OrderInfo.OrderNo);
}
} else {
tipPayWait(res.Message);
//that.Tip = res.Message;
}
}
});
},
morePay: function () {
this.MoreBuyModel.ConnectCount = parseInt(this.MoreBuyModel.ConnectCount)
if (!this.isNum(this.MoreBuyModel.ConnectCount)) return;
if (!this.checkMoreAccount() || !this.checkMorePwd() || this.MoreBuyModel.MaxPostfix>500) return;
var that = this;
if (this.MorePayAmount > 0 ) {
if (this.MoreBuyModel.UseAccountAmount){
alert('余额不足,请充值!');return;
}
}
if (this.MoreBuyModel.UseAccountAmount === true) this.MoreBuyModel.UseAccountAmount = 1;
if (this.MoreBuyModel.UseAccountAmount === false) this.MoreBuyModel.UseAccountAmount = 0;
showPayWait();
$.ajax({
type: 'POST',
url: '/product/CreateOrder',
dataType: "json",
contentType: "application/json",
data: JSON.stringify(this.MoreBuyModel),
success: function (res) {
console.log(res);
if (res.Code == 10000) {
hidePayWait();
if (res.Data == "00") {
//alert('购买成功')
showPayOk();
} else {
that.payCallback(res.Data)
that.isPay(res.Data.OrderInfo.OrderNo);
}
} else {
//that.Tip = res.Message;
tipPayWait(res.Message);
}
}
});
},
payCallback: function (data) {
this.OrderInfo = data.OrderInfo;
var payType = this.OrderInfo.PayType;
if (payType == 70) {
$(".payMask").show();
$('#qrcode').qrcode(data.PayData);
} else if (payType == 100) {
$("#aliPayBox").html(data.PayData);
//document.write(data.PayData);
}
},
checkAccount: function () {
var account = $("#sAccount").val()
var url = '/api/course/v1/productaccount/ExistAccount?productId=' + productId + '&accounts=' + account;
$.ajax({
type: 'GET',
url: url,
success: function (res) {
console.log(res);
if (res.Code != 10000) {
$("#sAccountTip").text(res.Message)
}
}
})
},
isPay: function (orderNo) {
var that = this;
this.payHandler= setInterval(function () {
var url = '/product/IsPay?orderNo=' + orderNo;
$.ajax({
type: 'GET',
url: url,
success: function (res) {
if (res.Code == 10000 && res.Data ==1) {
clearInterval(that.payHandler);
showPayOk();
$(".payMask").hide();
//window.location.href = "/user/myaccounts";
}
}
})
}, 3000)
},
close() {
clearInterval(this.payHandler);
$('.payMask').hide();
$('#qrcode').empty();
}
}
})
function checkAccount() {
var account = $("#sAccount").val()
var url = '/api/course/v1/productaccount/ExistAccount?productId=' + productId+ '&accounts=' + account;
$.ajax({
type: 'GET',
url: url,
success: function (res) {
console.log(res);
if (res.Code != 10000) {
$("#sAccountTip").text(res.Message)
}
}
})
}
</script>
}

View File

@@ -0,0 +1,376 @@
@using Hncore.Pass.Vpn.Response.Product
@using Hncore.Infrastructure.Extension
@using Hncore.Pass.BaseInfo.Response
@using Hncore.Infrastructure.Serializer;
@using Hncore.Pass.BaseInfo.Service
@model PackageInfoResponse
@inject UserService m_UserService
@{
ViewData["Title"] = "购买产品";
UserLoginModel user = null;
Hncore.Pass.BaseInfo.Models.User userEntity = new Hncore.Pass.BaseInfo.Models.User();
if (this.Context.Request.Cookies.TryGetValue("userInfo", out string userCookie))
{
user = userCookie.FromJsonTo<UserLoginModel>();
userEntity = await m_UserService.GetById(user.Id);
}
}
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script type="text/javascript">
$(function () {
$('.spinner .btn:first-of-type').on('click', function () {
$('.spinner input').val(parseInt($('.spinner input').val(), 10) + 1);
});
$('.spinner .btn:last-of-type').on('click', function () {
$('.spinner input').val(parseInt($('.spinner input').val(), 10) - 1);
});
$(".dan").addClass("cu");
$(".dan").click(function () {
$(this).addClass("cu");
$(".pi").removeClass("cu");
$(".t1").show();
$(".t2").hide();
});
$(".pi").click(function () {
$(this).addClass("cu");
$(".dan").removeClass("cu");
$(".t1").hide();
$(".t2").show();
})
})
</script>
<vc:pay-wait></vc:pay-wait>
<vc:pay-ok></vc:pay-ok>
<div class="container-fluid top">
<div class="container">
<div class="row">
<div class="col-lg-3 text-center">
当前已选产品:
</div>
<div class="col-lg-6">
<div class="selectCard">
<div class="item">
<p style="padding-top: 40px; font-size: 25px; font-weight: bold; color: #ee7a69;">@Model.Product.Name</p>
</div>
<div class="item">
<p class="sname">@Model.Package.Name</p>
<p class="sprice">@(Model.Package.DayPrice)元/天</p>
<p class="stime">@Model.Package.Profile</p>
</div>
<div class="item">
<p class="zongjia"><span>@Model.Package.Price</span>元</p>
</div>
</div>
<p class="tishi tishika" style="text-align:center">*请务必选好所需商品,换货会产生费用</p>
</div>
<div class="col-lg-3">
<a href="javascript:history.go(-1)">返回重新选择》</a>
</div>
</div>
</div>
</div>
<div id="app">
<!-- con -->
<div class="container zhuce">
<div class="reg_tab">
<div class="item dan active_dan">
续费
</div>
</div>
</div>
<div class="container t1">
<form action="~/product/CreateOrder" method="post" id="accountForm">
<input type="hidden" name="PackageId" value="@Model.Package.Id" />
<input type="hidden" name="OrderType" value="1" />
<div class="row">
<div class="col-lg-4 text-right">
PPTP产品账号
</div>
<div class="col-lg-4 regDan">
<input type="text" name="Account" value="" v-model="OneBuyModel.Account" disabled />
<p class="jinggao" id="sAccountTip"></p>
</div>
<div class="col-lg-4 text-left warnText">
<sapn class="grayText">支持10位以内字母数字</sapn>
</div>
</div>
@*<div class="row">
<div class="col-lg-4 text-right">
PPTP产品密码
</div>
<div class="col-lg-4 regDan">
<input type="text" name="Pwd" v-model="OneBuyModel.Pwd" />
</div>
<div class="col-lg-4 text-left">
<span class="grayText">支持6位以内字母数字</span>
</div>
</div>*@
<div class="row">
<div class="col-lg-4 text-right">
连接数:
</div>
<div class="col-lg-4">
<div class="buchang">
<div class="item">
{{OneBuyModel.ConnectCount}}
</div>
</div>
</div>
<div class="col-lg-4 text-left">
<span></span>
</div>
</div>
<div class="row">
<div class="col-lg-4 text-right">
选择优惠券:
</div>
<div class="col-lg-4 regDan">
<div class="dropdown">
<select name="" class="btn btn-default dropdown-toggle" v-model="OneBuyModel.CouponId">
<option value="0">请选择优惠券</option>
<option v-for="item in Coupons" :value="item.Id">{{item.Name}}</option>
</select>
</div>
</div>
<div class="col-lg-4 text-left">
<span class="grayText">每隔30天淘宝下单可获得一张优惠券</span>
</div>
</div>
<div class="row">
<div class="col-lg-4 text-right">
余额抵扣:
</div>
<div class="col-lg-4">
<input type="checkbox" v-model="OneBuyModel.UseAccountAmount" value="1"> 使用余额抵扣,当前账户余额<span class="blueText">@(userEntity.RestAmount)</span>元
</div>
<div class="col-lg-4 text-left">
<span></span>
</div>
</div>
<div class="row">
<div class="col-lg-4 text-right">
支付方式:
</div>
<div class="col-lg-4 zhifufangshi">
<input type="radio" name="OPayType" value="100" checked v-model="OneBuyModel.OPayType"> <img src="~/img/zfb.png">支付宝支付
<input type="radio" name="OPayType" value="70" v-model="OneBuyModel.OPayType"> <img src="~/img/wx.png">微信支付
</div>
<div class="col-lg-4 text-left">
<span></span>
</div>
</div>
<div class="row">
<div class="col-lg-4 text-right">
总金额:
</div>
<div class="col-lg-4">
<span class="blueText">{{TotalAmount}}</span>元
</div>
<div class="col-lg-4 text-left">
<span></span>
</div>
</div>
<div class="row">
<div class="col-lg-4 text-right">
应付款:
</div>
<div class="col-lg-4">
<span style="font-size: 30px;font-weight: bold;">{{PayAmount}}</span>元
</div>
<div class="col-lg-4 text-left">
<span></span>
</div>
</div>
<p class="ijiao-tip" style="color:red">{{Tip}}</p>
<p class="tijiao"><button class="btn btn-primary" type="button" v-on:click="onePay">确认支付</button></p>
</form>
</div>
<!-- 支付弹窗开始 -->
<div class="payMask">
<div class="payCon">
<img src="~/img/close.png" class="payClose" v-on:click="close">
<p class="payTit"><img src="~/img/wx.png">微信支付 收银台</p>
<div class="row">
<div class="col-lg-6 text-center">
@*<p>订单将在25分钟后关闭请及时付款</p>*@
<p>
@*<img id="wxPayQr" src="img/ewm.png">*@
<div id="qrcode" style="width:200px;height:200px"></div>
</p>
@*<p>二维码已经失效,请刷新后重新扫码支付</p>*@
</div>
<div class="col-lg-6 text-left leftBorder">
<p>新开订单</p>
<p class="payPrice">¥<span>{{OrderInfo.OtherPayAmount}}</span></p>
<p>收款方聚IP</p>
<p>下单时间:<span>{{OrderInfo.CreateTime}}</span></p>
<p>订单号:<span>{{OrderInfo.OrderNo}}</span></p>
</div>
</div>
</div>
</div>
<!-- 支付弹窗结束 -->
<div id="aliPayBox" style="display:none"></div>
</div>
@section Scripts{
<script>
var productId =@(Model.Product.Id);
var app = new Vue({
el: '#app',
data: {
payHandler: null,
Tip:'',
RestAmount: @(userEntity.RestAmount),
Coupons: [],
SelectCoupon: {},
OrderInfo: {},
OneBuyModel: {
Price:@(Model.Package.Price),
PackageId:@(Model.Package.Id),
OrderType: @ViewBag.orderType,
Account: '@ViewBag.accounts',
CouponAmount: 0,
Pwd: '',
ConnectCount: @(ViewBag.ConnectCount),
CouponId: 0,
UseAccountAmount: 0,
OPayType: 100,
PayChannel:50,
}
},
computed: {
TotalAmount: function () {
var count = this.OneBuyModel.Account.split(',').length;
var total = this.OneBuyModel.Price * this.OneBuyModel.ConnectCount * count;
return total.toFixed(2);
},
PayAmount: function () {
var count = this.OneBuyModel.Account.split(',').length;
var restAmout = this.OneBuyModel.UseAccountAmount == 1 ? this.RestAmount : 0;
var total = this.OneBuyModel.Price * this.OneBuyModel.ConnectCount * count - this.OneBuyModel.CouponAmount - restAmout;
total= total < 0 ? 0 : total;
return total.toFixed(2);
}
},
watch: {
'OneBuyModel.CouponId': { //加引号监听对象里的属性
handler: function (newValue, oldValue) {
var totalAmount = this.OneBuyModel.Price * this.OneBuyModel.ConnectCount;
for (var i = 0; i < this.Coupons.length; i++) {
var item = this.Coupons[i];
if (totalAmount < item.AllowMinAmount) {
continue;
}
if (item.Id == newValue) {
if (item.CouponType == 1) {//满减
this.OneBuyModel.CouponAmount = item.CouponValue;
} else {
this.OneBuyModel.CouponAmount = totalAmount * item.CouponValue * 0.1;
}
return;
}
}
},
immediate: true
},
'OneBuyModel.OPayType': { //加引号监听对象里的属性
handler: function (newValue, oldValue) {
this.OneBuyModel.PayChannel = newValue == 70 ? 30 : 50;
},
immediate: true
}
},
mounted: function () {
this.getCoupons();
},
methods: {
getCoupons: function () {
var that = this;
var url = '/api/sells/v1/coupon/GetAvailableCoupon';
$.ajax({
type: 'GET',
url: url,
success: function (res) {
console.log(res);
if (res.Code == 10000) {
that.Coupons = res.Data.map(m => m.Coupon);
}
}
})
},
onePay: function () {
if (this.PayAmount == 0 || this.OneBuyModel.UseAccountAmount) {
if (!confirm('余额和微信支付宝组合支付时,余额将立即扣除,请务必完成后续差额支付!')) return;
}
var that = this;
if (this.OneBuyModel.UseAccountAmount === true) this.OneBuyModel.UseAccountAmount = 1;
if (this.OneBuyModel.UseAccountAmount === false) this.OneBuyModel.UseAccountAmount = 0;
showPayWait();
$.ajax({
type: 'POST',
url: '/product/CreateOrder',
dataType: "json",
contentType: "application/json",
data: JSON.stringify(this.OneBuyModel),
success: function (res) {
console.log(res);
if (res.Code == 10000) {
hidePayWait();
if (res.Data == "00") {
alert("续费成功");
} else {
that.payCallback(res.Data)
that.isPay(res.Data.OrderInfo.OrderNo);
}
} else {
//that.Tip = res.Message;
tipPayWait(res.Message);
}
}
});
},
payCallback: function (data) {
this.OrderInfo = data.OrderInfo;
var payType = this.OrderInfo.PayType;
if (payType == 70) {
$(".payMask").show();
$('#qrcode').qrcode(data.PayData);
} else if (payType == 100) {
$("#aliPayBox").html(data.PayData);
}
},
isPay: function (orderNo) {
var that = this;
this.payHandler = setInterval(function () {
var url = '/product/IsPay?orderNo=' + orderNo;
$.ajax({
type: 'GET',
url: url,
success: function (res) {
if (res.Code == 10000 && res.Data == 1) {
clearInterval(that.payHandler);
$(".payMask").hide();
showPayOk();
//window.location.href = "/user/myaccounts";
}
}
})
}, 3000)
},
close() {
clearInterval(this.payHandler);
$('.payMask').hide();
$('#qrcode').empty();
}
}
})
</script>
}

View File

@@ -0,0 +1,35 @@
@using Hncore.Infrastructure.Extension
@model ViewComponents.PagerModel
@{
Model.PageIndex= Model.PageIndex == 0 ? 1 : Model.PageIndex;
var q = this.Context.Request.Remove("PageIndex");
if (string.IsNullOrEmpty(q))
{
q = "?";
}
else
{
q = "?"+ q + "&";
}
}
@if (Model.TotalPage > 1)
{
<ul class="pagination">
@if (Model.PageIndex > 1)
{
string href = $"{q}PageIndex={Model.PageIndex - 1}";
<li class="page-item"><a class="page-link" href="@href">上一页</a></li>
}
@for (var i = 1; i <= Model.TotalPage; i++)
{
<li class="page-item"><a class="page-link @(Model.PageIndex==i?"fenyeActive2":"")" href="@(q)PageIndex=@i">@i</a></li>
}
@if (Model.PageIndex < Model.TotalPage)
{
string href = $"{q}PageIndex={Model.PageIndex + 1}";
<li class="page-item"><a class="page-link" href="@href">下一页</a></li>
}
</ul>
}

View File

@@ -0,0 +1,68 @@
<style>
/* 支付成功弹窗开始 */
.paylayer {
position: fixed;
z-index: 999;
width: 360px;
height: 500px;
top: 50%;
margin-top: -200px;
left: 50%;
margin-left: -180px;
display: none;
}
.plTop img {
width: 100%;
}
.plFour {
background: #fff;
margin: 0;
padding-bottom: 20px;
}
.plFour img {
width: 90%;
margin: 10px 0;
}
.plClose {
position: absolute;
top: 30px;
right: 10px;
z-index: 999;
}
/* 支付成功弹窗结束 */
</style>
<!-- 支付成功弹窗开始 -->
<div class="paylayer">
<img src="~/img/close.png" class="plClose">
<div class="plTop">
<img src="~/img/payBg.png">
</div>
<div class="row plFour">
<div class="col-lg-6 text-center">
<a asp-action="MyAccounts" asp-controller="User"> <img src="~/img/pl1.png"></a>
</div>
<div class="col-lg-6 text-center">
<a asp-action="Index" asp-controller="LineList"> <img src="~/img/pl2.png"></a>
</div>
<div class="col-lg-6 text-center">
<a asp-action="index" asp-controller="article" asp-route-Catalog="4"> <img src="~/img/pl3.png"></a>
</div>
<div class="col-lg-6 text-center">
<a asp-action="soft" asp-controller="Product"> <img src="~/img/pl4.png"></a>
</div>
</div>
</div>
<script>
$(".plClose").on("click", function () { $(".paylayer").hide(); $(".popmask").hide() })
function showPayOk() {
$(".popmask").show()
$(".paylayer").show();
}
</script>
<!-- 支付成功弹窗结束 -->

View File

@@ -0,0 +1,79 @@
<style>
/* 支付等待弹窗开始 */
.paywait {
position: fixed;
z-index: 999;
width: 360px;
height: 500px;
top: 50%;
margin-top: -200px;
left: 50%;
margin-left: -180px;
display: none;
}
.plTop img {
width: 100%;
}
.plFour {
background: #fff;
margin: 0;
padding-bottom: 20px;
}
.plFour img {
width: 90%;
margin: 10px 0;
}
.plClose {
position: absolute;
top: 30px;
right: 10px;
z-index: 999;
}
.errorTip{
margin-top:30px;
color:red;
}
/* 支付等待弹窗结束 */
</style>
<!-- 支付等待 -->
<div class="paywait">
<img src="~/img/close.png" class="plClose">
<div class="plTop">
<img src="~/img/paywait.png">
</div>
<div class="row plFour">
<div class="col-lg-12 text-center loadingBox">
<img src="~/img/loading.gif" style="width:100px;height:20px">
<p>账号检测中请耐心等待</p>
</div>
<div class="col-lg-12 text-center errorTip">
</div>
</div>
</div>
<script>
function showPayWait() {
$(".popmask").show()
$(".paywait").show();
$(".loadingBox").show();
$(".errorTip").text("");
}
function hidePayWait() {
$(".popmask").hide()
$(".paywait").hide();
}
function tipPayWait(info) {
showPayWait();
$(".loadingBox").hide();
$(".errorTip").text(info)
}
$(".plClose").on("click", function () { hidePayWait() })
</script>
<!-- 支付等待弹窗结束 -->

View File

@@ -0,0 +1,25 @@
@model ErrorViewModel
@{
ViewData["Title"] = "Error";
}
<h1 class="text-danger">Error.</h1>
<h2 class="text-danger">An error occurred while processing your request.</h2>
@if (Model.ShowRequestId)
{
<p>
<strong>Request ID:</strong> <code>@Model.RequestId</code>
</p>
}
<h3>Development Mode</h3>
<p>
Swapping to <strong>Development</strong> environment will display more detailed information about the error that occurred.
</p>
<p>
<strong>The Development environment shouldn't be enabled for deployed applications.</strong>
It can result in displaying sensitive information from exceptions to end users.
For local debugging, enable the <strong>Development</strong> environment by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong>
and restarting the app.
</p>

View File

@@ -0,0 +1,25 @@
@using Microsoft.AspNetCore.Http.Features
@{
var consentFeature = Context.Features.Get<ITrackingConsentFeature>();
var showBanner = !consentFeature?.CanTrack ?? false;
var cookieString = consentFeature?.CreateConsentCookie();
}
@if (showBanner)
{
<div id="cookieConsent" class="alert alert-info alert-dismissible fade show" role="alert">
Use this space to summarize your privacy and cookie use policy. <a asp-area="" asp-controller="Home" asp-action="Privacy">Learn More</a>.
<button type="button" class="accept-policy close" data-dismiss="alert" aria-label="Close" data-cookie-string="@cookieString">
<span aria-hidden="true">Accept</span>
</button>
</div>
<script>
(function () {
var button = document.querySelector("#cookieConsent button[data-cookie-string]");
button.addEventListener("click", function (event) {
document.cookie = button.dataset.cookieString;
}, false);
})();
</script>
}

View File

@@ -0,0 +1,544 @@
@using Hncore.Pass.BaseInfo.Response
@using Hncore.Infrastructure.Serializer;
@using Hncore.Pass.Vpn.Service
@inject ProductService m_ProductService
@{
UserLoginModel user = null;
if (this.Context.Request.Cookies.TryGetValue("userInfo", out string userCookie))
{
user = userCookie.FromJsonTo<UserLoginModel>();
}
var products = m_ProductService.Query(true).ToList();
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>聚IP JUIP.COM </title>
<link rel="stylesheet" type="text/css" href="~/css/bootstrap.min.css" />
<link rel="stylesheet" type="text/css" href="~/css/base.css" />
<link rel="stylesheet" type="text/css" href="~/css/swiper.min.css" />
<link rel="stylesheet" type="text/css" href="~/css/animate.min.css" />
<link rel="Shortcut Icon" href="/img/favicon.ico" type="image/x-icon" />
<script src="~/js/jquery.min.js" type="text/javascript" charset="utf-8"></script>
<script src="~/js/bootstrap.min.js" type="text/javascript" charset="utf-8"></script>
<script src="~/js/swiper.min.js" type="text/javascript" charset="utf-8"></script>
<script src="~/js/jquery.qrcode.min.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
$.ajaxSetup({
complete: function (XMLHttpRequest, textStatus) {
console.log(XMLHttpRequest);
//var sessionstatus = XMLHttpRequest.getResponseHeader("sessionstatus");
if (textStatus =="parsererror") {
//如果超时就处理 ,指定要跳转的页面(比如登陆页)
$(".mask").show();
$(".main").show();
$(".main").addClass("animated bounceInDown");
}
}
});
var loginCallback = null;
var loginSuccess = null;
$(function () {
// 注册登录弹窗
$(".regLink").click(function () {
$(".main").hide();
$(".main_reg").show();
});
$(".loginLink").click(function () {
$(".main_reg").hide();
$(".main_find").hide();
$(".main").show();
});
$(".findLink").click(function () {
$(".main").hide();
$(".main_find").show();
});
$(".login").click(function () {
$(".mask").show();
$(".main").show();
$(".main").addClass("animated bounceInDown");
});
$(".reg").click(function () {
$(".mask").show();
$(".main_reg").show();
$(".main_reg").addClass("animated bounceInDown");
});
$(".btnClose").click(function () {
$(".main").addClass("animated bounceOutDown");
$(".mask").hide();
setTimeout(function () {
$(".main").removeClass("animated bounceOutDown");
$(".main").hide();
}, 1000)
});
$(".regClose").click(function () {
$(".main_reg").addClass("animated bounceOutDown");
$(".mask").hide();
$(".main_find").hide();
setTimeout(function () {
$(".main_reg").removeClass("animated bounceOutDown");
$(".main_reg").hide();
}, 1000)
});
$(".cpshow .item").click(function () {
$(this).addClass("kuang");
$(this).siblings().removeClass("kuang");
$(this).find(".check").show();
$(this).siblings().find(".check").hide();
});
$(".card .item").click(function () {
$(this).addClass("kuang");
$(this).siblings().removeClass("kuang");
$(this).find(".cardCheck").show();
$(this).siblings().find(".cardCheck").hide();
});
})
</script>
</head>
<body>
<div class="popmask"></div>
<!-- sideBar -->
<div class="sideBar">
<div class="item item_on_q">
<img src="~/img/qq.png" class="on_q"> <div class="kefu_tit">QQ</div>
<div class="side_q">
<h4 style="border-bottom:1px solid #ccc;text-align:center;width:100%;padding:5px;">实时响应 在线时间8:00-24:00</h4>
<div class="item">
<a href="https://admin.qidian.qq.com/template/blue/mp/menu/qr-code-jump.html?linkType=0&env=ol&kfuin=2852138148&fid=299&key=f377ec024ca45115a03a7632c7bda230&cate=1&source=&isLBS=&isCustomEntry=&type=16&ftype=1&_type=wpa&qidian=true" target="_blank">
<div class="ileft">
<img src="~/img/q.png">
</div>
<div class="iright">
<span>人工客服:售前</span>
</div>
</a>
</div>
<div class="item">
<a href="https://admin.qidian.qq.com/template/blue/mp/menu/qr-code-jump.html?linkType=0&env=ol&kfuin=2852138148&fid=299&key=f377ec024ca45115a03a7632c7bda230&cate=1&source=&isLBS=&isCustomEntry=&type=16&ftype=1&_type=wpa&qidian=true" target="_blank">
<div class="ileft">
<img src="~/img/q.png">
</div>
<div class="iright">
<span>人工客服:售后</span>
</div>
</a>
</div>
</div>
</div>
<div class="item item_on_wx">
<img src="~/img/weixin.png" class="on_wx"> <div class="kefu_tit">微信</div>
<div class="side_kefu">
<!-- Nav tabs -->
<ul class="nav nav-tabs" role="tablist" style="padding-top: 10px;padding-left:10px">
<li role="presentation" class="active"><a href="#xx" aria-controls="xx" role="tab" data-toggle="tab" style="border-color:#ccc">售前</a></li>
<li role="presentation"><a href="#qq" aria-controls="qq" role="tab" data-toggle="tab" style="border-color:#ccc">售后</a></li>
@*<li role="presentation"><a href="#ss" aria-controls="ss" role="tab" data-toggle="tab" style="border-color:#ccc">珊珊</a></li>
<li role="presentation"><a href="#tt" aria-controls="tt" role="tab" data-toggle="tab" style="border-color:#ccc">兔兔</a></li>*@
</ul>
<!-- Tab panes -->
<div class="tab-content" style="margin-top: 60px;">
<div role="tabpanel" class="tab-pane active" id="xx">
<img src="~/img/kf_sq.jpg">
<p style="color:#f90">实时响应 在线时间 8:00-24:00</p>
</div>
<div role="tabpanel" class="tab-pane" id="qq">
<img src="~/img/kf_sh.jpg">
<p style="color:#f90">实时响应 在线时间 8:00-24:00</p>
</div>
@*<div role="tabpanel" class="tab-pane" id="ss">
<img src="~/img/w3.png">
<p style="color:#f90">实时响应 在线时间 8:00-24:00</p>
</div>
<div role="tabpanel" class="tab-pane" id="tt">
<img src="~/img/w4.png">
<p style="color:#f90">实时响应 在线时间 8:00-24:00</p>
</div>*@
</div>
</div>
</div>
<div class="item">
<img src="~/img/gzh.png" class="on_gzh"><div class="kefu_tit">公众号</div>
<div class="side_gzh">
<p><img src="~/img/ewm.png"></p>
<p style="color:#f90">实时响应 在线时间 8:00-24:00</p>
<p style="color:#f90">关注公众号可获取免费的到期提醒服务</p>
</div>
</div>
<div class="item">
<img src="~/img/tel.png" class="on_tel"><div class="kefu_tit">电话</div>
<div class="side_tel">
<p><b>400 800 9925</b></p>
<p>实时接通</p>
<p>电话值班时间 8:00-24:00</p>
</div>
</div>
<div class="item">
<a href="#top"><img src="~/img/top.png"></a>
</div>
</div>
<div class="container-fluid nav nav_buy">
<div class="row">
<div class="col-lg-2 col-md-2 logo">
<a href="#"><img src="~/img/logo.png"></a>
</div>
<div class="col-lg-10 col-md-10">
<ul class="navList navList_buy pull-right">
<li><a href="/">首页</a></li>
<li><a href="/product/index">产品购买</a></li>
<li><a href="/LineList/index">PPTP线路表</a></li>
<li><a href="/product/soft">软件下载</a></li>
<li><a href="/article/index?Catalog=1">资讯&帮助</a></li>
<li><a href="/article/taobao">淘宝充值活动</a></li>
<li>
@if (user == null)
{
<button type="button" class="btn btn-primary reg">注册</button>
<button type="button" class="btn btn-primary login">登录</button>
}
else
{
<img src="/img/account.png" onmouseover="$('.exitBox').show()">
<div class="exitBox" onmouseleave="$('.exitBox').hide()">
<div class="item">
<a asp-action="index" asp-controller="user">个人中心</a>
</div>
<div class="item">
<a asp-action="LoginOut" asp-controller="user">退出登录</a>
</div>
</div>
}
</li>
</ul>
</div>
</div>
</div>
@RenderBody()
<!-- footer -->
<div class="container-fluid footer">
<div class="container">
<div class="col-lg-3">
<p class="cpTit">旗下产品</p>
<ul class="cp">
@foreach (var item in products)
{
<li><a asp-action="index" asp-controller="product" asp-route-id="@item.Id">@item.Name</a></li>
}
</ul>
</div>
<div class="col-lg-3">
<p class="cpTit">联系我们</p>
<ul class="cp">
<li>公司电话400 800 9925</li>
<li>工作时间: 8:00-24:00</li>
</ul>
</div>
<div class="col-lg-3">
<p class="cpTit">商务合作</p>
<ul class="cp">
<li>电话/微信18039519517</li>
<li>QQ508095081</li>
</ul>
</div>
<div class="col-lg-3">
<p class="cpTit">公众号</p>
<p class="ewm"><img src="~/img/ewm.png"></p>
<p class="sao">关注公众号即可获取</p>
<p class="sao">免费的到期提醒服务</p>
</div>
</div>
</div>
<!-- copyright -->
<div class="container-fluid copyr">
<div class="container text-center">
<p>
聚IP仅提供IP服务用户使用聚IP从事的任何行为均不代表聚IP的意志和观点与聚IP的立场无关。严禁用户使用聚IP从事任何违法犯罪行为
产生的相关责任用户自负对此聚IP不承担任何法律责任。
</p>
<p>
版权所有 河南华连网络科技有限公司|<a href="http://www.beian.miit.gov.cn" target="_blank">豫ICP备17004061号-15</a>增值电信业务经营许可证B1-20190663
</p>
@*<p class="logoD"><img src="~/img/logogD.png"></p>*@
<p class="logoD_"><img src="~/img/logogD.png"><a target="cyxyv" href="https://v.yunaq.com/certificate?domain=www.juip.com&from=label&code=90020"> <img src="https://aqyzmedia.yunaq.com/labels/label_sm_90020.png" style="width:70px;height:25px;"></a></p>
</div>
</div>
<!-- register -->
<div class="mask"></div>
<div class="main_reg" id="regBox" style="height: 580px">
<img src="~/img/close.png" class="regClose">
<div class="logoLogin">
<img src="~/img/logoBlue.png">
</div>
<div class="award">
<img src="~/img/award.png">
</div>
<div class="user">
<img src="~/img/phone.png"><input type="text" id="username" value="" placeholder="请输入手机号码" />
</div>
<div class="pwd">
<img src="~/img/password.png"><input type="password" id="password" value="" placeholder="请输入密码" />
</div>
<div class="yzm">
<img src="~/img/yanzhengma.png"><input type="text" id="yanzhengma" value="" placeholder="请输入验证码" /><button class="btn btn-primary" onclick="getCode(this)">获取验证码</button>
</div>
<div class="user">
<img src="~/img/phone.png"><input type="text" name="" id="wxhao" value="" placeholder="请输入微信号" />
</div>
<div class="user">
<img src="~/img/phone.png"><input type="text" name="" id="qqhao" value="" placeholder="请输入QQ" />
</div>
<p class="tixing">*手机号不是PPTP账号请登录后开通PPTP账号*</p>
<p class="tixing"><input type="checkbox" name="" id="" value="" />我同意<a href="#">聚IP JUIP.COM用户注册协议</a></p>
<p class="denglu"><button type="button" class="btn btn-reg">注册</button></p>
<p class="zhiyin grayText">已有账号?<a href="#" class="loginLink">立即登录</a></p>
</div>
<!-- login -->
<div class="mask"></div>
<div class="main" id="loginBox">
<img src="~/img/close.png" class="btnClose">
<div class="logoLogin">
<img src="~/img/logoBlue.png">
</div>
<div class="award">
<img src="~/img/award.png">
</div>
<div class="user">
<img src="~/img/user.png"><input type="text" name="" id="rLogin_Name" value="" placeholder="请输入会员手机号码" />
</div>
<div class="pwd">
<img src="~/img/password.png"><input type="password" name="" id="rLogin_Pwd" value="" placeholder="请输入密码" />
</div>
<div class="fuzhu">
<div class="item">
@*<input type="checkbox" name="" id="" value="" />自动登录*@
</div>
<div class="item">
<a href="#" class="grayText findLink">忘记密码?</a>
</div>
</div>
<p class="tixing">*手机号不是PPTP账号请登录后开通PPTP账号*</p>
<p class="denglu"><button type="button" class="btn btn-login">登录</button></p>
<p class="zhiyin grayText">还没有账号?<a href="#" class="regLink">立即注册</a></p>
</div>
<!-- findpwd -->
<div class="mask"></div>
<div class="main_find" id="FindBox">
<img src="~/img/close.png" class="regClose">
<div class="logoLogin">
<img src="~/img/logoBlue.png">
</div>
<div class="award">
<img src="~/img/award.png">
</div>
<div class="user">
<img src="~/img/phone.png"><input type="text" id="fusername" value="" placeholder="请输入手机号码" />
</div>
<div class="pwd">
<img src="~/img/password.png"><input type="password" id="fpassword" value="" placeholder="请输入新密码" />
</div>
<div class="yzm">
<img src="~/img/yanzhengma.png"><input type="text" id="fyanzhengma" value="" placeholder="请输入验证码" /><button class="btn btn-primary" onclick="getFindCode(this)">获取验证码</button>
</div>
<p class="tixing">*手机号不是PPTP账号请登录后开通PPTP账号*</p>
<p class="denglu"><button type="button" class="btn btn-reset">重置</button></p>
<p class="zhiyin grayText">已有账号?<a href="#" class="loginLink">立即登录</a></p>
</div>
<script>
function login() {
var name = $("#rLogin_Name").val()
var pwd = $("#rLogin_Pwd").val()
var data = { Logincode: name, Password: pwd, Code: 1 };
$.ajax({
type: 'POST',
url: '/user/login',
contentType: "application/json",
data: JSON.stringify(data),
success: function (res) {
console.log(res);
if (res.Code == 10000) {
try {
var callback = loginCallback || loginSuccess;
callback(res.Data)
} catch (err) {
window.location.reload();
}
} else {
alert(res.Message)
}
}
});
}
var time = 60;
function getCode(_self) {
if (!timing(_self)) return;
var name = $("#username").val()
var url = '/user/SendPhoneCode?key=User_Code&phone=' + name;
$.ajax({
type: 'GET',
url: url,
success: function (res) {
alert(res.Message)
}
});
}
function getFindCode(_self) {
if (!timing(_self)) return;
var name = $("#fusername").val()
var url = '/user/SendPhoneCode?key=FindUser_Code&phone=' + name;
$.ajax({
type: 'GET',
url: url,
success: function (res) {
alert(res.Message)
}
});
}
function timing(_self) {
if (time != 60) return false
var timerHandler = setInterval(function () {
time--;
if (time <= 1) {
clearInterval(timerHandler);
time = 60;
$(_self).text("获取验证码")
} else {
$(_self).text(time + "s");
}
}, 1000)
return true;
}
function reg() {
var name = $("#username").val()
var pwd = $("#password").val()
var code = $("#yanzhengma").val()
if (name == '') { alert('手机号不能为空'); return; }
if (code == '') { alert('验证码不能为空'); return; }
var wx = $("#wxhao").val()
var qq = $("#qqhao").val()
var data = { Phone: name, Pwd: pwd, Code: code, Wx: wx, QQ: qq };
$.ajax({
type: 'POST',
url: '/user/Regist',
contentType: "application/json",
data: JSON.stringify(data),
success: function (res) {
console.log(res);
if (res.Code == 10000) {
window.location.reload();
} else {
alert(res.Message)
}
}
});
}
function reset() {
var name = $("#fusername").val()
var pwd = $("#fpassword").val()
var code = $("#fyanzhengma").val()
if (name == '') { alert('手机号不能为空'); return; }
if (code == '') { alert('验证码不能为空'); return; }
var data = { Phone: name, Pwd: pwd, Code: code };
$.ajax({
type: 'POST',
url: '/user/FindPwd',
contentType: "application/json",
data: JSON.stringify(data),
success: function (res) {
console.log(res);
if (res.Code == 10000) {
alert("重置成功,请登录");
} else {
alert(res.Message)
}
}
});
}
$(function () {
$(".btn-login").click(function () {
login();
})
$(".btn-reg").click(function () {
reg();
})
$(".btn-reset").click(function () {
reset();
})
$("#loginBox").bind("keydown", function (e) {
var theEvent = e || window.event;
var code = theEvent.keyCode || theEvent.which || theEvent.charCode;
if (code == 13) {
login();
}
});
$("#regBox").bind("keydown", function (e) {
var theEvent = e || window.event;
var code = theEvent.keyCode || theEvent.which || theEvent.charCode;
if (code == 13) {
reg();
}
});
// 侧边栏
//$(".on_q").click(function () {
// $(".side_q").toggle();
//});
$(".item_on_q").mouseover(function () {
$(".side_q").stop().show();
});
$(".item_on_q").mouseleave(function () {
$(".side_q").stop().hide();
});
//$(".on_wx").click(function () {
// $(".side_kefu").toggle();
//});
$(".item_on_wx").mouseover(function () {
$(".side_kefu").stop().fadeIn();
});
$(".item_on_wx").mouseleave(function () {
$(".side_kefu").stop().fadeOut();
});
$(".on_gzh").mouseover(function () {
$(".side_gzh").stop().fadeIn();
});
$(".on_gzh").mouseleave(function () {
$(".side_gzh").stop().fadeOut();
});
$(".on_tel").mouseover(function () {
$(".side_tel").stop().fadeIn();
});
$(".on_tel").mouseleave(function () {
$(".side_tel").stop().fadeOut();
});
})
</script>
<!-- WPA start -->
<script id="qd28521381485d6faa97edf5ad07d7e159f6cb902af0" src="https://wp.qiye.qq.com/qidian/2852138148/5d6faa97edf5ad07d7e159f6cb902af0" charset="utf-8" async defer></script>
<!-- WPA end -->
@RenderSection("Scripts", required: false)
</body>
</html>

View File

@@ -0,0 +1,89 @@
@using Hncore.Pass.BaseInfo.Response
@using Hncore.Infrastructure.Serializer;
@{
UserLoginModel user = null;
if (this.Context.Request.Cookies.TryGetValue("userInfo", out string userCookie))
{
user = userCookie.FromJsonTo<UserLoginModel>();
}
string currentPath = this.Context.Request.Path.ToString().ToLower();
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>聚IP JUIP.COM</title>
<link rel="stylesheet" type="text/css" href="~/css/bootstrap.min.css" />
<link rel="stylesheet" type="text/css" href="~/css/base.css" />
<link rel="stylesheet" type="text/css" href="~/css/swiper.min.css" />
<link rel="stylesheet" type="text/css" href="~/css/animate.min.css" />
<link href="~/css/bootstrap-datetimepicker.min.css" rel="stylesheet">
<script src="~/js/jquery.min.js" type="text/javascript" charset="utf-8"></script>
<script src="~/js/bootstrap.min.js" type="text/javascript" charset="utf-8"></script>
<script src="~/js/swiper.min.js" type="text/javascript" charset="utf-8"></script>
<script src="~/js/moment-with-locales.js"></script>
<script src="~/js/bootstrap-datetimepicker.min.js"></script>
<script src="~/js/vue.js" type="text/javascript" charset="utf-8"></script>
<script src="~/js/jquery.qrcode.min.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div class="container-fluid nav nav_buy">
<div class="row">
<div class="col-lg-2 col-md-2 logo">
<a href="#"><img src="~/img/logo.png"></a>
</div>
<div class="col-lg-10 col-md-10">
<ul class="navList navList_buy pull-right">
<li><a href="/">首页</a></li>
<li><a href="/product/index">产品购买</a></li>
<li><a href="/LineList/index" ">PPTP线路表</a></li>
<li><a href="/product/soft">软件下载</a></li>
<li><a href="/article/index">资讯&帮助</a></li>
<li><a href="/article/taobao">淘宝充值活动</a></li>
<li>
<img src="/img/account.png" onmouseover="$('.exitBox').show()">
<div class="exitBox" onmouseleave="$('.exitBox').hide()">
<div class="item">
<a asp-action="index" asp-controller="user">个人中心</a>
</div>
<div class="item">
<a asp-action="LoginOut" asp-controller="user">退出登录</a>
</div>
</div>
</li>
</ul>
</div>
</div>
</div>
<!-- main -->
<div class="container-fluid clearMargin">
<div class="col-lg-2 leftArea">
<div class="leftBar">
<div class="item @(currentPath=="/user/index"?"active_b":"")">
<img src="~/img/p1.png"><a href="/user/index">个人中心</a>
</div>
<div class="item @(currentPath=="/user/myorders"?"active_b":"")">
<img src="~/img/p2.png"><a href="/user/myorders">订单管理</a>
</div>
<div class="item @(currentPath=="/user/myrefundorders"?"active_b":"")">
<img src="~/img/p3.png"><a href="/user/myrefundorders">退货订单管理</a>
</div>
<div class="item @(currentPath=="/user/myaccounts"?"active_b":"")">
<img src="~/img/p4.png"><a href="/user/myaccounts">PPTP账号管理</a>
</div>
<div class="item @(currentPath=="/user/mycoupons"?"active_b":"")">
<img src="~/img/p5.png"><a href="/user/mycoupons">我的优惠券</a>
</div>
</div>
</div>
<div class="col-lg-10 rightCon">
@RenderBody()
</div>
</div>
@RenderSection("Scripts", required: false)
</body>
</html>

View File

@@ -0,0 +1,18 @@
<environment include="Development">
<script src="~/lib/jquery-validation/dist/jquery.validate.js"></script>
<script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js"></script>
</environment>
<environment exclude="Development">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.17.0/jquery.validate.min.js"
asp-fallback-src="~/lib/jquery-validation/dist/jquery.validate.min.js"
asp-fallback-test="window.jQuery && window.jQuery.validator"
crossorigin="anonymous"
integrity="sha256-F6h55Qw6sweK+t7SiOJX+2bpSAa3b/fnlrVCJvmEj1A=">
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validation-unobtrusive/3.2.11/jquery.validate.unobtrusive.min.js"
asp-fallback-src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"
asp-fallback-test="window.jQuery && window.jQuery.validator && window.jQuery.validator.unobtrusive"
crossorigin="anonymous"
integrity="sha256-9GycpJnliUjJDVDqP0UEu/bsm9U+3dnQUH8+3W10vkY=">
</script>
</environment>

View File

@@ -0,0 +1,429 @@
@using Home.Models
@using Hncore.Infrastructure.Extension
@model UserHomeModel
@{
Layout = "_UserLayout";
var e = this.Context.Request.GetInt("e");
}
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script>
var edit =@(e)> 0;
$(function () {
$(".edit").click(function () {
$(".editList").show();
});
$(".quxiao").click(function () {
$(".editList").hide();
});
$(".changePwd").click(function () {
$(".pwdList").show();
});
$(".quxiaoPwd").click(function () {
$(".pwdList").hide();
})
if(edit) $(".editList").show();
})
</script>
<style>
.editList {
position: fixed;
width: 400px;
height: 420px;
left: 50%;
top: 50%;
margin-left: -200px;
margin-top: -210px;
z-index: 3;
background: #fff;
border-radius: 10px;
box-shadow: 0px 6px 8px 6px #ccc;
display: flex;
flex-direction: row;
flex-wrap: wrap;
padding: 30px;
display: none;
}
.editList form {
width: 100%;
}
.edit a, .changePwd,.charge a{
cursor: pointer;
}
.charge {
text-align: right;
margin-top: 5px;
}
.pwdList {
position: fixed;
width: 400px;
height: 320px;
left: 50%;
top: 50%;
margin-left: -200px;
margin-top: -160px;
z-index: 3;
background: #fff;
border-radius: 10px;
box-shadow: 0px 6px 8px 6px #ccc;
display: flex;
flex-direction: row;
flex-wrap: wrap;
padding: 30px;
display: none;
}
.pwdList form {
width: 100%;
}
.chargeList {
position: fixed;
width: 400px;
height: 320px;
left: 50%;
top: 50%;
margin-left: -200px;
margin-top: -160px;
z-index: 3;
background: #fff;
border-radius: 10px;
box-shadow: 0px 6px 8px 6px #ccc;
display: flex;
flex-direction: row;
flex-wrap: wrap;
padding: 30px;
display: none;
}
.chargeList form {
width: 100%;
}
</style>
<div class="editList">
<form asp-action="UpdateInfo" asp-controller="User" method="post">
<div class="form-group">
<label>QQ号</label>
<input type="text" class="form-control" placeholder="" name="QQ" value="@Model.UserModel.QQ">
</div>
<div class="form-group">
<label>微信号:</label>
<input type="text" class="form-control" placeholder="" name="Wx" value="@Model.UserModel.Wx">
</div>
<div class="form-group">
<label>淘宝会员号:</label>
<input type="text" class="form-control" placeholder="" name="TaoBao" value="@Model.UserModel.TaoBao">
</div>
<div class="form-group">
<label>邮箱:</label>
<input type="text" class="form-control" placeholder="" name="Email" value="@Model.UserModel.Email">
</div>
<p class="text-center">
<button type="submit" class="btn btn-primary">提交</button>
<button type="reset" class="btn btn-danger quxiao" style="margin-left:20px;">取消</button>
</p>
</form>
</div>
<div class="pwdList">
<form id="pwdForm">
<div class="form-group">
<label>原密码:</label>
<input type="text" class="form-control" placeholder="" name="OldPwd">
</div>
<div class="form-group">
<label>新密码:</label>
<input type="text" class="form-control" placeholder="" name="NewPwd">
</div>
<div class="form-group">
<label>确认新密码:</label>
<input type="text" class="form-control" placeholder="" name="ConfirmPwd">
</div>
<p class="text-center">
<button type="button" class="btn btn-primary" onclick="updatePwd()">提交</button>
<button type="reset" class="btn btn-danger quxiaoPwd" style="margin-left:20px;">取消</button>
</p>
</form>
</div>
@*充值*@
<div class="chargeList">
<form>
<div class="form-group">
<label>充值金额:</label>
<input type="number" id="orderAmount" class="form-control" placeholder="" value="100">
</div>
<div class="form-group">
</div>
<div class="form-group">
<label>支付方式:</label>
<input type="radio" name="PayChannel" value="50" checked> <img src="~/img/zfb.png">支付宝支付
<input type="radio" name="PayChannel" value="30"> <img src="~/img/wx.png">微信支付
</div>
<p class="text-center">
<button type="button" class="btn btn-primary" onclick="charge()">充值</button>
<button type="button" class="btn btn-danger quxiao" style="margin-left:20px;" onclick="$('.chargeList').hide()">取消</button>
</p>
</form>
</div>
<div class="row">
<div class="col-lg-5">
<div class="zhanghu">
<div class="accout_tit"><span class="lineBar"></span>账户信息</div>
<p class="edit"><a>编辑</a></p>
<div class="row">
<div class="col-lg-6 accoutLeft">
<div class="row">
<div class="col-lg-4 text-center">
<img src="~/img/bandPhone.png">
</div>
<div class="col-lg-8 xinxi">
<div class="item">
手机号/用户名:
</div>
<div class="item myPhone">
@(Model.UserModel.Phone??Model.UserModel.LoginCode)
</div>
<div class="item">
密码:
</div>
<div class="item myPwd">
<span>********</span>
@*<img src="~/img/closePwd.png">*@
</div>
<div class="item text-right">
<img src="~/img/fix.png"><a class="changePwd">修改密码</a>
</div>
</div>
</div>
</div>
<div class="col-lg-6">
<div class="xinxi2">
<div class="item">
QQ号<span>@(Model.UserModel.QQ??"--")</span>
</div>
<div class="item">
微信号:<span>@(Model.UserModel.Wx??"--")</span>
</div>
<div class="item">
淘宝会员名:<span>@(Model.UserModel.TaoBao??"--")</span>
</div>
<div class="item">
邮箱:<span>@(Model.UserModel.Email??"--")</span>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="col-lg-3">
<div class="zhanghu">
<div class="accout_tit"><span class="lineBar"></span>余额</div>
<p class="charge" onclick="$('.chargeList').show()" style="font-size:25px;"><a>充值</a></p>
<div class="money" style="padding: 20px 30px;">¥<span>@Model.UserModel.RestAmount</span></div>
<p class="grayText text-center">可通过淘宝充值,或联系管理员充值</p>
</div>
</div>
<div class="col-lg-4">
<div class="zhanghu">
<div class="accout_tit"><span class="lineBar"></span>PPTP账号</div>
<div class="row">
<div class="col-lg-6">
<div class="useCon">
<p><span>@(Model.AccountModel.TotalCount-Model.AccountModel.ExpriedCount)</span></p>
<p>使用中</p>
</div>
</div>
<div class="col-lg-6">
<div class="zhanghao">
<div class="item">
@Model.AccountModel.TotalCount
</div>
<div class="item">
总个数
</div>
<div class="item">
@Model.AccountModel.ExpriedCount
</div>
<div class="item">
已过期
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-7">
<div class="zhanghu2">
<div class="accout_tit"><span class="lineBar"></span>消费信息</div>
<div class="row xiaofeiArea">
<div class="col-lg-8">
<div class="xiaofei">
<div class="item x1">
<p>@Model.Statistic.TodayExpend</p>
<p>今日消费</p>
</div>
<div class="item x2">
<p>@Model.Statistic.TodayRefund</p>
<p>今日退款</p>
</div>
<div class="item x3">
<p>@Model.Statistic.TodayCharege</p>
<p>今日充值</p>
</div>
<div class="item x1">
<p>@Model.Statistic.MonthExpend</p>
<p>当月消费</p>
</div>
<div class="item x2">
<p>@Model.Statistic.MonthRefund</p>
<p>当月退款</p>
</div>
<div class="item x3">
<p>@Model.Statistic.MonthCharege</p>
<p>当月充值</p>
</div>
</div>
</div>
<div class="col-lg-4">
<div class="bennian">
<div class="bennianxiaofei">
<p>@Model.Statistic.YearExpend</p>
<p>本年消费</p>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="col-lg-5">
<div class="zhanghu2">
<div class="accout_tit"><span class="lineBar"></span>聚IP头条</div>
<ul class="toutiao">
@foreach (var item in Model.TopNewsModel)
{
<li><a asp-action="info" asp-controller="article" asp-route-id="@item.Id">@item.Title</a><span class="newTIme">@item.CreateTime.ToString("yyyy.MM.dd")</span></li>
}
</ul>
</div>
</div>
</div>
<!-- 支付弹窗开始 -->
<div class="payMask">
<div class="payCon">
<img src="~/img/close.png" class="payClose" onclick="$('.payMask').hide()">
<p class="payTit"><img src="~/img/wx.png">微信支付 收银台</p>
<div class="row">
<div class="col-lg-6 text-center">
<p>
<div id="qrcode" style="width:200px;height:200px"></div>
</p>
</div>
<div class="col-lg-6 text-left leftBorder">
<p>充值订单</p>
<p class="payPrice">¥<span id="orderAmountRet"></span></p>
<p>收款方聚IP</p>
<p>下单时间:<span id="orderTime"></span></p>
<p>订单号:<span id="OrderNo"></span></p>
</div>
</div>
</div>
</div>
<!-- 支付弹窗结束 -->
<div id="aliPayBox" style="display:none"></div>
<script>
/** 表单序列化成json字符串的方法 */
function form2JsonString(formId) {
var paramArray = $('#' + formId).serializeArray();
var jsonObj = {};
$(paramArray).each(function () {
jsonObj[this.name] = this.value;
});
console.log(jsonObj);
return JSON.stringify(jsonObj);
}
function updatePwd() {
$.ajax({
type: 'POST',
url: '/user/UpdatePwd',
dataType: "json",
contentType: "application/json",
data: form2JsonString("pwdForm"),
success: function (res) {
console.log(res);
if (res.Code == 10000) {
$(".pwdList").hide();
} else {
alert(res.Message)
}
}
});
}
function payCallback(data) {
var orderInfo= data.OrderInfo;
if (orderInfo.PayChannel == 30) {
$(".payMask").show();
$('#qrcode').empty();
$('#qrcode').qrcode(data.PayData);
$('#orderAmountRet').text(orderInfo.PaymentAmount);
$('#orderTime').text(orderInfo.CreateTime);
$('#OrderNo').text(orderInfo.OrderNo);
} else if (orderInfo.PayChannel == 50) {
$("#aliPayBox").html(data.PayData);
}
}
function isPay(orderNo) {
var that = this;
var payHandler = setInterval(function () {
var url = '/user/IsPay?orderNo=' + orderNo;
$.ajax({
type: 'GET',
url: url,
success: function (res) {
if (res.Code == 10000 && res.Data == 1) {
clearInterval(payHandler);
window.location.reload();
}
}
})
}, 3000)
}
function charge() {
var chargeData = {
ChargeAmount: $('#orderAmount').val(),
PayChannel: $('input[name="PayChannel"]:checked').val()
}
$.ajax({
type: 'POST',
url: '/user/CreateOrder',
dataType: "json",
contentType: "application/json",
data: JSON.stringify(chargeData),
success: function (res) {
console.log(res);
if (res.Code == 10000) {
payCallback(res.Data)
isPay(res.Data.OrderInfo.OrderNo);
} else {
alert(res.Message);
}
}
});
}
</script>

View File

@@ -0,0 +1,15 @@
@{
ViewData["Title"] = "登录";
}
@section Scripts{
<script type="text/javascript">
loginCallback = function () {
window.location.href="/"
}
$(".mask").show();
$(".main").show();
$(".main").addClass("animated bounceInDown");
</script>
}

View File

@@ -0,0 +1,693 @@
@using Hncore.Infrastructure.Data
@using Hncore.Pass.Vpn.Domain
@using Hncore.Infrastructure.Extension
@using ViewComponents
@model List<ProductAccountEntity>
@{
Layout = "_UserLayout";
}
<script>
$(function () {
$('#myTabs a').click(function (e) {
e.preventDefault()
$(this).tab('show')
});
//$(".edit").click(function () {
// $(".editList").show();
//});
$(".quxiao").click(function () {
$(".editList").hide();
});
$(".laozhanghao").click(function () {
$(".zhanghaoCon").show();
});
$(".btnClose").click(function () {
$(".zhanghaoCon").hide();
})
})
</script>
<style>
.zhanghaoCon {
position: fixed;
width: 400px;
height: 455px;
left: 50%;
top: 50%;
margin-left: -200px;
margin-top: -220px;
z-index: 3;
background: #fff;
border-radius: 10px;
box-shadow: 0px 6px 8px 6px #ccc;
display: flex;
flex-direction: row;
flex-wrap: wrap;
padding: 30px;
display: none;
}
.online {
position: fixed;
left: 300px;
width: 950px;
height: 700px;
top: 100px;
z-index: 3;
background: #fff;
border-radius: 10px;
box-shadow: 0px 6px 8px 6px #ccc;
padding: 30px;
overflow-y: auto;
}
.editList {
position: fixed;
width: 400px;
height: 240px;
left: 50%;
top: 50%;
margin-left: -200px;
margin-top: -120px;
z-index: 3;
background: #fff;
border-radius: 10px;
box-shadow: 0px 6px 8px 6px #ccc;
display: flex;
flex-direction: row;
flex-wrap: wrap;
padding: 30px;
display: none;
}
.editList form, .zhanghaoCon form, .tab-content {
width: 100%;
}
.activetit {
border-bottom: 1px solid #3157ad !important;
}
.nav-tabs > li.active > a, .nav-tabs > li.active > a:focus, .nav-tabs > li.active > a:hover {
border: none;
}
.btnClose {
width: 20px;
height: 20px;
position: absolute;
top: 10px;
right: 10px;
}
.btnOnlineClose {
width: 20px;
height: 20px;
position: absolute;
top: 10px;
right: 10px;
}
form .row {
height: 60px;
line-height: 60px;
}
form .row input {
height: 35px;
}
form .row select {
width: 160px;
height: 35px;
}
.btnClose {
cursor: pointer;
}
input[type=checkbox] {
width: 17px;
height: 17px;
}
.blueT{
cursor:pointer;
}
[v-cloak] {
display: none;
}
</style>
<div id="app">
<div class="zhanghaoCon">
<img src="~/img/close.png" class="btnClose" />
<!-- Nav tabs -->
<ul class="nav nav-tabs" role="tablist" style="margin-top:20px;border-bottom:none;">
<li role="presentation" class="activetit"><a href="#home" aria-controls="home" role="tab" data-toggle="tab">单个认证</a></li>
<li role="presentation"><a href="#profile" aria-controls="profile" role="tab" data-toggle="tab">批量认证</a></li>
</ul>
<!-- Tab panes -->
<div class="tab-content" style="margin-top:40px;">
<div role="tabpanel" class="tab-pane active" id="home">
<form>
<div class="row">
<div class="col-lg-3">选择产品:</div>
<div class="col-lg-9">
<select v-model="oneAuthModel.ProductId">
<option v-for="item in productWithPackage" :value="item.Product.Id">{{item.Product.Name}}</option>
</select>
</div>
</div>
<div class="row">
<div class="col-lg-3">输入账号:</div>
<div class="col-lg-9">
<input type="text" v-model="oneAuthModel.Account" />
</div>
</div>
<div class="row">
<div class="col-lg-3">验证密码:</div>
<div class="col-lg-9">
<input type="text" v-model="oneAuthModel.Pwd" />
</div>
</div>
<p v-if="oneAuthLoading" class="text-center" style="margin:8px;color:red;">认证中,请耐心等待...</p>
<p class="text-center" style="margin-top:20px"><button type="button" class="btn btn-primary" v-on:click="accountOneAuth">认证账号</button></p>
</form>
</div>
<div role="tabpanel" class="tab-pane" id="profile">
<form>
<div class="row">
<div class="col-lg-3">选择产品:</div>
<div class="col-lg-9">
<select v-model="mutilAuthModel.ProductId">
<option v-for="item in productWithPackage" :value="item.Product.Id">{{item.Product.Name}}</option>
</select>
</div>
</div>
<div class="row">
<div class="col-lg-3">账号前缀:</div>
<div class="col-lg-9">
<input type="text" v-model="mutilAuthModel.Account" />
</div>
</div>
<div class="row">
<div class="col-lg-3">开始数:</div>
<div class="col-lg-9">
<input type="number" v-model="mutilAuthModel.StartNum" />
</div>
</div>
<div class="row">
<div class="col-lg-3">认证个数:</div>
<div class="col-lg-9">
<input type="number" v-model="mutilAuthModel.Count" />
</div>
</div>
<div class="row">
<div class="col-lg-3">验证密码:</div>
<div class="col-lg-9">
<input type="text" v-model="mutilAuthModel.Pwd" />
</div>
</div>
<p v-if="mutilAuthLoading" class="text-center" style="margin:8px;color:red;">认证中,请耐心等待...</p>
<p class="text-center" style="margin-top:20px"><button type="button" class="btn btn-primary" v-on:click="accountMutilAuth">认证账号</button></p>
</form>
</div>
</div>
</div>
<div class="online" v-cloak v-if="showOnline">
<img src="~/img/close.png" class="btnOnlineClose" v-on:click="closeOnline()" />
<div class="tab-content" style="margin-top:40px;">
<table class="table table-striped table_person">
<tr>
<th>序号</th>
<th>账号</th>
<th>登录时间</th>
<th>在线时间</th>
<th>服务器Ip</th>
<th>登录ip</th>
<th>上行</th>
<th>下行</th>
<th>操作</th>
</tr>
<tr v-for="(item,index) in onLineData">
<td>#{{index+1}}</td>
<td>{{item.Account}}</td>
<td>{{item.LoginTime}}</td>
<td>{{item.OnlineTime}}</td>
<td>{{item.ServerIP}}</td>
<td>{{item.LoginIP}}</td>
<td>{{item.UpStream}}</td>
<td>{{item.DownStream}}</td>
<td class="blueT" @@click="killout(item)"> 强制离线</td>
</tr>
</table>
</div>
</div>
<div class="editList">
<form>
<div class="form-group">
<label>账户:</label>
<input type="text" class="form-control" placeholder="" v-model="UpdateAccountModel.Account">
</div>
<div class="form-group">
<label>新密码:</label>
<input type="text" class="form-control" placeholder="" v-model="UpdateAccountModel.Pwd">
</div>
<p class="text-center"><button type="button" class="btn btn-primary" v-on:click="UpdateAccountPwd">提交</button><button type="reset" class="btn btn-danger quxiao" style="margin-left:20px;">取消</button></p>
</form>
</div>
<p class="wanshan"><img src="~/img/smile.png"> 为了给您带来更好的服务体验请完善qq号和微信号。<a class="edit" asp-action="index" asp-controller="user" asp-route-e="1">立即完善》</a></p>
<div class="toolsBar">
<div class="item">
<div class="btn-group">
<select v-model="searchModel.ExpiredDay" style="height:35px;">
<option>剩余时间</option>
<option :value="-1">全部</option>
<option :value="0">过期</option>
<option :value="1">1天</option>
<option :value="3">3天</option>
<option :value="7">一周</option>
</select>
</div>
</div>
<div class="item">
<div class="row">
<div class='col-sm-6'>
<div class="form-group">
<!--指定 date标记-->
<div class='input-group date' id='datetimepicker1'>
<input type='text' class="form-control" v-model="searchModel.BTime" placeholder="到期开始时间" id="BTime" />
<span class="input-group-addon">
<span class="glyphicon glyphicon-calendar"></span>
</span>
</div>
</div>
</div>
<div class='col-sm-6'>
<div class="form-group">
<!--指定 date标记-->
<div class='input-group date' id='datetimepicker2'>
<input type='text' class="form-control" placeholder="到期结束时间" v-model="searchModel.ETime" id="ETime" />
<span class="input-group-addon">
<span class="glyphicon glyphicon-calendar"></span>
</span>
</div>
</div>
</div>
</div>
</div>
<div class="item">
<div class="btn-group">
<select v-model="searchModel.ProductId" style="height:35px;">
<option value="0">全部产品</option>
<option v-for="item in productWithPackage" :value="item.Product.Id">{{item.Product.Name}}</option>
</select>
</div>
</div>
<div class="item">
<div class="btn-group">
<select v-model="searchModel.PackageId" style="height:35px;">
<option value="0">全部套餐</option>
<option v-for="item in packages" :value="item.Id">{{item.Name}}</option>
</select>
</div>
</div>
<div class="item">
<input type="text" v-model="searchModel.Keyword" placeholder="账号" class="bianhao" />
<button type="button" class="btn btn-primary" v-on:click="search">查询</button>
</div>
</div>
<div class="row xufeiBar">
<div class="col-lg-6 text-left xuTui">
<button type="button" class="btn btn-danger btn-rebuy"><img src="~/img/xufei.png"> 续费</button> <button type="button" class="btn btn-primary btn-refund"><img src="~/img/tui.png"> 退货</button><a style="color:red">&nbsp;*非本系统开通账号无法退款,请联系客服处理</a>
</div>
<div class="col-lg-6 text-right">
<button type="button" class="btn btn-primary laozhanghao"><img src="~/img/renzheng_gray.png"> 老账号认证</button>
</div>
</div>
<table class="table table-striped table_person">
<tr>
<th><input type="checkbox" name="" id="checkAll" value="" /></th>
<th>开通时间</th>
<th>产品</th>
<th>套餐</th>
<th>账号</th>
<th>密码</th>
<th>连接数</th>
<th>到期时间</th>
<th>剩余时间</th>
<th>在线及踢线</th>
<th>服务器</th>
<th>软件下载</th>
</tr>
@foreach (var item in Model)
{
<tr>
<td><input type="checkbox" class="selectAccount" value="@item.Account" a-pid="@(item.ProductId)" a-connectCount="@item.ConnectCount" a-aType="@item.AccountType" /></td>
<td>@item.CreateTime.ToString("yyyy.MM.dd")</td>
<td>@item.ProductName</td>
<td>@item.PackageName</td>
<td>@item.Account</td>
<td>@item.Pwd <img src="~/img/change.png" class="change" v-on:click="showAccountBox(@item.Id,'@item.Account','@item.Pwd')" /></td>
<td>@item.ConnectCount</td>
<td>@item.EndTime.Value.ToString("yyyy.MM.dd")</td>
<td class="redT">@(item.Status==AccountStatus.Refund?"已退货": item.RestTime)</td>
@*<td class="greenT">查看</td>*@
<td class="blueT"><a @@click="online(@item.ProductId,'@item.Account')">查看</a> </td>
<td class="blueT"><a asp-action="Index" asp-controller="LineList" asp-route-ProductId="@item.ProductId" target="_blank">查看</a> </td>
<td class="blueT"> <a asp-action="soft" asp-controller="product" target="_blank">下载</a></td>
</tr>
}
</table>
@*<div class="fenye">
@await Component.InvokeAsync("Pager", new PagerModel() { Total = Model.RowCount, PageIndex = this.Context.Request.GetInt("PageIndex") })
</div>*@
</div>
<script type="text/javascript">
var app = new Vue({
el: '#app',
data: {
productWithPackage: [],
packages: [],
mutilAuthLoading: false,
oneAuthLoading: false,
showOnline: false,
searchModel: {
ExpiredDay:-1,
ProductId:@this.Context.Request.GetInt("ProductId"),
PackageId:@this.Context.Request.GetInt("PackageId"),
Keyword:'@this.Context.Request.Get("Keyword")',
BTime: '@this.Context.Request.Get("BTime")',
ETime: '@this.Context.Request.Get("ETime")',
},
oneAuthModel: {
ProductId: 0,
Account: "",
Pwd:""
},
mutilAuthModel: {
ProductId: 0,
Account: "",
Pwd: "",
StartNum: 0,
Count:0
},
UpdateAccountModel: {
ProductId:0,
UserId:0,
Account: "",
Pwd:""
},
onLineData:[]
},
computed: {
},
watch: {
'searchModel.ProductId': { //加引号监听对象里的属性
handler: function (newValue, oldValue) {
for (var i = 0; i < this.productWithPackage.length; i++) {
var item = this.productWithPackage[i];
if (item.Product.Id == newValue) {
this.packages = item.Packages
return;
}
}
},
immediate: true
}
},
created: function () {
},
mounted: function () {
this.getProducts();
},
methods: {
initPackages: function () {
var productId = this.searchModel.ProductId;
if (productId == 0) return;
for (var i = 0; i < this.productWithPackage.length; i++) {
var item = this.productWithPackage[i];
if (item.Product.Id == productId) {
this.packages = item.Packages
return;
}
}
},
getProducts() {
var that = this;
$.ajax({
type: 'GET',
url: '/api/course/v1/product/ProductWithPackage',
success: function (res) {
if (res.Code == 10000) {
that.productWithPackage = res.Data;
that.initPackages();
}
}
});
},
search() {
var ps = [];
this.searchModel.BTime = $("#BTime").val();
this.searchModel.ETime = $("#ETime").val();
for (var item in this.searchModel) {
var p = item + "=" + this.searchModel[item];
ps.push(p);
}
window.location.href = "?" + ps.join("&");
},
showAccountBox(id,account,pwd) {
$(".editList").show();
this.UpdateAccountModel.Id = id;
this.UpdateAccountModel.Account = account;
this.UpdateAccountModel.Pwd = pwd;
},
UpdateAccountPwd(){
$.ajax({
type: 'POST',
url: '/user/UpdateAccountPwd',
dataType: "json",
contentType: "application/json",
data: JSON.stringify(this.UpdateAccountModel),
success: function (res) {
console.log(res);
if (res.Code == 10000) {
window.location.reload();
} else {
alert(res.Message)
}
}
});
},
accountOneAuth() {
if (this.oneAuthModel.ProductId ==0) {
alert('请选择产品')
return;
}
if (this.oneAuthModel.Account == '' || this.oneAuthModel.Pwd == '') {
alert('账号和密码不能为空')
return;
}
var that = this;
if (this.oneAuthLoading) return
this.oneAuthLoading = true;
$.ajax({
type: 'POST',
url: '/user/OrginAccountAuth',
dataType: "json",
contentType: "application/json",
data: JSON.stringify(this.oneAuthModel),
success: function (res) {
that.oneAuthLoading = false;
console.log(res);
if (res.Code == 10000) {
alert('认证成功')
window.location.reload();
} else {
alert(res.Message)
}
}
});
},
accountMutilAuth() {
if (this.mutilAuthModel.ProductId == 0) {
alert('请选择产品')
return;
}
if (this.mutilAuthModel.Account == '' || this.mutilAuthModel.Pwd == '') {
alert('账号和密码不能为空')
return;
}
if (this.mutilAuthLoading) return;
this.mutilAuthLoading = true;
var that = this;
$.ajax({
type: 'POST',
url: '/user/OrginAccountAuth',
dataType: "json",
contentType: "application/json",
data: JSON.stringify(this.mutilAuthModel),
success: function (res) {
that.mutilAuthLoading = false;
console.log(res);
if (res.Code == 10000) {
alert('认证成功')
window.location.reload();
} else {
alert(res.Message)
}
}
});
},
online(productId, account) {
this.showOnline = true
var that = this;
$.ajax({
type: 'GET',
url: '/api/course/v1/productaccount/OnLine?productId=' + productId + '&account=' + account,
success: function (res) {
if (res.Code == 10000) {
that.onLineData = res.Data;
for (var i = 0; i < that.onLineData.length; i++) {
that.onLineData[i].ProductId = productId;
}
}
}
});
},
closeOnline() {
this.showOnline = false;
this.onLineData = [];
},
killout: function (item) {
var that = this;
$.ajax({
type: 'GET',
url: '/api/course/v1/productaccount/KillOut?productId=' + item.ProductId + '&id=' + item.Id,
success: function (res) {
if (res.Code == 10000) {
alert("操作成功");
that.online(item.ProductId, item.Account)
}
}
});
}
}
})
$(function () {
var picker1 = $('#datetimepicker1').datetimepicker({
format: 'YYYY-MM-DD',
locale: moment.locale('zh-cn'),
//minDate: '2016-7-1'
});
var picker2 = $('#datetimepicker2').datetimepicker({
format: 'YYYY-MM-DD',
locale: moment.locale('zh-cn')
});
//动态设置最小值
picker1.on('dp.change', function (e) {
picker2.data('DateTimePicker').minDate(e.date);
});
//动态设置最大值
picker2.on('dp.change', function (e) {
picker1.data('DateTimePicker').maxDate(e.date);
});
//退款
function caclRefund(account,refundFun) {
$.ajax({
type: 'GET',
url: '/api/course/v1/order/CaclRefund?account=' + account,
success: function (res) {
if (res.Code == 10000) {
var msg = res.Data.info +",确定要退款吗?"
//var msg ="剩余:"+res.Data.RefundRestTime+",还需退款:"+ res.Data.RefundAmount+",确定要退款吗?"
if (!confirm(msg)) { return; }
refundFun(account);
} else {
alert(res.Message)
}
}
});
}
function refund(account) {
$.ajax({
type: 'GET',
url: '/api/course/v1/order/Refund?account=' +account,
success: function (res) {
if (res.Code == 10000) {
alert('退款成功')
window.location.reload()
} else {
alert(res.Message)
}
}
});
}
$(".btn-refund").on('click', function () {
var accounts = [];
$.each($('input:checkbox:checked'), function () {
accounts.push($(this).val())
});
if (accounts.length >1) { alert('一次只能退款一个账号'); return; }
if (accounts.length == 0) { alert('请选择账号'); return; }
caclRefund(accounts[0],refund)
})
function isSame(data, property) {
if (data.length == 0) return true;
var first = data[0];
for (var i = 1; i < data.length; i++) {
var item = data[i];
if (first[property] != item[property])
return false;
}
return true;
}
//续费
$(".btn-rebuy").on('click', function () {
var accounts = [];
var accountModels = [];
var isTest = false
$.each($('input:checkbox:checked'), function () {
var account = $(this).val();
if (account) {
var accountItem = {
account: account,
pid: $(this).attr('a-pid'),
connectCount: $(this).attr('a-connectCount'),
isTest: $(this).attr('a-aType')==200
}
accountModels.push(accountItem)
accounts.push($(this).val())
if (accountItem.isTest) isTest = true;
}
});
if (accountModels.length == 0) { alert('请选择账号'); return; }
if (!isSame(accountModels, 'pid')) { alert('必须选择相同的产品'); return; }
if (!isSame(accountModels, 'connectCount')) { alert('必须选择相同的连接数'); return; }
if (isTest) { alert('测试账号暂不支持续费,请新开正式账号'); return; }
window.location.href = "/product/rebuyindex?productId=" + accountModels[0].pid + "&accounts=" + accounts.join(",");
})
$("#checkAll").on('click', function () {
console.log($(this).prop("checked"),"check")
$("td > input:checkbox").prop("checked", $(this).prop("checked"))
})
});
</script>

View File

@@ -0,0 +1,53 @@
@using Hncore.Pass.Sells.Model
@model List<UserCouponModel>
@{
Layout = "_UserLayout";
}
@foreach (var item in Model)
{
<div class="col-lg-3">
<div class="quan">
@if (item.Coupon.CouponType == ECouponType.Discount)
{
<span class="couponPrice">@(item.Coupon.CouponValue)折</span><span class="couponName">@item.Coupon.Name</span>
}
@if (item.Coupon.CouponType == ECouponType.Minus)
{
<div class="item">
¥<span class="couponPrice">@(item.Coupon.CouponValue)</span><span class="couponName">@item.Coupon.Name</span>
</div>
}
<div class="item">
使用规则:@(item.Coupon.AllowMinAmount > 0 ? $"满{item.Coupon.AllowMinAmount}元可用" : "无限制")
</div>
<div class="item">
有效时间:@(item.Orgin.StartTime.Value.ToString("yyyy.MM.dd"))-@(item.Orgin.EndTime.Value.ToString("yyyy.MM.dd"))
</div>
<div class="item">
获得途径: @item.Orgin.Remark
</div>
<div class="item">
@(item.IsUsed?"已使用":"未使用")
</div>
</div>
</div>
}
@*<div class="col-lg-3">
<div class="quan gray">
<div class="item">
¥<span class="couponPrice">3</span><span class="couponName">优惠券名称</span>
</div>
<div class="item">
使用规则:无限制
</div>
<div class="item">
有效时间:<span>2020.1.1-2020.2.3</span>
</div>
<div class="item">
获得途径;淘宝下单赠送
</div>
<div class="item">
已使用
</div>
</div>
</div>*@

View File

@@ -0,0 +1,234 @@
@using Hncore.Infrastructure.Data
@using Hncore.Pass.Vpn.Domain
@using Hncore.Infrastructure.Extension
@using ViewComponents
@model PageData<ProductOrderEntity>
@{
Layout = "_UserLayout";
Func<string, string> cut = word =>
{
if (word.Length > 15)
return word.Substring(0, 15) + "...";
return word;
};
}
<style>
.tipBox {
position: absolute;
padding:10px;
border: 1px solid #ccc;
background: #fff;
width: 260px;
min-height:100px;
white-space: normal;
word-break: break-all;
word-wrap: break-word;
display: none;
}
</style>
<form asp-action="myorders" asp-controller="user" method="get">
<div class="toolsBar" id="app">
<div class="item">
日期筛选:
</div>
<div class="item">
<div class="row">
<div class='col-sm-6'>
<div class="form-group">
<!--指定 date标记-->
<div class='input-group date' id='datetimepicker1'>
<input type='text' class="form-control" v-model="searchModel.BTime" placeholder="选择开始时间" id="BTime" />
<span class="input-group-addon">
<span class="glyphicon glyphicon-calendar"></span>
</span>
</div>
</div>
</div>
<div class='col-sm-6'>
<div class="form-group">
<!--指定 date标记-->
<div class='input-group date' id='datetimepicker2'>
<input type='text' class="form-control" v-model="searchModel.ETime" placeholder="选择结束时间" id="ETime" />
<span class="input-group-addon">
<span class="glyphicon glyphicon-calendar"></span>
</span>
</div>
</div>
</div>
</div>
</div>
<div class="item">
<div class="btn-group">
<select v-model="searchModel.OrderType" style="height:35px;">
<option value="0">全部类型</option>
<option value="1">新开</option>
<option value="2">续费</option>
<option value="3">批量新开</option>
<option value="4">批量续费</option>
</select>
</div>
</div>
<div class="item">
<div class="btn-group">
<select v-model="searchModel.ProductId" style="height:35px;">
<option value="0">全部产品</option>
<option v-for="item in productWithPackage" :value="item.Product.Id">{{item.Product.Name}}</option>
</select>
</div>
</div>
<div class="item">
<div class="btn-group">
<select v-model="searchModel.PackageId" style="height:35px;">
<option value="0">全部套餐</option>
<option v-for="item in packages" :value="item.Id">{{item.Name}}</option>
</select>
</div>
</div>
<div class="item">
<input type="text" v-model="searchModel.KeyWord" placeholder="订单编号" class="bianhao" /><button type="button" class="btn btn-primary" v-on:click="search">查询</button>
</div>
</div>
</form>
<table class="table table-striped table_person">
<tr>
<th>日期</th>
<th>订单编号</th>
<th>类型</th>
<th>产品</th>
<th>套餐</th>
<th>单价</th>
<th>总连接数</th>
<th>账号</th>
<th>订单金额</th>
<th>优惠券</th>
<th>实付金额</th>
</tr>
@foreach (var item in Model.List)
{
<tr>
<td>@item.CreateTime.ToString("yyyy.MM.dd")</td>
<td>@item.OrderNo</td>
<td>@item.OrderType.GetEnumDisplayName()</td>
<td>@item.ProductName</td>
<td>@item.PackageName</td>
<td>@item.DayPrice</td>
<td>@(item.ConnectCount*item.AccountCount)</td>
<td class="@(item.Accounts.Length>15?"cutTip":"")">
@cut(item.Accounts)
<div class="tipBox">@item.Accounts</div>
</td>
<td>@item.OrderAmount</td>
<td>@item.CouponAmount</td>
<td>@item.PaymentAmount</td>
</tr>
}
</table>
<div class="fenye">
@await Component.InvokeAsync("Pager", new PagerModel() { Total = Model.RowCount, PageIndex = this.Context.Request.GetInt("PageIndex") })
</div>
<script type="text/javascript">
$(function () {
var picker1 = $('#datetimepicker1').datetimepicker({
format: 'YYYY-MM-DD',
locale: moment.locale('zh-cn'),
//minDate: '2016-7-1'
});
var picker2 = $('#datetimepicker2').datetimepicker({
format: 'YYYY-MM-DD',
locale: moment.locale('zh-cn')
});
//动态设置最小值
picker1.on('dp.change', function (e) {
picker2.data('DateTimePicker').minDate(e.date);
});
//动态设置最大值
picker2.on('dp.change', function (e) {
picker1.data('DateTimePicker').maxDate(e.date);
});
$(".cutTip").mouseover(function () {
$(this).children().last().show();
}).mouseleave(function () {
$(this).children().last().hide();
})
});</script>
<script type="text/javascript">
var app = new Vue({
el: '#app',
data: {
productWithPackage: [],
packages: [],
searchModel: {
OrderType:0,
ProductId:@this.Context.Request.GetInt("ProductId"),
PackageId:@this.Context.Request.GetInt("PackageId"),
KeyWord:'',
BTime: '@this.Context.Request.Get("BTime")',
ETime: '@this.Context.Request.Get("ETime")',
},
oneAuthModel: {
ProductId: 0,
Account: "",
Pwd:""
},
mutilAuthModel: {
ProductId: 0,
Account: "",
Pwd: "",
StartNum: 0,
Count:0
}
},
computed: {
},
watch: {
'searchModel.ProductId': { //加引号监听对象里的属性
handler: function (newValue, oldValue) {
for (var i = 0; i < this.productWithPackage.length; i++) {
var item = this.productWithPackage[i];
if (item.Product.Id == newValue) {
this.packages = item.Packages
return;
}
}
},
immediate: true
}
},
created: function () {
this.getProducts();
},
methods: {
getProducts() {
var that = this;
$.ajax({
type: 'GET',
url: '/api/course/v1/product/ProductWithPackage',
success: function (res) {
if (res.Code == 10000) {
that.productWithPackage = res.Data;
}
}
});
},
search() {
var ps = [];
this.searchModel.BTime = $("#BTime").val();
this.searchModel.ETime = $("#ETime").val();
for (var item in this.searchModel) {
var p = item + "=" + this.searchModel[item];
ps.push(p);
}
window.location.href = "?" + ps.join("&");
},
}
})
</script>

View File

@@ -0,0 +1,195 @@
@using Hncore.Infrastructure.Data
@using Hncore.Pass.Vpn.Domain
@using Hncore.Infrastructure.Extension
@using ViewComponents
@model PageData<ProductOrderEntity>
@{
Layout = "_UserLayout";
}
<div class="toolsBar" id="app">
<div class="item">
日期:
</div>
<div class="item">
<div class="row">
<div class='col-sm-6'>
<div class="form-group">
<!--指定 date标记-->
<div class='input-group date' id='datetimepicker1'>
<input type='text' class="form-control" name="BTime" v-model="searchModel.BTime" placeholder="选择开始时间" id="BTime" />
<span class="input-group-addon">
<span class="glyphicon glyphicon-calendar"></span>
</span>
</div>
</div>
</div>
<div class='col-sm-6'>
<div class="form-group">
<!--指定 date标记-->
<div class='input-group date' id='datetimepicker2'>
<input type='text' class="form-control" name="ETime" v-model="searchModel.ETime" placeholder="选择结束时间" id="ETime" />
<span class="input-group-addon">
<span class="glyphicon glyphicon-calendar"></span>
</span>
</div>
</div>
</div>
</div>
</div>
<div class="item">
<div class="btn-group">
<select v-model="searchModel.ProductId" style="height:35px;">
<option value="0" selected >全部产品</option>
<option v-for="item in productWithPackage" :value="item.Product.Id">{{item.Product.Name}}</option>
</select>
</div>
</div>
<div class="item">
<div class="btn-group">
<select v-model="searchModel.PackageId" style="height:35px;">
<option value="0">全部套餐</option>
<option v-for="item in packages" :value="item.Id">{{item.Name}}</option>
</select>
</div>
</div>
<div class="item">
<input type="text" v-model="searchModel.KewWord" placeholder="订单编号" class="bianhao" />
<button type="button" class="btn btn-primary" v-on:click="search">查询</button>
</div>
</div>
<table class="table table-striped table_person">
<tr>
<th>日期</th>
<th>订单编号</th>
<th>类型</th>
<th>产品</th>
<th>套餐</th>
<th>账号</th>
<th>连接数</th>
<th>退款时长</th>
<th>退款单价</th>
<th>退款金额</th>
</tr>
@foreach (var item in Model.List)
{
<tr>
<td>@item.CreateTime.ToString("yyyy.MM.dd")</td>
<td>@item.OrderNo</td>
<td>@item.OrderType.GetEnumDisplayName()</td>
<td>@item.ProductName</td>
<td>@item.PackageName</td>
<td>@item.Accounts</td>
<td>@item.ConnectCount</td>
<td>@item.DayCount</td>
<td>@item.DayPrice</td>
<td>@item.RefundAmount</td>
</tr>
}
</table>
<div class="fenye">
@await Component.InvokeAsync("Pager", new PagerModel() { Total = Model.RowCount, PageIndex = this.Context.Request.GetInt("PageIndex") })
</div>
<script type="text/javascript">
var app = new Vue({
el: '#app',
data: {
productWithPackage: [],
packages: [],
searchModel: {
ProductId:@this.Context.Request.GetInt("ProductId"),
PackageId:@this.Context.Request.GetInt("PackageId"),
Keyword:'',
BTime: '',
ETime: ''
}
},
computed: {
},
watch: {
'searchModel.ProductId': { //加引号监听对象里的属性
handler: function (newValue, oldValue) {
for (var i = 0; i < this.productWithPackage.length; i++) {
var item = this.productWithPackage[i];
if (item.Product.Id == newValue) {
this.packages = item.Packages
return;
}
}
},
immediate: true
}
},
created: function () {
this.getProducts();
},
methods: {
selectFn: function (e) {
console.log(e.target.value) // 选择项的value
},
getProducts() {
var that = this;
$.ajax({
type: 'GET',
url: '/api/course/v1/product/ProductWithPackage',
success: function (res) {
if (res.Code == 10000) {
that.productWithPackage = res.Data;
}
}
});
},
search() {
var ps = [];
this.searchModel.BTime = $("#BTime").val();
this.searchModel.ETime = $("#ETime").val();
for (var item in this.searchModel) {
var p = item + "=" + this.searchModel[item];
ps.push(p);
}
window.location.href = "?" + ps.join("&");
}
}
})
$(function () {
var picker1 = $('#datetimepicker1').datetimepicker({
format: 'YYYY-MM-DD',
locale: moment.locale('zh-cn'),
//minDate: '2016-7-1'
});
var picker2 = $('#datetimepicker2').datetimepicker({
format: 'YYYY-MM-DD',
locale: moment.locale('zh-cn')
});
//动态设置最小值
picker1.on('dp.change', function (e) {
picker2.data('DateTimePicker').minDate(e.date);
});
//动态设置最大值
picker2.on('dp.change', function (e) {
picker1.data('DateTimePicker').maxDate(e.date);
});
//退款
$(".btn-refund").on('click', function () {
var accounts = [];
$.each($('input:checkbox:checked'), function () {
accounts.push($(this).val())
});
if (accounts.length == 0) { alert('请选择账号'); return; }
$.ajax({
type: 'GET',
url: '/api/course/v1/order/Refund?account=' + accounts[0],
success: function (res) {
if (res.Code == 10000) {
alert('退款成功')
} else {
alert(res.Message)
}
}
});
})
});
</script>

Some files were not shown because too many files have changed in this diff Show More