网站首页 网站源码
website
站点相关全部源代码,隐藏了一些关于服务器的信息
using Dpz.Core.Public.Entity.Option;
using Dpz.Core.Public.ViewModel.Option;

namespace Dpz.Core.Service.RepositoryServiceImpl;

public class AppOptionService : IAppOptionService
{
    private readonly IRepository<AppOption> _repository;
    private readonly IHybridCachingProvider _cachingProvider;
    private readonly IMapper _mapper;

    /// <summary>
    /// 友情链接 Option name
    /// </summary>
    private const string FriendOptionName = "friends";

    /// <summary>
    /// 页脚内容 Option name
    /// </summary>
    private const string FooterContentOptionName = "footer";

    /// <summary>
    /// 账号锁定 Option name
    /// </summary>
    private const string AccountLockOptionName = "AccountLoginFailLock";

    public AppOptionService(
        IRepository<AppOption> repository, 
        IHybridCachingProvider cachingProvider,
        IMapper mapper)
    {
        _repository = repository;
        _cachingProvider = cachingProvider;
        _mapper = mapper;
    }

    public async Task<IList<VmFriends>> GetFriendsAsync()
    {
        var friends = await _repository.SearchFor(x => x.OptionName == FriendOptionName).ToListAsync();
        if (friends == null || !friends.Any())
            return new List<VmFriends>();
        var list = friends.Cast<Friends>().ToList();
        return _mapper.Map<List<VmFriends>>(list);
    }

    public async Task AddFriendAsync(VmFriends friend)
    {
        //var entity = new AppOption {Option = friend, Name = "friends"};
        var entity = _mapper.Map<Friends>(friend);
        entity.CreateTime = DateTime.Now;
        entity.LastUpdateTime = DateTime.Now;
        entity.OptionName = FriendOptionName;
        await _repository.InsertAsync(entity);
    }


    public async Task EditFriendAsync(VmFriends? friend)
    {
        if (string.IsNullOrEmpty(friend?.Id) || !ObjectId.TryParse(friend.Id, out var oid)) return;
        var entity = await _repository.FindAsync(oid);
        if (entity == null || entity is not Friends entityFriend) return;
        entityFriend.Avatar = friend.Avatar;
        entityFriend.Description = friend.Description;
        entityFriend.Link = friend.Link;
        entityFriend.Name = friend.Name;
        entityFriend.LastUpdateTime = DateTime.Now;
        await _repository.UpdateAsync(entityFriend);
    }

    public async Task<VmAppOption?> FindAsync(string id)
    {
        var entity = await _repository.TryGetAsync(id);
        if (entity == null) return null;
        return _mapper.Map<VmAppOption>(entity);
    }

    public async Task<VmSaltOption> GetSaltAsync(string account)
    {
        var entity = await _repository.Collection.Aggregate()
            .Match(new BsonDocument {{"OptionName", "AccountSalt"}})
            .Match(new BsonDocument {{"Account", account}})
            .Match(new BsonDocument
            {
                {
                    "Expire", new BsonDocument
                    {
                        {"$gt", BsonDateTime.Create(DateTime.Now)}
                    }
                }
            }).FirstOrDefaultAsync();
        if (entity is SaltOption saltOption)
        {
            return _mapper.Map<VmSaltOption>(saltOption);
        }

        var salt = Guid.NewGuid().ToString("N");
        var saltEntity = new SaltOption
        {
            Account = account,
            CreateTime = DateTime.Now,
            Expire = DateTime.Now.AddDays(7),
            LastUpdateTime = DateTime.Now,
            OptionName = "AccountSalt",
            Salt = salt
        };

        await _repository.InsertAsync(saltEntity);
        return _mapper.Map<VmSaltOption>(saltEntity);
    }

    public async Task SaveFooterContentAsync(string content)
    {
        await _cachingProvider.SetAsync(CacheKey.FooterKey, content, TimeSpan.FromDays(30));

        var footer = await _repository.SearchFor(x => x.OptionName == FooterContentOptionName).FirstOrDefaultAsync();
        if (footer != null)
        {
            var set = new BsonDocument
            {
                {
                    "$set", new BsonDocument
                    {
                        {"Content", new BsonString(content)},
                        {"LastUpdateTime", new BsonDateTime(DateTime.Now)}
                    }
                }
            };
            UpdateDefinition<AppOption> update = new BsonDocumentUpdateDefinition<AppOption>(set);
            await _repository.UpdateAsync(x => x.Id == footer.Id, update);
            return;
        }

        var entity = new FooterContent
        {
            Content = content,
            CreateTime = DateTime.Now,
            LastUpdateTime = DateTime.Now,
            OptionName = FooterContentOptionName
        };
        await _repository.InsertAsync(entity);
    }

    public async Task<string> GetFooterContentAsync()
    {
        var footer = await _repository.SearchFor(x => x.OptionName == FooterContentOptionName).FirstOrDefaultAsync();
        return footer is FooterContent entity ? entity.Content : "";
    }

    public async Task LoginFailAsync(string account)
    {
        if (await _repository.Collection.Aggregate()
                .Match(new BsonDocument {{"OptionName", AccountLockOptionName}})
                .Match(new BsonDocument {{"Account", account}})
                .FirstOrDefaultAsync() is AccountLock accountLock)
        {
            // 如果锁定时间过期,那么重置
            if (accountLock.Expired.HasValue && DateTime.Now > accountLock.Expired.Value.ToLocalTime())
            {
                accountLock.Expired = null;
                accountLock.AttemptNumber = 1;
                accountLock.LastUpdateTime = DateTime.Now;
                await _repository.UpdateAsync(accountLock);
                return;
            }

            // 上次操作超过间隔时间,那么重置尝试次数
            if (DateTime.Now > accountLock.LastUpdateTime.ToLocalTime().AddHours(1))
            {
                accountLock.AttemptNumber = 1;
            }
            // 没有超过间隔时间,尝试次数累加
            else
            {
                accountLock.AttemptNumber++;
            }

            accountLock.LastUpdateTime = DateTime.Now;
            // 超过尝试次数,则锁定,设定锁定时间
            if (accountLock.AttemptNumber > 3)
            {
                accountLock.Expired = DateTime.Now.AddDays(1);
            }

            await _repository.UpdateAsync(accountLock);
            return;
        }

        var entity = new AccountLock
        {
            Account = account,
            AttemptNumber = 1,
            CreateTime = DateTime.Now,
            LastUpdateTime = DateTime.Now,
            OptionName = AccountLockOptionName
        };
        await _repository.InsertAsync(entity);
    }

    public async Task LoginSuccessfulAsync(string account)
    {
        if (await _repository.Collection.Aggregate()
                .Match(new BsonDocument {{"OptionName", AccountLockOptionName}})
                .Match(new BsonDocument {{"Account", account}})
                .FirstOrDefaultAsync() is AccountLock accountLock)
        {
            accountLock.AttemptNumber = 0;
            accountLock.Expired = null;
            accountLock.LastUpdateTime = DateTime.Now;
            await _repository.UpdateAsync(accountLock);
        }
    }

    public async Task<bool> IsAccountLockAsync(string account)
    {
        var entity = await _repository.Collection.Aggregate()
            .Match(new BsonDocument {{"OptionName", AccountLockOptionName}})
            .Match(new BsonDocument {{"Account", account}})
            .FirstOrDefaultAsync();
        return entity is AccountLock {Expired: { }} accountLock &&
               accountLock.Expired.Value.ToLocalTime() > DateTime.Now;
    }


    private const string SettingOptionName = "Application.Setting";

    public async Task<VmSetting?> GetSettingAsync()
    {
        var option = await _repository.SearchFor(x => x.OptionName == SettingOptionName).SingleOrDefaultAsync();
        if (option is Setting setting)
        {
            return _mapper.Map<VmSetting>(setting);
        }

        return null;
    }

    public async Task SaveSettingAsync(VmSetting setting)
    {
        await _cachingProvider.SetAsync(CacheKey.AppSettingKey, setting, TimeSpan.FromDays(7));

        var option = await _repository.SearchFor(x => x.OptionName == SettingOptionName).SingleOrDefaultAsync();
        if (option is Setting entitySetting)
        {
            entitySetting.Api = setting.Api;
            entitySetting.Cdn = setting.Cdn;
            entitySetting.Core = setting.Core;
            entitySetting.Image = setting.Image;
            entitySetting.Job = setting.Job;
            entitySetting.Main = setting.Main;
            entitySetting.Message = setting.Message;
            entitySetting.Script = setting.Script;
            entitySetting.Static = setting.Static;
            entitySetting.LastUpdateTime = DateTime.Now;
            await _repository.UpdateAsync(entitySetting);
            return;
        }

        var entity = _mapper.Map<Setting>(setting);
        entity.OptionName = SettingOptionName;
        entity.CreateTime = DateTime.Now;
        entity.LastUpdateTime = DateTime.Now;

        await _repository.InsertAsync(entity);
    }


    public async Task DeleteAsync(string id)
    {
        if (ObjectId.TryParse(id, out var oid))
        {
            await _repository.DeleteAsync(oid);
        }
    }
}
loading