From fb98eea517acdef61d9d9c1a1f537a728282fac9 Mon Sep 17 00:00:00 2001
From: sunpengfei <i@angelzzz.com>
Date: 星期五, 22 八月 2025 10:01:54 +0800
Subject: [PATCH] feat:开发

---
 FlexJobApi.Web.Entry/FlexJobApi.Web.Entry.sln                                                      |   24 ++++
 FlexJobApi.Core/Utils/ResourceUtils/ResourceHttpProvider/DefaultResourceHttpProvider.cs            |   55 +++++++-
 FlexJobApi.Core/Utils/ResourceUtils/ResourceHttpProvider/SystemUserResourceHttpProvider.cs         |    4 
 FlexJobApi.Core/FlexJobApi.Core.xml                                                                |   47 +++++++
 FlexJobApi.Core/Utils/ResourceUtils/ResourceHttpProvider/ElectronSignServerResourceHttpProvider.cs |    9 
 FlexJobApi.UserServer.Application/FlexJobApi.UserServer.Application.xml                            |    9 -
 FlexJobApi.Core/Utils/ResourceUtils/ResourceHttpUtils.cs                                           |   61 +++++++++
 FlexJobApi.UserServer.Application/Auths/Commands/LoginCommandHandler.cs                            |   43 ------
 FlexJobApi.Core/Utils/JwtUtils/JwtUtils.cs                                                         |   66 ++++++++++
 9 files changed, 250 insertions(+), 68 deletions(-)

diff --git a/FlexJobApi.Core/FlexJobApi.Core.xml b/FlexJobApi.Core/FlexJobApi.Core.xml
index 0a9ebb5..f779e45 100644
--- a/FlexJobApi.Core/FlexJobApi.Core.xml
+++ b/FlexJobApi.Core/FlexJobApi.Core.xml
@@ -12451,6 +12451,15 @@
             <param name="logier"></param>
             <returns></returns>
         </member>
+        <member name="M:FlexJobApi.Core.JwtUtils.GetCurrentLogier(FlexJobApi.Core.User,FlexJobApi.Core.EnumClientType,System.String)">
+            <summary>
+            鑾峰彇褰撳墠鐧诲綍鐢ㄦ埛
+            </summary>
+            <param name="user"></param>
+            <param name="clientType"></param>
+            <param name="session_key"></param>
+            <returns></returns>
+        </member>
         <member name="M:FlexJobApi.Core.JwtUtils.GetCurrentLogier">
             <summary>
             鑾峰彇褰撳墠鐧诲綍鐢ㄦ埛
@@ -12499,6 +12508,44 @@
             鍒锋柊浠ょ墝
             </summary>
         </member>
+        <member name="M:FlexJobApi.Core.ResourceHttpUtils.SendHttpAsync(System.Object,System.String,System.String,FlexJobApi.Core.EnumResourceMethod,System.Nullable{FlexJobApi.Core.EnumResourceHttpProvider},System.String,System.String)">
+            <summary>
+            鍙戦�佽姹�
+            </summary>
+            <param name="request">璇锋眰鍙傛暟</param>
+            <param name="serviceName">鏈嶅姟鍚嶇О</param>
+            <param name="route">璺敱</param>
+            <param name="method">璇锋眰鏂瑰紡</param>
+            <param name="provider">璧勬簮鎻愪緵鑰�</param>
+            <param name="accessToken">璁块棶浠ょ墝</param>
+            <param name="refreshToken">鍒锋柊浠ょ墝</param>
+            <returns></returns>
+        </member>
+        <member name="M:FlexJobApi.Core.ResourceHttpUtils.SendHttpAsync``2(``0,System.Nullable{FlexJobApi.Core.EnumResourceHttpProvider})">
+            <summary>
+            鍙戦�佽姹�
+            </summary>
+            <typeparam name="TRequest"></typeparam>
+            <typeparam name="TResponse"></typeparam>
+            <param name="request"></param>
+            <param name="provider"></param>
+            <returns></returns>
+        </member>
+        <member name="M:FlexJobApi.Core.ResourceHttpUtils.GetHttpMethod(FlexJobApi.Core.EnumResourceMethod)">
+            <summary>
+            鑾峰彇璇锋眰鏂瑰紡
+            </summary>
+            <param name="method"></param>
+            <returns></returns>
+        </member>
+        <member name="M:FlexJobApi.Core.ResourceHttpUtils.GetUrl(System.String,System.String)">
+            <summary>
+            鑾峰彇鍋ュ悍鏈嶅姟鍦板潃
+            </summary>
+            <param name="serviceName"></param>
+            <param name="route"></param>
+            <returns></returns>
+        </member>
         <member name="M:FlexJobApi.Core.ResourceHttpUtils.GetHealthyServiceDomain(System.String)">
             <summary>
             鑾峰彇鍋ュ悍鏈嶅姟鍩熷悕
diff --git a/FlexJobApi.Core/Utils/JwtUtils/JwtUtils.cs b/FlexJobApi.Core/Utils/JwtUtils/JwtUtils.cs
index f9d47e6..813c6d3 100644
--- a/FlexJobApi.Core/Utils/JwtUtils/JwtUtils.cs
+++ b/FlexJobApi.Core/Utils/JwtUtils/JwtUtils.cs
@@ -1,7 +1,10 @@
-锘縰sing Furion;
+锘縰sing Azure.Core;
+using Furion;
+using Furion.DatabaseAccessor;
 using Furion.DataEncryption;
 using Furion.FriendlyException;
 using Microsoft.AspNetCore.Http;
+using Microsoft.EntityFrameworkCore;
 using Microsoft.Extensions.Options;
 using Microsoft.IdentityModel.Tokens;
 using Newtonsoft.Json;
@@ -53,6 +56,67 @@
         /// <summary>
         /// 鑾峰彇褰撳墠鐧诲綍鐢ㄦ埛
         /// </summary>
+        /// <param name="user"></param>
+        /// <param name="clientType"></param>
+        /// <param name="session_key"></param>
+        /// <returns></returns>
+        public static LoginCommandCallback GetCurrentLogier(this User user, EnumClientType clientType, string session_key = null)
+        {
+            var logier = new CurrentLogier
+            {
+                Id = user.Id,
+                Avatar = user.Avatar,
+                Name = user.Name,
+                UserName = user.UserName,
+                PhoneNumber = user.PhoneNumber,
+                Level = user.Level,
+                Type = user.Type,
+                ClientType = clientType,
+                EnterpriseId = user.EnterpriseId,
+            };
+            GenerateToken(logier);
+
+            return new LoginCommandCallback
+            {
+                Id = logier.Id,
+                AccessToken = logier.AccessToken,
+                RefreshToken = logier.RefreshToken,
+                SessionKey = session_key,
+                IsBindPhoneNumber = logier.PhoneNumber.IsNotNull()
+            };
+        }
+
+        public static async Task<LoginCommandCallback> GetCurrentLogier(this string accessToken)
+        {
+            if (accessToken.IsNotNull())
+            {
+                var claims = JWTEncryption.ReadJwtToken(accessToken)?.Claims;
+                if (claims != null)
+                {
+                    var claimIdentity = new ClaimsIdentity("AuthenticationTypes.Federation");
+                    claimIdentity.AddClaims(claims);
+                    var claimsPrincipal = new ClaimsPrincipal(claimIdentity);
+                    var userId = claimsPrincipal.FindFirstValue("Id").ToGuid();
+                    var clientType = claimsPrincipal.FindFirstValue("ClientType").ToEnum<EnumClientType>();
+                    if (userId.HasValue && clientType.HasValue)
+                    {
+                        var user = await Db.GetRepository<User>().AsQueryable().AsNoTracking()
+                            .Where(it => it.Id == userId)
+                            .FirstOrDefaultAsync();
+                        if (user != null)
+                        {
+                            var logier = user.GetCurrentLogier(clientType.Value);
+                            return logier;
+                        }
+                    }
+                }
+            }
+            return null;
+        }
+
+        /// <summary>
+        /// 鑾峰彇褰撳墠鐧诲綍鐢ㄦ埛
+        /// </summary>
         /// <returns></returns>
         public static CurrentLogier GetCurrentLogier()
         {
diff --git a/FlexJobApi.Core/Utils/ResourceUtils/ResourceHttpProvider/DefaultResourceHttpProvider.cs b/FlexJobApi.Core/Utils/ResourceUtils/ResourceHttpProvider/DefaultResourceHttpProvider.cs
index 936b8b2..cd2c0a2 100644
--- a/FlexJobApi.Core/Utils/ResourceUtils/ResourceHttpProvider/DefaultResourceHttpProvider.cs
+++ b/FlexJobApi.Core/Utils/ResourceUtils/ResourceHttpProvider/DefaultResourceHttpProvider.cs
@@ -1,9 +1,13 @@
 锘縰sing Furion;
+using Furion.DatabaseAccessor;
+using Furion.DataEncryption;
 using Furion.HttpRemote;
+using Microsoft.EntityFrameworkCore;
 using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Net.Http.Headers;
+using System.Security.Claims;
 using System.Text;
 using System.Threading.Tasks;
 
@@ -16,21 +20,54 @@
     {
         public async Task<string> SendAsStringAsync(HttpRequestBuilder builder)
         {
-            var token = App.HttpContext.Request.Headers["Authorization"].ToString();
-            if (token.IsNotNull())
+            var httpRemoteService = App.GetRequiredService<IHttpRemoteService>();
+            builder = WithHeader(builder, "Authorization");
+            builder = WithHeader(builder, "X-Authorization");
+            var response = await httpRemoteService.SendAsStringAsync(builder);
+            try
             {
-                builder = builder.WithHeader("Authorization", token);
-                //builder = builder.AddAuthentication(new AuthenticationHeaderValue("Authorization", token));
+                var result = response.JsonTo(new
+                {
+                    Code = 0
+                });
+                if (result.Code == 401)
+                {
+                    var accessToken = GetHeaderValue(builder, "Authorization");
+                    var logier = await accessToken.GetCurrentLogier();
+                    if (logier != null)
+                    {
+                        builder = WithHeader(builder, "Authorization", logier.AccessToken);
+                        builder = WithHeader(builder, "X-Authorization", logier.RefreshToken);
+                        response = await httpRemoteService.SendAsStringAsync(builder);
+                    }
+                }
             }
+            catch { }
+            return response;
+        }
 
-            var refreshToken = App.HttpContext.Request.Headers["X-Authorization"].ToString();
-            if (refreshToken.IsNotNull())
+        public string GetHeaderValue(HttpRequestBuilder builder, string name)
+        {
+            string value = null;
+            if (builder.Headers.ContainsKey(name))
             {
-                builder = builder.WithHeader("X-Authorization", refreshToken);
-                //builder = builder.AddAuthentication(new AuthenticationHeaderValue("X-Authorization", refreshToken));
+                value = builder.Headers[name].ToString();
             }
+            else if (App.HttpContext.Request.Headers.ContainsKey(name))
+            {
+                value = App.HttpContext.Request.Headers[name].ToString();
+            }
+            return value;
+        }
 
-            return await App.GetRequiredService<IHttpRemoteService>().SendAsStringAsync(builder);
+        private HttpRequestBuilder WithHeader(HttpRequestBuilder builder, string name, string value = null)
+        {
+            value ??= GetHeaderValue(builder, name);
+            if (value.IsNotNull())
+            {
+                builder = builder.WithHeader(name, value);
+            }
+            return builder;
         }
     }
 }
diff --git a/FlexJobApi.Core/Utils/ResourceUtils/ResourceHttpProvider/ElectronSignServerResourceHttpProvider.cs b/FlexJobApi.Core/Utils/ResourceUtils/ResourceHttpProvider/ElectronSignServerResourceHttpProvider.cs
index f444131..3c1d186 100644
--- a/FlexJobApi.Core/Utils/ResourceUtils/ResourceHttpProvider/ElectronSignServerResourceHttpProvider.cs
+++ b/FlexJobApi.Core/Utils/ResourceUtils/ResourceHttpProvider/ElectronSignServerResourceHttpProvider.cs
@@ -49,8 +49,8 @@
                 var result = httpRemoteService.PostAs<ElectronSignServerResult<IdentityModelTokenCacheItem>>($"{builder.RequestUri.Scheme}://{builder.RequestUri.Authority}/api/Account/GetTokenForWeb", builder =>
                     builder.SetJsonContent(new AccessRequestDto
                     {
-                        UserName = "system",
-                        UserPassword = "qwe321"
+                        UserName = App.GetConfig<string>("ElectronSignServer:Account"),
+                        UserPassword = App.GetConfig<string>("ElectronSignServer:Password")
                     }));
                 if (result.Success)
                 {
@@ -70,13 +70,14 @@
                 var model = token.JsonTo<TokenDataModel>();
                 if (model.AccessToken.IsNotNull())
                 {
-                    builder = builder.AddAuthentication(new AuthenticationHeaderValue("Authorization", model.AccessToken));
+                    builder = builder.WithHeader("Authorization", model.AccessToken);
                 }
 
                 if (model.RefreshToken.IsNotNull())
                 {
-                    builder = builder.AddAuthentication(new AuthenticationHeaderValue("X-Authorization", model.RefreshToken));
+                    builder = builder.WithHeader("X-Authorization", model.RefreshToken);
                 }
+
             }
             return builder;
         }
diff --git a/FlexJobApi.Core/Utils/ResourceUtils/ResourceHttpProvider/SystemUserResourceHttpProvider.cs b/FlexJobApi.Core/Utils/ResourceUtils/ResourceHttpProvider/SystemUserResourceHttpProvider.cs
index 3afc9dd..08ea4c4 100644
--- a/FlexJobApi.Core/Utils/ResourceUtils/ResourceHttpProvider/SystemUserResourceHttpProvider.cs
+++ b/FlexJobApi.Core/Utils/ResourceUtils/ResourceHttpProvider/SystemUserResourceHttpProvider.cs
@@ -65,12 +65,12 @@
                 var model = token.JsonTo<TokenDataModel>();
                 if (model.AccessToken.IsNotNull())
                 {
-                    builder = builder.AddAuthentication(new AuthenticationHeaderValue("Authorization", model.AccessToken));
+                    builder = builder.WithHeader("Authorization", model.AccessToken);
                 }
 
                 if (model.RefreshToken.IsNotNull())
                 {
-                    builder = builder.AddAuthentication(new AuthenticationHeaderValue("X-Authorization", model.RefreshToken));
+                    builder = builder.WithHeader("X-Authorization", model.RefreshToken);
                 }
             }
             return builder;
diff --git a/FlexJobApi.Core/Utils/ResourceUtils/ResourceHttpUtils.cs b/FlexJobApi.Core/Utils/ResourceUtils/ResourceHttpUtils.cs
index 1983841..04199ce 100644
--- a/FlexJobApi.Core/Utils/ResourceUtils/ResourceHttpUtils.cs
+++ b/FlexJobApi.Core/Utils/ResourceUtils/ResourceHttpUtils.cs
@@ -7,6 +7,7 @@
 using Microsoft.EntityFrameworkCore;
 using Microsoft.Extensions.Caching.Distributed;
 using RabbitMQ.Client;
+using RTools_NTS.Util;
 using System;
 using System.Collections.Generic;
 using System.ComponentModel.Design;
@@ -20,16 +21,45 @@
 {
     public static class ResourceHttpUtils
     {
-        public static async Task<string> SendHttpAsync(this object request, string serviceName, string route, EnumResourceMethod method, EnumResourceHttpProvider? provider = null)
+        /// <summary>
+        /// 鍙戦�佽姹�
+        /// </summary>
+        /// <param name="request">璇锋眰鍙傛暟</param>
+        /// <param name="serviceName">鏈嶅姟鍚嶇О</param>
+        /// <param name="route">璺敱</param>
+        /// <param name="method">璇锋眰鏂瑰紡</param>
+        /// <param name="provider">璧勬簮鎻愪緵鑰�</param>
+        /// <param name="accessToken">璁块棶浠ょ墝</param>
+        /// <param name="refreshToken">鍒锋柊浠ょ墝</param>
+        /// <returns></returns>
+        public static async Task<string> SendHttpAsync(
+            this object request, 
+            string serviceName, 
+            string route, 
+            EnumResourceMethod method, 
+            EnumResourceHttpProvider? provider = null, 
+            string accessToken = null,
+            string refreshToken = null)
         {
             serviceName = App.GetConfig<string>($"{serviceName}:ServiceName");
             var url = await GetUrl(serviceName, route);
-            var builder = HttpRequestBuilder.Create(method.GetMethod(), url);
+            var builder = HttpRequestBuilder.Create(method.GetHttpMethod(), url);
+
             if (method == EnumResourceMethod.Get)
                 builder = builder.WithQueryParameters(request);
             else
                 builder = builder.SetJsonContent(request);
-            IResourceHttpProvider httpProvider = 
+
+            if (accessToken.IsNotNull())
+            {
+                builder = builder.WithHeader("Authorization", accessToken);
+            }
+            if (refreshToken.IsNotNull())
+            {
+                builder = builder.WithHeader("X-Authorization", refreshToken);
+            }
+
+            IResourceHttpProvider httpProvider =
                 provider == EnumResourceHttpProvider.SystemUser
                 ? new SystemUserResourceHttpProvider()
                 : provider == EnumResourceHttpProvider.ElectronSignServer
@@ -41,7 +71,17 @@
             return response;
         }
 
-        public static async Task<TResponse> SendHttpAsync<TRequest, TResponse>(this TRequest request, EnumResourceHttpProvider? provider = null)
+        /// <summary>
+        /// 鍙戦�佽姹�
+        /// </summary>
+        /// <typeparam name="TRequest"></typeparam>
+        /// <typeparam name="TResponse"></typeparam>
+        /// <param name="request"></param>
+        /// <param name="provider"></param>
+        /// <returns></returns>
+        public static async Task<TResponse> SendHttpAsync<TRequest, TResponse>(
+            this TRequest request, 
+            EnumResourceHttpProvider? provider = null)
         {
             var requestType = typeof(TRequest);
             var resourceAttribute = requestType.GetCustomAttribute<ResourceAttribute>();
@@ -75,7 +115,12 @@
             return response;
         }
 
-        public static HttpMethod GetMethod(this EnumResourceMethod method)
+        /// <summary>
+        /// 鑾峰彇璇锋眰鏂瑰紡
+        /// </summary>
+        /// <param name="method"></param>
+        /// <returns></returns>
+        public static HttpMethod GetHttpMethod(this EnumResourceMethod method)
         {
             switch (method)
             {
@@ -92,6 +137,12 @@
             }
         }
 
+        /// <summary>
+        /// 鑾峰彇鍋ュ悍鏈嶅姟鍦板潃
+        /// </summary>
+        /// <param name="serviceName"></param>
+        /// <param name="route"></param>
+        /// <returns></returns>
         public static async Task<string> GetUrl(string serviceName, string route)
         {
             var domain = await GetHealthyServiceDomain(serviceName);
diff --git a/FlexJobApi.UserServer.Application/Auths/Commands/LoginCommandHandler.cs b/FlexJobApi.UserServer.Application/Auths/Commands/LoginCommandHandler.cs
index 5e369b4..9150fa8 100644
--- a/FlexJobApi.UserServer.Application/Auths/Commands/LoginCommandHandler.cs
+++ b/FlexJobApi.UserServer.Application/Auths/Commands/LoginCommandHandler.cs
@@ -54,7 +54,7 @@
                 throw Oops.Oh(EnumUserErrorCodeType.u1000);
             if (user.Status == EnumUserStatus.Disabled)
                 throw Oops.Oh(EnumUserErrorCodeType.u1001);
-            return GetCurrentLogier(user, request.ClientType);
+            return user.GetCurrentLogier(request.ClientType);
         }
 
         /// <summary>
@@ -78,7 +78,7 @@
                 throw Oops.Oh(EnumUserErrorCodeType.u1000);
             if (user.Status == EnumUserStatus.Disabled)
                 throw Oops.Oh(EnumUserErrorCodeType.u1001);
-            return GetCurrentLogier(user, request.ClientType);
+            return user.GetCurrentLogier(request.ClientType);
         }
 
         /// <summary>
@@ -113,7 +113,7 @@
                 throw Oops.Oh(EnumUserErrorCodeType.u1000);
             if (user.Status == EnumUserStatus.Disabled)
                 throw Oops.Oh(EnumUserErrorCodeType.u1001);
-            return GetCurrentLogier(user, EnumClientType.Wxmp, snsJscode2session.session_key);
+            return user.GetCurrentLogier(EnumClientType.Wxmp, snsJscode2session.session_key);
         }
 
         /// <summary>
@@ -218,14 +218,14 @@
                 {
                     bindPhoneNumberUser.WxmpOpenId = user.WxmpOpenId;
                     await rep.DeleteAsync(user);
-                    return GetCurrentLogier(bindPhoneNumberUser, EnumClientType.Wxmp);
+                    return bindPhoneNumberUser.GetCurrentLogier(EnumClientType.Wxmp);
                 }
                 else if (bindPhoneNumberUser.WxmpOpenId != user.WxmpOpenId)
                 {
                     throw Oops.Oh(EnumUserErrorCodeType.u1120);
                 }
             }
-            return GetCurrentLogier(user, EnumClientType.Wxmp);
+            return user.GetCurrentLogier(EnumClientType.Wxmp);
         }
 
         /// <summary>
@@ -314,39 +314,6 @@
             model.CollectedUserCount = collects.Count(it => it.IsCollected);
             model.ContactedRecordCount = collects.Count(it => it.IsContacted);
             return model;
-        }
-
-        /// <summary>
-        /// 鑾峰彇褰撳墠鐧诲綍鐢ㄦ埛
-        /// </summary>
-        /// <param name="user"></param>
-        /// <param name="clientType"></param>
-        /// <param name="session_key"></param>
-        /// <returns></returns>
-        private LoginCommandCallback GetCurrentLogier(User user, EnumClientType clientType, string? session_key = null)
-        {
-            var logier = new CurrentLogier
-            {
-                Id = user.Id,
-                Avatar = user.Avatar,
-                Name = user.Name,
-                UserName = user.UserName,
-                PhoneNumber = user.PhoneNumber,
-                Level = user.Level,
-                Type = user.Type,
-                ClientType = clientType,
-                EnterpriseId = user.EnterpriseId,
-            };
-            JwtUtils.GenerateToken(logier);
-
-            return new LoginCommandCallback
-            {
-                Id = logier.Id,
-                AccessToken = logier.AccessToken,
-                RefreshToken = logier.RefreshToken,
-                SessionKey = session_key,
-                IsBindPhoneNumber = logier.PhoneNumber.IsNotNull()
-            };
         }
     }
 }
diff --git a/FlexJobApi.UserServer.Application/FlexJobApi.UserServer.Application.xml b/FlexJobApi.UserServer.Application/FlexJobApi.UserServer.Application.xml
index 3bc789e..adede66 100644
--- a/FlexJobApi.UserServer.Application/FlexJobApi.UserServer.Application.xml
+++ b/FlexJobApi.UserServer.Application/FlexJobApi.UserServer.Application.xml
@@ -79,15 +79,6 @@
             <param name="cancellationToken"></param>
             <returns></returns>
         </member>
-        <member name="M:FlexJobApi.UserServer.Application.LoginCommandHandler.GetCurrentLogier(FlexJobApi.Core.User,FlexJobApi.Core.EnumClientType,System.String)">
-            <summary>
-            鑾峰彇褰撳墠鐧诲綍鐢ㄦ埛
-            </summary>
-            <param name="user"></param>
-            <param name="clientType"></param>
-            <param name="session_key"></param>
-            <returns></returns>
-        </member>
         <member name="T:FlexJobApi.UserServer.Application.VerifyCodeCommandHandler">
             <summary>
             楠岃瘉鐮佸懡浠ゅ鐞嗗櫒
diff --git a/FlexJobApi.Web.Entry/FlexJobApi.Web.Entry.sln b/FlexJobApi.Web.Entry/FlexJobApi.Web.Entry.sln
new file mode 100644
index 0000000..4014a75
--- /dev/null
+++ b/FlexJobApi.Web.Entry/FlexJobApi.Web.Entry.sln
@@ -0,0 +1,24 @@
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.5.2.0
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FlexJobApi.Web.Entry", "FlexJobApi.Web.Entry.csproj", "{2590F706-6923-0B66-FA5B-FA0691CFE6C0}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Release|Any CPU = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{2590F706-6923-0B66-FA5B-FA0691CFE6C0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{2590F706-6923-0B66-FA5B-FA0691CFE6C0}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{2590F706-6923-0B66-FA5B-FA0691CFE6C0}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{2590F706-6923-0B66-FA5B-FA0691CFE6C0}.Release|Any CPU.Build.0 = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+	GlobalSection(ExtensibilityGlobals) = postSolution
+		SolutionGuid = {F871AC43-01DC-4184-B4B8-1B361367A910}
+	EndGlobalSection
+EndGlobal

--
Gitblit v1.9.1