using System;
using System.Linq;
using System.Threading.Tasks;
using NCC.Common.Const;
using NCC.Common.Core.Manager;
using NCC.Dependency;
using NCC.Extend.Entitys.lq_user_profile_version;
using NCC.Extend.Interfaces.UserProfileVersion;
using NCC.Extend.Models;
using NCC.System.Entitys.Permission;
using Newtonsoft.Json;
using SqlSugar;
using Yitter.IdGenerator;
namespace NCC.Extend
{
///
/// 用户主档时点全量版本写入(R-004)。
///
public class LqUserProfileVersionAppenderService : IUserProfileVersionAppender, ITransient
{
private static readonly JsonSerializerSettings FullSnapshotJsonSettings = new JsonSerializerSettings
{
NullValueHandling = NullValueHandling.Include,
DateFormatString = "yyyy-MM-dd HH:mm:ss",
DateTimeZoneHandling = DateTimeZoneHandling.Local
};
private readonly ISqlSugarClient _db;
public LqUserProfileVersionAppenderService(ISqlSugarClient db)
{
_db = db;
}
///
public async Task AfterUserProfilePersistedAsync(string targetUserId, string changeTrigger, bool forceNewVersion = false)
{
if (string.IsNullOrWhiteSpace(targetUserId))
{
return;
}
var row = await _db.Queryable()
.Where(x => x.Id == targetUserId)
.FirstAsync();
if (row == null)
{
return;
}
var sanitized = BuildSanitizedUserSnapshot(row);
var fullPayload = new LqUserProfileFullSnapshotDto
{
SchemaVersion = LqUserProfileSnapshotConstants.FullUserSchemaVersion,
User = sanitized
};
var fullJson = JsonConvert.SerializeObject(fullPayload, FullSnapshotJsonSettings);
var lastRows = await _db.Queryable()
.Where(x => x.TargetUserId == targetUserId)
.OrderBy(x => x.VersionNo, OrderByType.Desc)
.Take(1)
.ToListAsync();
var last = lastRows.FirstOrDefault();
if (!forceNewVersion
&& last != null
&& string.Equals(last.FullSnapshotJson ?? string.Empty, fullJson, StringComparison.Ordinal))
{
return;
}
var now = DateTime.Now;
if (last != null)
{
await _db.Updateable()
.SetColumns(x => new LqUserProfileVersionEntity { ValidTo = now })
.Where(x => x.Id == last.Id)
.ExecuteCommandAsync();
}
var (opId, opName) = ResolveOperatorFromClaims();
var ver = new LqUserProfileVersionEntity
{
Id = YitIdHelper.NextId().ToString(),
TargetUserId = row.Id,
VersionNo = (last?.VersionNo ?? 0) + 1,
ValidFrom = now,
ValidTo = null,
OperatorUserId = opId,
OperatorUserName = opName,
ChangeTrigger = changeTrigger,
Mdid = row.Mdid,
Gw = row.Gw,
OrganizeId = row.OrganizeId,
FullSnapshotJson = fullJson
};
await _db.Insertable(ver).ExecuteCommandAsync();
}
private static UserEntity BuildSanitizedUserSnapshot(UserEntity src)
{
var c = UserProfileAuditAppenderService.CloneUser(src);
if (c == null)
{
return null;
}
c.Password = null;
c.Secretkey = null;
return c;
}
private static (string opId, string opName) ResolveOperatorFromClaims()
{
var ctx = App.HttpContext;
if (ctx?.User?.Identity?.IsAuthenticated != true)
{
return (null, "系统");
}
var uid = ctx.User.FindFirst(ClaimConst.CLAINM_USERID)?.Value?.Trim();
var name = ctx.User.FindFirst(ClaimConst.CLAINM_REALNAME)?.Value?.Trim();
if (string.IsNullOrWhiteSpace(name))
{
name = ctx.User.FindFirst(ClaimConst.CLAINM_ACCOUNT)?.Value?.Trim();
}
if (string.IsNullOrWhiteSpace(name))
{
name = "系统";
}
return (uid, name);
}
}
}