You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
311 lines
10 KiB
311 lines
10 KiB
using System.Threading.Tasks;
|
|
using System.Threading;
|
|
using AIK.DataAccess;
|
|
using AIK.Models;
|
|
using AIK.Models.SQLiteModels;
|
|
using AIK.Service.IService;
|
|
using Dapper;
|
|
using System.Data.SQLite;
|
|
using Microsoft.Extensions.Logging;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Security.AccessControl;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using System.Windows.Media.Imaging;
|
|
|
|
namespace AIK.Service.Service
|
|
{
|
|
public class VehDataService : IVehDataService
|
|
{
|
|
private readonly IDataCacheService _cacheService;
|
|
private readonly ICarfactoryService _apiService;
|
|
private readonly IConfigurationService _configurationService;
|
|
|
|
private readonly TimeSpan _cacheExpiry = TimeSpan.FromHours(3);//默认3个小时有效期
|
|
private readonly ILogger<VehDataService> _logger;
|
|
|
|
private string GetCacheKey(int id) => $"{DbCore.CacheModelKey}_{id}";
|
|
|
|
private string GetCacheVehModelKey(int id) => $"{DbCore.CacheVehModelKey}_{id}";
|
|
|
|
public VehDataService(IDataCacheService cacheService, ICarfactoryService apiService, ILogger<VehDataService> logger, IConfigurationService configurationService)
|
|
{
|
|
_cacheService = cacheService;
|
|
_apiService = apiService;
|
|
_logger = logger;
|
|
_configurationService = configurationService;
|
|
_cacheExpiry = TimeSpan.FromHours(_configurationService.CacheSettings.DataCacheExpiryHours);
|
|
}
|
|
#region 获取品牌详情
|
|
public async Task<List<CarfactoryClass>> GetVehDataAsync(string vhetype, bool forceRefresh = false)
|
|
{
|
|
if (forceRefresh)
|
|
{
|
|
await _cacheService.RemoveAsync(DbCore.CacheKey);
|
|
}
|
|
|
|
var result = await _cacheService.GetOrCreateAsync<List<CarfactoryClass>>(
|
|
key: DbCore.CacheKey,
|
|
dataFetchFunc: () => GetVehDataFromApiAsync(vhetype),
|
|
expiry: _cacheExpiry
|
|
);
|
|
|
|
return result ?? new List<CarfactoryClass>();
|
|
}
|
|
|
|
public async Task<List<CarfactoryClass>> GetVehDataFromApiAsync(string vhetype)
|
|
{
|
|
try
|
|
{
|
|
// 调用第三方API获取数据
|
|
var data = await _apiService.GetCarfactoryClassListAsync(vhetype);
|
|
|
|
//// 可以在这里添加数据验证和转换逻辑
|
|
//if (data != null && data.Count > 0)
|
|
//{
|
|
// return data;
|
|
//}
|
|
return data;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
// 记录日志
|
|
//System.Diagnostics.Debug.WriteLine($"API调用失败: {ex.Message}");
|
|
_logger.LogError("执行方法:{Method},API调用失败:{Message}", nameof(GetVehDataFromApiAsync), ex.Message);
|
|
throw new Exception($"获取品牌数据失败: {ex.Message}");
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region 帮助方法
|
|
public async Task<bool> IsCacheValidAsync()
|
|
{
|
|
return await _cacheService.ExistsAsync(DbCore.CacheKey);
|
|
}
|
|
|
|
public async Task ClearCacheAsync()
|
|
{
|
|
await _cacheService.RemoveAsync(DbCore.CacheKey);
|
|
}
|
|
|
|
public async Task<CacheInfo> GetCacheInfoAsync()
|
|
{
|
|
var exists = await _cacheService.ExistsAsync(DbCore.CacheKey);
|
|
if (!exists)
|
|
{
|
|
return new CacheInfo { IsValid = false };
|
|
}
|
|
|
|
var data = await _cacheService.GetAsync<List<VehModelClass>>(DbCore.CacheKey);
|
|
var stats = await _cacheService.GetCacheStatsAsync();
|
|
var cacheItem = await GetCacheItemAsync(DbCore.CacheKey);
|
|
|
|
return new CacheInfo
|
|
{
|
|
IsValid = true,
|
|
LastUpdateTime = cacheItem?.CreatedAt,
|
|
DataCount = data?.Count ?? 0,
|
|
CacheSize = await _cacheService.GetCacheSizeAsync(),
|
|
TimeToExpire = cacheItem?.ExpiresAt - DateTime.Now
|
|
};
|
|
}
|
|
|
|
private async Task<CacheItem> GetCacheItemAsync(string key)
|
|
{
|
|
var sql = "SELECT * FROM CacheItems WHERE CacheKey = @Key";
|
|
using var connection = new SQLiteConnection($"Data Source={SQLiteCore.DatabasePath}");
|
|
return await connection.QueryFirstOrDefaultAsync<CacheItem>(sql, new { Key = key });
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region 获取钥匙详情
|
|
public async Task<List<VehModelClass>> GetVehKeyDataAsync(int id, bool forceRefresh = false)
|
|
{
|
|
var cacheKey = GetCacheKey(id);
|
|
|
|
if (forceRefresh)
|
|
{
|
|
await _cacheService.RemoveAsync(cacheKey);
|
|
}
|
|
|
|
var result = await _cacheService.GetOrCreateAsync<List<VehModelClass>>(
|
|
key: cacheKey,
|
|
dataFetchFunc: () => GetVehKeyDataFromApiAsync(id),
|
|
expiry: _cacheExpiry
|
|
);
|
|
|
|
return result ?? new List<VehModelClass>();
|
|
}
|
|
|
|
public async Task<List<VehModelClass>> GetVehKeyDataFromApiAsync(int id)
|
|
{
|
|
try
|
|
{
|
|
// 调用第三方API获取数据
|
|
var data = await _apiService.GetVehKeyClassListAsync(id);
|
|
return data;
|
|
//// 可以在这里添加数据验证和转换逻辑
|
|
//if (data != null && data.Count > 0)
|
|
//{
|
|
// return data;
|
|
//}
|
|
|
|
//throw new Exception("API返回数据为空");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
// 记录日志
|
|
_logger.LogError("执行方法:{Method},API调用失败:{Message}", nameof(GetVehDataFromApiAsync), ex.Message);
|
|
throw new Exception($"获取数据失败: {ex.Message}");
|
|
}
|
|
}
|
|
|
|
public async Task<Dictionary<int, List<VehModelClass>>> GetBatchVehKeyDataAsync(List<int> ids, bool forceRefresh = false)
|
|
{
|
|
var results = new Dictionary<int, List<VehModelClass>>();
|
|
var tasks = new List<Task>();
|
|
|
|
foreach (var id in ids)
|
|
{
|
|
var task = GetVehKeyDataAsync(id, forceRefresh).ContinueWith(t =>
|
|
{
|
|
if (t.IsCompleted)
|
|
{
|
|
results[id] = t.Result;
|
|
}
|
|
});
|
|
tasks.Add(task);
|
|
}
|
|
|
|
await Task.WhenAll(tasks);
|
|
return results;
|
|
}
|
|
public async Task ClearVehKeyCacheAsync(int id)
|
|
{
|
|
var cacheKey = GetCacheKey(id);
|
|
await _cacheService.RemoveAsync(cacheKey);
|
|
}
|
|
|
|
public async Task ClearAllVehKeyCacheAsync()
|
|
{
|
|
// 获取所有车辆钥匙相关的缓存键并清除
|
|
var cachedKeys = await GetCachedVehKeyIdsAsync();
|
|
foreach (var id in cachedKeys)
|
|
{
|
|
await ClearVehKeyCacheAsync(id);
|
|
}
|
|
}
|
|
|
|
public async Task<List<int>> GetCachedVehKeyIdsAsync()
|
|
{
|
|
// 获取所有缓存项并解析出ID
|
|
var cacheStats = await _cacheService.GetCacheStatsAsync();
|
|
var ids = new List<int>();
|
|
|
|
foreach (var item in cacheStats)
|
|
{
|
|
if (item.CacheKey.StartsWith(DbCore.CacheModelKey))
|
|
{
|
|
var idPart = item.CacheKey.Substring(DbCore.CacheModelKey.Length + 1); // +1 是为了去掉下划线
|
|
if (int.TryParse(idPart, out int id))
|
|
{
|
|
ids.Add(id);
|
|
}
|
|
}
|
|
}
|
|
|
|
return ids;
|
|
}
|
|
public async Task<Dictionary<int, DateTime>> GetVehKeyCacheInfoAsync()
|
|
{
|
|
var cacheStats = await _cacheService.GetCacheStatsAsync();
|
|
var result = new Dictionary<int, DateTime>();
|
|
|
|
foreach (var item in cacheStats)
|
|
{
|
|
if (item.CacheKey.StartsWith(DbCore.CacheModelKey))
|
|
{
|
|
var idPart = item.CacheKey.Substring(DbCore.CacheModelKey.Length + 1);
|
|
if (int.TryParse(idPart, out int id))
|
|
{
|
|
result[id] = item.LastAccessed;
|
|
}
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
#endregion
|
|
|
|
|
|
public async Task<BitmapImage> GetVehKeyImgAsync(string url, bool forceRefresh = false)
|
|
{
|
|
if (forceRefresh)
|
|
{
|
|
await _cacheService.RemoveAsync(DbCore.CacheKey);
|
|
}
|
|
|
|
var result = await _cacheService.GetOrCreateAsync<BitmapImage>(
|
|
key: DbCore.CacheKey,
|
|
dataFetchFunc: () => GetVehKeyImgDataFromApiAsync(url),
|
|
expiry: _cacheExpiry
|
|
);
|
|
|
|
return result ?? new BitmapImage();
|
|
}
|
|
|
|
public Task<BitmapImage> GetVehKeyImgDataFromApiAsync(string url)
|
|
{
|
|
try
|
|
{
|
|
// 调用第三方API获取数据
|
|
var data = _apiService.GetVehKeyImg(url);
|
|
|
|
// 可以在这里添加数据验证和转换逻辑
|
|
if (data != null)
|
|
{
|
|
return data;
|
|
}
|
|
|
|
throw new Exception("API返回数据为空");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
// 记录日志
|
|
_logger.LogError("执行方法:{Method},API调用失败:{Message}", nameof(GetVehDataFromApiAsync), ex.Message);
|
|
throw new Exception($"获取数据失败: {ex.Message}");
|
|
}
|
|
}
|
|
|
|
#region 获取钥匙详情(拆表版)
|
|
|
|
public async Task<List<VehModelClass>> GetVehKeyDataByIdAsync(int id)
|
|
{
|
|
var cacheKey = GetCacheVehModelKey(id);
|
|
|
|
var result = new List<VehModelClass>();
|
|
var resultCache = await _cacheService.GetSplitVehModelDataAsync(cacheKey);
|
|
|
|
if (resultCache == null)
|
|
{
|
|
var vehKeydataList = await GetVehKeyDataFromApiAsync(id);
|
|
result.AddRange(vehKeydataList);
|
|
foreach (var item in vehKeydataList)
|
|
{
|
|
await _cacheService.SetSplitVehModelDataAsync(cacheKey, item, _cacheExpiry);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
result.AddRange(resultCache);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
}
|
|
|