运行时优先读 t_system_other_config,修正管理端客户提示文案,并提供配置种子 SQL。
feat: 店铺平台 OAuth 配置迁入其他配置页
This commit is contained in:
commit
4c7dd9ed7c
47
sql/seed_platform_shop_other_config.sql
Normal file
47
sql/seed_platform_shop_other_config.sql
Normal file
@ -0,0 +1,47 @@
|
||||
-- 店铺平台 OAuth 配置种子(其他配置页可改;已存在则跳过)
|
||||
INSERT INTO t_system_other_config
|
||||
(ConfigCode, ConfigName, Enabled, BaseUrl, AppKey, AppSecret, TimeoutSeconds, Remark, IsDeleted, CreateTime)
|
||||
SELECT 'platform_shop', '店铺授权-公共', 1, 'http://localhost:5173', NULL, NULL, 30, NULL, 0, NOW()
|
||||
WHERE NOT EXISTS (SELECT 1 FROM t_system_other_config WHERE ConfigCode = 'platform_shop' AND IsDeleted = 0);
|
||||
|
||||
INSERT INTO t_system_other_config
|
||||
(ConfigCode, ConfigName, Enabled, BaseUrl, AppKey, AppSecret, TimeoutSeconds, Remark, IsDeleted, CreateTime)
|
||||
SELECT 'platform_shop_tiktok', '店铺授权-TikTok', 1,
|
||||
'https://auth.tiktok-shops.com',
|
||||
'6hc64lc6vl312',
|
||||
'5a691a96ee6d844534769bab5c21de1f848fb678',
|
||||
30,
|
||||
'https://open-api.tiktokglobalshop.com',
|
||||
0, NOW()
|
||||
WHERE NOT EXISTS (SELECT 1 FROM t_system_other_config WHERE ConfigCode = 'platform_shop_tiktok' AND IsDeleted = 0);
|
||||
|
||||
INSERT INTO t_system_other_config
|
||||
(ConfigCode, ConfigName, Enabled, BaseUrl, AppKey, AppSecret, TimeoutSeconds, Remark, IsDeleted, CreateTime)
|
||||
SELECT 'platform_shop_temu', '店铺授权-Temu', 1,
|
||||
'https://openapi-b-us.temu.com/openapi/router',
|
||||
'4ebbc9190ae410443d65b4c2faca981f',
|
||||
'4782d2d827276688bf4758bed55dbdd4bbe79a79',
|
||||
30, NULL, 0, NOW()
|
||||
WHERE NOT EXISTS (SELECT 1 FROM t_system_other_config WHERE ConfigCode = 'platform_shop_temu' AND IsDeleted = 0);
|
||||
|
||||
INSERT INTO t_system_other_config
|
||||
(ConfigCode, ConfigName, Enabled, BaseUrl, AppKey, AppSecret, TimeoutSeconds, Remark, IsDeleted, CreateTime)
|
||||
SELECT 'platform_shop_shopee', '店铺授权-Shopee', 1,
|
||||
'https://partner.shopeemobile.com',
|
||||
'2004112',
|
||||
'2f385d7ea38b087d5d71f7292e06a09c9f19022ca6c3f60ec0110a8214ef7d65',
|
||||
30,
|
||||
'https://openplatform.shopee.cn',
|
||||
0, NOW()
|
||||
WHERE NOT EXISTS (SELECT 1 FROM t_system_other_config WHERE ConfigCode = 'platform_shop_shopee' AND IsDeleted = 0);
|
||||
|
||||
INSERT INTO t_system_other_config
|
||||
(ConfigCode, ConfigName, Enabled, BaseUrl, AppKey, AppSecret, TimeoutSeconds, Remark, IsDeleted, CreateTime)
|
||||
SELECT 'platform_shop_lazada', '店铺授权-Lazada', 1,
|
||||
'https://auth.lazada.com/oauth/authorize',
|
||||
'123631',
|
||||
'7vBz2EaD6rIupeGEfwrgkabsTNsXt2ix',
|
||||
30,
|
||||
'https://auth.lazada.com/rest',
|
||||
0, NOW()
|
||||
WHERE NOT EXISTS (SELECT 1 FROM t_system_other_config WHERE ConfigCode = 'platform_shop_lazada' AND IsDeleted = 0);
|
||||
@ -2,13 +2,12 @@ using System.Net.Http.Json;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace Oms.Application.Integrations.PlatformShop;
|
||||
|
||||
public interface IPlatformShopApiClient
|
||||
{
|
||||
string BuildAuthUrl(string platformCode, string redirectUri, string state, string? siteCountry);
|
||||
Task<string> BuildAuthUrlAsync(string platformCode, string redirectUri, string state, string? siteCountry, CancellationToken ct = default);
|
||||
Task<PlatformShopTokenResult> ExchangeTokenAsync(PlatformShopTokenExchangeRequest request, CancellationToken ct = default);
|
||||
Task<PlatformShopTokenResult> CreateTemuStoreTokenAsync(string authorizationCode, CancellationToken ct = default);
|
||||
}
|
||||
@ -45,15 +44,26 @@ public sealed class PlatformShopBoundShop
|
||||
|
||||
internal sealed class PlatformShopApiClient(
|
||||
IHttpClientFactory httpClientFactory,
|
||||
IOptions<PlatformShopOptions> options,
|
||||
IPlatformShopConfigProvider configProvider,
|
||||
ILogger<PlatformShopApiClient> logger) : IPlatformShopApiClient
|
||||
{
|
||||
public const string HttpClientName = nameof(PlatformShopApiClient);
|
||||
|
||||
private readonly PlatformShopOptions _options = options.Value;
|
||||
private PlatformShopOptions _options = new();
|
||||
|
||||
public string BuildAuthUrl(string platformCode, string redirectUri, string state, string? siteCountry)
|
||||
private async Task LoadOptionsAsync(CancellationToken ct = default)
|
||||
{
|
||||
_options = await configProvider.GetAsync(ct);
|
||||
}
|
||||
|
||||
public async Task<string> BuildAuthUrlAsync(
|
||||
string platformCode,
|
||||
string redirectUri,
|
||||
string state,
|
||||
string? siteCountry,
|
||||
CancellationToken ct = default)
|
||||
{
|
||||
await LoadOptionsAsync(ct);
|
||||
return platformCode.ToLowerInvariant() switch
|
||||
{
|
||||
"lazada" => BuildLazadaAuthUrl(redirectUri, siteCountry),
|
||||
@ -67,6 +77,7 @@ internal sealed class PlatformShopApiClient(
|
||||
PlatformShopTokenExchangeRequest request,
|
||||
CancellationToken ct = default)
|
||||
{
|
||||
await LoadOptionsAsync(ct);
|
||||
return request.PlatformCode.ToLowerInvariant() switch
|
||||
{
|
||||
"lazada" => await ExchangeLazadaAsync(request.Code, ct),
|
||||
@ -78,6 +89,7 @@ internal sealed class PlatformShopApiClient(
|
||||
|
||||
public async Task<PlatformShopTokenResult> CreateTemuStoreTokenAsync(string authorizationCode, CancellationToken ct = default)
|
||||
{
|
||||
await LoadOptionsAsync(ct);
|
||||
EnsureTemuConfigured();
|
||||
var temu = _options.Temu;
|
||||
var body = new Dictionary<string, string>
|
||||
|
||||
@ -0,0 +1,147 @@
|
||||
using Fake.DependencyInjection;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Oms.Domain.SystemAggregate.Consts;
|
||||
using Oms.Domain.SystemAggregate.Entities;
|
||||
using Oms.Domain.SystemAggregate.Repositories;
|
||||
|
||||
namespace Oms.Application.Integrations.PlatformShop;
|
||||
|
||||
/// <summary>
|
||||
/// 平台店铺 OAuth 运行时配置:优先读「其他配置」,回退 appsettings。
|
||||
/// </summary>
|
||||
public interface IPlatformShopConfigProvider
|
||||
{
|
||||
Task<PlatformShopOptions> GetAsync(CancellationToken cancellationToken = default);
|
||||
}
|
||||
|
||||
internal sealed class PlatformShopConfigProvider(
|
||||
ISystemOtherConfigRepository repository,
|
||||
IOptions<PlatformShopOptions> options) : IPlatformShopConfigProvider, IScopedDependency
|
||||
{
|
||||
public async Task<PlatformShopOptions> GetAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
var fallback = options.Value ?? new PlatformShopOptions();
|
||||
var common = await repository.GetByConfigCodeAsync(SystemOtherConfigCodes.PlatformShop, cancellationToken);
|
||||
var lazada = await repository.GetByConfigCodeAsync(SystemOtherConfigCodes.PlatformShopLazada, cancellationToken);
|
||||
var shopee = await repository.GetByConfigCodeAsync(SystemOtherConfigCodes.PlatformShopShopee, cancellationToken);
|
||||
var tiktok = await repository.GetByConfigCodeAsync(SystemOtherConfigCodes.PlatformShopTiktok, cancellationToken);
|
||||
var temu = await repository.GetByConfigCodeAsync(SystemOtherConfigCodes.PlatformShopTemu, cancellationToken);
|
||||
|
||||
return new PlatformShopOptions
|
||||
{
|
||||
FrontendBaseUrl = Coalesce(common?.BaseUrl, fallback.FrontendBaseUrl),
|
||||
StateSecret = Coalesce(common?.Remark, fallback.StateSecret),
|
||||
Lazada = MergeLazada(lazada, fallback.Lazada),
|
||||
Shopee = MergeShopee(shopee, fallback.Shopee),
|
||||
Tiktok = MergeTiktok(tiktok, fallback.Tiktok),
|
||||
Temu = MergeTemu(temu, fallback.Temu)
|
||||
};
|
||||
}
|
||||
|
||||
private static LazadaPlatformOptions MergeLazada(SystemOtherConfig? entity, LazadaPlatformOptions fallback)
|
||||
{
|
||||
fallback ??= new LazadaPlatformOptions();
|
||||
if (entity == null || !entity.Enabled)
|
||||
{
|
||||
return CloneLazada(fallback);
|
||||
}
|
||||
|
||||
return new LazadaPlatformOptions
|
||||
{
|
||||
AppKey = Coalesce(entity.AppKey, fallback.AppKey),
|
||||
AppSecret = Coalesce(entity.AppSecret, fallback.AppSecret),
|
||||
AuthorizeUrl = Coalesce(entity.BaseUrl, fallback.AuthorizeUrl),
|
||||
AccessTokenUrl = Coalesce(entity.Remark, fallback.AccessTokenUrl)
|
||||
};
|
||||
}
|
||||
|
||||
private static ShopeePlatformOptions MergeShopee(SystemOtherConfig? entity, ShopeePlatformOptions fallback)
|
||||
{
|
||||
fallback ??= new ShopeePlatformOptions();
|
||||
if (entity == null || !entity.Enabled)
|
||||
{
|
||||
return CloneShopee(fallback);
|
||||
}
|
||||
|
||||
var partnerId = fallback.PartnerId;
|
||||
if (int.TryParse(entity.AppKey?.Trim(), out var parsed) && parsed > 0)
|
||||
{
|
||||
partnerId = parsed;
|
||||
}
|
||||
|
||||
return new ShopeePlatformOptions
|
||||
{
|
||||
PartnerId = partnerId,
|
||||
PartnerKey = Coalesce(entity.AppSecret, fallback.PartnerKey),
|
||||
HostAuthUrl = Coalesce(entity.BaseUrl, fallback.HostAuthUrl),
|
||||
HostUrl = Coalesce(entity.Remark, fallback.HostUrl)
|
||||
};
|
||||
}
|
||||
|
||||
private static TiktokPlatformOptions MergeTiktok(SystemOtherConfig? entity, TiktokPlatformOptions fallback)
|
||||
{
|
||||
fallback ??= new TiktokPlatformOptions();
|
||||
if (entity == null || !entity.Enabled)
|
||||
{
|
||||
return CloneTiktok(fallback);
|
||||
}
|
||||
|
||||
return new TiktokPlatformOptions
|
||||
{
|
||||
AppKey = Coalesce(entity.AppKey, fallback.AppKey),
|
||||
AppSecret = Coalesce(entity.AppSecret, fallback.AppSecret),
|
||||
HostAuth = Coalesce(entity.BaseUrl, fallback.HostAuth),
|
||||
HostApi = Coalesce(entity.Remark, fallback.HostApi)
|
||||
};
|
||||
}
|
||||
|
||||
private static TemuPlatformOptions MergeTemu(SystemOtherConfig? entity, TemuPlatformOptions fallback)
|
||||
{
|
||||
fallback ??= new TemuPlatformOptions();
|
||||
if (entity == null || !entity.Enabled)
|
||||
{
|
||||
return CloneTemu(fallback);
|
||||
}
|
||||
|
||||
return new TemuPlatformOptions
|
||||
{
|
||||
AppKey = Coalesce(entity.AppKey, fallback.AppKey),
|
||||
AppSecret = Coalesce(entity.AppSecret, fallback.AppSecret),
|
||||
HostAuthUrl = Coalesce(entity.BaseUrl, fallback.HostAuthUrl)
|
||||
};
|
||||
}
|
||||
|
||||
private static LazadaPlatformOptions CloneLazada(LazadaPlatformOptions src) => new()
|
||||
{
|
||||
AppKey = src.AppKey,
|
||||
AppSecret = src.AppSecret,
|
||||
AuthorizeUrl = src.AuthorizeUrl,
|
||||
AccessTokenUrl = src.AccessTokenUrl
|
||||
};
|
||||
|
||||
private static ShopeePlatformOptions CloneShopee(ShopeePlatformOptions src) => new()
|
||||
{
|
||||
PartnerId = src.PartnerId,
|
||||
PartnerKey = src.PartnerKey,
|
||||
HostUrl = src.HostUrl,
|
||||
HostAuthUrl = src.HostAuthUrl
|
||||
};
|
||||
|
||||
private static TiktokPlatformOptions CloneTiktok(TiktokPlatformOptions src) => new()
|
||||
{
|
||||
AppKey = src.AppKey,
|
||||
AppSecret = src.AppSecret,
|
||||
HostAuth = src.HostAuth,
|
||||
HostApi = src.HostApi
|
||||
};
|
||||
|
||||
private static TemuPlatformOptions CloneTemu(TemuPlatformOptions src) => new()
|
||||
{
|
||||
AppKey = src.AppKey,
|
||||
AppSecret = src.AppSecret,
|
||||
HostAuthUrl = src.HostAuthUrl
|
||||
};
|
||||
|
||||
private static string Coalesce(string? primary, string? fallback) =>
|
||||
!string.IsNullOrWhiteSpace(primary) ? primary.Trim() : (fallback ?? string.Empty);
|
||||
}
|
||||
@ -14,6 +14,7 @@ public static class PlatformShopServiceExtensions
|
||||
{
|
||||
client.Timeout = TimeSpan.FromSeconds(60);
|
||||
});
|
||||
services.AddScoped<IPlatformShopConfigProvider, PlatformShopConfigProvider>();
|
||||
services.AddScoped<IPlatformShopApiClient, PlatformShopApiClient>();
|
||||
return services;
|
||||
}
|
||||
|
||||
@ -2,7 +2,6 @@ using System.Linq.Expressions;
|
||||
using Fake.Application;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Oms.Application.Dtos.PlatformStore;
|
||||
using Oms.Application.Dtos.Shared;
|
||||
using Oms.Application.Integrations.PlatformShop;
|
||||
@ -23,8 +22,8 @@ public class PlatformStoreService : ApplicationService
|
||||
private ICustomerRepository CustomerRepository => LazyServiceProvider.GetRequiredService<ICustomerRepository>();
|
||||
private ISalesStoreRepository StoreRepository => LazyServiceProvider.GetRequiredService<ISalesStoreRepository>();
|
||||
private IPlatformShopApiClient PlatformShopApi => LazyServiceProvider.GetRequiredService<IPlatformShopApiClient>();
|
||||
private PlatformShopOptions PlatformShopOptions =>
|
||||
LazyServiceProvider.GetRequiredService<IOptions<PlatformShopOptions>>().Value;
|
||||
private IPlatformShopConfigProvider PlatformShopConfig =>
|
||||
LazyServiceProvider.GetRequiredService<IPlatformShopConfigProvider>();
|
||||
private IConfiguration Configuration => LazyServiceProvider.GetRequiredService<IConfiguration>();
|
||||
|
||||
[HttpPost("/order/platform-store/list")]
|
||||
@ -71,7 +70,7 @@ public class PlatformStoreService : ApplicationService
|
||||
return platform switch
|
||||
{
|
||||
"temu" => await CreateTemuStoreAsync(customerId, nickname, input),
|
||||
"lazada" or "shopee" or "tiktok" => BuildOAuthUrl(customerId, platform, nickname, input),
|
||||
"lazada" or "shopee" or "tiktok" => await BuildOAuthUrlAsync(customerId, platform, nickname, input),
|
||||
_ => throw new BusinessException($"暂不支持平台:{platform}")
|
||||
};
|
||||
}
|
||||
@ -100,7 +99,13 @@ public class PlatformStoreService : ApplicationService
|
||||
|
||||
var nickname = (input.StoreNickname ?? string.Empty).Trim();
|
||||
var siteCountry = input.SiteCountry?.Trim();
|
||||
var stateSecret = ResolveStateSecret();
|
||||
var stateSecret = ResolveStateSecretFallback();
|
||||
var shopOptions = await PlatformShopConfig.GetAsync();
|
||||
if (!string.IsNullOrWhiteSpace(shopOptions.StateSecret))
|
||||
{
|
||||
stateSecret = shopOptions.StateSecret;
|
||||
}
|
||||
|
||||
if (PlatformShopAuthState.TryDecode(input.State, stateSecret, out var statePayload)
|
||||
&& statePayload.CustomerId == customerId)
|
||||
{
|
||||
@ -277,16 +282,21 @@ public class PlatformStoreService : ApplicationService
|
||||
};
|
||||
}
|
||||
|
||||
private PlatformStoreAuthUrlOutput BuildOAuthUrl(
|
||||
private async Task<PlatformStoreAuthUrlOutput> BuildOAuthUrlAsync(
|
||||
int customerId,
|
||||
string platform,
|
||||
string nickname,
|
||||
PlatformStoreAuthUrlInput input)
|
||||
{
|
||||
var shopOptions = await PlatformShopConfig.GetAsync();
|
||||
var redirect = string.IsNullOrWhiteSpace(input.RedirectUri)
|
||||
? $"{PlatformShopOptions.FrontendBaseUrl.TrimEnd('/')}/oauth/platform-store/{platform}"
|
||||
? $"{shopOptions.FrontendBaseUrl.TrimEnd('/')}/oauth/platform-store/{platform}"
|
||||
: input.RedirectUri.Trim();
|
||||
|
||||
var stateSecret = !string.IsNullOrWhiteSpace(shopOptions.StateSecret)
|
||||
? shopOptions.StateSecret
|
||||
: ResolveStateSecretFallback();
|
||||
|
||||
var state = PlatformShopAuthState.Encode(new PlatformShopAuthStatePayload
|
||||
{
|
||||
CustomerId = customerId,
|
||||
@ -294,11 +304,11 @@ public class PlatformStoreService : ApplicationService
|
||||
StoreNickname = nickname,
|
||||
SiteCountry = input.SiteCountry?.Trim(),
|
||||
Exp = DateTimeOffset.UtcNow.AddHours(2).ToUnixTimeSeconds()
|
||||
}, ResolveStateSecret());
|
||||
}, stateSecret);
|
||||
|
||||
try
|
||||
{
|
||||
var authUrl = PlatformShopApi.BuildAuthUrl(platform, redirect, state, input.SiteCountry);
|
||||
var authUrl = await PlatformShopApi.BuildAuthUrlAsync(platform, redirect, state, input.SiteCountry);
|
||||
return new PlatformStoreAuthUrlOutput
|
||||
{
|
||||
AuthUrl = authUrl,
|
||||
@ -374,13 +384,8 @@ public class PlatformStoreService : ApplicationService
|
||||
return entity;
|
||||
}
|
||||
|
||||
private string ResolveStateSecret()
|
||||
private string ResolveStateSecretFallback()
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(PlatformShopOptions.StateSecret))
|
||||
{
|
||||
return PlatformShopOptions.StateSecret;
|
||||
}
|
||||
|
||||
return Configuration["Jwt:SecretKey"]
|
||||
?? Configuration["JwtSettings:SecretKey"]
|
||||
?? "oms-platform-shop-state-secret";
|
||||
|
||||
@ -188,8 +188,44 @@ public class SystemOtherConfigService : ApplicationService
|
||||
throw new BusinessException("微信公众号 AppSecret 不能为空");
|
||||
}
|
||||
}
|
||||
else if (string.Equals(configCode, SystemOtherConfigCodes.PlatformShop, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(input.BaseUrl))
|
||||
{
|
||||
throw new BusinessException("店铺授权前端回调根地址不能为空");
|
||||
}
|
||||
}
|
||||
else if (IsPlatformShopAppConfig(configCode))
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(input.AppKey))
|
||||
{
|
||||
throw new BusinessException("平台 AppKey / PartnerId 不能为空");
|
||||
}
|
||||
|
||||
if (excludeId == null && ShouldKeepExistingSecret(input.AppSecret))
|
||||
{
|
||||
throw new BusinessException("平台 AppSecret / PartnerKey 不能为空");
|
||||
}
|
||||
|
||||
if (string.Equals(configCode, SystemOtherConfigCodes.PlatformShopShopee, StringComparison.OrdinalIgnoreCase)
|
||||
&& !int.TryParse(input.AppKey.Trim(), out _))
|
||||
{
|
||||
throw new BusinessException("Shopee PartnerId 必须为数字");
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(input.BaseUrl))
|
||||
{
|
||||
throw new BusinessException("平台授权/API 地址不能为空");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static bool IsPlatformShopAppConfig(string configCode) =>
|
||||
string.Equals(configCode, SystemOtherConfigCodes.PlatformShopLazada, StringComparison.OrdinalIgnoreCase)
|
||||
|| string.Equals(configCode, SystemOtherConfigCodes.PlatformShopShopee, StringComparison.OrdinalIgnoreCase)
|
||||
|| string.Equals(configCode, SystemOtherConfigCodes.PlatformShopTiktok, StringComparison.OrdinalIgnoreCase)
|
||||
|| string.Equals(configCode, SystemOtherConfigCodes.PlatformShopTemu, StringComparison.OrdinalIgnoreCase);
|
||||
|
||||
private static SystemOtherConfigOutput MapOutput(SystemOtherConfig entity, bool maskSecret)
|
||||
{
|
||||
return new SystemOtherConfigOutput
|
||||
|
||||
@ -35,7 +35,7 @@ public static class WarehouseCustomerHelper
|
||||
var customerId = await ResolveListCustomerIdAsync(customerRepository, currentUser, requestedCustomerId);
|
||||
if (!customerId.HasValue || customerId.Value <= 0)
|
||||
{
|
||||
throw new BusinessException("客户ID不能为空(管理端请先在「我的包裹」选择客户后再使用采集插件)");
|
||||
throw new BusinessException("客户ID不能为空(管理端请先选择客户)");
|
||||
}
|
||||
|
||||
return customerId.Value;
|
||||
|
||||
@ -14,4 +14,29 @@ public static class SystemOtherConfigCodes
|
||||
/// 微信公众号配置(AppKey=AppId,AppSecret=Secret,Remark=Token,BaseUrl=OAuthRedirectBase)。
|
||||
/// </summary>
|
||||
public const string WeChatMp = "wechat_mp";
|
||||
|
||||
/// <summary>
|
||||
/// 店铺授权公共配置(BaseUrl=前端回调根地址 FrontendBaseUrl,Remark=StateSecret 可选)。
|
||||
/// </summary>
|
||||
public const string PlatformShop = "platform_shop";
|
||||
|
||||
/// <summary>
|
||||
/// Lazada(AppKey/AppSecret,BaseUrl=AuthorizeUrl,Remark=AccessTokenUrl)。
|
||||
/// </summary>
|
||||
public const string PlatformShopLazada = "platform_shop_lazada";
|
||||
|
||||
/// <summary>
|
||||
/// Shopee(AppKey=PartnerId,AppSecret=PartnerKey,BaseUrl=HostAuthUrl,Remark=HostUrl)。
|
||||
/// </summary>
|
||||
public const string PlatformShopShopee = "platform_shop_shopee";
|
||||
|
||||
/// <summary>
|
||||
/// TikTok(AppKey/AppSecret,BaseUrl=HostAuth,Remark=HostApi)。
|
||||
/// </summary>
|
||||
public const string PlatformShopTiktok = "platform_shop_tiktok";
|
||||
|
||||
/// <summary>
|
||||
/// Temu(AppKey/AppSecret,BaseUrl=HostAuthUrl)。
|
||||
/// </summary>
|
||||
public const string PlatformShopTemu = "platform_shop_temu";
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user