using System.Collections.Generic; using System.Linq; using System.Net.Http; using System.Net.Http.Json; using System.Text; using System.Text.Json; using Microsoft.Extensions.Caching.Distributed; using Microsoft.Extensions.Logging; using SimApi.Communications; using SimApi.Configurations; using SimApi.Helpers; namespace SimApi.CoceSdk; public class CoceApp(SimApiOptions simApiOptions, ILogger logger, IDistributedCache cache) { /// /// 获取Level Token /// /// /// /// public LevelTokenResponse? GetLevelToken(string lv1Token, int level = 5) { var dict = new Dictionary { { "lv1Token", lv1Token }, { "time", (int)SimApiUtil.TimestampNow }, { "appId", simApiOptions.CoceSdkOptions.AppId! }, { "level", level } }; return QueryAppApi("/api/app/token", dict); } /// /// 通过用户手机号搜索用户 /// /// /// public UserInfo? SearchUserByPhone(string phone) { var dict = new Dictionary { { "cell", phone }, { "time", (int)SimApiUtil.TimestampNow }, { "appId", simApiOptions.CoceSdkOptions.AppId! }, }; return QueryAppApi("/api/app/user/search-by-phone", dict); } /// /// 通过给出的UserId列表获取用户信息 /// /// /// public UserInfo[]? SearchUserByIds(IEnumerable userIds) { var dict = new Dictionary { { "ids", string.Join(",", userIds) }, { "time", (int)SimApiUtil.TimestampNow }, { "appId", simApiOptions.CoceSdkOptions.AppId! }, }; return QueryAppApi("/api/app/user/search-by-ids", dict); } /// /// 向用户发送消息 /// /// /// /// /// public bool SendUserMessage(string userId, string title, string content) { var dict = new Dictionary { { "time", (int)SimApiUtil.TimestampNow }, { "appId", simApiOptions.CoceSdkOptions.AppId! }, { "userId", userId }, { "type", "text" }, { "title", title }, { "text", content } }; return QueryAppApiNoResp("/api/app/message", dict); } /// /// 创建交易订单号 /// /// /// /// /// public string? TradeCreate(string name, int amount, string ext) { var dict = new Dictionary { { "time", (int)SimApiUtil.TimestampNow }, { "appId", simApiOptions.CoceSdkOptions.AppId! }, { "amount", amount }, { "ext", ext }, { "name", name } }; return QueryAppApi("/api/app/trade/create", dict); } /// /// 查询订单状态 /// /// /// public CheckTradeResponse? TradeCheck(string tradeNo) { var dict = new Dictionary { { "time", (int)SimApiUtil.TimestampNow }, { "appId", simApiOptions.CoceSdkOptions.AppId! }, { "tradeNo", tradeNo } }; return QueryAppApi("/api/app/trade/result", dict); } /// /// 对订单进行退款 /// /// /// public bool TradeRefund(string tradeNo) { var dict = new Dictionary { { "time", (int)SimApiUtil.TimestampNow }, { "appId", simApiOptions.CoceSdkOptions.AppId! }, { "tradeNo", tradeNo } }; return QueryAppApiNoResp("/api/app/trade/refund", dict); } private T? QueryAppApi(string endpoint, Dictionary request) { var response = QueryAppApi(endpoint, request); var result = response.Content.ReadFromJsonAsync>().Result!; if (result.Code == 200) return result.Data; logger.LogDebug("发生错误: {Code} => {Message}", result.Code, result.Message); return default; } private bool QueryAppApiNoResp(string endpoint, Dictionary request) { var response = QueryAppApi(endpoint, request); var result = response.Content.ReadFromJsonAsync().Result!; return result.Code == 200; } private HttpResponseMessage QueryAppApi(string endpoint, Dictionary request) { var platUrl = simApiOptions.CoceSdkOptions.ApiEndpoint + endpoint; var sorted = request.OrderBy(x => x.Key); var signStr = sorted.Aggregate("", (current, item) => current + $"{item.Key}={item.Value}&").TrimEnd('&'); logger.LogDebug("签名的字符串: {SignStr}", signStr); var sign = SimApiUtil.Md5(signStr + simApiOptions.CoceSdkOptions.AppKey); logger.LogDebug("签名: {Sign}", sign); request.Add("sign", sign); logger.LogDebug("请求地址: {PlatUrl} => {Data}", platUrl, JsonSerializer.Serialize(request)); var http = new HttpClient(); return http.PostAsJsonAsync(platUrl, request).Result; } /// /// 获取用户的群组信息 /// /// Level >=2 的Token /// public IEnumerable? GetUserGroups(string token) { const string uri = "/api/lv2/user/groups"; var resp = ProxyQuery(uri, token,"{}"); return resp; } /// /// 获取用户信息 /// /// /// public UserInfo? GetUserInfo(string token) { const string uri = "/api/lv1/user/info"; return ProxyQuery(uri, token); } public void SaveToken(string userId, string levelToken) { cache.SetString($"LEVEL:TOKEN:{userId}", levelToken); } public string? GetToken(string userId) { return cache.GetString($"LEVEL:TOKEN:{userId}"); } public dynamic? ProxyQuery(string uri, string token, string json) => ProxyQuery(uri, token, json); public dynamic? ProxyQueue(string uri, string token, object data) => ProxyQuery(uri, token, JsonSerializer.Serialize(data)); public T? ProxyQueue(string uri, string token, object data) => ProxyQuery(uri, token, JsonSerializer.Serialize(data)); public T? ProxyQuery(string uri, string token, string json = "{}") { var http = new HttpClient(); http.DefaultRequestHeaders.Add("Token", token); var realUrl = simApiOptions.CoceSdkOptions.ApiEndpoint + uri; var response = http.PostAsync(realUrl, new StringContent(json, Encoding.UTF8, "application/json")) .Result; var resp = response.Content.ReadFromJsonAsync>().Result!; if (resp.Code != 200) { logger.LogDebug("请求发生错误: {RespCode} => {RespMessage}", resp.Code, resp.Message); } return resp.Code == 200 ? resp.Data : default; } public ConfigResponse GetConfig() { return new ConfigResponse(simApiOptions.CoceSdkOptions.AppId!, simApiOptions.CoceSdkOptions.AuthEndpoint); } }