增加ImageCache微信 图片缓存
This commit is contained in:
1 parent
d6cb5b966b
commit
d0f9f00b76
15 files changed
+518
-30
No files matched your search
@@ -16,37 +16,31 @@ namespace MAX.Framework.Commons
|
||||
{
|
||||
if (context.Result is ObjectResult objResult)
|
||||
{
|
||||
if (!IsAlreadyWrapped(objResult.Value))
|
||||
if (objResult.Value is ApiResultBase)
|
||||
{
|
||||
objResult.StatusCode = 200;
|
||||
objResult.DeclaredType = objResult.Value.GetType();
|
||||
return;
|
||||
}
|
||||
|
||||
// 非成功响应交由状态码中间件处理,避免先包装成业务成功。
|
||||
var statusCode = objResult.StatusCode ?? 200;
|
||||
if (statusCode >= 200 && statusCode < 300)
|
||||
{
|
||||
var apiResult = ApiResult<object>.Ok(objResult.Value);
|
||||
|
||||
objResult.Value = apiResult;
|
||||
objResult.DeclaredType = null;
|
||||
objResult.StatusCode = 200;
|
||||
}
|
||||
}
|
||||
else if (context.Result is EmptyResult || context.Result is NoContentResult)
|
||||
{
|
||||
context.Result = new ObjectResult(ApiResult.Ok());
|
||||
context.Result = new ObjectResult(ApiResult.Ok()) { StatusCode = 200 };
|
||||
}
|
||||
}
|
||||
|
||||
public void OnActionExecuting(ActionExecutingContext context) { }
|
||||
private static bool IsAlreadyWrapped(object? value)
|
||||
{
|
||||
if (value is null) return false;
|
||||
|
||||
var type = value.GetType();
|
||||
|
||||
// 递归判断:只要类型链上有任何一层是 ApiResult<> 的开放泛型定义,或直接是 ApiResult,就算已包装
|
||||
while (type is not null)
|
||||
{
|
||||
if (type == typeof(ApiResult)) return true;
|
||||
if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(ApiResult<>)) return true;
|
||||
type = type.BaseType;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -59,7 +59,7 @@ namespace MAX.Framework.Commons
|
||||
}
|
||||
|
||||
var originalBody = context.Response.Body;
|
||||
var buffer = _streamManager.GetStream();
|
||||
using var buffer = _streamManager.GetStream();
|
||||
|
||||
context.Response.Body = buffer;
|
||||
|
||||
@@ -126,7 +126,6 @@ namespace MAX.Framework.Commons
|
||||
PropertyNamingPolicy = JsonNamingPolicy.CamelCase
|
||||
});
|
||||
|
||||
buffer.Dispose();
|
||||
}
|
||||
|
||||
private static bool IsPassthroughByRequest(HttpContext context)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using MAX.Framework.Commons;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace MAX.Framework.Dtos
|
||||
{
|
||||
@@ -29,10 +29,10 @@ namespace MAX.Framework.Dtos
|
||||
public abstract class ApiResultBase
|
||||
{
|
||||
/// <summary>业务状态码</summary>
|
||||
public int Code { get; set; } = ResultCode.Success;
|
||||
public int Code { get; init; } = ResultCode.Success;
|
||||
|
||||
/// <summary>提示信息</summary>
|
||||
public string? Msg { get; set; }
|
||||
public string? Msg { get; init; }
|
||||
|
||||
/// <summary>请求是否成功</summary>
|
||||
public bool Success => Code == ResultCode.Success;
|
||||
@@ -44,13 +44,25 @@ namespace MAX.Framework.Dtos
|
||||
/// </summary>
|
||||
public class ApiResult<T> : ApiResultBase
|
||||
{
|
||||
public T? Data { get; set; }
|
||||
/// <summary>响应数据;失败时不应依赖该值,值类型默认值并非 null。</summary>
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
|
||||
public T? Data { get; init; }
|
||||
|
||||
/// <summary>将无数据响应转换为当前数据类型,保留状态码和提示信息。</summary>
|
||||
public static implicit operator ApiResult<T>(ApiResult result)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(result);
|
||||
return new ApiResult<T> { Code = result.Code, Msg = result.Msg, Data = default };
|
||||
}
|
||||
|
||||
public static ApiResult<T> Ok(T data, string msg = "操作成功")
|
||||
=> new ApiResult<T> { Code = ResultCode.Success, Data = data, Msg = msg };
|
||||
|
||||
public static ApiResult<T> Fail(string msg = "操作失败", int code = ResultCode.Fail, T? data = default)
|
||||
=> new ApiResult<T> { Code = code, Msg = msg, Data = data };
|
||||
{
|
||||
ApiResult.ValidateFailureCode(code);
|
||||
return new ApiResult<T> { Code = code, Msg = msg, Data = data };
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -58,11 +70,32 @@ namespace MAX.Framework.Dtos
|
||||
/// </summary>
|
||||
public class ApiResult : ApiResultBase
|
||||
{
|
||||
public static ApiResult Ok(string msg = "操作成功")
|
||||
=> new ApiResult { Code = ResultCode.Success, Msg = msg };
|
||||
/// <summary>无数据响应仍输出 data: null,保持统一的响应字段。</summary>
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
|
||||
public object? Data => null;
|
||||
|
||||
/// <summary>创建带数据的成功响应,自动推断数据类型。</summary>
|
||||
public static ApiResult<T> Ok<T>(T data, string msg = "操作成功")
|
||||
=> ApiResult<T>.Ok(data, msg);
|
||||
|
||||
/// <summary>创建带数据的失败响应,自动推断数据类型。</summary>
|
||||
public static ApiResult<T> Fail<T>(string msg, T data, int code = ResultCode.Fail)
|
||||
=> ApiResult<T>.Fail(msg, code, data);
|
||||
|
||||
public static ApiResult Ok()
|
||||
=> new ApiResult { Code = ResultCode.Success, Msg = "操作成功" };
|
||||
|
||||
public static ApiResult Fail(string msg = "操作失败", int code = ResultCode.Fail)
|
||||
=> new ApiResult { Code = code, Msg = msg };
|
||||
{
|
||||
ValidateFailureCode(code);
|
||||
return new ApiResult { Code = code, Msg = msg };
|
||||
}
|
||||
|
||||
internal static void ValidateFailureCode(int code)
|
||||
{
|
||||
if (code == ResultCode.Success)
|
||||
throw new ArgumentOutOfRangeException(nameof(code), code, "失败响应不能使用成功状态码。");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
using Asp.Versioning;
|
||||
using MAX.Framework.Dtos;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using MySqlX.XDevAPI.Common;
|
||||
using Store.Framework.Base;
|
||||
using Store.Framework.Models;
|
||||
using Store.ImageCache.Dtos;
|
||||
using Store.ImageCache.Services;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
|
||||
namespace KJD_Web.Controllers
|
||||
{
|
||||
[ApiVersionNeutral]
|
||||
[Route("api/ImageCache/[action]")]
|
||||
public class ImageCacheController : AppControllerBase
|
||||
{
|
||||
private readonly ImageCacheService _imageCacheService;
|
||||
private readonly ILogger<ImageCacheController> _logger;
|
||||
|
||||
public ImageCacheController(ImageCacheService imageCacheService, ILogger<ImageCacheController> logger)
|
||||
{
|
||||
if (imageCacheService == null)
|
||||
{
|
||||
throw new ArgumentNullException("imageCacheService");
|
||||
}
|
||||
|
||||
_imageCacheService = imageCacheService;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 批量按 MD5 查询图片缓存。
|
||||
/// </summary>
|
||||
[HttpPost]
|
||||
public ApiResult<List<ImageCacheDto>> GetImageCache(ImageCacheBatchQueryRequest request)
|
||||
{
|
||||
List<ImageCacheDto> data = new List<ImageCacheDto>();
|
||||
try
|
||||
{
|
||||
if (request != null && request.Md5s != null)
|
||||
{
|
||||
data = _imageCacheService.GetByMd5s(request.Md5s, request.Platform);
|
||||
}
|
||||
return ApiResult.Ok(data);
|
||||
}
|
||||
catch (ArgumentException ex)
|
||||
{
|
||||
return ApiResult.Fail(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 按 MD5 和平台更新平台图片 URL。
|
||||
/// </summary>
|
||||
[HttpPost]
|
||||
public ApiResult<List<string>> AddOrUpdate(ImageCacheUpdateUrlRequest[] requests)
|
||||
{
|
||||
if (requests == null || requests.Length == 0)
|
||||
{
|
||||
return ApiResult.Fail("参数不能为空");
|
||||
}
|
||||
|
||||
var failedItems = new List<string>();
|
||||
foreach (var item in requests)
|
||||
{
|
||||
if (item == null)
|
||||
{
|
||||
return ApiResult.Fail("图片参数不能包含空项", ResultCode.ValidationError);
|
||||
}
|
||||
try
|
||||
{
|
||||
if (!_imageCacheService.AddOrUpdate(item.Md5, item.Platform, item.PlatformUrl))
|
||||
{
|
||||
failedItems.Add(item.Md5);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "AddOrUpdate 失败, Md5={Md5}", item.Md5);
|
||||
failedItems.Add(item.Md5);
|
||||
}
|
||||
}
|
||||
|
||||
return failedItems.Count == 0
|
||||
? ApiResult.Ok()
|
||||
: ApiResult.Fail("部分图片失败", failedItems);
|
||||
}
|
||||
public class ImageCacheBatchQueryRequest
|
||||
{
|
||||
public List<string> Md5s { get; set; }
|
||||
public byte? Platform { get; set; }
|
||||
}
|
||||
|
||||
public class ImageCacheUpdateUrlRequest
|
||||
{
|
||||
public string Md5 { get; set; }
|
||||
public byte Platform { get; set; }
|
||||
public string PlatformUrl { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Store.ImageCache.Dtos
|
||||
{
|
||||
public class ImageCacheDto
|
||||
{
|
||||
public byte platform { get; set; }
|
||||
public string md5 { get; set; }
|
||||
public string platform_url { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
using FreeSql.DataAnnotations;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Store.ImageCache.Entities
|
||||
{
|
||||
[Table(Name = "images_0")]
|
||||
public class ImageCacheEntity
|
||||
{
|
||||
[JsonIgnore]
|
||||
[Column(Name = "id", IsIdentity = true, IsPrimary = true)]
|
||||
public long id { get; set; }
|
||||
|
||||
[Column(Name = "platform")]
|
||||
public byte platform { get; set; }
|
||||
|
||||
//[JsonProperty("md5")]
|
||||
[Column(Name = "source_url_md5", StringLength = 32)]
|
||||
public string source_url_md5 { get; set; }
|
||||
|
||||
[Column(Name = "platform_url", StringLength = 1000)]
|
||||
public string platform_url { get; set; }
|
||||
[JsonIgnore]
|
||||
[Column(Name = "create_time")]
|
||||
public DateTime create_time { get; set; }
|
||||
[JsonIgnore]
|
||||
[Column(Name = "update_time")]
|
||||
public DateTime update_time { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using Riok.Mapperly.Abstractions;
|
||||
using Store.Framework.Models;
|
||||
using Store.ImageCache.Dtos;
|
||||
using Store.ImageCache.Entities;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Store.ImageCache.Mapper
|
||||
{
|
||||
[Mapper(RequiredMappingStrategy = RequiredMappingStrategy.Target)]
|
||||
public partial class ImageCacheMapper
|
||||
{
|
||||
[MapProperty(nameof(ImageCacheEntity.source_url_md5), nameof(ImageCacheDto.md5))]
|
||||
public partial ImageCacheDto ToDto(ImageCacheEntity entity);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
|
||||
using MAX.Core.Interfaces;
|
||||
using MAX.Framework.Interfaces;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using MySql.Data.MySqlClient;
|
||||
|
||||
namespace Store.Modules.CloudProduct
|
||||
{
|
||||
public class Module : IModule
|
||||
{
|
||||
/// <summary>
|
||||
/// 本模块自己的配置文件
|
||||
/// </summary>
|
||||
public const string ConfigurationFileName = "appsettings.ImageCache.json";
|
||||
|
||||
public int Priority => IntPriority.Normal;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 服务注册阶段(builder.Build() 之前):这里只能拿到容器和配置,碰不到 app
|
||||
/// </summary>
|
||||
public void AddModule(IHostApplicationBuilder host)
|
||||
{
|
||||
IServiceCollection services = host.Services;
|
||||
IConfigurationManager configuration = host.Configuration;
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(ConfigurationFileName))
|
||||
{
|
||||
string path = Path.IsPathRooted(ConfigurationFileName)? ConfigurationFileName: Path.Combine(AppContext.BaseDirectory, ConfigurationFileName);
|
||||
configuration.AddJsonFile(path, optional: false, reloadOnChange: true);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 管道装配阶段(builder.Build() 之后、app.Run() 之前):这里可以挂中间件、解析容器里的服务
|
||||
/// </summary>
|
||||
public void UseModule(IApplicationBuilder app)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
using MAX.Core.DependencyInjection;
|
||||
using MAX.Core.Interfaces;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace Store.Modules.CloudProduct
|
||||
{
|
||||
|
||||
public class Startup : IStartup
|
||||
{
|
||||
public int Priority => IntPriority.Normal;
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
}
|
||||
|
||||
public void Register(IServiceRegistrar registrar)
|
||||
{
|
||||
|
||||
|
||||
|
||||
Func<IServiceProvider, IFreeSql> KJDFsqlFactory = r =>
|
||||
{
|
||||
var config = r.GetRequiredService<IConfiguration>();
|
||||
var connection = config.GetValue<string>("ImageCache:ConnectionString");
|
||||
IFreeSql fsql = new FreeSql.FreeSqlBuilder()
|
||||
.UseConnectionString(FreeSql.DataType.MySql, connection)
|
||||
.UseAdoConnectionPool(true)
|
||||
.Build();
|
||||
return fsql;
|
||||
};
|
||||
registrar.RegisterSingleton<IFreeSql>("ImageCacheConnection", (s, k) =>
|
||||
{
|
||||
return KJDFsqlFactory(s);
|
||||
});
|
||||
}
|
||||
|
||||
public void Start(IServiceProvider serviceProvider)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<FrameworkReference Include="Microsoft.AspNetCore.App" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Store.Framework\Store.Framework.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Update="appsettings.ImageCache.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"ImageCache": {
|
||||
"ConnectionString": "Server=192.168.0.200;Port=3306;Database=ImageCache;Uid=root;Pwd=123456;Allow User Variables=true"
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,10 @@
|
||||
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove="Logs\**" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
@@ -17,6 +21,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Modules\CloudProduct\Store.CloudProduct.csproj" />
|
||||
<ProjectReference Include="..\Modules\Store.ImageCache\Store.ImageCache.csproj" />
|
||||
<ProjectReference Include="..\Modules\Store.Users\Store.Users.csproj" />
|
||||
<ProjectReference Include="..\Store.Framework\Store.Framework.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
}
|
||||
},
|
||||
"ConnectionStrings": {
|
||||
"DefaultConnection": "Server=11192.168.0.200;Port=3306;Database=mysql;Uid=root;Pwd=123456;",
|
||||
"DefaultConnection": "Server=192.168.0.200;Port=3306;Database=mysql;Uid=root;Pwd=123456;",
|
||||
"KJDConnection": "Server=192.168.0.200;Port=3306;Database=mysql;Uid=root;Pwd=123456;",
|
||||
"ConnKJD": "Server=192.168.0.200;Port=3306;Database=mysql;Uid=root;Pwd=123456;"
|
||||
//"KJDConnection": "Max Pool Size=512;Database='kjd';Data Source='nj-cynosdbmysql-grp-hl51pkfr.sql.tencentcdb.com';Port=27660;User Id='kjd';Password='Temukjd0625';Charset=utf8mb4;",
|
||||
|
||||
+2
-1
@@ -5,6 +5,7 @@
|
||||
</Folder>
|
||||
<Folder Name="/Modules/">
|
||||
<Project Path="Modules/CloudProduct/Store.CloudProduct.csproj" />
|
||||
<Project Path="Modules/Store.ImageCache/Store.ImageCache.csproj" Id="53cc9cf1-62f9-4980-bad9-958bb3314370" />
|
||||
<Project Path="Modules/Store.Shops.Contracts/Store.Shops.Contracts.csproj" Id="7d313823-f86a-450a-be29-8f915fc4b5b3" />
|
||||
<Project Path="Modules/Store.Shops/Store.Shops.csproj" Id="b1c06d62-9cfb-4e87-b495-7077dd0c088d" />
|
||||
<Project Path="Modules/Store.Users.Contracts/Store.Users.Contracts.csproj" Id="d4a8177b-503c-4205-96ce-da0e01c855db" />
|
||||
@@ -15,6 +16,6 @@
|
||||
</Folder>
|
||||
<Project Path="Store.API/Store.Api.csproj" />
|
||||
<Project Path="Store.Framework/Store.Framework.csproj" />
|
||||
<Project Path="StoreHub.KJDWebService/StoreHub.KJDWebService.csproj" />
|
||||
<Project Path="Store.KJDWebService/StoreHub.KJDWebService.csproj" />
|
||||
<Project Path="StoreHub.Services/Store.Services.csproj" />
|
||||
</Solution>
|
||||
Reference in new issue
Block a user