using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using AutoMapper;
using CommonUtil;
using EasyCaching.Core;
using Link.Api.Models;
using Link.IService;
using Microsoft.AspNetCore.Mvc;
using Link.DbModel;
using Link.Common;
using Newtonsoft.Json.Linq;
namespace Link.Api.Controllers
{
///
///
///
///
[Route("openwize/[controller]/[action]")]
[Route(TopConstants.API_ROUTE, Order = 2)]
public class TopController : BaseController
{
///
/// 短链接口
///
private readonly ILkLinkService _lkLinkService;
///
/// 短链访问记录接口
///
private readonly ILkAccessHistoryService _lkAccessHistoryService;
///
/// 短链访问统计接口
///
private readonly ILkAccessStatisticService _lkAccessStatisticService;
///
/// 映射
///
private readonly IMapper _mapper;
///
/// 缓存容器
///
private readonly IEasyCachingProvider _provider;
///
/// 构造函数
///
///
///
///
///
///
public TopController(IMapper mapper, IEasyCachingProvider provider, ILkLinkService lkLkinkService, ILkAccessHistoryService lkAccessHistoryService, ILkAccessStatisticService lkAccessStatisticService)
{
_mapper = mapper;
_provider = provider;
_lkLinkService = lkLkinkService;
_lkAccessHistoryService = lkAccessHistoryService;
_lkAccessStatisticService = lkAccessStatisticService;
}
///
/// 申请生成短链
///
///
[HttpPost]
[ProducesDefaultResponseType(typeof(TopResponse))]
public IActionResult Execute([FromBody]TopRequest request)
{
TopResponse response = new TopResponse();
string linkKeyName = $"{request.AppName}_{request.Nick}_{request.Url}";
var link = TryGetInMemory(linkKeyName, () =>
{
var existWhere = ExpressionUtil.Create().And(j => j.OriginUrl == request.Url)
.And(j => j.AppName == request.AppName)
.And(j => j.Nick == request.Nick)
.And(j => j.ExpireTime >= DateTime.Now)
.And(j => j.IsDelete == 0)
.ToExpression();
return _lkLinkService.GetFirst(existWhere);
});
if (!link.IsNull() && request.AppName != "mjy")
{
response.Key = link.Key;
response.ShortUrl = link.ShortUrl;
response.ExpireTime = link.ExpireTime;
return Success(response);
}
LkLink linkDTO = new LkLink
{
CreateTime = DateTime.Now,
IsDelete = 0,
OriginUrl = request.Url,
Key = string.Empty,
ShortUrl = string.Empty,
AppName = request.AppName,
Nick = request.Nick,
};
DateTime now = DateTime.Now;
DateTime expireTime = now.AddMonths(1);
var result = _lkLinkService.UseTran(() =>
{
var entity = _lkLinkService.InsertReturnEntity(linkDTO);
string key = LinkUtil.MixValueConvertTo64(entity.Id);
string shortUrl = ConfigUtil.Configuration["ShortUrl"];
shortUrl += $"/{key}";
LkAccessStatistic statistic = new LkAccessStatistic
{
CreateTime = DateTime.Now,
Key = key,
Pv = 0,
Uv = 0,
};
_lkAccessStatisticService.Insert(statistic);
_lkLinkService.Update(j => new LkLink { Key = key, ShortUrl = shortUrl, UpdateTime = now, ExpireTime = expireTime }, j => j.Id == entity.Id);
linkDTO.Key = key;
linkDTO.ShortUrl = shortUrl;
linkDTO.UpdateTime = now;
linkDTO.ExpireTime = expireTime;
response.Key = key;
response.ShortUrl = shortUrl;
response.ExpireTime = expireTime;
});
if (!result.IsSuccess)
{
return Error(result.ErrorMessage);
}
//插入短码缓存
TrySetInMemory(linkDTO, linkDTO.Key, expireTime);
//插入长转短记录缓存
TrySetInMemory(linkDTO, linkKeyName, expireTime);
return Success(response);
}
///
/// 申请生成短链-不验证URL
///
///
[HttpPost]
[ProducesDefaultResponseType(typeof(TopResponse))]
public IActionResult SpExecute([FromBody]SpTopRequest request)
{
TopResponse response = new TopResponse();
string linkKeyName = $"{request.AppName}_{request.Nick}_{request.Url}";
var link = TryGetInMemory(linkKeyName, () =>
{
var existWhere = ExpressionUtil.Create().And(j => j.OriginUrl == request.Url)
.And(j => j.AppName == request.AppName)
.And(j => j.Nick == request.Nick)
.And(j => j.ExpireTime >= DateTime.Now)
.And(j => j.IsDelete == 0)
.ToExpression();
return _lkLinkService.GetFirst(existWhere);
});
if (!link.IsNull() && request.AppName != "mjy")
{
response.Key = link.Key;
response.ShortUrl = link.ShortUrl;
response.ExpireTime = link.ExpireTime;
return Success(response);
}
LkLink linkDTO = new LkLink
{
CreateTime = DateTime.Now,
IsDelete = 0,
OriginUrl = request.Url,
Key = string.Empty,
ShortUrl = string.Empty,
AppName = request.AppName,
Nick = request.Nick,
};
DateTime now = DateTime.Now;
DateTime expireTime = now.AddMonths(1);
var result = _lkLinkService.UseTran(() =>
{
var entity = _lkLinkService.InsertReturnEntity(linkDTO);
string key = LinkUtil.MixValueConvertTo64(entity.Id);
string shortUrl = ConfigUtil.Configuration["ShortUrl"];
shortUrl += $"/{key}";
LkAccessStatistic statistic = new LkAccessStatistic
{
CreateTime = DateTime.Now,
Key = key,
Pv = 0,
Uv = 0,
};
_lkAccessStatisticService.Insert(statistic);
_lkLinkService.Update(j => new LkLink { Key = key, ShortUrl = shortUrl, UpdateTime = now, ExpireTime = expireTime }, j => j.Id == entity.Id);
linkDTO.Key = key;
linkDTO.ShortUrl = shortUrl;
linkDTO.UpdateTime = now;
linkDTO.ExpireTime = expireTime;
response.Key = key;
response.ShortUrl = shortUrl;
response.ExpireTime = expireTime;
});
if (!result.IsSuccess)
{
return Error(result.ErrorMessage);
}
//插入短码缓存
TrySetInMemory(linkDTO, linkDTO.Key, expireTime);
//插入长转短记录缓存
TrySetInMemory(linkDTO, linkKeyName, expireTime);
return Success(response);
}
///
/// 分页查询访问记录
///
///
[HttpPost]
[ProducesDefaultResponseType(typeof(ListPageGetAccessHistoryResponse))]
public IActionResult ListPageGetAccessHistory([FromBody]ListPageGetAccessHistoryRequest request)
{
var response = new ListPageGetAccessHistoryResponse();
var where = ExpressionUtil.Create().And(j => j.Key == request.Key)
.ToExpression();
int totalCount = 0;
response.AccessHistoryList = _lkAccessHistoryService.ListPageGet(j => new AccessHistoryResponse
{
CreateTime = j.CreateTime,
Ip = j.Ip,
EquipmentCode = j.EquipmentCode,
EquipmentName = j.EquipmentName,
Nick = j.Nick
}, where, j => j.CreateTime, DbEnum.OrderType.Desc, request.CurrentPage, request.PageSize, ref totalCount);
return Success(response, request.CurrentPage, request.PageSize, totalCount);
}
///
/// 按创建时间范围查询访问统计
///
///
[HttpPost]
[ProducesDefaultResponseType(typeof(ListGetAccessStatisticRangeResponse))]
public IActionResult ListGetAccessStatisticRange([FromBody]ListGetAccessStatisticRangeRequest request)
{
if (request.MaxCreateTime.HasValue && request.MinCreateTime.HasValue && request.MinCreateTime.Value > request.MaxCreateTime.Value)
{
return Error("时间范围不正确");
}
var response = new ListGetAccessStatisticRangeResponse();
var linkWhere = ExpressionUtil.Create().And(j => j.AppName == request.AppName)
.And(j => j.Nick == request.Nick)
.And(j => j.IsDelete == 0)
.AndIF(request.MinCreateTime.HasValue, j => j.CreateTime >= request.MinCreateTime.Value)
.AndIF(request.MaxCreateTime.HasValue, j => j.CreateTime <= request.MaxCreateTime.Value)
.ToExpression();
var keyList = _lkLinkService.ListGet(j => j.Key, linkWhere);
if (keyList.Count == 0)
{
return Error("时间范围内未生成短码");
}
var statisticWhere = ExpressionUtil.Create().And(j => keyList.Contains(j.Key))
.ToExpression();
response.StatisticList = _lkAccessStatisticService.ListGet(j => new StatisticResponse { Key = j.Key, Pv = j.Pv, Uv = j.Uv }, statisticWhere);
return Success(response);
}
///
/// 指定短码查询访问统计
///
///
[HttpPost]
[ProducesDefaultResponseType(typeof(StatisticResponse))]
public IActionResult GetAccessStatistic([FromBody]GetAccessStatisticRequest request)
{
var result = TryGetInMemory(request.Key, () =>
{
var statisticWhere = ExpressionUtil.Create().And(j => j.Key == request.Key)
.ToExpression();
return _lkAccessStatisticService.GetFirst(statisticWhere);
});
if (result.IsNull())
{
return Error("短码不存在");
}
var response = _mapper.Map(result);
return Success(response);
}
///
/// 尝试从内存中获取,若没有则从委托中获取
///
///
///
///
///
///
private bool TrySetInMemory(T t, string cacheKey, DateTime expireTime)
{
string key = $"LINK_{cacheKey}";
TimeSpan expiration = expireTime.Subtract(DateTime.Now);
_provider.Remove(key);
_provider.Set(key, t, expiration);
return true;
}
///
/// 尝试从内存中获取,若没有则从委托中获取
///
///
///
///
///
private T TryGetInMemory(string cacheKey, Func func)
{
string key = $"LINK_{cacheKey}";
T t = default(T);
if (!_provider.Exists(key))
{
t = func.Invoke();
return t;
}
CacheValue cacheResult = _provider.Get(key);
if (cacheResult.HasValue && !cacheResult.IsNull)
{
LogUtil.Trace($"{key}缓存中:{ cacheResult.Value.ObjectToJson()}");
return cacheResult.Value;
}
t = func.Invoke();
return t;
}
///
/// 根据日期设备统计发送量
///
///
[HttpPost]
[ProducesDefaultResponseType(typeof(List))]
public IActionResult GetEquipmentStatistic([FromBody]GetEquipmentStatisticRequest request)
{
string sql = $"SELECT count(1) as count,equipment_name from lk_access_history where nick='{request.Nick}'";
sql += GetWhere(request);
sql += " GROUP BY equipment_name ";
var st = _lkAccessHistoryService.SqlQuery(sql);
return Success(st);
}
///
/// 根据日期设备统计pvuv
///
///
[HttpPost]
[ProducesDefaultResponseType(typeof(List))]
public IActionResult GePvUvStatistic([FromBody]GetEquipmentStatisticRequest request)
{
string pvuvsql = $"SELECT count(1) as pv,count(DISTINCT(ip)) as uv from lk_access_history where nick='{request.Nick}' { GetWhere(request)} ";
var st = _lkAccessHistoryService.SqlQuery(pvuvsql);
List resarr = JSONUtil.JsonToObject>(JSONUtil.ObjectToJson(st));
GePvUvStatisticResponse res = resarr[0];
string phonecountsql = $"SELECT count(1) as count from lk_access_history where nick='{request.Nick}' { GetWhere(request)} and equipment_code in ('huawei','samsung','iphone','mi') ";
st = _lkAccessHistoryService.SqlQuery(phonecountsql);
res.phoneCount = (JSONUtil.JsonToObject(JSONUtil.ObjectToJson(st)))[0]["count"].ToString();
return Success(res);
}
///
/// 根据时间,key统计pvuv
///
///
[HttpPost]
[ProducesDefaultResponseType(typeof(List))]
public IActionResult GePvUvByKey([FromBody] GePvUvByTimeRequest request)
{
string pvuvsql = $"SELECT count(1) as pv,count(DISTINCT(ip)) as uv from lk_access_history where `key`='{request.Key}' { GetPvUvWhere(request)} ";
var st = _lkAccessHistoryService.SqlQuery(pvuvsql);
List resarr = JSONUtil.JsonToObject>(JSONUtil.ObjectToJson(st));
GePvUvByTimeResponse res = resarr.FirstOrDefault();
StatisticResponse statisticResponse = new StatisticResponse()
{
Key = request.Key,
Pv = res.pv.ToLong(),
Uv = res.uv.ToLong()
};
return Success(statisticResponse);
}
private string GetWhere(GetEquipmentStatisticRequest request)
{
string sql = string.Empty;
if (!request.MinCreateTime.IsNull())
{
sql += $" and create_time>='{((DateTime)request.MinCreateTime).ToString("yyyy-MM-dd HH:mm:ss")}' ";
}
if (!request.MaxCreateTime.IsNull())
{
sql += $" and create_time<='{((DateTime)request.MaxCreateTime).ToString("yyyy-MM-dd HH:mm:ss")}' ";
}
if (!request.Key.IsNullOrEmpty())
{
sql += $" and key='{request.Key}' ";
}
return sql;
}
private string GetPvUvWhere(GePvUvByTimeRequest request)
{
string sql = string.Empty;
if (!request.MinCreateTime.IsNull())
{
sql += $" and create_time>='{((DateTime)request.MinCreateTime).ToString("yyyy-MM-dd HH:mm:ss")}' ";
}
if (!request.MaxCreateTime.IsNull())
{
sql += $" and create_time<='{((DateTime)request.MaxCreateTime).ToString("yyyy-MM-dd HH:mm:ss")}' ";
}
if (!request.Nick.IsNullOrEmpty())
{
sql += $" and nick='{request.Nick}' ";
}
return sql;
}
}
}