using CommonUtil;
using EasyCaching.Core;
using Link.DbModel;
using Link.DTOModel;
using Link.IService;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
namespace Link.Api.Controllers
{
///
///
///
public class IndexController : BaseController
{
///
/// 短链接口
///
private readonly ILkLinkService _lkLinkService;
///
/// 短链访问记录接口
///
private readonly ILkAccessHistoryService _lkAccessHistoryService;
///
/// 短链访问统计接口
///
private readonly ILkAccessStatisticService _lkAccessStatisticService;
///
/// 缓存容器
///
private readonly IEasyCachingProvider _provider;
///
/// 构造函数
///
///
///
///
///
public IndexController(IEasyCachingProvider provider, ILkLinkService lkLkinkService, ILkAccessHistoryService lkAccessHistoryService, ILkAccessStatisticService lkAccessStatisticService)
{
_provider = provider;
_lkLinkService = lkLkinkService;
_lkAccessHistoryService = lkAccessHistoryService;
_lkAccessStatisticService = lkAccessStatisticService;
}
///
///
///
///
///
[HttpGet("/{id}")]
[ProducesResponseType((int)HttpStatusCode.Redirect)]
[ProducesResponseType((int)HttpStatusCode.NotFound)]
public IActionResult Index([Required]string id)
{
string mobEncry = "";//加密手机号
if (id.Length > 7)
{
try
{
mobEncry = id.Substring(id.Length - 7, 7);
mobEncry = MobileDecry(mobEncry);
}
catch
{
}
id = id.Substring(0, id.Length - 7);
}
if (id == "favicon.ico")
{
return NotFound();
}
LkLink link = null;
var linkCache = _provider.Get($"LINK_{id}");
if (!linkCache.HasValue)
{
//var where = ExpressionUtil.Create().And(j => j.Key == id)
// .And(j => j.ExpireTime >= DateTime.Now)
// .ToExpression();
var where = ExpressionUtil.Create().And(j => j.Key == id)
.ToExpression();
link = _lkLinkService.GetFirst(where);
}
else
{
link = linkCache.Value;
}
if (link.IsNull())
{
return NotFound();
}
//if (link.IsNull() || link.ExpireTime < DateTime.Now)
//{
// return NotFound();
//}
var result = _lkAccessStatisticService.UseTran(() =>
{
string ip = GetClientIp();
DateTime minTime = DateTime.Now.Date;
DateTime maxTime = minTime.AddHours(23).AddMinutes(59).AddSeconds(59);
var historyWhere = ExpressionUtil.Create().And(j => j.Key == id)
.And(j => j.CreateTime >= minTime)
.And(j => j.CreateTime <= maxTime)
.And(j => j.Ip == ip)
.ToExpression();
var statistic = _lkAccessStatisticService.GetFirst(j => j.Key == id);
if (!statistic.IsNull())
{
StringBuilder updateSql = new StringBuilder();
updateSql.Append($"UPDATE lk_access_statistic SET pv=pv+1,update_time=NOW() ");
bool isExist = _lkAccessHistoryService.IsExist(historyWhere);
if (!isExist)
{
updateSql.Append($",uv=uv+1 ");
}
updateSql.Append($" WHERE id={statistic.Id};");
//更新访问统计
_lkAccessStatisticService.ExecuteCommand(updateSql.ToString());
}
UserAgentDTO agent = GetUserAgent();
var history = new LkAccessHistory
{
CreateTime = DateTime.Now,
Ip = ip,
Key = id,
EquipmentCode = agent.EquipmentCode,
EquipmentName = agent.EquipmentName,
Nick = link.Nick,
Mob = mobEncry
};
//插入访问历史
_lkAccessHistoryService.Insert(history);
});
return Redirect(link.OriginUrl);
}
///
/// 获取远程客户端IP
///
///
private string GetClientIp()
{
if (Request.Headers.ContainsKey("X-Forwarded-For"))
{
return Request.Headers["X-Forwarded-For"].ToString();
}
string ip = Request.HttpContext.Connection.RemoteIpAddress.ToString();
return ip == "::1" ? "127.0.0.1" : ip;
}
///
/// 获取请求设备信息
///
///
private UserAgentDTO GetUserAgent()
{
UserAgentDTO agentInfo = new UserAgentDTO();
if (Request.Headers.ContainsKey("User-Agent"))
{
string agent = Request.Headers["User-Agent"].ToString();
CommonUtil.LogUtil.Info(agent, "Agent");
Dictionary agentList = GetAgentList();
foreach (var item in agentList)
{
Regex rx = new Regex(item.Value, RegexOptions.Compiled | RegexOptions.IgnoreCase);
MatchCollection match = rx.Matches(agent);
if (match.Count > 0)
{
agentInfo.EquipmentCode = item.Key.Split('|')[0];
agentInfo.EquipmentName = item.Key.Split('|')[1];
return agentInfo;
}
}
}
agentInfo.EquipmentCode = "other";
agentInfo.EquipmentName = "其他";
return agentInfo;
}
private Dictionary GetAgentList()
{
Dictionary dic = new Dictionary();
dic.Add("mi|小米", "/*mi.*Build/QKQ1");
dic.Add("huawei|华为", "/*HUAWEI");
dic.Add("iphone|苹果", "/*iPhone");
dic.Add("windows|WindowsPC", "/*Windows");
dic.Add("samsung|三星", "/*Android.*SM.*Build/QP1A");
return dic;
}
///
/// 解密
///
///
///
private string MobileDecry(string s)
{
s = s.Replace("_", "/").Replace("-", "+").PadRight((s.Length + 3) / 4 * 4, '=');
byte[] bytes = Convert.FromBase64String(s).Reverse().Concat(new byte[8]).Take(8).ToArray();
string re = BitConverter.ToInt64(bytes, 0).ToString();
return re.Length == 11 ? re : s;
}
}
}