using JNPF.Common.Const;
using JNPF.Common.Dtos.OAuth;
using JNPF.Common.Enums;
using JNPF.Common.Extension;
using JNPF.Common.Net;
using JNPF.Common.Options;
using JNPF.Common.Security;
using JNPF.DataEncryption;
using JNPF.DependencyInjection;
using JNPF.DynamicApiController;
using JNPF.Extras.DatabaseAccessor.SqlSugar.Models;
using JNPF.FriendlyException;
using JNPF.Logging.Attributes;
using JNPF.Message.Entitys.Entity;
using JNPF.Message.Interfaces.Message;
using JNPF.RemoteRequest.Extensions;
using JNPF.Systems.Entitys.Permission;
using JNPF.Systems.Interfaces.System;
using JNPF.UnifyResult;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using SqlSugar;
namespace JNPF.Message.Service;
///
/// 公众号.
/// 版 本:V3.2
/// 版 权:拓通智联科技有限公司(http://www.tuotong-tech.com)
/// 日 期:2021-06-01.
///
[ApiDescriptionSettings(Tag = "Message", Name = "ShortLink", Order = 240)]
[Route("api/message/[controller]")]
public class ShortLinkService : IShortLinkService, IDynamicApiController, ITransient
{
private readonly ISqlSugarRepository _repository;
private readonly ISysConfigService _sysConfigService;
private readonly ConnectionStringsOptions _connectionStrings;
private readonly TenantOptions _tenant;
private readonly MessageOptions _messageOptions = App.GetConfig("Message", true);
private SqlSugarScope _sqlSugarClient;
public ShortLinkService(
ISqlSugarRepository repository,
ISysConfigService sysConfigService,
IOptions connectionOptions,
IOptions tenantOptions,
ISqlSugarClient sqlSugarClient
)
{
_repository = repository;
_sysConfigService = sysConfigService;
_connectionStrings = connectionOptions.Value;
_tenant = tenantOptions.Value;
_sqlSugarClient = (SqlSugarScope)sqlSugarClient;
}
///
/// 新建.
///
/// 实体对象.
///
[HttpGet("{shortLink}")]
[HttpGet("{shortLink}/{tenantId}")]
[AllowAnonymous]
[IgnoreLog]
public async Task GetInfo(string shortLink, string tenantId)
{
ConnectionConfigOptions options = JNPFTenantExtensions.GetLinkToOrdinary(_connectionStrings.ConfigId, _connectionStrings.DBName);
UserAgent userAgent = new UserAgent(App.HttpContext);
if (tenantId.IsNotEmptyOrNull())
{
var interFace = string.Format("{0}{1}", _tenant.MultiTenancyDBInterFace, tenantId);
var response = await interFace.GetAsStringAsync();
var result = response.ToObject>();
if (result.code != 200)
{
throw Oops.Oh(result.msg);
}
else if (result.data.dotnet == null && result.data.linkList == null)
{
throw Oops.Oh(ErrorCode.D1025);
}
else
{
if (result.data.linkList == null || result.data.linkList?.Count == 0)
{
options = JNPFTenantExtensions.GetLinkToOrdinary(tenantId, result.data.dotnet);
}
else if (result.data.dotnet == null)
{
options = JNPFTenantExtensions.GetLinkToCustom(tenantId, result.data.linkList);
}
}
if (!"default".Equals(tenantId) && _tenant.MultiTenancyType.Equals("COLUMN"))
{
_sqlSugarClient.QueryFilter.AddTableFilter(it => it.TenantId == tenantId);
}
else
{
_sqlSugarClient.AddConnection(JNPFTenantExtensions.GetConfig(options));
_sqlSugarClient.ChangeDatabase(tenantId);
}
}
var entity = await _sqlSugarClient.Queryable().SingleAsync(x => x.ShortLink == shortLink && x.DeleteMark == null);
if (entity == null) throw Oops.Oh(ErrorCode.D7009);
// 验证失效以及修改点击次数
if (entity.IsUsed == 1)
{
if (entity.UnableTime < DateTime.Now || entity.ClickNum == entity.UnableNum) throw Oops.Oh(ErrorCode.D7010);
++entity.ClickNum;
await _repository.AsUpdateable(entity).IgnoreColumns(ignoreAllNullColumns: true).CallEntityMethod(m => m.LastModify()).ExecuteCommandHasChangeAsync();
}
string accessToken = CreateToken(entity.UserId);
// 验证请求端
var urlLink = userAgent.IsMobileDevice ? entity.RealAppLink : entity.RealPcLink;
urlLink = string.Format("{0}&token={1}", urlLink, accessToken);
App.HttpContext.Response.Redirect(urlLink);
}
///
/// 新建.
///
/// 实体对象.
///
[NonAction]
public async Task Create(string userId, string bodyText)
{
var sysconfig = await _sysConfigService.GetInfo();
var entity = new MessageShortLinkEntity();
entity.ShortLink = RandomExtensions.NextLetterAndNumberString(new Random(), 6);
entity.UserId = userId;
if (sysconfig.isClick == 1)
{
entity.IsUsed = 1;
entity.ClickNum = 0;
entity.UnableNum = sysconfig.unClickNum;
entity.UnableTime = DateTime.Now.AddHours(sysconfig.linkTime);
}
entity.BodyText = bodyText;
entity.RealAppLink = string.Format("{0}/pages/workFlow/flowBefore/index?config={1}", _messageOptions.DoMainApp, bodyText.ToBase64String());
entity.RealPcLink = string.Format("{0}/workFlowDetail?config={1}", _messageOptions.DoMainPc, bodyText.ToBase64String());
return await _repository.AsInsertable(entity).IgnoreColumns(ignoreNullColumn: true).CallEntityMethod(m => m.Create()).ExecuteReturnEntityAsync();
}
public string CreateToken(string userId)
{
ConnectionConfigOptions options = JNPFTenantExtensions.GetLinkToOrdinary(_connectionStrings.ConfigId, _connectionStrings.DBName);
var userEntity = _sqlSugarClient.Queryable().Single(u => u.Id == userId && u.DeleteMark == null);
var token = JWTEncryption.Encrypt(
new Dictionary
{
{ ClaimConst.CLAINMUSERID, userEntity.Id },
{ ClaimConst.CLAINMACCOUNT, userEntity.Account },
{ ClaimConst.CLAINMREALNAME, userEntity.RealName },
{ ClaimConst.CLAINMADMINISTRATOR, userEntity.IsAdministrator },
{ ClaimConst.TENANTID, options.ConfigId },
{ ClaimConst.CONNECTIONCONFIG, options},
{ ClaimConst.SINGLELOGIN, 1 }
}, 900);
return string.Format("Bearer%20{0}", token);
}
}