641 lines
21 KiB

///-----------------------------------------------------------------------
/// <copyright file="ServiceBase.cs" company="Origtek">
/// 程式代號: ServiceBase
/// 程式名稱: ServiceBase
/// 程式說明:
/// 起始作者: Nelson
/// 起始日期: 2016/09/03 17:03:37
/// 最新修改人: Hercules
/// 最新修日期: 2017/05/15 12:24:49
/// </copyright>
///-----------------------------------------------------------------------
#region 程式異動記錄
/// xx.YYYY/MM/DD VER AUTHOR COMMENTS(說明修改的內容)
/// 01.2016/09/20 1.000 Justin.liu 底層訊息標準化(RV.385)
/// 02.2016/10/04 1.001 Hercules For Phase2 Develop(RV.574)
/// 03.2016/12/13 1.002 Hercules 移除Warning(RV.2014)
/// 04.2016/12/17 1.003 Hercules 實作1-1-1版號(RV.2105)
/// 05.2016/12/29 1.004 Hercules 上傳元件後端(RV.2310)
/// 06.2017/03/09 1.005 Hercules Commit DB LOCK底層(RV.3065)
/// 07.2017/05/09 1.006 Rexxar.eng bse Upload(RV.4198)
/// 08.2017/05/12 1.007 Rexxar.eng UploadFile(RV.4270)
/// 09.2017/05/12 1.008 Rexxar.eng UploadFile(RV.4272)
/// 10.2017/05/15 1.009 Hercules 檔案上傳 獨立成Helper(RV.4293)
#endregion
namespace CounsellorBL
{
using CounsellorBL.BLStructure;
using CounsellorBL.Common;
using log4net;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Caching.Memory;
using MonumentDefine;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using OT.COM.ArsenalDB;
using OT.COM.SignalerMessage;
using SoldierData.EnterprizeV4;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Net;
using System.Reflection;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using static CounsellorBL.Common.EntityBaseExtension;
/// <summary>
/// 類別名稱:ServiceBase
/// 類別說明:
/// 起始作者:
/// 起始日期:
/// 最新修改人:
/// 最新修改日:
/// </summary>
public class ServiceBase
{
private static string _LocalIP = null;
protected static string LocalIP
{
get
{
if (_LocalIP == null)
{
_LocalIP = GetLocalIPAddress();
}
return _LocalIP;
}
}
/// <summary>
/// 類別成員、類別屬性說明:Logger
/// </summary>
protected ILog Logger
{
get
{
if (_inst == null)
{
_inst = LogManager.GetLogger(this.GetType());
}
return _inst;
}
}
/// <summary>
/// 類別成員、類別屬性說明:_inst
/// </summary>
private ILog _inst = null;
/// <summary>
/// 類別成員、類別屬性說明:OriRequest
/// </summary>
public CRequestMessage OriRequest { get; set; }
/// <summary>
/// 類別成員、類別屬性說明:SERVICE
/// </summary>
public const string SERVICE = "service";
/// <summary>
/// 類別成員、類別屬性說明:_dicInitData
/// </summary>
protected Dictionary<string, object> _dicInitData { get; private set; }
/// <summary>
/// 類別成員、類別屬性說明:RootPath
/// </summary>
public static string RootPath { get; set; } = AppDomain.CurrentDomain.BaseDirectory;
/// <summary>
/// 函式名稱:SetRootPath
/// 函式說明:
/// 起始作者:
/// 起始日期:
/// 最新修改人:
/// 最新修改日:
/// </summary>
/// <param name="i_sRootPath">
/// 參數說明
/// </param>
/// <returns>
/// 回傳
/// </returns>
public static void SetRootPath(string i_sRootPath)
{
RootPath = i_sRootPath;
}
#region 1-1-1
/// <summary>
/// 類別成員、類別屬性說明:1-1-1 JS路徑
/// </summary>
protected virtual string JSPath => "NOT SET";
/// <summary>
/// 類別成員、類別屬性說明:1-1-1 HTML路徑
/// </summary>
protected virtual string HTMLPath => "NOT SET";
/// <summary>
/// 類別成員、類別屬性說明:1-1-1 JS Version
/// </summary>
protected string JSVersion => _getVersion(JSPath, "g_JSRevisionVersioin");
/// <summary>
/// 類別成員、類別屬性說明:1-1-1 JS Version
/// </summary>
protected string HTMLVersion => _getVersion(HTMLPath, "g_HTMLRevisionVersioin");
/// <summary>
/// 類別成員、類別屬性說明:取得Service版本號
/// </summary>
protected string ServiceVersion => ParseServiceVersion();
/// <summary>
/// 函式名稱:_getVersion
/// 函式說明:
/// 起始作者:
/// 起始日期:
/// 最新修改人:
/// 最新修改日:
/// </summary>
/// <param name="i_sPath"></param>
/// <param name="i_sPattern">
/// 參數說明
/// </param>
/// <returns>
/// 回傳
/// </returns>
private static string _getVersion(string i_sPath, string i_sPattern)
{
string sRes = "-1";
do
{
if (i_sPath == "NOT SET")
{
break;
}
string sPath = System.IO.Path.Combine(RootPath, i_sPath);
if (!System.IO.File.Exists(sPath))
{
break;
}
string sContent = System.IO.File.ReadAllText(sPath);
int nIdx = sContent.LastIndexOf(i_sPattern, StringComparison.OrdinalIgnoreCase);
if (nIdx == -1)
{
break;
}
int nVersionStart = sContent.IndexOf('"', nIdx);
if (nVersionStart == -1)
{
nVersionStart = sContent.IndexOf('\'', nIdx);
if (nVersionStart == -1)
{
break;
}
}
nVersionStart++;
int nVersionEnd = sContent.IndexOf('"', nVersionStart);
if (nVersionEnd == -1)
{
nVersionEnd = sContent.IndexOf('\'', nVersionStart);
if (nVersionEnd == -1)
{
break;
}
}
sRes = sContent[nVersionStart..nVersionEnd];
}
while (false);
return sRes;
}
/// <summary>
/// 函式名稱:ParseServiceVersion
/// 函式說明:取得Service版本號
/// 起始作者:
/// 起始日期:
/// 最新修改人:
/// 最新修改日:
/// </summary>
/// <param name="參數名稱">
/// 參數說明
/// </param>
/// <returns>版號。 -1表示沒有取得版本號</returns>
/// <summary>
protected string ParseServiceVersion()
{
string sRes = "-1";
PropertyInfo pi = this.GetType().GetProperty("ServiceRevisionVersion");
if (pi != null)
{
object oValue = pi.GetValue(this, null);
if (oValue != null)
{
sRes = oValue.ToString();
}
}
return sRes;
}
#endregion 1-1-1
/// <summary>
/// 函式名稱:Entry
/// 函式說明:
/// 起始作者:
/// 起始日期:
/// 最新修改人:
/// 最新修改日:
/// </summary>
/// <param name="i_crm">
/// 參數說明
/// </param>
/// <returns>
/// 回傳
/// </returns>
public CResponseMessage Entry(CRequestMessage i_crm)
{
string sMsg = null;
CResponseMessage crm = null;
do
{
try
{
if (i_crm == null)
{
sMsg = MessageWording.PARAM_NOT_EXPECTED;
break;
}
SoldierData.EnterprizeV4.tb_sys_session userSession = null;
// Find Native Method
string sFunctionName = i_crm.method;
MethodInfo mi = this.GetType().GetMethod(sFunctionName);
if (null == mi)
{
sMsg = MessageWording.METHOD_NO_MATCH; //NO MATCH METHOD
break;
}
#if DEBUG
System.Diagnostics.Debug.Write($"Process {this.GetType().Name}::{sFunctionName}");
#endif
AuthAttribute auClass = EntityUtil.GetClassAttribute<AuthAttribute>(this.GetType());
object[] oaAttr = mi.GetCustomAttributes(true);
bool bCheck = true;
if (auClass != null)
{
bCheck = auClass.TokenCheck;
}
if (oaAttr != null)
{
foreach (AuthAttribute oAttr in oaAttr)
{
if (oAttr is AuthAttribute aa)
{
bCheck = oAttr.TokenCheck;
break;
}
}
}
if (bCheck)
{
if (this is DBService dbsCur)
{
CResponseMessage crmToken = dbsCur.CheckTokenWithCRequestMessage(i_crm, out Dictionary<string, object> _);
if (EResponseResult.RR_FALSE == crmToken.result)
{
sMsg = crmToken.msg;
break;
}
else
{
userSession = crmToken.param[BLWording.SESSION_USER] as SoldierData.EnterprizeV4.tb_sys_session;
i_crm.customparam.Add(BLWording.SESSION_USER, userSession);
}
}
}
else
{
DBService dbsCur = this as DBService;
dbsCur?.SetupGuestSession(i_crm);
}
// Make sure that reflection service method can only input CRequestMessage, output CResponseMessage!!
// Even default parameter is also not allowed!
crm = ((Func<CRequestMessage, CResponseMessage>)Delegate.CreateDelegate(typeof(Func<CRequestMessage, CResponseMessage>), this, mi))(i_crm);
}
catch (Exception ex)
{
Logger.Error(new StringBuilder().Append("StackTrace: " + ex.StackTrace + ", Exception Information: " + ex.ToString()).ToString());
}
}
while (false);
if (null != sMsg)
{
crm = new CErrorResponseMessage(sMsg, i_crm);
}
return crm;
}
/// <summary>
/// 函式名稱:MakeDebugFullDump
/// 函式說明:
/// 起始作者:
/// 起始日期:
/// 最新修改人:
/// 最新修改日:
/// </summary>
/// <param name="i_sMsg"></param>
/// <param name="i_crm">
/// 參數說明
/// </param>
/// <returns>
/// 回傳
/// </returns>
public static string MakeDebugFullDump(string i_sMsg, CRequestMessage i_crm)
{
string sRes = Environment.NewLine;
sRes += "**** Start Dump **************************" + Environment.NewLine;
sRes += string.Format(CultureInfo.CurrentCulture, "Custom Message:{0}", i_sMsg) + Environment.NewLine;
sRes += string.Format(CultureInfo.CurrentCulture, "Parameter Json:{0}", JsonConvert.SerializeObject(i_crm)) + Environment.NewLine;
sRes += "Call Stack Dump:" + Environment.NewLine;
sRes += Environment.StackTrace + Environment.NewLine;
sRes += "*****End Dump *************************" + Environment.NewLine;
return sRes;
}
/// <summary>
/// 函式名稱:JProperty2Dic
/// 函式說明:
/// 起始作者:
/// 起始日期:
/// 最新修改人:
/// 最新修改日:
/// </summary>
/// <param name="i_jpData"></param>
/// <param name="io_dicData">
/// 參數說明
/// </param>
/// <returns>
/// 回傳
/// </returns>
public static string JProperty2Dic(JObject i_jpData, ref Dictionary<string, object> io_dicData)
{
string sRes = null;
Dictionary<string, object> dicRes = new Dictionary<string, object>();
if (i_jpData != null)
{
foreach (JProperty property in i_jpData.Properties())
{
JToken jv = property.Value;
dicRes.Add(property.Name, jv.Value<string>());
}
}
else
{
sRes = MessageWording.PARAM_NOT_EXPECTED;
}
io_dicData = dicRes;
return sRes;
}
public virtual FileUploadInfo GetFileUploadInfo()
{
return new FileUploadInfo()
{
Logger = Logger,
RootPath = RootPath
};
}
protected static EColumnFilter getQueryCustomerFilter(CRequestMessage i_crmInput)
{
EColumnFilter ecfRes = EColumnFilter.ES_NO;
if (i_crmInput != null && i_crmInput.customparam != null && i_crmInput.customparam.ContainsKey(BLWording.COLUMN_FILTER))
{
ecfRes = (EColumnFilter)Enum.Parse(typeof(EColumnFilter),
i_crmInput.customparam[BLWording.COLUMN_FILTER].ToString());
}
return ecfRes;
}
public IMemoryCache GetMemoryCache()
{
IMemoryCache imc = null;
if (OriRequest != null && OriRequest.system_param.ContainsKey(typeof(ControllDataPack).Name))
{
ControllDataPack cdp = OriRequest.system_param[typeof(ControllDataPack).Name] as ControllDataPack;
if (cdp.MemoryCache != null)
{
imc = cdp.MemoryCache;
}
}
return imc;
}
//public IDistributedCache GetDistributedCache()
//{
// IDistributedCache imc = null;
// if (OriRequest != null && OriRequest.system_param.ContainsKey(typeof(ControllDataPack).Name))
// {
// ControllDataPack cdp = OriRequest.system_param[typeof(ControllDataPack).Name] as ControllDataPack;
// if (cdp.MemoryCache != null)
// {
// imc = cdp.DistributedCache;
// }
// }
// return imc;
//}
protected byte[] ObjectToByteArray(object obj)
{
var binaryFormatter = new BinaryFormatter();
using (var memoryStream = new MemoryStream())
{
binaryFormatter.Serialize(memoryStream, obj);
return memoryStream.ToArray();
}
}
protected T ByteArrayToObject<T>(byte[] bytes)
{
using (var memoryStream = new MemoryStream())
{
var binaryFormatter = new BinaryFormatter();
memoryStream.Write(bytes, 0, bytes.Length);
memoryStream.Seek(0, SeekOrigin.Begin);
var obj = binaryFormatter.Deserialize(memoryStream);
return (T)obj;
}
}
/// <summary>
/// 函式名稱:_fetchString
/// 函式說明:
/// 起始作者:
/// 起始日期:
/// 最新修改人:
/// 最新修改日:
/// </summary>
/// <param name="i_crmInput"></param>
/// <param name="i_sKey">
/// 參數說明
/// </param>
/// <returns>
/// 回傳
/// </returns>
protected static string _fetchString(CRequestMessage i_crmInput, string i_sKey)
{
return i_crmInput != null ? _fetchString(i_crmInput.param, i_sKey) : null;
}
/// <summary>
/// 函式名稱:_fetchString
/// 函式說明:
/// 起始作者:
/// 起始日期:
/// 最新修改人:
/// 最新修改日:
/// </summary>
/// <param name="i_dic"></param>
/// <param name="i_sKey">
/// 參數說明
/// </param>
/// <returns>
/// 回傳
/// </returns>
protected static string _fetchString(Dictionary<string, object> i_dic, string i_sKey)
{
string sRes = null;
if (i_dic != null && i_dic.ContainsKey(i_sKey))
{
object obj = i_dic[i_sKey];
if (null != obj)
{
sRes = obj.ToString();
}
}
return sRes;
}
public static string GetLocalIPAddress()
{
var host = Dns.GetHostEntry(Dns.GetHostName());
string sIPRes = null;
foreach (var ip in host.AddressList)
{
if (ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
{
sIPRes = ip.ToString();
}
}
return sIPRes;
}
protected static string getCommonParameter(CRequestMessage i_crmInput, string i_sRequestType, out JArray o_jaDataArray, out tb_sys_session o_sUserSession, bool i_bIsRequestTypeNeed = true)
{
string sMsg = null;
JArray jaDataArray = null;
tb_sys_session sUserSession = null;
// Leave exception for caller function
do
{
if (i_crmInput == null)
{
sMsg = MessageWording.PARAM_NOT_EXPECTED;
break;
}
if (i_sRequestType != null)
{
bool bFind = true;
if (i_crmInput.param == null ||
!i_crmInput.param.ContainsKey(i_sRequestType) ||
!(i_crmInput.param[i_sRequestType] is JArray))
{
bFind = false;
if (i_bIsRequestTypeNeed)
{
sMsg = MessageWording.PARAM_NOT_EXPECTED;
break;
}
}
if (bFind)
{
jaDataArray = i_crmInput.param[i_sRequestType] as JArray;
}
}
if (i_crmInput.customparam != null &&
i_crmInput.customparam.ContainsKey(BLWording.SESSION_USER))
{
sUserSession = i_crmInput.customparam[BLWording.SESSION_USER] as tb_sys_session;
}
}
while (false);
o_jaDataArray = jaDataArray ?? throw new NullReferenceException(nameof(jaDataArray) + ", " + MessageWording.PARAM_NOT_EXPECTED);
o_sUserSession = sUserSession ?? throw new NullReferenceException(nameof(sUserSession) + ", " + MessageWording.PARAM_NOT_EXPECTED);
return sMsg;
}
public static string GetRequestProgramID(CRequestMessage i_crmInput)
{
object oProgramID = i_crmInput != null && i_crmInput.customparam != null && i_crmInput.customparam.ContainsKey(BLWording.PROGRAMID) ? i_crmInput.customparam[BLWording.PROGRAMID] : null;
return oProgramID?.ToString();
}
public static string GetRequestMessage(Dictionary<string, object> i_dic)
{
object oMessage = i_dic != null && i_dic.ContainsKey(BLWording.MESSAGE) ? i_dic[BLWording.MESSAGE] : null;
return oMessage?.ToString();
}
}
}