增加ImageCache微信 图片缓存
This commit is contained in:
1 parent
d6cb5b966b
commit
d0f9f00b76
15 files changed
+518
-30
No files matched your search
@@ -0,0 +1,172 @@
|
||||
using MAX.Core.DependencyInjection;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Store.ImageCache.Dtos;
|
||||
using Store.ImageCache.Entities;
|
||||
using Store.ImageCache.Mapper;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Store.ImageCache.Services
|
||||
{
|
||||
public class ImageCacheService : ISingletonDependency
|
||||
{
|
||||
private const int Md5Length = 32;
|
||||
private const int PlatformUrlMaxLength = 1000;
|
||||
|
||||
private readonly IFreeSql _freeSql;
|
||||
private ImageCacheMapper mapper;
|
||||
public ImageCacheService([FromKeyedServices("ImageCacheConnection")] IFreeSql freeSql)
|
||||
{
|
||||
mapper = new ImageCacheMapper();
|
||||
if (freeSql == null)
|
||||
{
|
||||
throw new ArgumentNullException("freeSql");
|
||||
}
|
||||
|
||||
_freeSql = freeSql;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 按 MD5 查询图片缓存;platform 为空时返回该 MD5 在所有平台的缓存。
|
||||
/// </summary>
|
||||
public ImageCacheDto GetByMd5(string sourceUrlMd5, byte? platform = null)
|
||||
{
|
||||
var md5 = NormalizeMd5(sourceUrlMd5);
|
||||
return GetByMd5sInternal(new List<string> { md5 }, platform).FirstOrDefault();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 批量按 MD5 查询图片缓存。MD5 会按首字符分组,只查询对应的 images_0 到 images_f 分表。
|
||||
/// </summary>
|
||||
public List<ImageCacheDto> GetByMd5s(IEnumerable<string> sourceUrlMd5s, byte? platform = null)
|
||||
{
|
||||
return GetByMd5sInternal(NormalizeMd5s(sourceUrlMd5s), platform);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 按 MD5 和平台直接修改平台图片 URL,未找到时返回 false。
|
||||
/// </summary>
|
||||
public bool AddOrUpdate(string sourceUrlMd5, byte platform, string platformUrl)
|
||||
{
|
||||
var md5 = NormalizeMd5(sourceUrlMd5);
|
||||
ValidatePlatformUrl(platformUrl);
|
||||
var tableName = GetTableName(md5[0]);
|
||||
var existing = _freeSql.Select<ImageCacheEntity>()
|
||||
.AsTable((type, oldName) => tableName)
|
||||
.Where(a => a.source_url_md5 == sourceUrlMd5 && a.platform == platform)
|
||||
.First();
|
||||
|
||||
var now = DateTime.Now;
|
||||
if (existing != null)
|
||||
{
|
||||
var affected = _freeSql.Update<ImageCacheEntity>()
|
||||
.AsTable(tableName)
|
||||
.Set(a => a.platform_url, platformUrl)
|
||||
.Set(a => a.update_time, now)
|
||||
.Where(a => a.source_url_md5 == md5 && a.platform == platform)
|
||||
.ExecuteAffrows();
|
||||
return affected > 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
ImageCacheEntity imageCache = new ImageCacheEntity();
|
||||
imageCache.id = 0;
|
||||
imageCache.source_url_md5 = md5;
|
||||
imageCache.platform = platform;
|
||||
imageCache.platform_url = platformUrl;
|
||||
imageCache.create_time = now;
|
||||
imageCache.update_time = now;
|
||||
imageCache.id = _freeSql.Insert(imageCache)
|
||||
.AsTable(tableName)
|
||||
.ExecuteIdentity();
|
||||
return imageCache.id > 0;
|
||||
}
|
||||
}
|
||||
|
||||
private List<ImageCacheDto> GetByMd5sInternal(List<string> md5s, byte? platform)
|
||||
{
|
||||
var result = new List<ImageCacheDto>();
|
||||
if (md5s.Count == 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
foreach (var shard in md5s.GroupBy(a => a[0]))
|
||||
{
|
||||
var tableName = GetTableName(shard.Key);
|
||||
var md5sInTable = shard.ToList();
|
||||
var query = _freeSql.Select<ImageCacheEntity>()
|
||||
.AsTable((type, oldName) => tableName)
|
||||
.Where(a => md5sInTable.Contains(a.source_url_md5));
|
||||
|
||||
if (platform.HasValue)
|
||||
{
|
||||
var platformValue = platform.Value;
|
||||
query = query.Where(a => a.platform == platformValue);
|
||||
}
|
||||
result.AddRange(query.ToList().Select(mapper.ToDto));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private List<string> NormalizeMd5s(IEnumerable<string> sourceUrlMd5s)
|
||||
{
|
||||
if (sourceUrlMd5s == null)
|
||||
{
|
||||
throw new ArgumentNullException("sourceUrlMd5s");
|
||||
}
|
||||
|
||||
var result = new List<string>();
|
||||
foreach (var sourceUrlMd5 in sourceUrlMd5s)
|
||||
{
|
||||
var md5 = NormalizeMd5(sourceUrlMd5);
|
||||
if (!result.Contains(md5))
|
||||
{
|
||||
result.Add(md5);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private string NormalizeMd5(string sourceUrlMd5)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(sourceUrlMd5))
|
||||
{
|
||||
throw new ArgumentException("MD5 不能为空", "sourceUrlMd5");
|
||||
}
|
||||
|
||||
var md5 = sourceUrlMd5.Trim().ToLowerInvariant();
|
||||
if (md5.Length != Md5Length || md5.Any(a => !Uri.IsHexDigit(a)))
|
||||
{
|
||||
throw new ArgumentException("MD5 必须是 32 位十六进制字符串", "sourceUrlMd5");
|
||||
}
|
||||
|
||||
return md5;
|
||||
}
|
||||
|
||||
private string GetTableName(char shard)
|
||||
{
|
||||
return "images_" + shard;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void ValidatePlatformUrl(string platformUrl)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(platformUrl))
|
||||
{
|
||||
throw new ArgumentException("平台图片 URL 不能为空", "platformUrl");
|
||||
}
|
||||
|
||||
if (platformUrl.Length > PlatformUrlMaxLength)
|
||||
{
|
||||
throw new ArgumentException("平台图片 URL 长度不能超过 1000", "platformUrl");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user