159 lines
6.6 KiB
C#
159 lines
6.6 KiB
C#
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.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;
|
||
|
||
/// <summary>
|
||
/// 公众号.
|
||
/// 版 本:V3.2
|
||
/// 版 权:拓通智联科技有限公司(http://www.tuotong-tech.com)
|
||
/// 日 期:2021-06-01.
|
||
/// </summary>
|
||
[ApiDescriptionSettings(Tag = "Message", Name = "ShortLink", Order = 240)]
|
||
[Route("api/message/[controller]")]
|
||
public class ShortLinkService : IShortLinkService, IDynamicApiController, ITransient
|
||
{
|
||
private readonly ISqlSugarRepository<MessageShortLinkEntity> _repository;
|
||
private readonly ISysConfigService _sysConfigService;
|
||
private readonly ConnectionStringsOptions _connectionStrings;
|
||
private readonly TenantOptions _tenant;
|
||
private readonly MessageOptions _messageOptions = App.GetConfig<MessageOptions>("Message", true);
|
||
private SqlSugarScope _sqlSugarClient;
|
||
|
||
public ShortLinkService(
|
||
ISqlSugarRepository<MessageShortLinkEntity> repository,
|
||
ISysConfigService sysConfigService,
|
||
IOptions<ConnectionStringsOptions> connectionOptions,
|
||
IOptions<TenantOptions> tenantOptions,
|
||
ISqlSugarClient sqlSugarClient
|
||
)
|
||
{
|
||
_repository = repository;
|
||
_sysConfigService = sysConfigService;
|
||
_connectionStrings = connectionOptions.Value;
|
||
_tenant = tenantOptions.Value;
|
||
_sqlSugarClient = (SqlSugarScope)sqlSugarClient;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 新建.
|
||
/// </summary>
|
||
/// <param name="input">实体对象.</param>
|
||
/// <returns></returns>
|
||
[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<RESTfulResult<TenantInterFaceOutput>>();
|
||
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);
|
||
}
|
||
}
|
||
|
||
_sqlSugarClient.AddConnection(JNPFTenantExtensions.GetConfig(options));
|
||
_sqlSugarClient.ChangeDatabase(tenantId);
|
||
}
|
||
|
||
var entity = await _sqlSugarClient.Queryable<MessageShortLinkEntity>().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);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 新建.
|
||
/// </summary>
|
||
/// <param name="input">实体对象.</param>
|
||
/// <returns></returns>
|
||
[NonAction]
|
||
public async Task<MessageShortLinkEntity> 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<UserEntity>().Single(u => u.Id == userId && u.DeleteMark == null);
|
||
var token = JWTEncryption.Encrypt(
|
||
new Dictionary<string, object>
|
||
{
|
||
{ 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);
|
||
}
|
||
}
|